題解——單調棧 單調棧題解

單調棧題解

單調棧結構

牛客鏈接

方法:單調棧

算法

這裏維護一個單調遞增棧,可以找到比當前元素要小的元
約定:當前元素 cur,棧頂元素 top,出棧的棧頂元素 tempTop

  • 遍歷數組
  • 如果當前元素大於棧頂元素,則入棧(入棧元素索引,而不是值)
  • 否則,將棧頂元素出棧,此時,離 tempTop 左邊最近且值比 tempTop 小的就是當前的棧頂元素 top,離 tempTop 右邊最近且值比 tempTop 小的就是當前元素 cur。 然後循環此過程,直到第二步條件滿足。
  • 遍歷數組結束後,最後將棧內元素按上述規則輸出
    private static void leftRightWay(int[] arr){
        int len = arr.length;
        int[] right = new int[len];
        int[] left = new int[len];
        Stack<Integer> stack = new Stack<>();
        for(int i = 0; i < len; i++) {
            while(!stack.empty() && arr[i] < arr[stack.peek()]) {
                int tempTop = stack.pop();
                left[tempTop] = stack.empty() ? -1 : stack.peek();
                right[tempTop] = i;
            }
            stack.push(i);
        }

        while(!stack.empty()) {
            int tempTop = stack.pop();
            left[tempTop] = stack.empty() ? -1 : stack.peek();
            right[tempTop] = -1;
        }

        for(int i = 0; i < len; i++) {
            System.out.println(left[i] + " " + right[i]);
        }
    }

複雜度

  • 時間複雜度:O(N),每個元素被處理兩次,其索引入棧和出棧。

739. 每日溫度

LeetCode 鏈接

方法一:動態規劃,詳解可去鏈接裏查看

    public int[] dailyTemperatures(int[] T) {
        int len = T.length;
        int[] result = new int[len];
        result[len - 1] = 0;
        for(int i = len - 2; i >= 0; i--) {
            for(int j = i + 1; j < len; j += result[j]) {
                // 重點在 j += result[j] 上
                // 當天溫度小於後一天溫度,那麼直接得出結果 1
                // 當天溫度大於後一天溫度,那麼就得比較 [比後一天溫度還要高的那一天],循環這個過程。
                // 如果後一天溫度的後面沒有比它大的了,那自然也不可能比當天溫度大了
                if (T[i] < T[j]) {
                    result[i] = j - i;
                    break;
                } else if (result[j] == 0) {
                    result[i] = 0;
                    break;
                }
            }
        }

        return result;
    }

方法二:單調棧

算法

維護一個單調遞減的棧即可,棧內存放的是元素索引

  • 遍歷數組
  • 如果當前元素小於棧頂元素,則入棧
  • 否則,將棧頂元素出棧,當前元素索引 - 棧頂元素 就是對應位置的結果
    public int[] dailyTemperatures(int[] T) {
        int len = T.length;
        int[] result = new int[len];
        Stack<Integer> stack = new Stack();
        for(int i = 0; i < len; i++) {
            while(!stack.empty() && T[i] > T[stack.peek()]) {
                int tempTop = stack.pop();
                result[tempTop] = i - tempTop;
            }
            stack.push(i);
        }

        while(!stack.empty()) {
            result[stack.pop()] = 0;
        }

        return result;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章