刚看到一个挺有意思的帖子,有网友分享他们组的Leader已经40岁了,仍然每天泡在一线写核心代码,空闲时还会翻看 Go 的源码。
帖子里说,楼主好奇地问他,担不担心被优化。这位Leader笑着回应,大意是:如果你到了35岁,还需要跟25岁的年轻人拼手速、拼加班,那确实危险。但如果你能解决他们解决不了的问题,你就是团队里的宝贝。

我觉得这件事,与其说是内卷,不如说是关于价值感的体现。这位Leader并非在证明自己还能“熬夜打螺丝”,而是在持续构筑自己的不可替代性——能够拆解复杂难题、为项目兜底、带领团队前进,这才是资深工程师真正的护城河。
当然,并非人人都要去深究源码,但至少别让自己活成一颗“谁都能替换的螺丝钉”。与其每天焦虑“我几岁会被优化”,不如换个角度思考:在当前的工作中,我的离开是否会让事情明显变得更难?
算法实战:宝石与石头
昨晚临下班前,我顺手点开LeetCode,刷到一道对新手很友好的题目——“宝石与石头”。这道题很多人在初学算法时都会遇到,思路清晰,很适合拿来练手,顺便聊聊用 Python 实现的几种思路。
题目的描述很简单: 给你两个字符串,jewels 代表宝石的类型,字符串中的每个字符都是一种独特的宝石;stones 代表你拥有的石头,每个字符代表一块石头的类型。问题就是,在你所有的石头中,有多少块是宝石?
举个例子:
jewels = "aA"
stones = "aAAbbbb"
石头序列是:a A A b b b b,将其与宝石种类 aA 比对,匹配的宝石是 a A A,所以答案是 3。需要注意,题目是区分大小写的,a 和 A 被视为两种不同的宝石。
思路一:暴力比对
最直观的想法,就像我们在一堆杂物里找东西。拿起一块石头,然后去“宝石清单”里逐个比对,看看它是不是宝石,如果是就计数加一。用代码实现大概是这样:
def numJewelsInStones(jewels: str, stones: str) -> int:
ans = 0
for ch in stones: # 遍历每一块石头
for j in jewels: # 在宝石列表里挨个比对
if ch == j:
ans += 1
break # 找到了就跳出内层循环,处理下一块石头
return ans
这个写法非常直白,一看就懂,就是两层循环嵌套。但是,我们分析一下复杂度:假设宝石种类有 m 个,石头有 n 块,那么每块石头在最坏情况下需要比对 m 次,总的时间复杂度就是 O(m * n)。在这道题常见的数据范围内,这样写也能通过。但如果在面试中,面试官很可能会追问一句:“有没有优化空间?”
思路二:利用集合(Set)优化
优化的核心在于加快“判断某个字符是否属于宝石集合”这个操作。对于字符串,使用 in 操作符进行成员查找,本质上需要遍历,效率不高。而Python中的 set(集合)数据结构,其“成员是否存在”的查询操作平均时间复杂度是 O(1),即常数时间。
因此,我们可以先把所有宝石类型放入一个集合中,然后只需遍历一次石头字符串即可:
def numJewelsInStones(jewels: str, stones: str) -> int:
jewel_set = set(jewels) # 例如 "aA" -> {'a', 'A'}
ans = 0
for ch in stones:
if ch in jewel_set: # O(1) 时间复杂度的查找
ans += 1
return ans
这样,时间复杂度就降为了 O(m + n):构建集合需要遍历一次 jewels,统计数量需要遍历一次 stones。对于大多数情况,这已经足够高效和简洁。
思路三:更Pythonic的写法
如果你对Python已经比较熟悉,这道题还可以写得更简洁一些,利用生成器表达式和 sum 函数一行搞定计数:
def numJewelsInStones(jewels: str, stones: str) -> int:
jewel_set = set(jewels)
return sum(1 for ch in stones if ch in jewel_set)
这里的 sum 函数对一个生成器表达式进行求和。生成器会遍历 stones,每当遇到一块宝石(ch in jewel_set 为真)就产生一个 1,最后将这些 1 加起来就是宝石的总数。这种写法既简洁又易于阅读,是Python中常见的惯用法。
需要注意的细节
有几个小细节,初学者容易忽略:
- 空字符串处理:如果
jewels 是空字符串,意味着没有宝石,那么无论 stones 是什么,结果都应为0。如果 stones 是空字符串,遍历结果自然也是0。上面的代码都能自然地处理这些边界情况,无需额外写 if 判断。
- 字符去重:题目通常会说明
jewels 中的字符互不相同。但即便没说明,使用 set(jewels) 已经自动完成了去重,保证了逻辑的正确性。
通过解决这道题,你可以巩固几个重要的编程思维:
- 将频繁的“查找是否存在”操作,优先考虑使用哈希表(在Python中是
set 或 dict)来优化。
- 看到多重循环时,思考是否可以通过数据预处理(如构建查找表)来降低复杂度。
- 善用Python标准库提供的高效数据结构(如
set, dict),它们是提升代码性能的利器。
下次如果在面试或实际开发中遇到类似问题,先写出清晰的暴力解法,再自然地引出基于哈希集合的优化方案,并阐述复杂度变化,就能很好地展示你的问题分析和解决能力。
如果你对这类技术话题和实战编程感兴趣,欢迎来 云栈社区 交流讨论,这里聚集了许多乐于分享和探讨的开发者。