京东2017校招编程题全解析:从算法基础到笔试实战的思维拆解
2026/9/5 8:29:41 网站建设 项目流程

作为一个经历过校招、也做过面试官的人,我太清楚“京东2017校招编程题”在技术圈的分量了。那一年京东的笔试题目质量相当高,虽然没有特别偏难怪的题,但胜在全面,基础、算法、思维一个不落。很多题后来被各大公司的题库反复引用,直到今天,你在牛客网、力扣上依然能看到它们的变体。趁着最近又有不少读者在后台问我“校招编程题该怎么刷”、“京东的题难不难”,我把当年那套题重新扒出来,结合我自己的解题记录和后来做面试官时看到的考生常见错误,做一次系统的拆解。

这篇文章不是简单地贴题目和答案,而是想告诉你:每一道题背后到底在考什么,出题人希望看到你具备哪些能力,以及当你拿到一道陌生编程题时,应该用什么样的思维路径去拆解它。无论你是正在准备校招的应届生,还是工作几年想回头补基础的同学,这份梳理应该都能帮到你。

1. 京东2017校招编程题的整体画像:到底在考什么

先给没参加过那场笔试的同学还原一下当时的场景。京东的校招笔试通常是线上笔试,编程题部分一般有2到3道,时间大概在1到1.5小时之间。你不仅要写对,还得写得快、写得稳。2017年的题目整体风格非常“京东化”——务实、贴近业务场景、不追求偏怪难,但对基础数据结构和算法的要求一点都不含糊。

1.1 核心考察方向:基础算法能力,而不是炫技

我那年刷完题后,又把能找到的版本都做了一遍,最大的感受是:这组题考察的核心,是“你是否具备扎实的计算机基础功”。它的题目类型主要集中在:

  • 字符串处理与模拟
  • 基础动态规划
  • 图论与搜索(尤其是网格类场景)
  • 数学推导与规律发现
  • 集合与哈希表的高效应用

你会发现它没有那种要求你三分钟默写红黑树的变态问题,也没有需要半小时推公式的数学竞赛题。但它会把你要解决的问题藏在业务场景里。比如“分苹果”、“找最少步数”、“字典序排列”这类题,表面上是生活化描述,骨子里考的却是DP、BFS、贪心这些经典算法。

1.2 难度分布与题量结构

根据我找得到的真题回忆汇总,2017年京东笔试的编程题大致呈阶梯式分布:

  • 第一题通常是纯送分题,考字符串操作或者简单模拟,细心就能全对。
  • 第二题进入中等难度,一般是DP或者二分查找的变体,需要你能准确建模。
  • 第三题开始区分度就出来了,要么是图上搜索,要么是带有数学规律的构造题,需要你不仅会算法,还能优化常数。

这三题做下来,基本就能把一个候选人的编码能力、算法功底、调试能力、心理素质看得七七八八。说实话,三年后我坐在面试官的位置上看候选人笔试代码时,依然会拿当年这组题当尺子。它不高级,但真的能量出水平。

1.3 为什么今天仍值得刷这套题

有读者可能会问:2017年的题,放到现在还有参考价值吗?我明确告诉你:有,而且价值不小。原因有三:

第一,校招笔试的核心考察能力这些年没有变,依然是算法功底加编码实现力。这套题的考察维度完全不过时。

第二,京东这套题在难度设置上非常“经典”,既不像某些公司那样入门劝退,也不像另一些公司那样全是模板题。它处在一个恰到好处的“能力探测区间”。

第三,这组题中的很多原题或变体,后来反复出现在其他公司的题库中。你刷熟了这一套,等于同时做了好几家公司的准备。

2. 高频考点拆解:把题目变成知识点地图

刷题最忌讳的就是“就题论题”。写出一道题,过两天换了个皮,又不会了。这本质上是没有完成“题目到知识点”的抽象过程。我当年刷完京东这套题后,专门做了一张知识点地图,今天分享给你。

2.1 字符串处理类:细节决定成败

这类题属于“看起来简单,做起来想摔键盘”的类型。京东的笔试里,字符串题经常是第一题,但它的坑从来不藏在算法里,而是藏在边界条件和特殊情况里。

举个例子,当时有道题是“给定一个字符串,删除其中所有重复字符,且保持第一次出现的顺序”。我见过很多人的第一反应是“用HashSet边遍历边去重”,思路确实对,但写出来却各种小问题:有人忘了处理空字符串,有人忽略了字符大小写是否敏感,有人没有考虑字符集范围。你去看官方题解会觉得,这也太小儿科了,但考场上全对的人就是不多。

字符串题的复习重点应该放在:遍历边界、字符集范围、输入输出格式、大小写/空格的处理、以及代码的健壮性。这些能力没法靠背模板获得,只能靠大量手写代码形成肌肉记忆。

2.2 动态规划与状态定义:区分度的分水岭

如果字符串题是热身,那动态规划题就是校招笔试真正的分水岭。京东2017的题目里,至少有三分之一的题需要用到DP思想。

很多人学DP的通病是“状态方程看不懂,看懂了也不会推”。我提供一个亲测有效的方法:拿到一道DP题,先别急着写递推公式,而是先问自己三个问题:

  • 我关注的结果是什么?(比如最大价值、最小步数、方案总数)
  • 我在决策的过程中,哪些信息是必须记住的?(这就是状态维度的来源)
  • 每一步决策,和上一步的关系是什么?(这就是状态转移方程)

以京东考过的那道“分苹果”来说,很多人的第一反应是搜所有方案,但n一旦变大,组合爆炸。用我上面的三个问题来拆解:关注的是“最少搬动几次”;必须记住“当前苹果数”和“已搬动次数”;每一步可以搬1、2或3个——这就是一个非常标准的“最少步数到达目标”的动态规划模型,状态转移方程其实就是dp[i] = min(dp[i-1], dp[i-2], dp[i-3]) + 1。

我当时在博客里写过一句话,今天依然觉得是对的:动态规划不考智商,考的是你有没有建立“状态”这个概念的习惯。

2.3 图论与搜索:网格题里的陷阱与突破

京东的题里还有一类非常高频:给定一个网格或者地图,求从起点到终点的最短路径、最少步数、或者判断是否可达。这类题几乎就是为BFS量身定制的。

但是请相信我,这类题拿到满分远比想象中难。因为网格题的坑不在算法本身,而在工程细节。方向数组写错了会导致全部走偏;visited数组忘记标记会导致队列内存爆炸;对越界条件的判断顺序写错了,甚至会造成数组越界访问。

我当时做过一个统计,笔试中BFS题做错的人里,有将近一半是挂在“边界检查”和“visited标记”这两个细节上。它不考你懂不懂BFS原理,考的是你代码写得好不好。

2.4 数学思维与规律题:最后的亮点

京东的题还有一个特色:时不时会出现一道看起来像数学竞赛、实际上是编程题的题目。这类题往往是整套卷子的“小彩蛋”,区分度极高。

我印象最深的是一道跟“数字和”相关的题:给定一个正整数,每次操作可以将其替换为各个数位之和,问多少次操作可以变成一位数。很多人拿到之后就写循环、求数位和、再循环。这个没错,但如果出题人把测试数据范围调大到10^18以上,你的解法就需要优化。

这里其实藏着一个“数学优化”的关键:不是等数位和小于10才停下来,而是直接用一次“数位和模9”的技巧判断。类似的规律题,你不知道这个规律时,怎么写都觉得别扭;知道了以后,三行代码解决问题。这就是数学思维的价值。

3. 典型题目精讲:从读题到AC的完整推演

前面讲了考什么,现在我们来实战。我挑了几道有代表性的题目,带着你走一遍从读题到AC的完整思考过程。我不会只贴一个标准答案,而是把每一步的思维过程、备选方案、以及我会踩的坑都摊开给你看。

3.1 题目一:数字序列拼接

我们先从一道常见题入手。题目大致是:给定n个正整数,将它们拼接成一个新数,问怎么拼接可以得到最大的数。比如输入[3, 30, 34, 5, 9],能拼成的最大数是9534330。

很多人的第一直觉是“按字典序从大到小排”,但一提交,发现连示例都过不了。问题出在哪?因为“3”和“30”这两个数,按字典序“3”的确比“30”大,但拼接结果是330,而另一个顺序是303,显然前者更大。可如果你把“9”和“98”放一起,“9”字典序比“98”大,但拼接“998”确实大于“989”,所以这组又没问题。你稍微多试几组,就会发现其实这是一个自定义排序问题。

正确的做法是:定义一个新的比较规则——对于字符串a和b,如果“a+b”大于“b+a”,则a应该排在b前面。用Python写的话,核心就两行:

from functools import cmp_to_key def largest_number(nums): strs = list(map(str, nums)) strs.sort(key=cmp_to_key(lambda a, b: -1 if a+b > b+a else 1)) result = ''.join(strs).lstrip('0') return result or '0'

这道题给我的启发是:当直觉的排序规则不成立时,不要死磕,而是回到定义本身,重新定义“谁在谁前面”的比较关系。这个思维模式不仅适用于这道题,很多需要自定义排序的算法题都靠它。

3.2 题目二:快速求整数各个数位之和的实现

这道题看起来像是来送分的:输入一个整数,求它各位数字的和。有人会说这也算编程题?但请注意,当测试数据的范围达到10^18甚至更大的时候,部分语言的基本类型就会溢出,同时用字符串处理时的效率也会有差别。

最稳妥的实现方式是先转字符串再逐位累加,或者用取模运算:

def digit_sum(n): total = 0 while n: total += n % 10 n //= 10 return total

这样写代码非常短,但对于极端的大整数,如果题目允许用字符串输入,那么直接遍历字符更稳妥。我见过不少同学在考场上直接用int接收输入,然后发现溢出报错,心态直接崩了。所以这种看似幼稚的题反而是最值得警惕的。

通常这种“送分题”里还有隐藏考点:比如数位和能不能被3整除、能不能被9整除。判断某个数是否被3整除,可以不用算完整数位和,因为一个数模3等于它的数位和模3,模9同理。很多后来的笔试题都直接用了这个结论。记住:有时面试官不是考你会不会循环,而是考你知不知道背后的数学性质。

3.3 题目三:带状态的网格最短步数问题

这是2017年京东笔试里最有区分度的一道题。题目描述是这样的:在一个m行n列网格中,0表示空地,1表示障碍物。玩家从左上角出发,想到达右下角,每次可以向上、下、左、右四个方向移动。现在你有一个特殊能力,可以使用一次,使用后可以“跳过”一个障碍物。问最少需要多少步。

如果你没有做过带状态的BFS,第一次看到会有点懵:单纯BFS求最短路径可以,但“可以跳过障碍物一次”这个条件怎么处理?

实际上,这个题目需要把一个普通的节点状态拆成两个:没使用能力前和使用能力后。如果你在没使用能力时到达某个节点,但是后来你用掉了能力,你的可选路径就变了,所以你不能仅仅用一个二维visited来记录,而要用三维数组visited[x][y][used]来记录状态,其中used取0或1。

搜索的过程是:从起点开始,如果当前位置是空地,两个状态都可以转移;如果是障碍物且未使用能力,可以使用能力,进入used=1的状态;如果是障碍物且能力已使用,则不能进入。终点可以是used=0或used=1的任意一种。由于BFS按层扩展,第一次到达终点时一定是最小步数。

我当时第一次写这道题的代码时,因为方向数组的顺序写错了,导致搜索路径不是最小,卡了将近半小时。后来发现了这个低级错误,真的是哭笑不得。所以我真诚建议每位准备笔试的同学,方向数组最好固定为“上、下、左、右”和坐标数组一一对应,就不要再改了,免得自己把自己绕晕。

认真说,这道题是BFS进阶的基础,也是很多“至少使用K次道具”问题的雏形,后来我在不少大厂的题库里都见到过类似模型。

3.4 题目四:股票买卖的最佳时机(变体)

2017年京东也考过买卖股票的问题,但它的变体比较特殊:不是一次买卖,也不是无限次买卖,而是限定了最多两次交易。原题通常是这样说的:给定一个数组,它的第i个元素是一支给定股票第i天的价格。设计一个算法来计算你所能获取的最大利润,最多可以完成两笔交易。

很多人第一次接触时直接懵了,不知道该从哪个角度拆。其实这个题是DP的经典变体,有两种比较普适的做法。

第一种做法是“分段法”:因为最多两笔交易,一定存在一个分界点,第一次交易在分界点左边完成,第二次在右边完成。所以我们可以先从左往右预处理出“到第i天为止进行一次交易能获得的最大利润”,再从右往左预处理出“从第i天开始进行一次交易能获得的最大利润”,然后枚举分界点,答案就是两者之和的最大值。

用代码来写,大概是这样的:

def max_profit(prices): n = len(prices) if n < 2: return 0 left = [0] * n right = [0] * n # 从左往右 min_price = prices[0] for i in range(1, n): left[i] = max(left[i-1], prices[i] - min_price) min_price = min(min_price, prices[i]) # 从右往左 max_price = prices[-1] for i in range(n-2, -1, -1): right[i] = max(right[i+1], max_price - prices[i]) max_price = max(max_price, prices[i]) ans = 0 for i in range(n): ans = max(ans, left[i] + (right[i+1] if i+1 < n else 0)) return ans

第二种做法是状态机DP。把整个过程当成四个状态:第一次买入、第一次卖出、第二次买入、第二次卖出,然后不断更新。这个思路从原理上来说更通用,扩展性更强。但在这道题上,分段法更好理解、编码也更快,应对笔试更实际。

这道题的价值在于,它训练的是“把复杂交易拆成独立可优化的子问题”的能力。这个思路在后续很多难题里都能复用。

3.5 题目五:集合与哈希表的经典配合

还有一道印象很深的题是:“给定一个整数数组,找出其中没有出现的最小正整数。”比如数组是[3, 4, -1, 1],答案就是2;如果数组是[1, 2, 0],答案就是3。

暴力解法很简单:把所有数放进哈希集合,然后从1开始逐个检查是否在集合里。时间复杂度O(n),空间复杂度O(n)。笔试里这么做已经能过了。但如果面试官追问“能不能做到O(1)空间”,相信很多人会卡住。

我当时总结的O(1)空间做法是:把数组本身当成哈希表,利用下标与数值的对应关系。具体思路是,将所有在[1, n]范围内的数放到它对应的下标位置,即让nums[i] = i+1,然后遍历数组,第一个不满足的位置就是缺失的最小正整数。这个技巧叫“原地哈希”,在“找缺失数”“找重复数”这一系列问题里非常常用。

Python代码如下:

def first_missing_positive(nums): n = len(nums) for i in range(n): while 1 <= nums[i] <= n and nums[nums[i]-1] != nums[i]: nums[nums[i]-1], nums[i] = nums[i], nums[nums[i]-1] for i in range(n): if nums[i] != i + 1: return i + 1 return n + 1

很多同学看不懂这个while循环在干嘛。我解释一下:它做的事情是“不断把当前i位置的数交换到它该去的位置”,直到当前位置的数要么不在[1,n]范围内,要么它已经待在正确的位置上。交换后,i位置又来了一个新数,就继续处理,所以要套一层while。

这道题展示了“如何用常数辅助空间解决看似需要哈希表的问题”,也常作为面试现场手撕环节的考察题。刷透它能给你带来不少底气。

4. 解题效率与代码风格:如何让阅卷官眼前一亮

写完题目答案只是第一步。我做过面试官之后才真正体会到,阅卷官看一份笔试代码时,注意力是非常有限的。一个人如果代码写得清晰、规范、有注释、边界处理到位,即使算法不是最优解,也能在阅卷官心里拿高分。相反,即使AC了,如果代码一团乱麻,也容易被扣印象分。

4.1 笔试中的高分段代码长什么样

根据我的经验,能拿高分的代码通常具备以下特点:

  • 变量命名有意义。用i、j、k本身不是错,但如果能用start、end、cur、prev这样语意明确的命名,阅读体验会好很多。
  • 边界处理前置。空数组、空字符串、只有一个元素的数组,这一类特殊输入的处理一定要在函数开头就写好。
  • 关键逻辑有注释。不是说每行都注释,而是在状态转移、搜索剪枝、边界判断这些关键点用一行中文或英文点明你的思路。
  • 不做多余操作。一眼就能看出的无用代码、重复计算,比报错的代码更让人崩溃。

我见过一位候选人,在笔试卷上写了一段BFS,代码里居然带了完整的输入输出调试信息没删掉,这给人留下的印象非常不专业。考场上时间再紧,也一定要养成提交前清理调试代码的习惯。

4.2 从“能AC题目”到“高质量编码”的三个层次

我把自己的编码能力提升路径总结成三个阶段,你看看自己在哪个位置:

第一阶段:能针对个别题目写出正确答案,但思路依赖“背模板”,换一道新题就卡壳。

第二阶段:能自主推导常见算法套路,知道BFS、DFS、DP、二分这类算法分别适用于什么场景,写出来的代码格式规范,边界问题考虑齐全。

第三阶段:能通过建立“模型映射”,把新题快速归类为已知的算法模型,并且能在有限时间内完成编码和验证。

京东2017这组题,恰恰就是帮你从第一阶段走向后续阶段的绝佳训练材料。它没有超纲内容,也不依赖偏门技巧,只要你认真做、认真总结,每一题都能转化为你的通用能力。我特别建议你把每道题都做三遍:第一遍不设限,怎么顺手怎么写;第二遍限制时间,模拟笔试环境;第三遍,尝试用不同的解法来实现,对比时间和空间复杂度。这样做完一套题,收获会非常显著。

4.3 考场时间分配策略

还有一点非常关键的考场心得:编程题的题量通常不多,但每道题需要调试的时间常常比你预想的长。我的建议是,开考后先快速扫一遍所有编程题,判断每道题对自己来说是大题还是小题。

如果遇到一眼就有思路的题,尽快写,写完了先别急着交,留时间检查边界。如果遇到完全没有思路的题,先跳过,去做后面的题,保证能拿到的分一分不丢。等基础题都AC了,再回头啃难题,心态完全不同。

一个我反复强调的细节是:笔试系统一般要求你提交完整代码,而不是只提交函数体,但很多在线编程平台会自动帮你处理输入输出,所以你只需要实现核心函数。如果你不确定平台规则,第一题可以先花30秒做一个“空函数提交”测试,看看返回什么,再决定后续的写法。这个技巧虽小,但能帮你避免格式错误带来的无谓扣分。

5. 常见问题与独家避坑指南

最后这个部分,我把自己备考和后来辅导学弟学妹过程中,最常见的坑给揪出来。这里面既有技术层面的,也有心态层面的,希望你能绕开。

5.1 刷题数量至上:方向跑偏的典型表现

“我刷了500题,为什么笔试还是挂?”每次听到这句话,我就想问:你是刷了500题,还是把同一道题做了500遍?刷题的作用不是让你“见过更多题”,而是让你“在遇到没见过题时有足够的解题套路可用”。

我见过太多考生,写了一道京东真题,看完题解觉得“哦原来是DP”,然后马不停蹄刷下一题。这是完全无效的。正确姿势是:做完一道题后,至少做三件事——第一,不看题解,重新写一遍;第二,总结这道题属于哪个算法模型;第三,找到一两道同类型的题,趁热打铁巩固。所以不必贪多,能把京东这套题做到这种程度,笔试基本就稳了。

5.2 阅读输入不仔细:最容易控制的高频扣分点

京东的笔试题有一个特点,就是题干往往较长,有很多业务化的描述。有些同学读题读到一半,就迫不及待开始编码,结果写完才发现“哦,原来输入不止一组数据”或者“原来要按照字典序输出”。

我的习惯是,读题阶段至少花两分钟把第一段题目描述和最后一段输入输出说明都完整看完,再动手。如果题目上说“多组测试数据”,就要记得外层套一层while循环。对这种问题,我建议你在草稿纸上写下:输入类型、输出要求、边界条件、是否多组,四个要点再动笔。

5.3 过度追求最优解:笔试中的隐形杀手

刚刷题的人容易陷入一种心态:看到一道题,总想找到传说中的“最优解”,仿佛不用上最高级的算法就对不起这道题。

但笔试拼的是分数,分数是按测试点算的。你能用O(n^2)的算法AC一个n=10^4的题,你是拿满分;你用O(n)的算法想了半小时没写出来,你拿零分。我见过不少真实案例,都是因为“想在考场上给一个优雅解”反而把时间耗尽。正确的策略是:先写暴力解法拿基础分,再考虑优化。暴力解并不是丢人,它在很多情况下是通往最优解的第一步。

5.4 真题和变体之间的学习留白

还有一个秘密,很多人刷真题时没有意识到:京东这套题中的很多题,后来都在其他公司的考试中“换壳登场”。比如股票买卖、网格最短步数、最小正整数缺失,分别套过“兼职赚钱”“寻宝地图”“整理工牌”之类的故事外壳。

所以学习时务必把题目还原成算法模型来记忆:看到“求最少步数”联想到BFS或DP,看到“最大利润”联想到状态机或二分贪心,看到“缺失数字”联想到原地哈希或位运算。背书是背不完的,但把模型练熟了,万变不离其宗。

5.5 心态与健康:笔试最后的隐形竞争力

最后一个看似和编程无关、实际上非常影响发挥的点,就是身体状态和心态。笔试通常需要连续高强度用脑两小时,如果前一晚熬夜刷题,第二天精神状态一定很差。我自己当年笔试前夜就是失眠加焦虑,第二天写代码的时候脑子像灌了浆糊,本来能做出来的题愣是卡了四十分钟。

后来我给自己定了一个规矩:笔试前一天不再碰新题,只简单复习笔记和错题;晚上11点前上床,不带手机进卧室;第二天开考前做十分钟深呼吸。这个习惯一直保留到我后来工作后的每一次线上技术考核。听起来很玄学,但实测非常有效。基本功是平时积累的,考场上比的是谁发挥得稳。把自己调整到能打出全部水平的状态,比多刷十道题重要得多。

京东2017校招编程题这套题,我一直认为它是校招笔试训练的“黄金材料”,难度适中、考点全面、和业务结合紧密。如果你正在准备技术岗校招,不妨把这套题认真吃透,甚至可以做上两遍三遍。这个过程中收获的,绝不仅仅是几道题的答案,而是一套能陪伴你整个职业生涯的算法思维和编码习惯。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询