1423. 可获得的最大点数 #
- 标签:数组、前缀和、滑动窗口
- 难度:中等
题目大意 #
将卡牌排成一行,给定每张卡片的点数数组 cardPoints
,其中 cardPoints[i]
表示第 i
张卡牌对应点数。
每次行动,可以从行的开头或者末尾拿一张卡牌,最终保证正好拿到了 k
张卡牌。所得点数就是你拿到手中的所有卡牌的点数之和。
现在给定一个整数数组 cardPoints
和整数 k
。
要求:返回可以获得的最大点数。
解题思路 #
可以用固定长度的滑动窗口来做。
由于只能从开头或末尾位置拿 k
张牌,则最后剩下的肯定是连续的 len(cardPoints) - k
张牌。要求求出 k
张牌可以获得的最大收益,我们可以反向先求出连续 len(cardPoints) - k
张牌的最小点数。则答案为 sum(cardPoints) - min_sum
。维护一个固定长度为 len(cardPoints) - k
的滑动窗口,求最小和。具体做法如下:
window_sum
用来维护窗口内的元素和,初始值为0
。min_sum
用来维护滑动窗口元素的最小和。初始值为sum(cardPoints)
。滑动窗口的长度为window_size
,值为len(cardPoints) - k
。- 使用双指针
left
、right
。left
、right
都指向序列的第一个元素,即:left = 0
,right = 0
。 - 向右移动
right
,先将window_size
个元素填入窗口中。 - 当窗口元素个数为
window_size
时,即:right - left + 1 >= window_size
时,计算窗口内的元素和,并维护子数组最小和min_sum
。 - 然后向右移动
left
,从而缩小窗口长度,即left += 1
,使得窗口大小始终保持为k
。 - 重复 4 ~ 5 步,直到
right
到达数组末尾。 - 最后输出
sum(cardPoints) - min_sum
即为答案。
注意:如果 window_size
为 0
时需要特殊判断,此时答案为数组和 sum(cardPoints)
。
代码 #
|
|