Leader今年40了,依然在一线写核心代码,我问他担不担心被优化, 他笑着说:如果你到了35岁,还要跟25岁的人拼手速~
刚看到个贴子,说有网友吐槽:他们组的Leader,40岁了还天天趴一线写核心代码,闲了还啃Go源码。
网友问他怕不怕被优化,他来句大实话:35岁还在跟25岁拼手速拼熬夜,那肯定危险;但你要是能搞定别人搞不定的事,你就是团队的宝。
我觉得这事吧,关键不在“写不写代码”,而在你有没有不可替代的能力:能顶住线上事故,能拍板技术方案,能把业务理顺,让一群年轻人少走弯路。
说到底,职场从来不按身份证决定去留,只按“你解决问题的上限”给价。
与其纠结年龄焦虑,不如问问自己:现在这点本事,离“别人搞不定就会想到你”,还有多远?只要在往这个方向走,被优化的概率就会一点点降低。
算法题:宝石与石头
直接说事儿哈,就是那个很经典的小题:宝石与石头,LeetCode 上那道。
大概意思是这样的:
有一个字符串 jewels,里边的每一个字符,代表一种“宝石类型”还有一个字符串 stones,表示你手上所有的石头问: stones里面,有多少个字符,是属于“宝石类型”的
举个小例子:
jewels = "aA"
stones = "aAAbbbb"
stones 里面有三个是宝石:a、A、A,所以答案是 3。
注意一点:大小写是区分的,a 跟 A 不一样。
如果完全不想动脑子,一个很自然的写法就是: 对于 stones 里的每一个字符 c,看看它是不是在 jewels 里,如果是就 +1。
翻成 Python 差不多这样:
defnumJewelsInStones(jewels: str, stones: str) -> int:
count = 0
for c in stones:
if c in jewels: # 每次都在 jewels 里找一圈
count += 1
return count
这个写法好处是:谁都看得懂。 但小问题也很明显:如果 stones 很长,每个字符都要在 jewels 里扫一遍。
时间复杂度大概是 O(len(stones) * len(jewels))。 在这道题里其实也够用,但既然是写算法文章,咱们还是稍微讲讲优化。
用集合 set 优化一下查找
关键点:jewels 只是用来“判断某个字符是不是宝石类型”,查不查询顺序完全不重要。 这种场景,拿 Python 的 set 来做就很合适。
set 查找一个元素是不是在里面,平均时间复杂度是 O(1), 比字符串的 in (平均 O(n))快多了。
改造一下:
defnumJewelsInStones(jewels: str, stones: str) -> int:
jewel_set = set(jewels) # 把宝石类型放到集合里
count = 0
for c in stones:
if c in jewel_set: # 现在查找是 O(1)
count += 1
return count
这样整体时间复杂度就变成了:
建集合: O(len(jewels))遍历 stones: O(len(stones))
加起来就是 O(len(jewels) + len(stones)),已经是这题能想到的比较理想的复杂度了。
要是你平时习惯用一行解决问题,也可以写成这样:
defnumJewelsInStones(jewels: str, stones: str) -> int:
jewel_set = set(jewels)
return sum(1for c in stones if c in jewel_set)
sum(1 for c in stones if ...) 就是数一数有多少个满足条件的字符。 逻辑跟上一版一模一样,只是写得更“紧凑”一点,看你个人习惯。
就这题本身其实没啥大坑,但写代码的时候,有几个小点可以顺手注意下:
别在循环里反复
set(jewels)有人这么写过:for c in stones:
if c in set(jewels): # 这里每次都会重新建一个 set
...这样就变成
O(len(stones) * len(jewels)),还比最原始的暴力多了一步建集合的开销,相当于白搞。如果字符可能很多种,set 比 list / str 更合适
in对 list / str 是线性扫描,对 set / dict 才是哈希查找。 以后只要场景是“频繁判断某个东西在不在集合里”,优先往 set 上靠就完事。不要想太多数据结构这题完全用不到什么复杂结构,比如字典统计次数啊之类的, 因为题目只问“有多少个是宝石”,并不要求分类型计数。
当然,要是你自己想扩展一下题目也行,比如改成: “统计每种宝石在 stones 里各出现了几次”,那就可以这样:
from collections import Counter
defcountJewelsDetail(jewels: str, stones: str) -> dict:
jewel_set = set(jewels)
counter = Counter(stones)
result = {}
for ch in jewel_set:
if ch in counter:
result[ch] = counter[ch]
return result
这个算是在原题基础上的一个小升级玩法。
整个题的核心就一句话:把宝石类型丢进 set,然后数 stones 里有多少个字符在这个 set 里,就够了。
-END-
我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html
虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB