列表

详情


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

X轴 上有一些奖品。给你一个整数数组 prizePositions ,它按照 非递减 顺序排列,其中 prizePositions[i] 是第 i 件奖品的位置。数轴上一个位置可能会有多件奖品。再给你一个整数 k 。

你可以选择两个端点为整数的线段。每个线段的长度都必须是 k 。你可以获得位置在任一线段上的所有奖品(包括线段的两个端点)。注意,两个线段可能会有相交。

请你返回在选择两个最优线段的前提下,可以获得的 最多 奖品数目。

 

示例 1:

输入:prizePositions = [1,1,2,2,3,3,5], k = 2
输出:7
解释:这个例子中,你可以选择线段 [1, 3] 和 [3, 5] ,获得 7 个奖品。

示例 2:

输入:prizePositions = [1,2,3,4], k = 0
输出:2
解释:这个例子中,一个选择是选择线段 [3, 3][4, 4] ,获得 2 个奖品。

 

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: int maximizeWin(vector<int>& prizePositions, int k) { } };

golang 解法, 执行用时: 59 ms, 内存消耗: 8.3 MB, 提交时间: 2024-09-11 09:31:32

func maximizeWin(prizePositions []int, k int) (ans int) {
    n := len(prizePositions)
    if k*2+1 >= prizePositions[n-1]-prizePositions[0] {
        return n
    }
    mx, left, right := 0, 0, 0
    for mid, p := range prizePositions {
        // 把 prizePositions[mid] 视作第二条线段的左端点,计算第二条线段可以覆盖的最大奖品下标
        for right < n && prizePositions[right]-p <= k {
            right++
        }
        // 循环结束后,right-1 是第二条线段可以覆盖的最大奖品下标
        ans = max(ans, mx+right-mid)
        // 把 prizePositions[mid] 视作第一条线段的右端点,计算第一条线段可以覆盖的最小奖品下标
        for p-prizePositions[left] > k {
            left++
        }
        // 循环结束后,left 是第一条线段可以覆盖的最小奖品下标
        mx = max(mx, mid-left+1)
    }
    return
}

python3 解法, 执行用时: 85 ms, 内存消耗: 27.5 MB, 提交时间: 2024-09-11 09:31:18

class Solution:
    def maximizeWin(self, prizePositions: List[int], k: int) -> int:
        n = len(prizePositions)
        if k * 2 + 1 >= prizePositions[-1] - prizePositions[0]:
            return n
        ans = mx = left = right = 0
        for mid, p in enumerate(prizePositions):
            # 把 prizePositions[mid] 视作第二条线段的左端点,计算第二条线段可以覆盖的最大奖品下标
            while right < n and prizePositions[right] - p <= k:
                right += 1
            # 循环结束后,right-1 是第二条线段可以覆盖的最大奖品下标
            ans = max(ans, mx + right - mid)
            # 把 prizePositions[mid] 视作第一条线段的右端点,计算第一条线段可以覆盖的最小奖品下标
            while p - prizePositions[left] > k:
                left += 1
            # 循环结束后,left 是第一条线段可以覆盖的最小奖品下标
            mx = max(mx, mid - left + 1)
        return ans

javascript 解法, 执行用时: 76 ms, 内存消耗: 56.8 MB, 提交时间: 2024-09-11 09:30:46

/**
 * @param {number[]} prizePositions
 * @param {number} k
 * @return {number}
 */
var maximizeWin = function(prizePositions, k) {
    const n = prizePositions.length;
    if (k * 2 + 1 >= prizePositions[n - 1] - prizePositions[0]) {
        return n;
    }
    const mx = Array(n + 1).fill(0);
    let ans = 0, left = 0;
    for (let right = 0; right < n; right++) {
        const p = prizePositions[right];
        while (p - prizePositions[left] > k) {
            left++;
        }
        ans = Math.max(ans, mx[left] + right - left + 1);
        mx[right + 1] = Math.max(mx[right], right - left + 1);
    }
    return ans;
};

rust 解法, 执行用时: 11 ms, 内存消耗: 3.3 MB, 提交时间: 2024-09-11 09:30:26

impl Solution {
    pub fn maximize_win(prize_positions: Vec<i32>, k: i32) -> i32 {
        let n = prize_positions.len();
        if k * 2 + 1 >= prize_positions[n - 1] - prize_positions[0] {
            return n as _;
        }
        let mut ans = 0;
        let mut left = 0;
        let mut mx = vec![0; n + 1];
        for (right, &p) in prize_positions.iter().enumerate() {
            while p - prize_positions[left] > k {
                left += 1;
            }
            ans = ans.max(mx[left] + right - left + 1);
            mx[right + 1] = mx[right].max(right - left + 1);
        }
        ans as _
    }
}

golang 解法, 执行用时: 64 ms, 内存消耗: 9.1 MB, 提交时间: 2023-02-06 10:24:16

func maximizeWin(prizePositions []int, k int) (ans int) {
	pre := make([]int, len(prizePositions)+1)
	left := 0
	for right, p := range prizePositions {
		for p-prizePositions[left] > k {
			left++
		}
		ans = max(ans, right-left+1+pre[left])
		pre[right+1] = max(pre[right], right-left+1)
	}
	return
}

func max(a, b int) int { if a < b { return b }; return a }

cpp 解法, 执行用时: 76 ms, 内存消耗: 54 MB, 提交时间: 2023-02-06 10:23:53

class Solution {
public:
    int maximizeWin(vector<int> &prizePositions, int k) {
        int ans = 0, left = 0, n = prizePositions.size(), pre[n + 1];
        pre[0] = 0;
        for (int right = 0; right < n; right++) {
            while (prizePositions[right] - prizePositions[left] > k) ++left;
            ans = max(ans, right - left + 1 + pre[left]);
            pre[right + 1] = max(pre[right], right - left + 1);
        }
        return ans;
    }
};

java 解法, 执行用时: 4 ms, 内存消耗: 50.6 MB, 提交时间: 2023-02-06 10:23:39

class Solution {
    public int maximizeWin(int[] prizePositions, int k) {
        int ans = 0, left = 0, n = prizePositions.length;
        int[] pre = new int[n + 1];
        for (int right = 0; right < n; right++) {
            while (prizePositions[right] - prizePositions[left] > k) ++left;
            ans = Math.max(ans, right - left + 1 + pre[left]);
            pre[right + 1] = Math.max(pre[right], right - left + 1);
        }
        return ans;
    }
}

python3 解法, 执行用时: 316 ms, 内存消耗: 23.5 MB, 提交时间: 2023-02-06 10:23:25

'''
同向双指针,记录第一条线段的最大覆盖数
'''
class Solution:
    def maximizeWin(self, prizePositions: List[int], k: int) -> int:
        pre = [0] * (len(prizePositions) + 1)
        ans = left = 0
        for right, p in enumerate(prizePositions):
            while p - prizePositions[left] > k:
                left += 1
            ans = max(ans, right - left + 1 + pre[left])
            pre[right + 1] = max(pre[right], right - left + 1)
        return ans

上一题