最长字符串链
难度:
标签:
题目描述
代码结果
运行时间: 68 ms, 内存: 16.3 MB
/*
* 使用Java Stream的实现思路:
* 1. 依然是先对单词进行排序。
* 2. 使用一个HashMap记录每个单词的最长链长度。
* 3. 使用Stream API来遍历每个单词,计算每个单词的最长链长度。
* 4. 使用Optional来获取最长链的最大值。
*/
import java.util.*;
import java.util.stream.*;
public class LongestStringChainStream {
public int longestStrChain(String[] words) {
Arrays.sort(words, Comparator.comparingInt(String::length));
Map<String, Integer> dp = new HashMap<>();
return Arrays.stream(words)
.map(word -> {
int currentLength = IntStream.range(0, word.length())
.mapToObj(i -> new StringBuilder(word).deleteCharAt(i).toString())
.mapToInt(predecessor -> dp.getOrDefault(predecessor, 0) + 1)
.max().orElse(1);
dp.put(word, currentLength);
return currentLength;
})
.max(Integer::compareTo)
.orElse(1);
}
}
解释
方法:
此题解采用动态规划的思想,核心是用哈希表d记录每个单词长度对应的单词列表,同时使用哈希表mp存储到当前单词为止可能形成的最长字符串链的长度。首先,将单词按长度分类并存入d中,并记录最长单词的长度maxd。接着,从最长单词长度开始,向下查找可能的前身单词。如果长度为fad的单词能通过删除一个字符得到长度为fad-1的单词,则更新该前身单词在mp中的值。整个过程从最大长度递减到1,每次尝试通过删除操作找到可能的前身,并更新最长链的长度。
时间复杂度:
O(N*fad^2)
空间复杂度:
O(N)
代码细节讲解
🦆
题解中提到了通过删除一个字符来寻找单词的前身,如何确保删除的过程中不会漏掉某些可能的前身单词?
▷🦆
题解中使用了两个哈希表d和mp,能否具体解释一下这两个哈希表在算法中具体扮演的角色是什么?
▷🦆
对于每个单词,题解中提到尝试删除其每个位置的字符,这种方法是否存在效率上的问题,特别是当单词长度非常长时?
▷🦆
题解计算最长字符串链时,是如何确保通过删除字符得到的新单词确实存在于单词列表中的?
▷