- dictionary查找的优越性
python 中dictionary和list的查找机制不同,dictionary的查找hashmap,时间效率是O(1),list查找是挨个对比时间效率是O(n),所以使用list来查找的话时间效率远不如dictionary乐观。
127这道题,好像是经过多次变迁的题目,之前题目中的的wordlist是dictionary类型,所以这道题如果将list转为dictionary来进行处理的话就能将超时的代码AC,所以第一大关键就是dictionary的查找
- 字母查找范围缩小
对每个单词各自对应位置出现过的字母进行统计之后在缩小后的这个范围内。
dijistra或广搜 (递归和迭代)
这个题可以给用dijistra的最短路径和广搜方法来解决,思路是一致。针对当前单词与它一个字母之差的单词进行比较,并且如果它在wordlist当中,就将它作为当前单词,直到找到endword。dijistra方法使用了两个列表,new_list是上次产生的要访问的新词,unreached是待考察的list。每次考察结束后的只与new_list中的单词有一个字母之差的词构成下一次递归的new_list。递归方法消耗的时间还是比较多的
class Solution(object):
def ladderLength(self, beginWord, endWord, wordList):
"""
:type beginWord: str
:type endWord: str
:type wordList: List[str]
:rtype: int
"""
def dijkstra(new_list,unreached_list,endWord,count):
#new_list 就是当前要来进行考察的词
if len(unreached_list)==0 or len(new_list)==0:
#unreached_list为空表示都已经考察结束了,new_list为空表示上一次考察没有结果
return 0
count = count + 1 #这已经是新一轮的考察
list_return = {}#下一次要考察的对象,所以每次都弄成空的
#print('newlist', new_list)
#print('dijistra', unreached_list)
for i in new_list.keys():#d对每个单词进行同样的处理
for j in range(len(endWord)):#对这个单词的每个字母变化
for k in self.dic1[j]:#for k in character #这个方法在26个字母中找比较慢一点
#对这个单词每个字母可能的变化变化
temp = i
tmp1 = temp[:j]
tmp2 = temp[j+1:]
temp = tmp1+k+tmp2 #得到的新的改变单词的结果
if temp==i:
continue
else:
if temp in unreached_list:#说明变化后的结果是存在的
list_return[temp] = 0
#print('list_return', list_return)
if temp==endWord:
return count
del unreached_list[temp] #这个单词已经是匹配过的了
return dijkstra(list_return,unreached_list,endWord,count)
character = 'abcdefghijklmnopqrstuvwxyz'
begin = {}
begin[beginWord] = 0
dict_unreach = {}
#首先先将整个wordlist 变成字典
self.dic1 = []
length = len(wordList[1])
#对范围缩小一下
for j in range(length):
temp = []
for i in range(len(wordList)):
if temp.count(wordList[i][j]) == 0:
temp.append(wordList[i][j])
self.dic1.append(temp)
for i in range(len(wordList)):
if wordList[i] not in dict_unreach:
dict_unreach[wordList[i]] = 1
# print(dict_unreach)
return dijkstra(begin, dict_unreach, endWord, 1)
- 使用广搜的方法,广搜用到了队列这种数据结构。python中的队列:
import queue queue.Queue()
,对应的操作函数是:q.put() q.get()
import queue
class Solution(object):
def ladderLength(self, beginWord, endWord, wordList):
"""
:type beginWord: str
:type endWord: str
:type wordList: Set[str]
:rtype: int
"""
#广搜
ans,dic1,wordList0 = queue.Queue() ,{} ,{}# 创建一个队列
if wordList.count(endWord) == 0:
return 0
for i in range(len(wordList)):
wordList0[wordList[i]] = 0
ans.put(beginWord) # 首先先把第一个词压入
dic1[beginWord] = 1
length = len(beginWord)
wo = []
for t in range(length):
wo1 =[]
for k in range(len(wordList)):
if wo1.count(wordList[k][t]) == 0:
wo1.append(wordList[k][t])
wo.append(wo1)
# print(wo)
while not ans.empty() :
temp = ans.get()
if temp == endWord:
return dic1[endWord]
for i in range(length):
temp1 = temp[:i]
temp2 = temp[i+1:]
for j in wo[i]:
if temp[i] != j:
result = temp1+j+temp2
if result in wordList0:
ans.put(result)
dic1[result] = dic1[temp]+1
#print(result,end=" ")
del wordList0[result]
return 0
还是考察了基本的数据结构的使用(队列),和广搜的操作。一个字母变化单词的比较也是比较巧妙的。