摇人!今年我们新招16000+人

353 阅读4分钟

摇人,明天开始

7 月 26 日,京东总部 1 号园区 DEF 座启用,新的现代化职场园区"蓝方方 Plus"正式组成。

更加值得关注的是,借此机会,京东 2025 校园招聘将于 8 月 1 日全面启动,累积提供 10000+ 就业岗位和 6000+ 实习岗位,并提供极具竞争力的条件。

往年京东的校园招聘,大多都是在 8 月底开始,这次提前了近一个月,同时放出的 HC 增长也成百上千。

话说今年传统电商"阿里"和"京东"又走出了截然不同的路线,阿里换帅后不断砍掉一些非主营核心业务,马老师也依然是"半隐身"状态;京东则是多次被爆出刘强东经常半夜微信群安排工作,试图不断拓展新边界。

但无论如何,当下就业环境恶劣,七八月还时常出现企业毁应届的局面,多个机会总是好的,希望会有越来越多的互联网公司和京东一样,重回到招聘市场的上升通道。

...

回归主线。

来一道和「京东」相关的算法题。

题目描述

平台:LeetCode

题号:1423

几张卡牌排成一行,每张卡牌都有一个对应的点数,点数由整数数组 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<=1051 <= cardPoints.length <= 10^5
  • 1<=cardPoints[i]<=1041 <= cardPoints[i] <= 10^4
  • 1<=k<=cardPoints.length1 <= k <= cardPoints.length

滑动窗口

从两边选卡片,选 k 张,卡片总数量为 n 张,即有 n - k 张不被选择。

所有卡片总和 sum 固定,要使选择的 k 张的总和最大,反过来就是要让不被选择的 n - k 张总和最小。

原问题等价为:cardPoints 中找长度为 n - k 的连续段,使其总和最小。

具体的,用变量 sum 代指 cardPoints 总和,cur 代表长度固定为 n - k 的当前窗口总和,minv 代表所有长度为 n - k 的窗口中总和最小的值。

起始先将滑动窗口压满,取得第一个滑动窗口的目标值 cur(同时更新为 minv),随后往后继续处理 cardPoints,每往前滑动一位,需要删除一个和添加一个元素,并不断更新 minv,最终 sum - minv 即是答案。

Java 代码:

class Solution {
    public int maxScore(int[] cardPoints, int k) {
        int n = cardPoints.length, len = n - k;
        int sum = 0, cur = 0;
        for (int i = 0; i < n; i++) sum += cardPoints[i];
        for (int i = 0; i < len; i++) cur += cardPoints[i]; 
        int minv = cur;
        for (int i = len; i < n; i++) { 
            cur = cur + cardPoints[i] - cardPoints[i - len]; 
            minv = Math.min(minv, cur);
        }
        return sum - minv;
    }
}

C++ 代码:

class Solution {
public:
    int maxScore(vector<int>& cardPoints, int k) {
        int n = cardPoints.size(), len = n - k;
        int sum = 0, cur = 0;
        for (int i = 0; i < n; i++) sum += cardPoints[i];
        for (int i = 0; i < len; i++) cur += cardPoints[i]; 
        int minv = cur;
        for (int i = len; i < n; i++) { 
            cur = cur + cardPoints[i] - cardPoints[i - len]; 
            minv = min(minv, cur);
        }
        return sum - minv;
    }
};

Python 代码:

class Solution:
    def maxScore(self, cardPoints: List[int], k: int) -> int:
        n, m = len(cardPoints), len(cardPoints) - k
        total, cur = sum(cardPoints), sum(cardPoints[:m])
        minv = cur
        for i in range(m, n):
            cur = cur + cardPoints[i] - cardPoints[i - m]
            minv = min(minv, cur)
        return total - minv

TypeScript 代码:

function maxScore(cardPoints: number[], k: number): number {
    const n = cardPoints.length, m = n - k;
    let tot = 0, cur = 0;
    for (let i = 0; i < n; i++) tot += cardPoints[i];
    for (let i = 0; i < m; i++) cur += cardPoints[i];
    let minv = cur;
    for (let i = m; i < n; i++) {
        cur = cur + cardPoints[i] - cardPoints[i - m];
        minv = Math.min(minv, cur);
    }
    return tot - minv;
};
  • 时间复杂度:每个元素最多滑入和滑出窗口一次,复杂度为 O(n)O(n)
  • 空间复杂度:O(1)O(1)