力扣2555. 两个线段获得的最多奖品
题目解析及思路
题目要求找到可重叠的两个线段使线段上元素和最大
因为元素均为非负数且只能取一次,因此答案是单调的
-
当最终取到两线段重合时,一定为整个数组的全部元素和,这种情况特判掉即可
-
当两线段不重合时,枚举第二段的右端点并维护第二段的左端点
- 此时第二段的左右端点卡出来一个合法的区间
- 同时更新并维护左边最大值,二者相加为答案
代码
class Solution {
public:
int maximizeWin(vector<int>& prizePositions, int k) {
int n = prizePositions.size();
//两段一定重合
if(prizePositions[n-1] - prizePositions[0] - 1 <= 2 * k)
return n;
//l存第二段的左端点
int ans = 0,l = 0;
//mx存左边最大值
vector<int> mx(n+1);
for(int r = 0;r<n;r++)
{
//找到合法区间
while(prizePositions[r] - prizePositions[l] > k)
l ++;
//答案为左边最大值 + 右边当前值
ans = max(ans,mx[l] + r - l + 1);
//更新左边最大值
mx[r + 1] = max(mx[r],r-l+1);
}
return ans;
}
};