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() {}
    }
    
  • 相关阅读:
    hdu 3342 Legal or Not 拓排序
    hdu 1596 find the safest road Dijkstra
    hdu 1874 畅通工程续 Dijkstra
    poj 2676 sudoku dfs
    poj 2251 BFS
    poj Prime Path BFS
    poj 3278 BFS
    poj 2387 Dijkstra 模板
    poj 3083 DFS 和BFS
    poj 1062 昂贵的聘礼 dijkstra
  • 原文地址:https://www.cnblogs.com/emptyCoder/p/14094454.html
Copyright © 2011-2022 走看看