503.下一个更大元素 Ⅱ

503.下一个更大元素 Ⅱ

LeetCode题目:503.下一个更大元素 Ⅱ

思路分析

  • 题目大意:在循环数组中,寻找当前数字nums[i]的下一个比他大的数字。

  • 我的思路:

    • 朴素想法:遍历数组中每一个元素nums[i],再使用一层循环寻找比nums[i]大的那个数字nums[j]。可以将nums数组中的数字 重复一遍 以减少其他操作。
      • 时间复杂度:O(n^2)
    • 为了减少时间复杂度。我想,可以寻找严格单调递减区间。比如栗子,5 2 1 6,严格单调减区间是5 2 1,那么5 2 1的数字都是6。但是显然这种想法格局小了。因为可以轻松举出反例:5 2 1 4 6,显然单调减区间5 2 1的数字不能是4,显然54的数字是6,而2 1的数字是4
    • 然后,就没有思路了。用朴素想法写了一发,交上了。
  • 使用

    • 考虑栗子5 2 1 4 65 2 1是严格单调递减区间,直到碰到了一个比1大的数字4,此时,需要往前检索,直到找到第一个4小的数字545这个区间所有的数字(1 2)都寻找到了比它们大的数字4了,然后删除2 15 4继续组成一个严格单调递减区间。
    • 上述思路的实现可以借助
    • 维护这样一个严格单调递减区间,当遍历到数字nums[i]时,如果nums[i] < stack.top(),那么将nums[i]压到栈中;如果nums[i] >= stack.top(),将栈顶元素弹出直到nums[i] <= stack.top()或者栈空,然后将nums[i]压入栈中。
    • 显然,上述两种情况,无论如何都会将nums[i]压栈,因此,基本流程是:当遍历到nums[i]时,将栈顶元素弹出直到nums[i] <= stack.top()或者栈空,然后将nums[i]入栈。
    • 栈实现
      • 这里还有一个小技巧,单调栈应该存放的是下标,这样可以简化操作。
      • 显然,数组中的最大元素一定不回从栈中弹出。
      • 实现循环数组,可以不用直接操作nums数组,可以只对下标取模即可。

朴素想法

代码实现:

class Solution {
public:
    vector<int> nextGreaterElements(vector<int>& nums) {
        int n = nums.size();
        vector<int> ret(n, -1);
        for (int i = 0; i < n; i ++){
            nums.push_back(nums[i]);
        }
        for (int i = 0; i < n; i ++){
            int now = nums[i];
            for (int j = i + 1; j < 2*n; j ++){
                if (nums[j] > now){
                    ret[i] = nums[j];
                    break;
                }
            }
        }
        return ret;
    }
};
  • 没想到竟然过了!

执行用时:204 ms, 在所有 C++ 提交中击败了11.42%的用户
内存消耗:23 MB, 在所有 C++ 提交中击败了33.30%的用户

栈实现

class Solution {
public:
    vector<int> nextGreaterElements(vector<int>& nums) {
        int n = nums.size();
        vector<int> ret(n, -1);
        stack<int> st;
        for (int i = 0; i < 2*n; i ++){
            while (!st.empty() && nums[i % n] > nums[st.top()]){
                ret[st.top()] = nums[i % n];
                st.pop();
            }
            st.push(i % n);
        }
        return ret;
    }
};

时间复杂度:O(n)

执行用时:44 ms, 在所有 C++ 提交中击败了72.22%的用户
内存消耗:22.6 MB, 在所有 C++ 提交中击败了66.55%的用户

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值