可获得的最大点数

LeetCode-可获得的最大点数(滑动窗口)

#resource / algorithm #type / snippet #status / evergreen #source / leetcode #algo / sliding-window

[!info] related notes 算法面试题型 MOC 滑动窗口

可获得的最大点数

题目

[1423. 可获得的最大点数](https://leetcode.cn/problems/maximum-points-you-can-obtain-from-cards/)

中等

相关标签

![premium lock icon](https://static.leetcode.cn/cn-frontendx-assets/production/_next/static/images/lock-a6627e2c7fa0ce8bc117c109fb4e567d.svg)相关企业

提示

几张卡牌 **排成一行**,每张卡牌都有一个对应的点数。点数由整数数组 `cardPoints` 给出。

每次行动,你可以从行的开头或者末尾拿一张卡牌,最终你必须正好拿 `k` 张卡牌。

你的点数就是你拿到手中的所有卡牌的点数之和。

给你一个整数数组 `cardPoints` 和整数 `k`,请你返回可以获得的最大点数。

**示例 1:**

**输入:**cardPoints = [1,2,3,4,5,6,1], k = 3
**输出:**12
**解释:**第一次行动,不管拿哪张牌,你的点数总是 1 。但是,先拿最右边的卡牌将会最大化你的可获得点数。最优策略是拿右边的三张牌,最终点数为 1 + 6 + 5 = 12 。

**示例 2:**

**输入:**cardPoints = [2,2,2], k = 2
**输出:**4
**解释:**无论你拿起哪两张卡牌,可获得的点数总是 4 。

**示例 3:**

**输入:**cardPoints = [9,7,7,9,7,7,9], k = 7
**输出:**55
**解释:**你必须拿起所有卡牌,可以获得的点数为所有卡牌的点数之和。

**示例 4:**

**输入:**cardPoints = [1,1000,1], k = 1
**输出:**1
**解释:**你无法拿到中间那张卡牌,所以可以获得的最大点数为 1 。 

**示例 5:**

**输入:**cardPoints = [1,79,80,1,1,1,200,1], k = 3
**输出:**202

**提示:**

- `1 <= cardPoints.length <= 10^5`
- `1 <= cardPoints[i] <= 10^4`
- `1 <= k <= cardPoints.length`

题解

定长滑动窗口

本质上是必须包含最左或者最右数据的长度为 k 的滑动窗口,窗口内所有数字和的最大值。 直接先默认取左边的,再一次替换成右边的,遍历所有可能。

var maxScore = function(cardPoints, k) {
    let n = cardPoints.length;
    let leftInx = k-1;
    let rightInx = 0;
    let max = 0;
    let result = 0;
    for (let i = 0; i < k; i++) {
        max += cardPoints[i];
        // 第一次忘了这个,漏掉开始时的最大解
        result = max;
    }
    if (n === k) {
        return max;
        console.log(max)
    }
    
    for (let i = 0; i < k; i++) {
        max = max - cardPoints[leftInx] + cardPoints[n-1-rightInx];

        result = Math.max(result, max);
        leftInx--;
        rightInx++;
    }
    return result;
};

反向滑动窗口

取走的值最大,即剩余的 n-k 窗口的和的值最小,只需遍历一次!!!!

创建于 2025/1/1 更新于 2026/5/27