@@ -44,13 +44,17 @@ https://leetcode.cn/problems/maximum-score-of-a-good-subarray/description/
44
44
45
45
这种题目基本上都是贡献法。即计算每一个元素对答案的贡献,累加即为答案。
46
46
47
- 如果不考虑 k,枚举每个元素 nums[ i] 作为最小值,尽可能扩张(因为数组每一项都大于 0 )。备胎求最大值。考虑 k 后,再加上一个下标 k 在前一个更小下标和下一个更小下标之前判断。如果不在,无法找到最小值为 nums[ i] 的且下标满足条件的最好子数组,跳过 。
47
+ 如果不考虑 k,枚举每个元素 nums[ i] 作为最小值,尽可能扩张(因为数组每一项都大于 0 ),尽可能指的是保证先满足 nums[ i] 为最小值的前提,备胎求最大值 。
48
48
49
- 在这道题中,就是计算每一个 nums [ i ] 作为最小值的好子数组的分数。那么问题转化为求 nums [ i ] 左右两侧严格小于 nums [ i ] 的元素的位置 left 和 right。这样 (left, right) 内的所有子数组, nums[ i] 都是最小值(注意是开区间) 。
49
+ 考虑 k 后,再加上一个下标 k 在前一个更小下标和下一个更小下标之前判断。如果不在,无法找到最小值为 nums[ i] 的且下标满足条件的最好子数组则跳过。这并不是难点 。
50
50
51
- 求左右严格小于的位置让我们想到单调栈。不熟悉的可以看下我的单调栈专题 。
51
+ 问题转化为求 nums [ i ] 左右两侧严格小于 nums [ i ] 的元素的位置 left 和 right。这样 (left, right) 内的所有子数组,nums [ i ] 都是最小值(注意是开区间)。所有子数组的个数就是 right - left - 1,每次 nums [ i ] 对答案的贡献就是 nums [ i ] ,那么 nums [ i ] 对答案的总贡献就是 nums [ i ] * (right - left - 1) 。
52
52
53
- 套入模板即可。只不过一般的单调栈只求某一侧的严格小于的位置。这个要求左右两侧。不过这实际非常简单。比如 stack 目前是 [ 0,2,3] (stack 中存的是索引)。那么对于 stack 中的 3 来说,前面严格小于它的就是 stack 中它左侧的。
53
+ 求左右严格小于的位置让我们想到单调栈。不熟悉的可以看下我的单调栈专题。套入模板即可。只不过一般的单调栈只求某一侧的严格小于的位置。这个要求左右两侧。
54
+
55
+ 容易想到的是从左向右遍历用一次单调栈,求每个位置 i 右侧第一个比它小的位置 right。再从右向左遍历用一次单调栈,求每个位置 i 左侧第一个比它小的位置 left。这样就可以求出每个位置的 left 和 right。
56
+
57
+ 不过我们用一个单调栈* 从左向右遍历*** 也可以轻松完成。从左向右计算右边第一个比它小的简单,那么如果求左边第一个比它小的呢?举个例子你就明白了。比如 stack 目前是 [ 0,2,3] (stack 中存的是索引)。那么对于 stack 中的 3 来说,前面严格小于它的就是 stack 中它左侧相邻的索引 2。
54
58
55
59
## 关键点
56
60
0 commit comments