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

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

时间: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() {}
}
posted @ 2020-12-06 21:33 我在这儿 阅读(380) 评论(0) 推荐(1) 编辑
摘要: 来源:967 质量检测 大意:n 种 商品有 a、b 两种分数,确定一种分数,大于等于 maxScore*p 分数的商品可被取到,求最多能取到的商品 吐槽 从天池居然看到了周赛(我还疑心阿里怎么也办起算法比赛来啦,原来是和九章合作的 lintcode 周赛,只是同步到天池而已),饶有兴趣了选了一道3 阅读全文
posted @ 2020-12-05 11:51 我在这儿 阅读(133) 评论(0) 推荐(0) 编辑
摘要: 剑指 Offer 56 - I. 数组中数字出现的次数 大意:找出数组中只出现一次的两个数(其它出现两次) 思路 & 代码 思路:首先需要知道一个前置问题:找出数组中只出现一次的一个数(其它出现两次),显然,对整个数组进行异或操作即可。那么,我们是否有可能将本题中的数组分隔成两部分呢(不要求连续)? 阅读全文
posted @ 2020-12-02 18:28 我在这儿 阅读(181) 评论(0) 推荐(0) 编辑
摘要: 题目见这里 和1099略微相似,考察二叉树和基本的遍历,算是简单的啦,下标还充当了数据域,主要是知道要标记访问到的下标,从而确定root 阅读全文
posted @ 2017-07-10 14:52 我在这儿 阅读(258) 评论(0) 推荐(0) 编辑
摘要: 题目见这里 题目并不难,不过一开始我没能理清题意,参考了下这里,明白题目实际是考进制转换(13进制),外加一个映射(hash),这当然比较简单啦!需要注意的是,样例中tam(Mars Number) >13(Earth),由此可知,以13的整倍数(Earth)出现时,不带‘tret’ (earth: 阅读全文
posted @ 2017-07-09 11:37 我在这儿 阅读(272) 评论(0) 推荐(0) 编辑
摘要: 题目见这里 (分析) 分四步进行: 1)根据给定的结点情况建二叉树 2)对输入的键值排序(asending) 3)对二叉树中序遍历,同时对应赋key值 4)层次遍历(队列应用) 题目并不困难,但是我误入了trick,错误假定了结点按先序遍历是按顺序编号的(当然是受样例的影响),所以有了下面22分(满 阅读全文
posted @ 2017-07-07 23:48 我在这儿 阅读(426) 评论(0) 推荐(0) 编辑
摘要: 题目见这里 分析:实际上是静态链表的应用,只不过要删除的结点链接成一个新的Removed List 阅读全文
posted @ 2017-07-07 16:10 我在这儿 阅读(327) 评论(0) 推荐(0) 编辑
摘要: 题目链接见这里 分析:考察的是插入排序和堆排序两种基本的数据结构,注意利用两种排序的基本特征 插入排序不影响全局,而堆排序影响全局 阅读全文
posted @ 2017-07-07 06:12 我在这儿 阅读(285) 评论(0) 推荐(0) 编辑
摘要: 首先,给上题目链接:http://hihocoder.com/problemset/problem/1048 ,简要描述如下: 有1个N*M的盘子,要装2*1的蛋糕,问有多少种方法?(结果对1000000007取余,其中2≤N≤1000,3≤M≤5) 最简单的例子如下: 下面我们来分析: 这个题目类 阅读全文
posted @ 2017-03-14 14:58 我在这儿 阅读(307) 评论(0) 推荐(0) 编辑
摘要: 水池数目(YES)时间限制:3000 ms | 内存限制:65535 KB难度:4 描述 南阳理工学院校园里有一些小河和一些湖泊,现在,我们把它们通一看成水池,假设有一张我们学校的某处的地图,这个地图上仅标识了此处是否是水池,现在,你的任务来了,请用计算机算出该地图中共有几个水池。输入 第一行输入一 阅读全文
posted @ 2017-03-11 14:19 我在这儿 阅读(229) 评论(0) 推荐(0) 编辑

喜欢请打赏

扫描二维码打赏

了解更多

点击右上角即可分享
微信分享提示