单调栈

32 阅读1分钟

单调栈步骤:

解决 Next Greater Number 一类问题

  1. 遍历数组
    1. 弹出元素时的处理
    2. 元素入栈
  2. 最后处理栈中剩余的元素

有重复元素时的情况:

  1. 只求左侧Next Greater Number,无需处理重复元素,从右向左走单调栈即可。
  2. 只求右侧Next Greater Number,无需处理重复元素,从左向右走单调栈即可。
  3. 左右两侧Next Greater Number,栈中存储列表,入栈时判断重复元素进行处理。
public static int[][] getNearLessNoRepeat(int[] arr) {
   int[][] res = new int[arr.length][2];
   Deque<Integer> stack = new ArrayDeque<>();
   for (int i = 0; i < arr.length; i++) {
      // 弹出时的处理
      while (!stack.isEmpty() && arr[stack.peek()] > arr[i]) {
         int j = stack.pop();
         int left = stack.isEmpty() ? -1 : stack.peek();
         res[j][0] = left;
         res[j][1] = i;
      }
      // 入栈
      stack.push(i);
   }
   // 处理栈中剩余元素
   while(!stack.isEmpty()){
      int j = stack.pop();
      int left = stack.isEmpty() ? -1 : stack.peek();
      res[j][0] = left;
      res[j][1] = -1;
   }
   return res;
}

题目

给定一个只包含正数的数组arr,arr中任何一个子数组sub,一定都可以算出(sub累加和 )* (sub中的最小值)是什么,那么所有子数组中,这个值最大是多少?

  1. 遍历求前缀和数组
  2. 遍历,根据单调栈得到各元素的最大子数组区间范围。(左边第一个小的,右边第一个小的。)
  3. 根据前缀和及单调栈得到 元素i最大子数组的sum * i ,更新max。