2019-06-02 23:16:01 +08:00
|
|
|
|
#coding: utf-8
|
|
|
|
|
''' mbinary
|
|
|
|
|
#######################################################################
|
|
|
|
|
# File : dfs.py
|
|
|
|
|
# Author: mbinary
|
|
|
|
|
# Mail: zhuheqin1@gmail.com
|
|
|
|
|
# Blog: https://mbinary.xyz
|
|
|
|
|
# Github: https://github.com/mbinary
|
|
|
|
|
# Created Time: 2019-05-27 10:02
|
|
|
|
|
# Description:
|
|
|
|
|
from leetcode-cn #1048: https://leetcode-cn.com/problems/longest-string-chain/
|
|
|
|
|
给出一个单词列表,其中每个单词都由小写英文字母组成。
|
|
|
|
|
|
|
|
|
|
如果我们可以在 word1 的任何地方添加一个字母使其变成 word2,那么我们认为 word1 是 word2 的前身。例如,"abc" 是 "abac" 的前身。
|
|
|
|
|
|
|
|
|
|
词链是单词 [word_1, word_2, ..., word_k] 组成的序列,k >= 1,其中 word_1 是 word_2 的前身,word_2 是 word_3 的前身,依此类推。
|
|
|
|
|
|
|
|
|
|
从给定单词列表 words 中选择单词组成词链,返回词链的最长可能长度。
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
'''
|
|
|
|
|
|
2020-04-15 12:28:20 +08:00
|
|
|
|
|
2019-06-02 23:16:01 +08:00
|
|
|
|
class Solution:
|
|
|
|
|
def longestStrChain(self, words: List[str]) -> int:
|
2020-04-15 12:28:20 +08:00
|
|
|
|
def isAdj(s1, s2):
|
|
|
|
|
if len(s1) > len(s2):
|
|
|
|
|
s1, s2 = s2, s1
|
|
|
|
|
n1, n2 = len(s1), len(s2)
|
|
|
|
|
if n2-n1 != 1:
|
2019-06-02 23:16:01 +08:00
|
|
|
|
return False
|
2020-04-15 12:28:20 +08:00
|
|
|
|
i = j = 0
|
2019-06-02 23:16:01 +08:00
|
|
|
|
flag = False
|
2020-04-15 12:28:20 +08:00
|
|
|
|
while i < n1 and j < n2:
|
|
|
|
|
if s1[i] != s2[j]:
|
2019-06-02 23:16:01 +08:00
|
|
|
|
if flag:
|
|
|
|
|
return False
|
|
|
|
|
flag = True
|
2020-04-15 12:28:20 +08:00
|
|
|
|
j += 1
|
2019-06-02 23:16:01 +08:00
|
|
|
|
else:
|
2020-04-15 12:28:20 +08:00
|
|
|
|
i += 1
|
|
|
|
|
j += 1
|
2019-06-02 23:16:01 +08:00
|
|
|
|
return True
|
2020-04-15 12:28:20 +08:00
|
|
|
|
|
2019-06-02 23:16:01 +08:00
|
|
|
|
def dfs(begin):
|
|
|
|
|
ans = 1
|
|
|
|
|
w = words[begin]
|
|
|
|
|
n = len(w)
|
|
|
|
|
if n+1 in lenDic:
|
|
|
|
|
for nd in lenDic[n+1]:
|
2020-04-15 12:28:20 +08:00
|
|
|
|
# print(w,words[nd],isAdj(w,words[nd]))
|
|
|
|
|
if isAdj(w, words[nd]):
|
|
|
|
|
ans = max(ans, 1+dfs(nd))
|
2019-06-02 23:16:01 +08:00
|
|
|
|
return ans
|
|
|
|
|
lenDic = {}
|
|
|
|
|
for i in range(len(words)):
|
|
|
|
|
n = len(words[i])
|
|
|
|
|
if n in lenDic:
|
|
|
|
|
lenDic[n].add(i)
|
|
|
|
|
else:
|
2020-04-15 12:28:20 +08:00
|
|
|
|
lenDic[n] = {i}
|
|
|
|
|
|
2019-06-02 23:16:01 +08:00
|
|
|
|
lens = sorted(lenDic)
|
|
|
|
|
n = len(lens)
|
|
|
|
|
ans = 0
|
|
|
|
|
for i in range(n):
|
|
|
|
|
if ans < n-i:
|
|
|
|
|
for nd in lenDic[lens[i]]:
|
2020-04-15 12:28:20 +08:00
|
|
|
|
ans = max(ans, dfs(nd))
|
2019-06-02 23:16:01 +08:00
|
|
|
|
return ans
|