数据结构-单调栈

1 定义

栈中数据呈现单调性的栈,叫做单调栈。

2 分类

(1)单调递增栈:从栈底到栈顶,元素从小到大的栈。

数据结构-单调栈_第1张图片

(2)单调递减栈:从栈底到栈顶,元素从大到小的栈。

数据结构-单调栈_第2张图片

3 解决问题

(1)单调递增栈:找出数组所有元素,下一个比它小的元素。

(2)单调递减栈:找出数组所有元素,下一个比它大的元素。

4 实际应用:找到数组元素下一个比它大的元素

示例1:输入:[2,1,5] ,输出:[5,5,0]

示例2:输入:[2,7,4,3,5],输出:[7,0,5,5,0]

解法一:暴力破解

遍历数组每个元素后面的元素,找出第一个比它大的元素。时间复杂度是 O(n^2)。

public static int[] nextLargerForce(int[] arr) {。
    int[] res = new int[arr.length];
    for (int i = 0; i < arr.length - 1; i++) {
        for (int j = i + 1; j < arr.length; j++) {
            if (arr[i] < arr[j]) {
                res[i] = arr[j];
                break;
            }
        }
    }
    return res;
}

解法二:单调递减栈

只遍历一遍数组就找到所有元素的目标元素,时间复杂度是O(n)。

思路:遍历数组元素依次入栈。如果当前元素小于/等于栈顶元素,当前元素直接入栈;否则栈顶元素出栈,并且确定了栈顶元素的目标元素就是当前元素。

注意:入栈的是数组下标,不是数组元素。

具体的代码实现如下:

public static int[] nextLargerStack(int[] arr) {
    Stack stack = new Stack<>();
    int[] res = new int[arr.length];
    // 遍历一遍数组就可以了
    for (int i = 0; i < arr.length; i++) {
        while (!stack.isEmpty() && arr[i] > arr[stack.peek()]) {
            int index = stack.pop();
            res[index] = arr[i];
        }
        stack.add(i);
    }
    return res;
}

举例:

拿数组[2,7,4,3,5]为例

数据结构-单调栈_第3张图片

第一次循环:栈为空,arr[0]直接入栈;

第二次循环:arr[1]跟栈顶元素比较,大于栈顶元素,栈顶元素arr[0]出栈,arr[0]目标元素是arr[1];

栈为空,arr[1]入栈;

第三次循环:arr[2]跟栈顶元素比较,小于栈顶元素,arr[2]直接入栈;

第四次循环:arr[3]跟栈顶元素比较,小于栈顶元素,arr[3]直接入栈;

第五次循环:arr[4]跟栈顶元素比较,大于栈顶元素,栈顶元素arr[3]出栈,确定arr[3]目标元素是arr[4];

arr[4]跟栈顶元素比较,大于栈顶元素,栈顶元素arr[2]出栈,确定arr[2]目标元素是arr[4];

arr[4]跟栈顶元素比较,小于栈顶元素,arr[4]入栈。

5 类似题目

LeetCode1019:下一个比它大的元素。

LeetCode739:每日温度。

LeetCode84:柱状图中最大的矩形。

LeetCode42:接雨水。

你可能感兴趣的:(算法,算法,java)