LeetCode 140高效通关:三种解法对比与避坑指南
def backtrack(start, path):
if start == len(s):
result.append(' '.join(path))
return
for end in range(start+1, len(s)+1):
word = s[start:end]
if word in wordDict:
backtrack(end, path + [word])
memo = {} def backtrack(start):
if start in memo:
return memo[start]
memo[start] = results
return results
memo = {}
def dfs(start):
if start in memo:
return memo[start]
if start == len(s):
return [""]
results = []
for word in wordDict:
if s.startswith(word, start):
sub_results = dfs(start + len(word))
for res in sub_results:
results.append(word + (" " + res if res else ""))
memo[start] = results
return results
def wordBreakDP(s, wordDict):
dp = [[] for _ in range(len(s)+1)]
dp[-1] = [""]
for i in range(len(s)-1, -1, -1):
for word in wordDict:
if i + len(word) <= len(s) and s.startswith(word, i):
for sentence in dp[i + len(word)]:
dp[i].append(word + (" " + sentence if sentence else ""))
return dp[0]
5. 登顶后的全景观测台
站在解法之巅的观测平台,脚下蜿蜒着三条解法路线:暴力回溯的荆棘小径泛着红光,记忆化优化的蓝光栈道在中段盘旋,动态规划的金色天梯笔直贯通山体。处理"aaaaab"这个案例时,三种解法呈现不同景象——回溯路线在第五个"a"处突然塌陷成万丈深渊,记忆化路径在此架起蓝色光桥,而DP天梯早已在岩层中预埋好钢筋骨架。
5.1 不同解法路线的风景对比
暴力回溯法在短字符串处理时展现出野花遍地的原始美感,输入"catdog"时递归树只有两个分叉。但当遭遇含25个重复字符的测试案例,这片原始森林就会变成吞噬计算资源的无底洞。记忆化版本像是给森林装上导航灯塔,在"aaaaa"的处理中,重复子问题被标记为荧光蘑菇集群,引导后续探索者快速穿越。
动态规划路线自带工程机械的轰鸣声,处理"helloWorld"时从右向左逐段修筑的解法公路平坦但略显呆板。当字典中存在"hel"和"hell"时,两条分支在第四个字符处交汇的景象,就像立交桥的多层匝道在空中编织几何图案。时间复杂度同为O(n^2),但DP的空间占用总是规整如集装箱码头,而记忆化版本更像山间散落的临时营地。
5.2 调试望远镜:常见报错排查指南
在拼接"catsandog"的分割结果时,发现记忆化缓存返回了幽灵空格。调试发现是基础案例处理不当——当递归到达字符串末尾时,应该返回包含空字符串的列表而非空列表。这个错误就像望远镜镜片上的雾气,使得最终结果缺失最后一个单词间的空隙。
栈溢出警报常在山腰处响起,特别是处理超长输入时。将递归改为显式栈管理后,就像给望远镜加装减震支架。遇到"aabb..."型输入时,未优化的缓存键设计会导致内存爆炸,此时给字典键加上当前字符位置,相当于调节望远镜的焦距旋钮,让模糊的重影变得清晰锐利。
5.3 远征补给包:延伸练习题单
继续深入单词分割领域,推荐尝试LeetCode 472(连接词),这道题像在现有解法基础上加装多级火箭推进器。需要先完成单词拆分再验证连接词,就像用已经建好的登山路线探查隐藏洞穴。
进阶挑战可以攀登LeetCode 139(单词拆分)的简化版山峰,那里不需要收集具体路径只需判断可行性,相当于把重型装备换成轻量化登山杖。对于渴望探索解法变体的勇者,LeetCode 472(连接词)和LeetCode 648(单词替换)构成双子峰,考验如何将单词拆分技术应用于更复杂的语义地形。