刷LeetCode最忌讳的就是“看答案-觉得自己懂了-换道题又卡住”
很多同事在公司内部刷题准备晋升面试时,经常陷入这种伪学习状态。其实大部分人不是逻辑不行,而是陷入了“记忆幻觉”,以为看懂了代码就等同于掌握了算法。
下一篇
把学习笔记当成代码来重构,这逻辑其实挺通的。 →
我试过一套极其简单但反直觉的实操流程,专门用来打破这种状态,核心就是:先口述解释,延迟后再盲写。
具体步骤如下:
一、正常解题。不管是暴力破解还是看题解,先把它跑通。
二、强制关掉编辑器。对着空气或者笔记本,像教小白一样把解题逻辑讲一遍。必须要把每一个变量的含义、循环的边界条件、为什么这么处理边界 case 讲清楚。
三、强制休息。离开电脑 10 分钟,或者干脆等第二天。
四、无参考重写。在完全不看之前的代码和笔记的情况下,重新从零实现一遍。
如果卡住了,只能看自己刚才写的“逻辑解释”,绝对不能看代码。
拿 3Sum 这种经典题来说,很多人第一反应是写三层循环,结果效率极低且去重逻辑写得极其恶心:
def threeSum(nums):
res = []
nums.sort()
for i in range(len(nums)):
for j in range(i+1, len(nums)):
for k in range(j+1, len(nums)):
if nums[i] + nums[j] + nums[k] == 0:
triple = [nums[i], nums[j], nums[k]]
if triple not in res: # 这种 O(n) 的检查简直是灾难
res.append(triple)
return res这种写法在公司 Code Review 时绝对会被怼死。按照上面的方法,我强迫自己先把双指针的逻辑口述清楚:“先排序,固定一个数,剩下的用左右指针逼近,和大了右移,小了左移,同时跳过重复值。”
把这个逻辑在脑子里跑通,休息一会儿再写,出来的代码才真正属于自己:
def threeSum(nums):
nums.sort()
res = []
n = len(nums)
for i in range(n - 2):
if i > 0 and nums[i] == nums[i-1]:
continue
left, right = i + 1, n - 1
while left < right:
s = nums[i] + nums[left] + nums[right]
if s < 0:
left += 1
elif s > 0:
right -= 1
else:
res.append([nums[i], nums[left], nums[right]])
while left < right and nums[left] == nums[left + 1]:
left += 1
while left < right and nums[right] == nums[right - 1]:
right -= 1
left += 1
right -= 1
return res这种方法虽然慢,但能有效避免那种“看完题解觉得自己是个天才,写代码时发现是个废物”的挫败感。