贪心+滑窗+递推,LeetCode 2555. 两个线段获得的最多奖品

一、题目

1、题目描述

2、接口描述

python3
 ​
class Solution:
    def maximizeWin(self, prizePositions: List[int], k: int) -> int:
cpp
 ​
class Solution {
public:
    int maximizeWin(vector<int>& prizePositions, int k) {
        int n = prizePositions.size();
        std::vector<int> pre(n);
        int res = 0;
        for (int j = 0, i = 0; j < n; ++ j) {
            while (prizePositions[j] - prizePositions[i] > k) ++ i;
            res = std::max(res, j - i + 1 + pre[i]);
            if (j + 1 < n)
                pre[j + 1] = std::max(pre[j], j - i + 1);
        }
        return res;
    }
};
C#
 ​
public class Solution
{
    public int MaximizeWin(int[] prizePositions, int k)
    {

    }
}

3、原题链接

2555. 两个线段获得的最多奖品


二、解题报告

1、思路分析

考虑最优解的两个线段会相交吗?

不会,我们总能将两个相交线段分开来得到更优解

我们考虑滑窗维护当前线段[i, j],在过程中维护答案 res = max(res, j - i + 1 + pre[i])

pre[i] 指 [0, i) 内的最长线段

pre[] 可以在滑窗 的过程中递推

2、复杂度

时间复杂度: O(N)空间复杂度:O(N)

3、代码详解

python3
 ​
class Solution:
    def maximizeWin(self, prizePositions: List[int], k: int) -> int:
        n = len(prizePositions)
        pre = [0] * n
        res = i = 0
        for j in range(n):
            while prizePositions[j] - prizePositions[i] > k:
                i += 1
            res = max(res, j - i + 1 + pre[i])
            if j + 1 < n:
                pre[j + 1] = max(pre[j], j - i + 1)
        return res
cpp
 ​
class Solution {
public:
    int maximizeWin(vector<int>& prizePositions, int k) {
        int n = prizePositions.size();
        std::vector<int> pre(n);
        int res = 0;
        for (int j = 0, i = 0; j < n; ++ j) {
            while (prizePositions[j] - prizePositions[i] > k) ++ i;
            res = std::max(res, j - i + 1 + pre[i]);
            if (j + 1 < n)
                pre[j + 1] = std::max(pre[j], j - i + 1);
        }
        return res;
    }
};
C#
 ​
public class Solution
{
    public int MaximizeWin(int[] prizePositions, int k)
    {
        int n = prizePositions.Length;
        int[] pre = new int[n];
        int res = 0;
        for (int j = 0, i = 0; j < n; ++ j)
        {
            while (prizePositions[j] - prizePositions[i] > k)
                ++i;
            res = Math.Max(res, j - i + 1 + pre[i]);
            if (j + 1 < n)
                pre[j + 1] = Math.Max(j - i + 1, pre[j]);
        }
        return res;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EQUINOX1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值