• [LeetCode] Next Greater Element II | 循环数组查找下一个比某位置元素大的


    https://leetcode.com/problems/next-greater-element-ii/?tab=Description

    思路1:Brute Force

    简单粗暴的方法是遍历数组,对每一个位置的元素,往后查找第一个比它大的,走到终点再折回头部查找,直到回到该位置。

    Time complexity: O(n^2)
    Space complexity: O(1)

    ps. 本不报希望,然而leetcode允许该算法通过, C++ 652ms

    class Solution {
    public:
        vector<int> nextGreaterElements(vector<int>& nums) {
            if (nums.empty()) return vector<int>();
            
            int n = nums.size();
            vector<int> ret(n);
            for (int i = 0; i < n; ++i) {
                int next_greater = -1;
                for (int j = (i+1) % n; j != i; j = (j+1) % n) {
                    if (nums[j] > nums[i]) {
                        next_greater = nums[j];
                        break;
                    }
                }
                ret[i] = next_greater;
            }
            
            return ret;
        }
    };
    

    思路2:Stack

    单调栈是一种巧妙且有通用意义的技术(比如也可以用在求直方图最大矩形问题里)。开一个栈,先把数组第一个元素的下标压栈(注意是下标),然后从第二个元素开始遍历:

    1. 如果遍历到的当前元素大于栈顶,则说明我们发现了栈顶元素的next greater number,记录好结果后pop掉栈顶;并继续考察新的栈顶,重复这个过程;
    2. 否则直接把当前元素的下标压栈
    举例:数组[2,1,3,5,4]
    - 初始栈:[2 (注意实际操作时保留的是元素下标)
    - 1比栈顶(2)小,1入栈,栈:[2 1
    - 3比栈顶(1)大,1出栈,栈:[2  (记录1的next greater是3)
      - 3比栈顶(2)大,2出栈,栈空  (记录2的next greater是3)
      - 栈空,3入栈,栈:[3
    - 5比栈顶(3)大,3出栈,栈空    (记录3的next greater是5)
      - 栈空,5入栈,栈:[5
    - 4比栈顶(5)小,4入栈,栈:[5 4
    

    一次遍历完成后,栈中保存的是一个单调不增的序列(从栈底到栈顶),由于题目要求是循环查找,所以再进行第二次遍历,方法和第一次一样,为的是确定还留在栈中的元素的next greater number。第二次遍历结束后还留在栈中的那些可怜的家伙们,就是找不到next greater number的啦

    当然,可以把原数组复制一遍连到尾巴上,一次遍历大概也是可以的,不过这样就修改了输入参数。

    Time complexity: O(n)
    Space complexity: O(n)

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

    ps. leetcode C++ 140ms左右

  • 相关阅读:
    结构型设计模式——享元
    结构型设计模式——装饰模式
    结构型设计模式——外观
    结构型设计模式——桥接模式
    结构型设计模式——适配器模式(Go)
    创建型设计模式——工厂模式
    创建型设计模式——单例模式
    Linux03
    阅读《构建之法》八九十章
    作业五 5.2 5.3
  • 原文地址:https://www.cnblogs.com/ilovezyg/p/6477503.html
Copyright © 2020-2023  润新知