來源:字節跳動編程題
大意:找出一個數組中區間最小數*區間和的最大值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() {} }