年薪90万,税后到手也就68万,天天加班到凌晨一点,回家还被老婆数落:你这是拿命换钱,值当吗?
刚看到个贴子,说有哥们年薪90万,税后到手68万,天天加班到凌晨一点,回家还被老婆说“拿命换钱不值”,一年到头竟然只存20万出头。
网友回帖我看了,有的说赶紧辞职保命要紧,有的说装什么穷,一年存20万不少了。怎么说呢,我觉得关键不是钱多钱少,而是这家人谁都没搞清:我到底在为谁拼、拼到什么程度算够。
天天干到一点,人身体总要还债的;老婆一个人管全家的开销和情绪,也迟早会爆炸。与其吵“值不值”,不如夫妻俩把账摊开算一算:房贷、父母、孩子、自己想要的生活,各自排个优先级,再决定是换工作、降杠杆,还是干脆休整一段。
钱重要,但命更重要,关系也重要。能一起算账、一起扛事的家庭,比任何年薪数字都更抗风险。
力
算法题:自定义字符串排序
昨天加班到快十一点,在公司楼下便利店买水的时候,隔壁组一个小伙子跟我吐槽:“东哥,Python 排序都写麻了,结果被一个‘自定义字符串排序’干懵了……” 我一听,这不就是典型面试题嘛,正好拿来跟你们唠一唠。
给你两个字符串:
order:排序规则,比如"cba"s:随便乱放的字符串,比如"abcd"
要求把 s 重新排个序,让它尽量按照 order 的顺序来排。 举个具体的:
order = "cba"s = "abcd"
那结果应该是:"cbad"
因为在 order 里,c 在最前,然后是 b,然后是 a,d 在规则里没出现,就随便丢后面就行,一般默认扔到最后,保持原来的相对顺序也可以。
我当时在便利店就跟他说,你既然用 Python,那就别跟排序硬刚,用好人家给的现成轮子就行。
思路很简单:
先把 order变成一个“优先级表”,类似:{'c': 0, 'b': 1, 'a': 2}排序 s的时候,根据这个优先级表给每个字符一个“权重”不在 order里的,就给个很大的权重,让它们自动排在最后
代码直接上:
defcustom_sort_string(order: str, s: str) -> str:
# 1. 规则字符串里的每个字符,给一个优先级,数字越小越靠前
rank = {ch: i for i, ch in enumerate(order)}
# 2. 用 sorted 排 s,key 决定排序依据
# 不在 rank 里的字符,用 len(order) 当默认优先级,自动排到后面
defsort_key(ch: str) -> int:
return rank.get(ch, len(order))
sorted_chars = sorted(s, key=sort_key)
return"".join(sorted_chars)
if __name__ == "__main__":
print(custom_sort_string("cba", "abcd")) # cbad
你看,逻辑其实就一句话:“根据我自己定义的优先级排序”,剩下都交给 sorted 这个内置函数干。
时间复杂度呢,也别背公式,按套路来:
建 rank表:扫一遍order,O(len(order))排序: sorted是快排/TimSort 这一类,复杂度差不多O(n log n),这里的n = len(s)所以整体就是: O(len(order) + len(s) log len(s))
一般面试说到这就够了,正常业务场景也完全能打。
但是有时候面试官爱较真,会问一句:“能不能更快,不用排序?” 那咱就再较真一下。
想象一下,这题的本质是:按 order 规定的顺序,把 s 里的字符分组拼起来。
那我干嘛非要“比较大小”呢?我可以直接数啊:
先统计 s里面每个字符出现了几次按 order的顺序,把这些字符按次数拼出来最后再把那些不在 order里的字符,原样补上
用 Python 写出来是这样:
from collections import Counter
defcustom_sort_string_fast(order: str, s: str) -> str:
# 1. 统计 s 每个字符的出现次数
cnt = Counter(s)
res = []
# 2. 先按照 order 的顺序,把在规则里的字符拼完
for ch in order:
if ch in cnt:
res.append(ch * cnt[ch])
del cnt[ch] # 用完就删,后面剩的就是“不在 order 里的”
# 3. 把剩下那些没有规则的字符,随便追加上去
for ch, c in cnt.items():
res.append(ch * c)
return"".join(res)
if __name__ == "__main__":
print(custom_sort_string_fast("cba", "abcd")) # cbad
这个版本的时间复杂度就很好看了:
统计次数:扫一遍 s,O(len(s))按 order拼接:O(len(order))拼剩下的:最多再扫一次字符种类数,通常远小于 len(s)总体可以看成: O(len(s) + len(order)),没有排序那一层log n了
面试官要是问你“为什么更快”,你就一句话:“前面那个是基于比较的排序,这个是计数型的,直接用次数+规则拼接”,就显得挺有数。
-END-
我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html
虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB