给你一个整数数组 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 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
class Solution {
public:
int maximumScore(vector<int>& nums, int k) {
int n = nums.size();
vector<int> right(n,-1), left(n,-1);
stack<int> s;
for(int i = n-1; i >= 0; i--)
{
while(!s.empty() && nums[s.top()] >= nums[i])
s.pop();//大于等于我的,我是最小的啦,删除,接着往后找
if(!s.empty())
right[i] = s.top()-1;
else
right[i] = n-1;
s.push(i);
}
while(!s.empty()) s.pop();
for(int i = 0; i < n; i++)
{
while(!s.empty() && nums[s.top()] >= nums[i])
s.pop();
if(!s.empty())
left[i] = s.top()+1;
else
left[i] = 0;
s.push(i);
}
int maxScore = 0;
for(int i = 0; i < n; i++)
if(left[i] <= k && k <= right[i])
maxScore = max(maxScore, nums[i]*(right[i]-left[i]+1));
return maxScore;
}
};
288 ms 98.2 MB C++
我的CSDN博客地址 https://michael.blog.csdn.net/
长按或扫码关注我的公众号(Michael阿明),一起加油、一起学习进步!