1793. 好子数组的最大分数Java
文章发布较早,内容可能过时,阅读注意甄别。
# 题目
给你一个整数数组 nums (下标从 0 开始)和一个整数 k 。
一个子数组 (i, j) 的 分数 定义为 min(nums[i], nums[i+1], ..., nums[j]) * (j - i + 1) 。一个 好 子数组的两个端点下标需要满足 i <= k <= j 。
请你返回 好 子数组的最大可能 分数 。
示例 1:
输入:nums = [1,4,3,7,4,5], k = 3
输出:15
解释:最优子数组的左右端点下标是 (1, 5) ,分数为 min(4,3,7,4,5) * (5-1+1) = 3 * 5 = 15 。
示例 2:
输入:nums = [5,5,4,5,4,1,1,1], k = 0
输出:20
解释:最优子数组的左右端点下标是 (0, 4) ,分数为 min(5,5,4,5,4) * (4-0+1) = 4 * 5 = 20 。
提示:
- 1 <= nums.length <= 105
- 1 <= nums[i] <= 2 * 104
- 0 <= k < nums.length
# 思路
Stack
# 解法
class Solution {
public int maximumScore(int[] nums, int k) {
int n = nums.length;
int[] left = new int[n]; // 存放每个位置向左第一个小于等于当前值的位置
int[] right = new int[n]; // 存放每个位置向右第一个小于等于当前值的位置
Stack<Integer> stack = new Stack<>();
for (int i = 0; i < n; i++) {
while (!stack.isEmpty() && nums[stack.peek()] >= nums[i]) {
stack.pop();
}
left[i] = stack.isEmpty() ? 0 : stack.peek() + 1;
stack.push(i);
}
stack.clear();
for (int i = n - 1; i >= 0; i--) {
while (!stack.isEmpty() && nums[stack.peek()] >= nums[i]) {
stack.pop();
}
right[i] = stack.isEmpty() ? n - 1 : stack.peek() - 1;
stack.push(i);
}
int maxScore = 0;
for (int i = 0; i < n; i++) {
if (left[i] <= k && right[i] >= k) {
maxScore = Math.max(maxScore, nums[i] * (right[i] - left[i] + 1));
}
}
return maxScore;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 总结
- 分析出几种情况,然后分别对各个情况实现