求最小数 * 区间和最大值
来源:字节跳动编程题
大意:找出一个数组中区间最小数*区间和的最大值
思路 & 代码
思路:每个数都可以成为区间最小数,那么当它成为最小数时,使所在区间尽可能大则乘积更大,然后取所有乘积最大值即可。计算区间时,我们可以分为左右区间来计算,为避免重复计算区间范围,计算左区间时,可以维护一个单调递增栈(不小于当前值的自动构成左区间一员),右区间同理。时间: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() {}
}
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 对象命名为何需要避免'-er'和'-or'后缀
· SQL Server如何跟踪自动统计信息更新?
· AI与.NET技术实操系列:使用Catalyst进行自然语言处理
· 分享一个我遇到过的“量子力学”级别的BUG。
· Linux系列:如何调试 malloc 的底层源码
· C# 中比较实用的关键字,基础高频面试题!
· .NET 10 Preview 2 增强了 Blazor 和.NET MAUI
· Ollama系列05:Ollama API 使用指南
· 为什么AI教师难以实现
· 如何让低于1B参数的小型语言模型实现 100% 的准确率