class Solution {
public int maxWidthRamp(int[] A) {
int res = 0;
for(int i = 0;i < A.length;i++) {
int j = A.length-1;
while(i < j) {
if(A[i] <= A[j])
break;
j--;
}
res = Math.max(res, j-i);
}
return res;
}
}
这个思路很简单,也是我第一开始想到的,没有优化的思路,不过也可以通过测试,思路是:遍历数组,每次从右边找到第一个大于等于A[i]的索引 j然后每次遍历更新最大的j-i,最后将结果返回就可以了。
该思路可以优化,因为遍历时候i是逐渐增大的,所以如果我从后面找到一个索引j满足要求,我可以讲这个j记录下来,然后遍历i后面的数时候,j只需要走到上次记录的j的位置就可以了。
举个例子[3,7,6,4,8,5,2],i指向3,j指向5,是第一次遍历,那么在i指向下一个位置7时候,j只需要从后遍历最多到5就可以了,因为再往下遍历肯定会比上一次得到的宽度小。
class Solution {
public int maxWidthRamp(int[] A) {
int res = 0;
int maxJ = 0;
for(int i = 0;i < A.length;i++) {
int j = A.length-1;
while(i < j) {
if(j < maxJ)
break;
if(A[i] <= A[j])
break;
j--;
}
maxJ = Math.max(maxJ, j); //下一次到maxJ就可以break;
res = Math.max(res, j-i); //最终结果。
}
return res;
}
}
有小伙伴评论说超时了,好像确实超了,不过当时打周赛时候是可以通过的,可能更改了测试用例,现修改如下:
class Solution {
public int maxWidthRamp(int[] A) {
int n = A.length;
int i, j , max = 0;
int[] maxR = new int[n], minL = new int[n];
minL[0] = A[0];
for (i = 1; i < n; i++){
minL[i] = Math.min(A[i], minL[i - 1]);
}
maxR[n - 1] = A[n - 1];
for (j = n - 2; j >= 0; j--){
maxR[j] = Math.max(A[j], maxR[j + 1]);
}
i = 0; j = 0;
while (i < n && j < n){
if (minL[i] <= maxR[j]){
max = Math.max(max, j - i);
j++;
}else{
i++;
}
}
return max;
}
}