算法笔记之单调栈

1. 单调栈定义

从栈顶到栈底的元素是严格递增或递减的栈叫单调栈

2.单调栈用途

可以以 O(1) 的时间复杂度得知某个位置左右两侧比他大(或小)的数的位置和个数

3.单调栈应用

  1. 每日温度(来源leetcode

描述如下:

	请根据每日 气温 列表,重新生成一个列表。对应位置的输出为:要想观测到更高的气温,至少需要等待的天数。如果气温在这之后都不会升高,请在该位置用 0 来代替。

例如,给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]。

提示:气温 列表长度的范围是 [1, 30000]。每个气温的值的均为华氏度,都是在 [30, 100] 范围内的整数。

代码:

public int[] dailyTemperatures(int[] T) {
        int length = T.length;
        int[] ans = new int[length];
        Deque<Integer> stack = new LinkedList<Integer>();//存放未找到更高温的下标
        for (int i = 0; i < length; i++) {
            int temperature = T[i];
            while (!stack.isEmpty() && temperature > T[stack.peek()]) {//当前温度大于栈顶元素说明出现更高温
                int prevIndex = stack.pop();//栈顶元素出栈
                ans[prevIndex] = i - prevIndex;//用当前下标减去之前出现未更高温的下标,既需要等待的天数
            }
            stack.push(i);//下一个下标入栈
        }
        return ans;
    }
  1. 高楼大厦(来源lintcode
    描述如下
	小Q在周末的时候和他的小伙伴来到大城市逛街,一条步行街上有很多高楼,共有n座高楼排成一行,楼高用arr表示。
小Q从第一栋一直走到了最后一栋,小Q从来都没有见到这么多的楼,所以他想知道他在每栋楼的位置处能看到多少栋楼呢?(当前面的楼的高度大于等于后面的楼时,后面的楼将被挡住)
解释:
输入:[5,3,8,3,2,5]
输出:[3,3,5,4,4,4]
解释:
当小Q处于位置0时,他能看到位置0,1,2的3栋高楼。
当小Q位于位置1时,他能看到位置0,1,2的3栋高楼。
当小Q处于位置2时,他可以向前看到位置0,1处的楼,向后看到位置3,5处的楼,加上第3栋楼,共可看到5栋楼。
当小Q处于位置3时,他能看到位置2,3,4,5的4栋高楼。
当小Q处于位置4时,他能看到位置2,3,4,5的4栋高楼。
当小Q处于位置5时,他能看到位置2,3,4,5的4栋高楼。

代码:

    public int[] tallBuilding(int[] arr) {
        int[] result = new int[arr.length];
         for (int i = 0; i < arr.length; i++) {
            result[i] = 1;//能看到自身所在高楼初始为1
        }
       Stack<Integer> s1 = new Stack<>(); //从右往左能看到的楼
       Stack<Integer> s2 = new Stack<>();//从左往右能看到的楼
       for(int i = 0; i < arr.length; i++) {
            int j = arr.length - i - 1;//
            result[i] += s1.size(); 
            result[j] += s2.size();
            while (!s1.empty() && s1.peek() <= arr[i]) {
                s1.pop(); //把比当前所在楼小的都出栈
            }
            s1.add(arr[i]);//左边第一个总是能看到的
            while (!s2.empty() && s2.peek() <= arr[j]) {
                s2.pop();//把比当前所在楼小的都出栈
            }
            s2.add(arr[j]);//右边第一个总是能看到的
        }
        return result;
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值