[LeetCode] 1048. Longest String Chain

You are given an array of words where each word consists of lowercase English letters.

wordA is a predecessor of wordB if and only if we can insert exactly one letter anywhere in wordA without changing the order of the other characters to make it equal to wordB.

  • For example, "abc" is a predecessor of "abac", while "cba" is not a predecessor of "bcad".

A word chain is a sequence of words [word1, word2, ..., wordk] with k >= 1, where word1 is a predecessor of word2word2 is a predecessor of word3, and so on. A single word is trivially a word chain with k == 1.

Return the length of the longest possible word chain with words chosen from the given list of words.

Example 1:

Input: words = ["a","b","ba","bca","bda","bdca"]
Output: 4
Explanation: One of the longest word chains is ["a","ba","bda","bdca"].

Example 2:

Input: words = ["xbc","pcxbcf","xb","cxbc","pcxbc"]
Output: 5
Explanation: All the words can be put in a word chain ["xb", "xbc", "cxbc", "pcxbc", "pcxbcf"].

Example 3:

Input: words = ["abcd","dbqca"]
Output: 1
Explanation: The trivial word chain ["abcd"] is one of the longest word chains.
["abcd","dbqca"] is not a valid word chain because the ordering of the letters is changed.

Constraints:

  • 1 <= words.length <= 1000
  • 1 <= words[i].length <= 16
  • words[i] only consists of lowercase English letters.

最长字符串链。

给出一个单词数组 words ,其中每个单词都由小写英文字母组成。

如果我们可以 不改变其他字符的顺序 ,在 wordA 的任何地方添加 恰好一个 字母使其变成 wordB ,那么我们认为 wordA 是 wordB 的 前身 。

例如,"abc" 是 "abac" 的 前身 ,而 "cba" 不是 "bcad" 的 前身
词链是单词 [word_1, word_2, ..., word_k] 组成的序列,k >= 1,其中 word1 是 word2 的前身,word2 是 word3 的前身,依此类推。一个单词通常是 k == 1 的 单词链 。

从给定单词列表 words 中选择单词组成词链,返回 词链的 最长可能长度 。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/longest-string-chain
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

这道题我给出一个 hashmap 的思路。这里我们一开始创建一个HashMap<word, length of the chain starts with this word>,存的是每个单词和以当前这个单词为结尾的最长的链的长度是多少。此时我们将 input 数组按照单词长度排序,这样单词长度短的在前。

对于每个单词而言,如果他不能跟其他任何单词形成链表,那么以这个单词为结尾的链表的长度起码就是 1,这是一开始我需要把每个单词存入 hashmap 放的默认值。接着我们开始遍历 input 中的每个单词 w,对于当前这个单词 w 而言,我们需要按 char 逐个尝试删除字符,这样我们会形成一个新的,更短的单词 next。我们去 hashmap 看一下这个更短的单词 next 是否存在,如果存在,同时需要看一下 next 在 hashmap 中是否存在一个比以 w 结尾的更长的链表,如果有,则更新 w 在 hashmap 的 value。

时间O(nlogn * m) - n 是单词的个数,m 是单词的平均长度

空间O(n) - hashmap

Java实现

 1 class Solution {
 2     public int longestStrChain(String[] words) {
 3         int res = 1;
 4         HashMap<String, Integer> map = new HashMap<>();
 5         Arrays.sort(words, (a, b) -> a.length() - b.length());
 6         for (String w : words) {
 7             map.put(w, 1);
 8             for (int i = 0; i < w.length(); i++) {
 9                 String previous = w.substring(0, i) + w.substring(i + 1);
10                 if (map.containsKey(previous) && map.get(previous) + 1 > map.get(w)) {
11                     map.put(w, map.get(previous) + 1);
12                 }
13             }
14             res = Math.max(res, map.get(w));
15         }
16         return res;
17     }
18 }

 

LeetCode 题目总结

posted @ 2021-05-23 00:57  CNoodle  阅读(259)  评论(0)    收藏  举报