zoukankan      html  css  js  c++  java
  • 求最小数 * 区间和最大值

    来源:字节跳动编程题
    大意:找出一个数组中区间最小数*区间和的最大值

    思路 & 代码 思路:每个数都可以成为区间最小数,那么当它成为最小数时,使所在区间尽可能大则乘积更大,然后取所有乘积最大值即可。计算区间时,我们可以分为左右区间来计算,为避免重复计算区间范围,计算左区间时,可以维护一个单调递增栈(不小于当前值的自动构成左区间一员),右区间同理。

    时间:O(n),空间:O(n)

    import java.util.Deque;
    import java.util.LinkedList;
    import java.util.Scanner;
    
    /**
     * 〈一句话功能简述〉<br> 
     * 〈区间最大值:https://www.nowcoder.com/questionTerminal/3f4867e9cbe54403ac5df55b8e678df9〉
     *
     * @author Administrator
     * @create 2020/12/5
     * @since 1.0.0
     */
    public class Main {
        public static void main(String[] args) {
            Scanner in = new Scanner(System.in);
            Deque<Integer> stack = new LinkedList<>(); // 单调递增栈(记录下标)
            int n = in.nextInt();
            int[] num = new int[n+1];
            int[] prefix = new int[n+1];
            Node[] goal = new Node[n+1];
            for(int i = 1; i <= n; i++) {
                goal[i] = new Node(); // 对象初始化必须 new
            }
            for(int i = 1; i <= n; i++) {
                num[i] = in.nextInt();
                prefix[i] = prefix[i-1] + num[i];
                // 注意:如果最终的结果是对相应乘积求和而非取最大值,这里的出栈比较和下面的比较两处只能取一处等号
                // eg: [1 2 2 2 1]
                while(!stack.isEmpty() && num[stack.peek()] >= num[i]) stack.pop();
                goal[i].start = stack.isEmpty() ? 0 : stack.peek(); // 栈空应该赋予 0 而非 i-1
                stack.push(i);
            }
            stack.clear();
            for(int i = n; i >= 1; i--) {
                while(!stack.isEmpty() && num[stack.peek()] > num[i]) stack.pop();
                goal[i].end = stack.isEmpty() ? n : stack.peek()-1; // 栈空时赋予 n 而非 i
                stack.push(i);
            }
            long ans = 0;
            for(int i = 1; i <= n; i++) ans = Math.max(ans, (long)(prefix[goal[i].end]- prefix[goal[i].start])*(long)num[i]);
            System.out.print(ans);
        }
    }
    
    class Node {
        int start;
        int end;
        Node() {}
    }
    
  • 相关阅读:
    Java对象克隆
    Java对象toString()方法
    Java对象相等比较(Equals)
    数据传送到后端(二)
    前端数据传送至后端(一)
    jquery导航栏(方法1)
    js导航栏
    纯css导航栏
    jquery导航栏(方法2)
    带尖角的边框(方法二)
  • 原文地址:https://www.cnblogs.com/emptyCoder/p/14094454.html
Copyright © 2011-2022 走看看