刚刷到这个帖,我第一反应就是,互联网这行是真的把人惯坏了,也把人吓坏了。40+,之前P8,年薪130万,歇了快两年,现在还能拿到70万offer,这放别的行业都不是“犹豫”,是做梦都得笑醒。

打开网易新闻 查看精彩图片

可放大厂语境里,又确实会拧巴,心里那根线还吊在过去那个价位上,总觉得一旦降下来,后面就很难抬头了。

但话又说回来,空窗两年还能有人接,已经说明市场没完全翻脸。很多人不是嫌70万少,是接受不了自己从“高配人生”切到“正常行情”。这玩意最难受的不是钱少了,是身份感往下掉半格。你说他矫情吧,也不全是,毕竟130到70这个落差,搁谁都得坐那儿发会儿呆。

算法题: 神奇字符串

这题看着像字符串,真下手的时候,很多人第一反应还是去“构造整个串”。写着写着就容易别扭:一边生成,一边数 1 的个数,代码不长,但很容易把指针绕晕。

“神奇字符串”的坑,不在定义多复杂,而在它自己描述自己。

题目的规则是这样的:字符串只由 12 组成,把连续相同字符的长度写出来,恰好又能得到它自己。开头固定是 122 。往后推的时候,当前这一位到底要补几个字符,不是你拍脑袋定的,是前面已经生成好的数字告诉你的。

这地方我一般不建议先想数学公式,先把“谁决定谁”捋顺。

比如一开始有:

s = [1, 2, 2]

现在要继续补内容。补几个?看 s[i] 。补什么?看当前应该写 1 还是 2 。补完以后,数字切换,继续往后走。

关键代码我会写成这样:

defmagicalString(n: int) -> int:
if n <= 0:
return0
if n <= 3:
return1

s = [1, 2, 2]
i = 2
next_num = 1
ones = 1

while len(s) < n:
repeat = s[i]
for _ in range(repeat):
s.append(next_num)
if next_num == 1 and len(s) <= n:
ones += 1
next_num = 2 if next_num == 1 else1
i += 1

return ones

这段代码有两个位置容易写错。

一个是 repeat = s[i] 。这里不是固定补 1 个,也不是看前一个字符补,而是看当前“读指针”指向的值。它是 1 就补 1 次,是 2 就补 2 次。

另一个是统计 1 的个数时,必须卡住 len(s) <= n 。因为最后一次追加,可能会把长度从 n-1 直接补到 n+1 ,多出来的那位不能算进去。这个地方如果偷懒,结果就会偏 1,我见过不少人栽在这。

n = 6 走一遍,大概是这样:

  • 初始: 122

  • 看第 3 位是 2 ,补两个 1 ,变成 12211

  • 下一轮该补 2 ,看当前位是 1 ,补一个 2

  • 得到 122112

前 6 个字符里, 1 一共有 3 个。

复杂度其实不高。虽然看起来像一边扩容一边遍历,但每个字符最多追加一次,所以时间复杂度O(n) ,空间复杂度也是 O(n) 。这题没有必要为了省那点空间把写法搞得特别拧巴,比赛和面试里,稳比炫重要。

这题说白了不是考字符串操作快不快,而是考你能不能接受“结果反过来指导生成过程”这种写法。谁负责读,谁负责写,谁负责切换字符,这三个角色别混,题就顺了。