最大区间值

题目描述

给定一个数组序列,要求选出一个区间。使得该区间是所有区间中经过如下计算之后得出的值最大的一个:

计算规则:区间中最小的数✖️区间所有数的和

最程序输出经过计算的最大值即可,不需要输出具体的区间

如给定序列 [6,2,1] 经过计算后的最大值为:36

解题思路-java

​ 两个关键点是 区间中最小的数、区间所有数的和。单个元素可以被认为是一个区间。然后就是在找到区间中最小的数的同时,如何

计算其区间和。

public int getMax(int[] numbers) {
    
    
  if(numbers == null || numbers.length == 0) {
    
    
    return -1;
  }
  //  定义一个最大值
  int max = 0;
  int len = numbers.length;
  //  定义一个数组用来维护区间和,数组的默认值是0
  int[] sum = new int[len+1];
  
  // 计算出区间和
  for(int i = 1;i < len;i++) {
    
    
    sum[i] = numbers[i-1]+sum[i-1];
  }
  
  //  利用单调栈解法解决问题
  Stack<Integer> stack = new Stack<>();
  for(int i = 0;i < len;i++) {
    
    
    //  如果栈为空  或者  当前值大于等于栈中元素
    if(stack.isEmpty() || numbers[i] >= numbers[stack.peek()]) {
    
    
      // 把  数组下标存入栈中  存入数组下标方便计算区间和
      stack.push(i);
    } else {
    
    
      // 如果栈不为空 并且  当前元素小于等于栈中元素,开始进行计算
      while(!stack.isEmpty() && numbers[i] <= numbers[stack.peek()]) {
    
    
        //  开始对栈中元素进行计算
        int pop = stack.pop();
        //  寻找左边界,右边界为 当前  i...这里+1是因为栈中如果不为空,肯定是比所计算的元素更小的值
        int left = stack.isEmpty()?0:(stack.peek()+1);
        max = Math.max(max, numbers[pop]*(sum[i] - sum[left]));
      }
      // 计算完毕,把元素推入栈中
      stack.push(i);
    }
  }
  
  //  计算完毕之后,若栈不为空
  while(!stack.isEmpty()) {
    
    
    int pop = stack.pop();
    int left = stack.isEmpty()?0:(stack.peek()+1);
    max = Math.max(max, numbers[pop]*(sum[len] - sum[left]));
  }
  
  return max;
}
  • 测试结果
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/GoNewWay/article/details/115094389