本文主要是介绍单调栈,LeetCode 1793. 好子数组的最大分数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一、题目
1、题目描述
给你一个整数数组
nums
(下标从 0 开始)和一个整数k
。一个子数组
(i, j)
的 分数 定义为min(nums[i], nums[i+1], ..., nums[j]) * (j - i + 1)
。一个 好 子数组的两个端点下标需要满足i <= k <= j
。请你返回 好 子数组的最大可能 分数 。
2、接口描述
class Solution {
public:int maximumScore(vector<int>& nums, int k) {}
};
3、原题链接
1793. 好子数组的最大分数
二、解题报告
1、思路分析
贪心+双指针
和84. 柱状图中最大的矩形类似, 本质都是求最大矩形面积,只不过本题要求矩形包含k
那么我们考虑从k开始,双指针向两边遍历
双指针l,r初始指向k,如果nums[l - 1]大于nums[r + 1],就l--,否则r++
然后维护区间[l, r]内的最小值mi,矩形面积就是mi * (r - l + 1)
下面证明贪心策略的正确性:
假设最终答案矩形边界为L,R
那么一定有nums[L - 1] < nums[L],nums[R + 1] < nums[R],否则矩形可以进一步扩大
我们只需证明l ,r最终一定停留在L,R的位置
不失一般性的假设l先抵达L,此时由于nums[L - 1] < mi <= nums[r],故r会一直右移直到R
反之如果r先抵达R,亦然
2、复杂度
时间复杂度: O(n)空间复杂度:O(1)
3、代码详解
class Solution {
public:int maximumScore(vector<int>& nums, int k) {int n = nums.size(), l = k, r = k, ret = nums[k];for(int i = 0, mi = nums[k]; i < n - 1; i++){if(r == n - 1 || (l && nums[l - 1] > nums[r + 1]))mi = min(mi, nums[--l]);elsemi = min(mi, nums[++r]);ret = max(ret, (r - l + 1) * mi);}return ret;}
};
这篇关于单调栈,LeetCode 1793. 好子数组的最大分数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!