[Lintcode]120. Word Ladder /[Leetcode]127. Word Ladder

120. Word Ladder / 127. Word Ladder

  • 本题难度: Hard/Medium
  • Topic: Data Structure

Description

Given two words (start and end), and a dictionary, find the length of shortest transformation sequence from start to end, such that:

Only one letter can be changed at a time
Each intermediate word must exist in the dictionary
Example
Given:
start = "hit"
end = "cog"
dict = ["hot","dot","dog","lot","log"]
As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
return its length 5.

Notice
Return 0 if there is no such transformation sequence.
All words have the same length.
All words contain only lowercase alphabetic characters.

我的代码

from collections import deque


class Solution(object):
    def ladderLength(self, beginWord, endWord, wordList):
        
        def getDic(wordList):
            d = {}
            for word in wordList:
                for i in range(len(word)):
                    s = word[:i] + '#' + word[i + 1:]
                    d[s] = d.get(s, []) + [word]
            return d


        def bfs(beginWord, endWord, wordList):
            # 1.不要出现圈
            visited = set(beginWord)
            # 2.记录走了多少步
            q = collections.deque([[beginWord, 1]])
            # 3.某个单词,改变某个位置,有多少个单词
            d = getDic(wordList)
            #print(d)
            while q:
                tmpW, tmpLen = q.popleft()
                for i in range(len(tmpW)):
                    changed_word = tmpW[:i]+'#'+tmpW[i+1:]
                    next_words = d.get(changed_word,[] )
                    for next_word in next_words:
                        if next_word in visited:
                            continue
                        else:
                            #防止重复访问
                            visited.add(next_word)
                            #达到endWord
                            if next_word == endWord:
                                return tmpLen+1
                            else:
                                q.append([next_word,tmpLen+1])
            return 0
            
        if endWord==beginWord:
            return 1
        wordList.add(endWord)
        return bfs(beginWord, endWord, wordList)

别人的代码

双端
https://github.com/illuz/leetcode/blob/master/solutions/126.Word_Ladder/AC_two_end_BFS_n.py

#!/usr/bin/python
# -*- coding: utf-8 -*-
# Author:      illuz <iilluzen[at]gmail.com>
# File:        AC_two_end_BFS_n.py
# Create Date: 2015-03-29 15:10:46
# Usage:       AC_two_end_BFS_n.py 
# Descripton:  


import string
class Solution:
    # @param start, a string
    # @param end, a string
    # @param dict, a set of string
    # @return an integer
    def ladderLength(self, start, end, dict):
        start_set, end_set = set([start]), set([end])

        n = len(start)
        dis = 1
        chars = string.ascii_lowercase

        while start_set and end_set:
            dis += 1
            if len(start_set) < len(end_set):
                start_set, end_set = end_set, start_set
            new_start_set = set()
            for word in start_set:
                for idx in range(n):
                    for c in chars:
                        s = word[:idx] + c + word[idx+1:]
                        if s in end_set:
                            return dis
                        if s in dict:
                            new_start_set.add(s)
                            dict.remove(s)
            start_set = new_start_set
            
        return 0


# debug
s = Solution()
print s.ladderLength("hot", "dog", ["hot","dog"])

思路
BFS

  1. 最短,可以用bfs
  2. change 我的理解是改变(非增删)
    3. 用树的结构来理解
  3. 注意要防止重复
  4. 用字典,减少重复查询
  • 出错
    忘记将endword加入字典中
posted @ 2019-03-26 02:15  siriusli  阅读(154)  评论(0编辑  收藏  举报