LeetCode——1793. 好子数组的最大分数[Maximum Score of a Good Subarray][困难]——分析及代码[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 <= 10^5
- 1 <= nums[i] <= 2 * 10^4
- 0 <= k < nums.length
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-score-of-a-good-subarray
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二、分析及代码
1. 单调栈 + 双指针
(1)思路
根据题意,好子数组为从索引 k 向两侧延伸的数组,其分数取决于区间内的最小值和区间长度。
因此可在数组中索引为 k 的元素两侧,设计 2 个单调栈,存储各个最小值及对应的范围。在此基础上,结合双指针方法,遍历选取左、右区间中下一个较大的最小值(若相等则任意选取)并计算分数。过程中计算得到的分数最大值,就是待求的解。
(2)代码
class Solution {
public int maximumScore(int[] nums, int k) {
int n = nums.length, maxScore = 0;
List<Integer> leftRange = new ArrayList<Integer>(</