You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
class Solution {
public:
int maxWidthRamp(vector<int>& A) {
int n = A.size(), res = 0;
vector<int> idx;
for (int i = 0; i < n; ++i) {
if (idx.size() == 0 || A[i] < A[idx.back()]) {
idx.push_back(i);
} else {
int left = 0, right = (int)idx.size() - 1;
while (left < right) {
int mid = left + (right - left) / 2;
if (A[idx[mid]] > A[i]) {
left = mid + 1;
} else {
right = mid;
}
}
res = max(res, i - idx[right]);
}
}
return res;
}
};
Given an array
A
of integers, a ramp is a tuple(i, j)
for whichi < j
andA[i] <= A[j]
. The width of such a ramp isj - i
.Find the maximum width of a ramp in
A
. If one doesn't exist, return 0.Example 1:
Example 2:
Note:
2 <= A.length <= 50000
0 <= A[i] <= 50000
这道题说给了一个数组A,这里定义了一种叫做 Ramp 的范围 (i, j),满足
i < j
且A[i] <= A[j]
,而 ramp 就是j - i
,这里让求最宽的 ramp,若没有,则返回0。其实就是让在数组中找一前一后的两个数字,前面的数字小于等于后面的数字,且两个数字需要相距最远,让求这个最远的距离。二话不说,博主直接上暴力搜索了,遍历任意两个数字的组合,只要前面的数字小于等于后面的数字,用二者间的距离更新结果 res,结果超时了,后来加了些剪枝,还是超时。看来 OJ 根本不想放平方级的复杂度一丝生路。必须要要另谋出路了,先想一下,什么时侯不存在这个 ramp,就是当数组是严格递减的时候,那么不存在前面的数字小于等于后面的数字的情况,于是 ramp 是0,对于这种情况下平方级的复杂度基本都是白计算,难怪 OJ 不给过。其实这道题的优化解法应该是使用单调栈,可以参见博主之前的一篇总结帖 LeetCode Monotonous Stack Summary 单调栈小结。这里用一个数组 idx,来记录一个单调递减数组中数字的下标,遍历原数组A,对于每个遍历到的数字 A[i],判断若此时下标数组为空,或者当前数字 A[i] 小于该下标数组中最后一个坐标在A中表示的数字时,将当前坐标i加入 idx,继续保持单调递减的顺序。反之,若 A[i] 比较大,则可以用二分搜索法来找出单调递减数组中第一个小于 A[i] 的数字的坐标,这样就可以快速得到 ramp 的大小,并用来更新结果 res 即可,这样整体的复杂度就降到了 O(nlgn),从而完美通过 OJ,参见代码如下:Github 同步地址:
#962
参考资料:
https://leetcode.com/problems/maximum-width-ramp/
https://leetcode.com/problems/maximum-width-ramp/discuss/208348/JavaC%2B%2BPython-O(N)-Using-Stack
https://leetcode.com/problems/maximum-width-ramp/discuss/265765/Detailed-Explaination-of-all-the-three-approaches
LeetCode All in One 题目讲解汇总(持续更新中...)
The text was updated successfully, but these errors were encountered: