某老板娘:试用期结束了,你没通过考核,试用期没有工资!
刚刷到这个,真给我看乐了。
老板说试用期结束了,你没通过考核,所以试用期没有工资。啊?这话听着就像把公司当自己家游戏厅了,规则现编,输了员工买单。
试用期是试用,不是白干。人家天天打卡、干活、交付,你最后一句“不通过”就想把工资抹了,这不是考核,这是空手套打工人。 老板可能觉得自己挺聪明,省了一笔钱,实际上这话一说出口,HR估计都得沉默两秒。
最搞笑的是,有些公司还真把“试用期”当免死金牌,想留就留,想踢就踢,钱也想赖。问题是员工不是来体验生活的,房租水电饭钱哪个不真要钱?
这种老板别考核员工了,先考核一下自己懂不懂当老板吧。
字符串反转这题,看着太短,反而容易写飘。
尤其是 Python,一上来写:
s = s[::-1]
本地一跑,结果是对的。提交到要求“原地修改”的题目里,可能直接不认。
这个地方我一般先看题目给的数据结构。如果传进来的是字符串,那字符串不可变,返回一个新字符串没问题;如果传进来的是字符数组,比如:
["h", "e", "l", "l", "o"]
那就别偷懒了,题目大概率要你在原数组上改。
最容易误判的是这种写法:
defreverse_string(chars):
chars = chars[::-1]
这段代码看着像反转了,其实只是让局部变量 chars 指向了一个新列表。外面的那个列表,没动。
写个现场小测试就能看出来:
data = ["h", "e", "l", "l", "o"]
defbad_reverse(chars):
chars = chars[::-1]
bad_reverse(data)
print(data)
输出还是:
['h', 'e', 'l', 'l', 'o']
这种 bug 不难,但很讨厌。因为你盯着函数里面看,觉得没问题;真正的问题在“引用没改到原对象”。
这题最稳的写法,就是双指针。
defreverse_string(chars):
left = 0
right = len(chars) - 1
while left < right:
chars[left], chars[right] = chars[right], chars[left]
left += 1
right -= 1
没花活。
左边一个指针,右边一个指针,每次交换两个字符,然后往中间收。直到两个指针撞上,或者交错,反转就结束了。
拿 "hello" 走一遍:
["h", "e", "l", "l", "o"]
第一轮交换 h 和 o:
["o", "e", "l", "l", "h"]
第二轮交换 e 和 l:
["o", "l", "l", "e", "h"]
中间那个 l 不用管,它自己就在正确位置上。
如果是偶数长度,比如:
["c", "o", "d", "e"]
流程也一样:
data = ["c", "o", "d", "e"]
reverse_string(data)
print(data)
输出:
['e', 'd', 'o', 'c']
这题有个小细节:循环条件要写 left < right,别写复杂了。写成 left <= right 也能跑,但中间那个字符会跟自己交换一次,没有意义。算法题里这种多余动作不一定扣分,但我不太喜欢,说明边界没想清楚。
时间复杂度是 O(n),因为每个字符最多参与一次交换。
空间复杂度是 O(1),因为没有重新开一个列表,只用了两个指针变量。
如果题目不是要求原地修改,而是让你返回一个新字符串,那 Python 可以这么写:
defreverse_text(text):
buf = list(text)
left, right = 0, len(buf) - 1
while left < right:
buf[left], buf[right] = buf[right], buf[left]
left += 1
right -= 1
return"".join(buf)
为什么不直接用 text[::-1]?
面试或者刷题时可以用,但你要知道它背后会创建新对象。题目考“反转字符串”,多数时候不是考你会不会切片,而是看你能不能把原地修改、边界、复杂度这几个点讲清楚。
这题真正该记住的不是代码,而是判断顺序:
先看输入是字符串还是字符数组。
再看题目要返回新值,还是原地修改。
最后再决定能不能用切片。
顺序错了,代码越短,坑越隐蔽。