100道Python经典练手题:从基础语法到算法实战,附精讲与刷题路线
2026/9/17 8:45:56 网站建设 项目流程

如果你正在学Python,大概率已经见过不少“200道练习题”“500道面试题”的资源。但真练下来你会发现,大部分题单要么简单到只有print,要么直接跳进算法题,中间缺少一个循序渐进的过程。今天说的这套“100道Python经典练手题”,是这些年我实际带新人时反复调整过的一套题单:从print语句、变量交换开始,一路覆盖数据类型、循环、函数、字符串、文件、面向对象、标准库,最后落到二分、排序、动态规划和综合项目。每道题都标了核心考点,能直接对着练、对着查、对着复盘。

这套题单适合谁?刚装好Python、连VSCode或PyCharm还没配明白的新手,可以从第1题慢慢推;已经能写循环和函数的初级开发者,可以重点刷函数模块之后的内容;准备面试的人,可以直接跳到栈、装饰器和动态规划题目。它解决的核心问题只有一个:让你不是“看过Python”,而是“真能用Python写出东西”。下面我就把这套题单的整体设计、完整分类、典型精讲和刷题方法一次性摊开讲。

1. 为什么说这100道题值得“苦练”

1.1 练手题和面试题、项目题有什么区别

很多人学Python有个误区:要么只看语法教程不动手,要么一上来就做爬虫、Web项目,结果卡在环境配置和框架细节里,语法反而没打牢。面试题偏重“考察”,用到的知识面窄,而且经常有刁钻边界;项目题偏重“工程”,需要前置掌握的东西太多,不适合拿来当日常训练。练手题的定位正好在两者之间:每道题目标明确、单点突破、反馈快,写完一行代码马上能看到结果,非常适合用来建立“代码手感”。

“苦练”这两个字,重点在“苦”上。Python语法看起来简洁,但真到用的时候,你会发现列表切片越界、闭包变量绑定、装饰器参数传递、浅拷贝深拷贝,全是坑。这些坑不是看书能看出来的,必须亲手踩一遍再爬出来,记忆才深刻。我见过太多人“眼睛会了手不会”,一到自己写就报错,原因就是练得不够。这100道题就是把Python里最容易出问题的知识点,拆成一个个小任务,让你在安全的环境里反复摔打。

另外,练手题还有一个容易被忽略的价值:它能帮你积累“可复用代码片段”。比如第57题的括号匹配,核心是一个栈的使用模板,后面做计算器、HTML标签解析都能用到;第44题的装饰器计时,稍微改改就能变成项目里的日志装饰器。刷题的意义不是背答案,而是把这些高频片段变成肌肉记忆。

1.2 这套题单的整体设计思路

这100道题不是随便凑数的。第一,覆盖了Python入门的全部核心语法节点:基础输入输出、条件循环、列表字典字符串、函数、文件异常、面向对象、常用标准库、基础算法,一共9大模块。第二,难度按“认知负荷”递增,从单行代码能解决的问题,逐步过渡到需要拆解状态、设计数据结构的题目。第三,每个模块内都有几道“硬菜”,比如螺旋矩阵、汉诺塔、装饰器计时、括号匹配、最大子数组和,这些题不是简单Ctrl+C能抄过去的,必须真正理解思路才能写出来。

选这些题的标准也很简单:要么是日常写代码最高频用到的能力,比如字符串处理、字典操作、文件读写;要么是面试常考的基础算法,比如二分查找、快排、动态规划。那些偏门、冷门、只在竞赛里存在的题目,我一律没放进去。把这100道题吃透,不敢说成为Python大师,但应付日常工作开发、大部分初级和中级岗位面试笔试,完全够用。

提示:这套题单建议按顺序刷,但不用平均用力。如果你时间有限,优先保证函数模块和算法模块的题目质量,这两块是新手最容易“断层”的地方。

2. 一百道经典练手题全题单:按模块分类,配核心考点

下面把100道题按模块完整列一遍,每道题都标注了核心考点。表格里的描述就是解析线索,刷题时先按考点自己写,写不出来再回来看对应章节的精讲,效果最好。

2.1 基础语法与输入输出(第1-10题)

这个模块是热身区,目的不是让你学会print,而是让你熟悉Python的运行方式、类型转换、字符串格式化和条件分支的基础写法。新手别觉得简单就跳,这里有个隐藏能力:把“人话描述的需求”翻译成“代码操作”,这种翻译能力从第1题就开始训练了。

题号题目核心考点
1改造版Hello Worldprint的sep、end参数与转义字符
2交换两个变量的值临时变量、元组解包、加减法交换
3数字类型转换“变形记”int/float/str互相转换及异常输入处理
4从键盘输入半径计算圆面积周长input、math模块、格式化保留小数
5反转一个三位数(120反转为21)取余取整运算、字符串切片
6字符编码查看与转换ord()、chr()、ASCII与Unicode的关系
7摄氏温度与华氏温度互转分支判断、公式计算
8格式化输出学生成绩表f-string对齐、整数与浮点数格式控制
9时间格式互转:时分秒与总秒数乘除取整、复合赋值
10BMI计算器多分支条件、浮点数精度处理

2.2 数据类型与序列操作(第11-25题)

列表、字典、字符串、元组是Python里最常用的四种数据容器,大部分程序本质上都是在操作它们。这个模块的题不会给你现成的API提示,比如“列表去重”不允许直接看set方法的用法,要求你自己推导;矩阵转置要求你理解嵌套列表的索引规律。这个模块刷完,Python的数据结构基本功就稳了一半。

题号题目核心考点
11列表去重且保持原顺序集合去重与列表遍历的顺序控制
12统计字符串中每个字符的出现次数字典计数、collections.Counter
13不用内置函数求列表最大值最小值平均值手写遍历、初始化哨兵值
14判断两个字符串是否为字母异位词排序后比较、计数器比较
15找出列表中第二大的数一次遍历、边界值处理
16自己实现列表反转切片步长为负、双指针交换
17字符串压缩(aabbbc变为a2b3c1)循环拼接、相邻字符比较
18字典按值排序sorted函数、lambda表达式
19矩阵转置嵌套列表、zip拆包
20求两个列表的交集、并集、差集集合运算、类型转换
21元组拆包提取学生信息多变量赋值、下划线占位
22统计英文句子中的单词数split切分、正则去标点
23嵌套列表扁平化递归、循环逐层展开
24求多个字符串的最长公共前缀逐位比较、zip配合enumerate
25生成n阶螺旋矩阵四方向边界模拟、while循环状态控制

2.3 条件与循环逻辑(第26-40题)

这个模块是经典“编程思维”训练区,几乎不依赖任何高级特性,全靠对循环、分支、边界条件的掌控。很多人写代码容易“差一个数”或者“多跑一次”,核心就是循环条件没想清楚。九九乘法表、素数、水仙花数这些题看起来老土,但它们能让你的循环肌肉记忆变得非常扎实。

题号题目核心考点
26判断闰年if条件组合、模运算
27百分制成绩转等级制多分支判断、逻辑运算符
28求所有三位水仙花数拆分个十百位、幂运算
29打印九九乘法表嵌套for、格式化对齐
30斐波那契数列前n项递推迭代、变量滚动更新
31判断素数并输出100以内全部素数试除法、循环提前break
32求最大公约数和最小公倍数辗转相除法、公式推导
33判断整数和字符串是否为回文反转比较、双指针
34十进制转二进制、八进制、十六进制除基取余、循环拼接
35打印等腰三角形、菱形、空心正方形嵌套循环、空格与星号数量规律
36猜数字游戏random随机数、while循环与条件反馈
37鸡兔同笼:知道头脚数求数量穷举法、多元方程模拟
38将一个整数分解为质因数while嵌套、质因数递增判断
39小球自由落体反弹高度与总路程等比数列递推、浮点累加
40统计1到n中某个数字出现的总次数逐位拆解、循环计数

2.4 函数与模块(第41-52题)

很多初学者写代码喜欢把所有的逻辑堆在一起,换个数就得改代码。到函数模块,要求你用参数和返回值把逻辑“装进盒子”,这是从“写脚本”到“写程序”的分水岭。默认参数陷阱、*args、装饰器、闭包、生成器这些不仅是考试重点,也是实际项目里每天都会碰到的特性。这12道题值得反复咀嚼。

题号题目核心考点
41用牛顿迭代法实现自己的sqrt函数函数定义、迭代逼近
42默认参数使用列表的陷阱题可变对象做默认参数的问题
43用*args和**kwargs写求和函数参数收集、字典展开
44装饰器统计函数执行时间装饰器结构、time模块
45递归实现阶乘并设置递归保护递归出口、sys.setrecursionlimit
46lambda结合sorted对学生信息排序高阶函数、key参数
47用map/reduce/filter清洗成绩数据内置高阶函数组合
48生成器实现斐波那契数列yield关键字、惰性求值
49闭包计数器闭包保存状态、nonlocal声明
50自定义迭代器模拟range函数迭代器协议、iter__与__next
51偏函数实现批量单位转换functools.partial
52汉诺塔递归实现并输出移动步骤递归拆解、参数交换

2.5 字符串进阶与正则(第53-62题)

字符串处理在数据分析、爬虫、日志分析里是高频场景,而这部分恰恰是很多自学者的薄弱区。正则表达式单独拿出来讲题不多,但配合字符串方法能解决90%以上的文本处理需求。第57题括号匹配是“栈思想”的入门题,第60题最长不重复子串则是滑动窗口的雏形,建议多花时间。

题号题目核心考点
53反转句子中单词顺序但保持单词内部不变split切分、列表反转、join拼接
54用四种方法去掉字符串中的指定字符replace、列表推导、filter、正则
55驼峰命名转下划线命名正则边界、re.sub回调
56手机号中间四位脱敏字符串切片拼接、re.sub替换
57判断多种括号是否匹配栈、字典映射
58实现简易模板字符串解析find定位、replace、正则分组
59统计字符串中每个字符首次出现的位置字典记录、index陷阱
60找出字符串中最长不重复子串滑动窗口、集合去重
61单词首字母大写并保留连续空格title方法的替代实现
62下划线命名与驼峰命名互相转换正则分组、字符串拼接

2.6 文件处理与异常(第63-72题)

文件操作是Python最实用的能力之一,读写配置、日志分析、批量处理文件都是这个场景。这10道题让你把with语法、异常捕获、CSV和JSON处理全部过一遍。第66题自定义异常和第72题递归目录遍历,在真实项目里尤其常见,建议按“能直接交给同事用的标准”来写。

题号题目核心考点
63读取大文件统计行数和单词数with open、流式读取
64复制文件并比较大小shutil模块、文件流读写
65按日期切分日志文件正则提取日期、动态文件名
66自定义“余额不足”异常继承Exception、raise与except
67try/except/else/finally资源释放完整异常结构、finally作用
68读取JSON配置并与默认配置合并json模块、字典update归并
69CSV文件读写并统计平均成绩csv模块、DictReader
70合并多个txt文件并去重保存列表集合操作、文件批量处理
71检测文件编码并转成UTF-8codecs、编码错误处理
72递归遍历目录查找指定扩展名文件os.walk、os.path.join

2.7 面向对象与设计模式(第73-85题)

面向对象是Python进阶绕不开的一块。这里不要求你背概念,而是直接写类:银行账户、向量运算、单例、描述符、链表、栈队列……把这些代码写过一遍,你才能真正理解“类是对数据和行为的封装”这句话。第80题描述符和第82题观察者模式有一定难度,但无论做框架开发还是应对面试,都值得啃下来。

题号题目核心考点
73设计银行账户类(存款、取款、流水)类属性与实例方法
74实例方法、类方法、静态方法对比@classmethod与@staticmethod
75继承和多态:不同形状计算面积父类抽象、子类重写
76用property实现温度自动转换@property、setter
77用__slots__限制动态属性内存优化、属性白名单
78向量类支持加法和乘法add、__mul__运算符重载
79单例模式实现new、类变量控制
80描述符实现属性类型校验getset
81工厂模式:按类型创建对象条件分支创建产品类
82观察者模式:事件发布订阅列表维护观察者、消息通知
83链表节点类并实现反转链表节点引用、指针遍历
84用类实现栈和队列列表操作、先进后出/先进先出
85学员管理系统类协作、循环菜单、列表操作

2.8 常用标准库与算法思维(第86-100题)

最后15道题是“拔高区”:先熟悉datetime、random、collections、itertools、argparse、logging这些日常开发离不开的标准库,再上二分查找、排序算法、动态规划,最后落到一个综合性命令行项目上。第100题负担很重,但它把前面几十道题全部串了起来,相当于一次大考。

题号题目核心考点
86计算两个日期相差天数和星期几datetime模块、date对象
87生成6位验证码(字母+数字)random.choice、字符集拼接
88用Counter统计词频并输出TOP10Counter、most_common
89笛卡尔积生成扑克牌组合itertools.product
90用lru_cache加速递归斐波那契functools.lru_cache
91用argparse写命令行加法工具命令行参数解析
92os.path和pathlib路径操作练习路径拼接、判断文件目录
93logging日志同时输出到文件和终端logger配置、Handler绑定
94二分查找(递归与非递归)有序数组查找、边界更新
95手写冒泡、选择、插入排序三类排序实现与区别
96手写快速排序分治思想、基准值选择
97爬楼梯问题(动态规划入门)状态转移方程
98求最大子数组和(Kadane算法)连续子问题、贪心递推
99实现字典树Trie节点嵌套字典、前缀查找
100命令行学生成绩管理系统增删改查+统计+JSON持久化+菜单

3. 六道高频经典题精讲:从思路到完整代码

题单列完了,但光有题目没有答案,收藏了也练不动。下面挑6道覆盖不同难度层的经典题,把完整的思考过程和代码写出来。每道题我都会先说“拿到题怎么想”,再给代码,最后讲易错点,这样你能直接照着自己的思路对照。

3.1 变量交换的三种写法:基础题里藏着大知识点

第2题“交换两个变量的值”看似简单,但能拆出三种写法。新手通常只会临时变量法,写着写着就忘了变量覆盖的顺序;进阶者知道Python有元组解包;老手则明白,在某些底层场景里可以用加减法避免额外空间,但要注意溢出风险。

a, b = 3, 5 # 方法1:临时变量 tmp = a a = b b = tmp # 方法2:Python独有的元组解包(最推荐) a, b = b, a # 方法3:加减法(仅限数值类型) a = a + b b = a - b a = a - b

这道题真正想考的是“对变量的理解”:变量是对象的引用,交换的本质是重新绑定引用。元组解包之所以成立,是因为右边先构造了一个临时元组(b, a),再按位置依次赋值给a和b,所以不需要担心覆盖问题。新手写方法1时最容易犯的错是写成a = b; b = a,结果两个变量都变成同一个值。这不是粗心,而是没有建立“每一步执行后变量里存什么”的追踪意识。建议新手把每行代码执行后的a、b值都写在纸上,练两道题就能纠正过来。

3.2 温度转换:分支判断的标准范式

第7题“摄氏温度转华氏温度”本身就是一道完整的程序题:要有输入、有计算、有输出,还需要考虑用户输错的情况。很多人只写核心公式就收工,但实际开发中,输入数据是不可信的,所以正规写法必须处理异常。

try: celsius = float(input("请输入摄氏温度: ")) except ValueError: print("输入错误:请输入数字。") exit() fahrenheit = celsius * 9 / 5 + 32 print(f"{celsius:.1f}℃ = {fahrenheit:.1f}℉")

float(input(...))这一步融合了input和类型转换两个知识点。转换失败抛出的ValueError,由try/except接住并给出友好提示,这比让程序直接崩溃好得多。如果还想扩大范围,可以加一个单位参数,让用户输入“36.5C”或“97.7F”自动判断方向,这正好把第27题的多分支也练了。这种“先做核心功能,再补异常处理,最后扩展交互”的流程,就是我说的标准范式。

3.3 螺旋矩阵:四方向模拟是面试常客

第25题“螺旋矩阵”是典型的模拟类题目,思路不复杂,难在边界控制。面试时这种题最能看出候选人写代码的细致程度。想象一个n行n列的矩阵,你拿着笔从1开始顺时针画圈。程序的做法就是把这个画圈过程翻译成四个方向的循环:从左到右填充上边,从上到下填充右边,从右到左填充下边,从下到上填充左边,然后缩小边界,继续下一圈。

def spiral_matrix(n): matrix = [[0] * n for _ in range(n)] top, bottom, left, right = 0, n - 1, 0, n - 1 num = 1 while top <= bottom and left <= right: for col in range(left, right + 1): matrix[top][col] = num num += 1 top += 1 for row in range(top, bottom + 1): matrix[row][right] = num num += 1 right -= 1 if top <= bottom: for col in range(right, left - 1, -1): matrix[bottom][col] = num num += 1 bottom -= 1 if left <= right: for row in range(bottom, top - 1, -1): matrix[row][left] = num num += 1 left += 1 return matrix for row in spiral_matrix(4): print(row)

这段代码里有三个关键点。第一,[[0] * n for _ in range(n)]是创建n阶零矩阵的标准写法,不能写成[[0] * n] * n,后者会让所有行指向同一个列表,改一行全变。第二,每完成一个方向,对应的边界就要收缩,比如填充完上边后top += 1。第三,后两个方向的循环要加边界判断,否则n为奇数或循环到最后一行时会重复填充。运行结果的第4行会是[10, 11, 12, 1],对照这个结果能判断自己的方向控制是否正确。

3.4 用装饰器给函数计时:函数进阶必过的一关

第44题“装饰器统计函数执行时间”是Python进阶最经典的一道题。第一次接触装饰器的人很容易懵,因为代码里套了三层函数。拆开看其实不难:timer是“装饰器工厂”,接收一个原函数funcwrapper是“增强版函数”,它先记录时间,再调用func,最后打印耗时并返回结果;@timer语法糖就是告诉Python“执行下面这个函数时,自动用wrapper替换它”。

import time def timer(func): def wrapper(*args, **kwargs): start = time.perf_counter() result = func(*args, **kwargs) end = time.perf_counter() print(f"{func.__name__} 执行耗时: {end - start:.6f} 秒") return result return wrapper @timer def sum_square(n): total = 0 for i in range(1, n + 1): total += i * i return total print(sum_square(1000000))

time.perf_counter()而不是time.time(),是因为perf_counter专门用于测量短时间间隔,精度更高,受系统时间调整的影响更小。这里有一个高频易错点:wrapper的参数必须写成*args, **kwargs,因为被装饰的函数可能带任意参数,如果不做参数收集,原函数的参数就会传不进去。另一个易错点是wrapper内部必须return result,否则原函数的返回值会被吞掉,写出来变成了None。第47题的map/reduce/filter和第90题的lru_cache,本质上都是同一套“函数包装”思想,理解了装饰器,那些题都会顺畅很多。

3.5 括号匹配:用栈解决字符串问题

第57题“判断括号是否匹配”是栈最经典的应用。很多人在学校学过栈的定义,但不知道怎么写代码。思路一句话:遇到左括号就压栈,遇到右括号就检查栈顶是不是对应的左括号,是就弹出,不是就返回False。最后栈为空才说明全部匹配。

def is_valid(s: str) -> bool: stack = [] pairs = {')': '(', ']': '[', '}': '{'} for ch in s: if ch in '([{': stack.append(ch) elif ch in ')]}': if not stack or stack[-1] != pairs[ch]: return False stack.pop() return not stack print(is_valid("()[]{}")) print(is_valid("([)]")) print(is_valid("({[]})"))

三种典型输入对应三种结果:()[]{}返回True,因为每种括号都是标准的闭合;([)]返回False,虽然括号数量成对,但交叉嵌套是非法的;({[]})返回True,正确嵌套。这里最容易漏的处理是not stack判断:当输入只有右括号比如}时,栈为空,直接访问stack[-1]会抛IndexError,所以必须先把“栈为空”排除掉。理解了这道题,后续做“逆波兰表达式求值”“HTML标签匹配”都是换汤不换药。

3.6 最大子数组和:从暴力到动态规划的思维升级

第98题是算法模块的入门大师题:给定一个整数数组,求其中连续子数组的最大和。比如[-2, 1, -3, 4, -1, 2, 1, -5, 4]的最大子数组和是6,对应子数组[4, -1, 2, 1]。暴力法需要三重循环枚举所有子数组再求和,复杂度O(n^3),而Kadane算法能把复杂度降到O(n),核心就一句话:要么扩展当前子数组,要么以当前元素重新开始,取两者中较大的那个。

def max_subarray(nums): max_ending_here = nums[0] max_so_far = nums[0] for num in nums[1:]: max_ending_here = max(num, max_ending_here + num) max_so_far = max(max_so_far, max_ending_here) return max_so_far print(max_subarray([-2, 1, -3, 4, -1, 2, 1, -5, 4]))

手动推演一遍就明白了。遍历到4时,max_ending_here会变成4,因为4比4 + (-2)更大,此时表示“我决定从头开始一个新的子数组”;遍历到2时,max_ending_here变成5,因为2比2 + 3小,扩展它。关键是理解max_ending_here保存的永远是“以当前位置结尾的最大子数组和”,一旦它变成负数,后面的元素带着它只会更小,不如重置。这就是状态转移方程dp[i] = max(nums[i], dp[i-1] + nums[i])的直观理解,也是做各种动态规划题的基本思维模型——先找子问题,再写递推关系,最后优化空间。

4. 刷题方法、时间规划与避坑指南

4.1 按基础分层的刷题路径

这套题单虽然是从0开始排的,但不同基础的人,刷法应该不一样。

零基础的人,老老实实从第1题刷到第40题,先不碰函数和面向对象。这个阶段的目标是熟练使用变量、循环、列表和字典,遇到报错会看traceback。第25题螺旋矩阵如果卡住了,可以先放着往后学,等循环理解更透再回头补。

已经有语法基础、只是没做过题的人,重点在函数模块之后的内容。第41到第85题是提升区,尤其第42、43、44、49、57、70、76、80题,分别对应函数参数、装饰器、闭包、栈、文件、property、描述符等高频难点。做题时不要追求“跑通就行”,要问自己“换一种写法行不行”“如果输入特殊值会怎样”。

准备面试的人,先做第57、60、84、94、95、96、97、98、100题。这9道题直接对应栈、滑动窗口、队列、二分、排序、动态规划、综合设计,是笔试里出现频率最高的一批。做完之后建议把时间和空间复杂度标注在代码旁边,面试官问起来能对答如流。

4.2 四周实战时间规划表

每天留出1到1.5小时,按下面的节奏推进,四周刚好能过完一遍完整题单。

时间段刷题范围核心目标复盘重点
第一周第1-30题打牢语法基础和循环逻辑运行报错能不能独立看懂
第二周第31-57题掌握函数、字符串、正则、栈能否不看资料写出装饰器和括号匹配
第三周第58-85题攻克文件和面向对象类设计是否合理,对象间是否解耦
第四周第86-100题标准库与算法入门能否独立完成第100题综合项目

第一周和第而周(第二周)的任务是“量”,后两周是“质”。第三周开始,每道题写完要顺手补充测试用例,比如第60题的最长不重复子串,至少测空字符串、全相同字符、全部不重复三种情况。第四周的第100题不要直接写代码,先画一个功能清单,把“增删改查、统计平均分、JSON保存”拆成多个函数,再逐个实现,这就是从刷题到项目的过渡。

4.3 新手必踩的6个Python坑

刷题过程中,下面6个坑几乎每人都会踩至少一次,这里提前列出来,等于帮你省下几个小时的排查时间。

  • 默认参数使用可变对象。def append_item(item, lst=[]): lst.append(item); return lst,第二次调用时列表还保留着上一次的数据。原因是默认参数在函数定义时只创建一次,解决方法是默认值写成None,函数内部再赋值。
  • ==is混用。==比较值,is比较对象身份。小整数驻留、短字符串驻留等场景下两者结果偶尔相同,但列表、字典等可变对象绝不能这样用。
  • 在遍历列表的同时删除元素。for x in lst: lst.remove(x)会跳元素,因为删除后索引自动前移。正确做法是遍历副本for x in lst[:],或者用列表推导式过滤。
  • 对不可变类型做“原地修改”。字符串的replaceupper等方法的返回值才是新字符串,不少人忘了接住返回值,结果发现原字符串“没变”。
  • 浅拷贝误伤嵌套列表。new_list = old_list[:]只拷贝了外层,内层列表仍然是同一对象;需要深拷贝时用copy.deepcopy
  • 整数除法结果不对。两个整数用/会得到浮点数,如果希望整除,要用//;这个坑在写递归除法或需要精确整数结果的场景里特别隐蔽。

4.4 拿到一道题之后的标准思考流程

刷题盲目上手,容易越写越乱。我建议每道题都过一遍固定流程:第一步,读题后先把输入和输出写下来,包括边界情况;第二步,用自然语言描述解法,比如“先遍历列表,遇到大于max的就更新max”;第三步,构思需要几个变量,变量的初始值是什么;第四步,写代码并自测用例;第五步,复盘这段代码的时间复杂度和空间复杂度。

以第40题“统计1到n中数字x出现次数”为例。拿到题先写边界:n=1时返回什么,x=0时怎么处理,x大于9时怎么处理。然后思考解法,最简单的是把每个数字转成字符串后count,但这样不够高效;进一步优化是逐位分析,直接算每一位上x出现多少次。从“能跑”到“跑得更快”这个升级过程,就是面试官真正想考察的能力。所以刷题时,别满足于写出一种解法,有条件就再问自己一句:能不能少一层循环?能不能省掉临时变量?这种提问习惯,比多刷50道题都管用。

这100道题我自己带人刷过好几轮,最大的体会是:重要的不是“看起来懂”,而是“合上书能不能写出来”。每道题独立写对一遍,再隔一周不看答案重写一遍,才算真正消化。把做错的题单独存成一个文件,记录错误原因,两周后回头重新做,比连续刷完两遍新题效果好得多。到最后你把第100题完整写出来,再回头翻第一周的代码,会明显看到自己逻辑清晰了多少。那就是“苦练”最大的回报。

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

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

立即咨询