單調棧

一、單調棧定義

  • 單調遞增棧:數據出棧的序列爲單調遞增序列(比站內元素小就入棧,否則將棧中比當前元素小的元素彈出後再入棧)
  • 單調遞減棧:數據出棧的序列爲單調遞減序列(比站內元素大就入棧,否則將棧中比當前元素大的元素彈出後再入棧)

二、題目

(一)視野總和

【題目】

描敘:有 n 個人站隊,所有的人全部向右看,個子高的可以看到個子低的髮型,給出每個人的身高,問所有人能看到其他人發現總和是多少。

輸入:4 3 7 1
輸出:2

輸入:20,10,5,7,15,8,6
輸出:11

思路:每次入棧的時候,即棧頂元素大於入棧元素的時候,sum加上當前棧內元素個數。

	/**
     * 視野總和
     *描敘:有 n 個人站隊,所有的人全部向右看,個子高的可以看到個子低的髮型,
     * 給出每個人的身高,問所有人能看到其他人發現總和是多少。
     *
     * 輸入:4 3 7 1
     * 輸出:2
     *
     * 每次入棧的時候,即棧頂元素大於入棧元素的時候,總和加上當前棧內元素個數
     * */
    public int sightSum(int[] nums) {
        if (nums == null || nums.length==0) return 0;

        Stack<Integer> stack = new Stack<>();

        int i,sum;

        sum = 0;
        for (i=0; i<nums.length; i++) {
            // 棧爲空的時候,sum不變,只是加入元素
            if (stack.empty()) {
                stack.add(nums[i]);
            } else {
                // 棧不爲空,同時棧頂小於入棧元素
                while (!stack.empty() && stack.peek()<nums[i]) {
                    stack.pop();
                }
                sum += stack.size();
                stack.add(nums[i]);
            }
        }

        return sum;
    }

    public static void main(String[] args) {
        int[] a = {20,10,5,7,15,8,6};
        System.out.println(new MonotonousStack().sightSum(a));
    }

(二)下一個更大元素

【題目】

給定兩個沒有重複元素的數組 nums1 和 nums2 ,其中 nums1 是 nums2 的子集。找到 nums1 中每個元素在 nums2 中的下一個比其大的值。

nums1 中數字 x 的下一個更大元素是指 x 在 nums2 中對應位置的右邊的第一個比 x 大的元素。如果不存在,對應位置輸出 - 1。

【代碼】

public int[] nextGreaterElement(int[] nums1, int[] nums2) {

        if (nums1.length == 0 || nums2.length == 0)
            return new int[0];

        Stack<Integer> stack = new Stack<>();
        HashMap<Integer,Integer> map = new HashMap<>();

        int i;

        stack.add(nums2[0]);
        for (i=0; i<nums2.length; i++) {
            if (stack.peek()<nums2[i]) {
                
                while (!stack.empty() && stack.peek()<nums2[i]) {
                    map.put(stack.peek(),nums2[i]);
                    stack.pop();
                }
            }
            stack.add(nums2[i]);
        }

        int[] res = new int[nums1.length];
        for (i=0; i<nums1.length; i++) {
            if (map.containsKey(nums1[i])) {
                res[i] = map.get(nums1[i]);
            } else {
                res[i] = -1;
            }
        }

        return res;

    }

【思路】

我們可以忽略數組 nums1,先對將 nums2 中的每一個元素,求出其下一個更大的元素。隨後對於將這些答案放入哈希映射(HashMap)中,再遍歷數組 nums1,並直接找出答案。對於 nums2,我們可以使用單調棧來解決這個問題。

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