[LeetCode]127. Word Ladder 深入浅出讲解和代码示例
来源:互联网 发布:win7安装apache 编辑:程序博客网 时间:2024/06/04 20:11
本题解题思路中用到了哈希、堆栈的知识点。
2、题目
Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that:
- Only one letter can be changed at a time.
- Each transformed word must exist in the word list. Note that beginWord is not a transformed word.
For example,
Given:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log","cog"]
As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog"
,
return its length 5
.
Note:
- Return 0 if there is no such transformation sequence.
- All words have the same length.
- All words contain only lowercase alphabetic characters.
- You may assume no duplicates in the word list.
- You may assume beginWord and endWord are non-empty and are not the same.
UPDATE (2017/1/20):
The wordList parameter had been changed to a list of strings (instead of a set of strings). Please reload the code definition to get the latest changes.
3、审题
已知条件:起始单词、目的单词、词典
动作:起始单词每次变化其中一个字母,经过N次变化后,变为目的单词
求:从起始单词变化为目的单词的最小路径(N最小)
4、解题思路
以题目中的example来讲解思路。
本题的基本思路可以用暴力破解法,用多叉树的思路,找到所有从起始单词到目的单词的路径,再比较取最短路径即可。
但该方法空间复杂度消耗太大(需保存所有的多叉树路径),舍弃。
=> 本题用堆栈、哈希的思路来求解。
Step1:从起始单词到目的单词,可达路径用堆栈来保存,每次求取一组可达路径;
Step2:在迭代求取可达路径时,因已遍历过的路径不会保存,而只保留最优的一组,所以需标记记录已经迭代过的路径,这里用hash+list来设计标记。
建立个hash表,将beginWord、endWord、wordList中所有出现的单词建立一张映射表,key=word,value是一存放所有与该word相差一个字符的单词数组,如下:
{
'hit': ['hot'], 'lot': ['hot', 'dot', 'log'], 'dog': ['dot', 'log', 'cog'], 'hot': ['dot', 'lot', 'hit'], 'cog': ['dog', 'log'], 'dot': ['hot', 'dog', 'lot'], 'log': ['dog', 'lot', 'cog']}
Step3:迭代过程如下图(反复往stack中push和pop的过程)
1) 将起始单词(hit)放入stack堆栈;
2) 从hash表中查找hit对应的value,顺序从该数组中选取,此处选取"hot"放入堆栈;
3) 循环调用2),依次将"dot","dog"...等放入堆栈 (见上图中最左处stack中的值)
4) 这里说明下"lot",lot对应的value数组为[‘hot’,‘dot’,‘log’],而hot,dot,log都已在stack中,即lot后无单词可往stack中放,该路径结束(弹出lot)
5) 继续按照4)的规则,依次弹出lot,放入cog,后又弹出cog、弹出log,放入cog,一条可达路径完成,记录下该路径;
6) 继续迭代,止到所有路径都遍历完毕(结束条件为stack中只剩下底部单词hit时)
5、代码示例 - Python
import timeimport copyclass Solution: def dist(self,word1,word2): len1 = len(word1) len2 = len(word2) disNum = len1 if(len1 == len2): for i in range(0,len1): if (word1[i] == word2[i]): disNum = disNum - 1 else: disNum = disNum + 1 return disNum def listToDict(self,begin,wd): #build hash + link from wordlist wd.append(begin) #add begin into dict lenw = len(wd) wdict = {} for i in range (0,lenw): for j in range(0,lenw): dres = self.dist(wd[i],wd[j]) if(dres == 1): if wdict.has_key(wd[i]): wdict[wd[i]].append(wd[j]) else: wdict[wd[i]] = [wd[j]] return wdict def ifLast(self,key,value,wdict): valuel = wdict[key] index = valuel.index(value) if index == len(valuel)-1: return 0 else: return 1 def findLabbers(self,begin,end,wd): wdict = self.listToDict(begin,wd) max = len(wd) + 1 wstack = [] index = 0 wstack.append(begin) top = 1 #top is the stack length toppre = "" res = [[]]; reslen = 0 #build stack pre = "" while wstack: print "\n\n go while ---" time.sleep(0.1) ''' 1. push to stack 2. loop to push until top == 1 or stack[top] = end 3. if top == 1 pop item and go to step 2 if stack[top] = end save the res and pop item and go to step 2 if index + 1 > next.len end the loop ''' if wstack[top-1] == end: #get one res if reslen == 0: res[reslen] = copy.deepcopy(wstack) reslen = reslen + 1 else: #find the min one min = len(res[0]) if min > top: while reslen > 1: res.pop() reslen = reslen - 1 res[reslen-1] = copy.deepcopy(wstack) else: if min == top: res.append("") res[reslen] = copy.deepcopy(wstack) reslen = reslen + 1 else: print "min<top: the result > exist res, not put into res list" #loop to find another res pre = wstack.pop() top = top - 1 if wstack: pre = wstack.pop() top = top - 1 #when get res, pop twice #if checked all the res, end the loop if top == 1: key = wstack[top-1] if pre != "": if self.ifLast(key,pre,wdict): break #end the all loop # build the stack if wdict.has_key(wstack[top-1]): valuel = wdict[wstack[top-1]] #get the pre index, and loop from it if pre == "" or pre not in valuel: #need remove duplicate here index = 0; else: index = valuel.index(pre) index = index + 1 #loop to get the item, which not in stack while(index <= len(valuel)-1): if (valuel[index] in wstack): print "go 7 ---" index = index + 1; print "index, len(valuel)-1",index, len(valuel)-1 else: break #check whether have item to put into stack if index <= len(valuel)-1: #have item to put into stack lenws = len(wstack) #get the right item into stack #the stack length shouldn't to be too long if (lenws < max): wstack.append(valuel[index]) else: #if not the right item, pop to reloop pre = wstack.pop() top = top - 1 continue else: #no item to put into stack, pop to reloop pre = wstack.pop() top = top - 1 continue top = top + 1 return res if __name__ == "__main__": wd = ["hot","dot","dog","lot","log","cog"] begin = "hit" end = "log" st = Solution() res = st.findLabbers(begin,end,wd) print "\n\nget result ==============\n",res
---------------------------------------------------------------------------------------------------
本文链接:http://blog.csdn.net/karen0310/article/details/75013953
请尊重作者的劳动成果,转载请注明出处!
---------------------------------------------------------------------------------------------------
阅读全文
0 0
- [LeetCode]127. Word Ladder 深入浅出讲解和代码示例
- [LeetCode]632. Smallest Range 深入浅出讲解和代码示例
- [LeetCode]147. Insertion Sort List 深入浅出讲解和代码示例
- [LeetCode]146. LRU Cache 深入浅出讲解和代码示例
- [LeetCode]44. Wildcard Matching 深入浅出讲解和代码示例
- [LeetCode]68. Text Justification 深入浅出讲解和代码示例
- [LeetCode]493. Reverse Pairs 深入浅出算法讲解和代码示例
- [LeetCode]127.Word Ladder
- [Leetcode] 127. Word Ladder
- [leetcode] 127.Word Ladder
- Leetcode-127.Word Ladder
- 127. Word Ladder LeetCode
- Leetcode 127. Word Ladder
- LeetCode 127. Word Ladder
- leetcode 127. Word Ladder
- LeetCode 127. Word Ladder
- LeetCode-127.Word Ladder
- Leetcode 127. Word Ladder
- 数据抽取方式和各方式特点
- spring中异步配置
- Z字形编排
- rxjava+Retrofit+okhttp 实战网络请求
- 初始化容器
- [LeetCode]127. Word Ladder 深入浅出讲解和代码示例
- 记:第一次使用Nginx搭建图片服务器
- 一起做RGB-D SLAM(5)
- Android BottomNavigationView与ViewPager+fragment结合实现material Tab标准效果
- 最长公共子序列(LCS)
- JAVA图片压缩
- LINUX(CENTOS7.X)SVN部署文档
- Lua数据类型
- RichTextBox控件操作