求数组中满足a[i]<a[j]的相距最远的元素

求数组中满足以下条件的相距最远的元素(即j - i 的值最大):

1. a[i] < a[j]

2. i < j

题目出处:LeetCode

 

(按ctrl + A查看提示和代码)

提示:可以在O(N)时间和O(N)空间复杂度内解决。

 

解法:

首先我们可以用一个长度为N的数组RMax记录从每一个位置i开始往后最大的元素。

从数组末端开始往前遍历,对于每个位置i的元素:

1) 如果它比i+1位置元素小,那么i处的元素max可以被i+1处覆盖。因为a[i] < a[i+1],如果存在a[i]之前的某个元素a[k] < a[i],那么必然也有a[k] < a[i+1],且i + 1 - k > i - k, 于是a[i+1]是一个更好的选择。

2) 如果比i+1位置的元素大,我们将i处的max元素置为a[i],因为虽然a[i]比a[i+1]位置靠前,但其值较大,可能匹配到前面更多的元素。

当遍历完成,我们得到了一个降序的数组RMax。

然后我们开始从头遍历数组分别设置两个指针指向原数组a和辅助数组RMax的头,取数组中的元素a[i],不断和RMax里的元素比较,对于a[i]<RMax[j],我们可以继续用a[i]跟下一个元素RMax[j+1]比较,因为RMax是降序的,当a[i]和RMax的某个元素不匹配时,此时i, j的距离应该就是a[i]能到达的最大距离,后续不可能再有比a[i]大的元素了。此时可以继续用a[i+1]和RMax比较,如果a[i+1] < a[i],则可能匹配到更后面的元素。

如此循环继续。同时用一个maxDist变量记录a[i]失配时i-j的最大值。

C++代码:

int GetMaxDist(int *a, int len){
    if(!a || len < 2) return 0;
    int *RMax = new int[len];
    RMax[len-1] = a[len-1];
    for(int i = len-2; i >= 0; --i){
        RMax[i] = a[i] > RMax[i +1]?a[i]:RMax[i+1];
    }
    int maxDist = 0, dist = 0, c = a[0];
    for(int i = 1; i < len; ++i){
        if(c < RMax[i]){
            dist++;
        }else{
            c = a[i];
            if(dist > maxDist) maxDist = dist;
            dist = 0;
        }       
    }
    if(dist > maxDist) maxDist = dist;
    return maxDist;
}

posted on 2011-12-19 18:30  谢绝围观  阅读(238)  评论(0编辑  收藏  举报

导航