Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LeetCode] 962. Maximum Width Ramp #962

Open
grandyang opened this issue May 30, 2019 · 0 comments
Open

[LeetCode] 962. Maximum Width Ramp #962

grandyang opened this issue May 30, 2019 · 0 comments

Comments

@grandyang
Copy link
Owner

grandyang commented May 30, 2019

Given an array A of integers, a  ramp  is a tuple (i, j) for which i < j and A[i] <= A[j].  The width of such a ramp is j - i.

Find the maximum width of a ramp in A.  If one doesn't exist, return 0.

Example 1:

Input: [6,0,8,2,1,5]
Output: 4
Explanation:
The maximum width ramp is achieved at (i, j) = (1, 5): A[1] = 0 and A[5] = 5.

Example 2:

Input: [9,8,1,0,1,9,4,0,4,1]
Output: 7
Explanation:
The maximum width ramp is achieved at (i, j) = (2, 9): A[2] = 1 and A[9] = 1.

Note:

  1. 2 <= A.length <= 50000
  2. 0 <= A[i] <= 50000

这道题说给了一个数组A,这里定义了一种叫做 Ramp 的范围 (i, j),满足 i < jA[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,参见代码如下:

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;
    }
};

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 题目讲解汇总(持续更新中...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant