题目描述
给了一个单子数组words
给了字母前身的定义:A在任何地方加一个字符,凑成B,A就是B的前身
问从words中怎么选,能构成最长的词链?
基本分析
- 怎么找到子问题?假如s是词链的最后一个单词,那么枚举去掉s某位后的构成新的词s-1,s-1就是s的更小一级的子问题
- dfs怎么实现?传入参数:s就行了;结束条件?长度是1的时候返回1;
- 为啥要记忆化?可能去掉某个字符后会重复,减少计算
代码
| class Solution: |
| def longestStrChain(self, words: List[str]) -> int: |
| ws = set(words) |
| |
| @cache |
| def dfs(s): |
| cnt = 0 |
| for i in range(len(s)): |
| prev = s[:i] + s[i+1:] |
| if prev in ws: |
| cnt = max(cnt, dfs(prev)) |
| return cnt + 1 |
| |
| return max(dfs(word) for word in words) |
总结
- 能找到子问题
- 从定到更小的问题是递,从小的问题返回结果是归
基本分析
- 怎么找到递推的规律?对某个字符s来说,他的结果是之前mp[s-1]的最大值+1
- mp[s-1]从哪里来?定义一个字典专门来存
- 按照什么顺序递推?words排序,从小到大
代码
| class Solution: |
| def longestStrChain(self, words: List[str]) -> int: |
| |
| words.sort(key = len) |
| # 记录某个字符能对应的最长结果 |
| mp = dict() |
| |
| for s in words: |
| cnt = 0 |
| for i in range(len(s)): |
| cnt = max(cnt, mp.get(s[:i] + s[i+1:], 0)) |
| mp[s] = cnt + 1 |
| |
| return max(mp.values()) |
| |
总结
- 能找到递推的规律,这里不是看前一个和当前字符的关系,而是枚举当前字符s去掉后的在不在之前的结果中
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现