leetcode127单词接龙

leetcode 127 Word Ladder

Posted by BY on August 4, 2020

前言

持续更新了

正文

问题来源

本问题来自leetcode上的127题。

问题描述

给定两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列的长度。转换需遵循如下规则:

每次转换只能改变一个字母。
转换过程中的中间单词必须是字典中的单词。

说明:

如果不存在这样的转换序列,返回 0。
所有单词具有相同的长度。
所有单词只由小写字母组成。
字典中不存在重复的单词。
你可以假设 beginWord 和 endWord 是非空的,且二者不相同。

示例 1:

输入:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"]

输出: 5

解释: 一个最短转换序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog",
     返回它的长度 5。

示例 2:

输入:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

输出: 0

解释: endWord "cog" 不在字典中,所以无法进行转换。

分析:

第一步:根据字符串相差为1认为可达,抽象成为邻接表表示的无向图;
第二步:根据广度搜索计算最短距离

type node struct {
  word int
  level int
}

func distance1(s1, s2 string) bool { // 用于判断两个字符串是否距离为1
    count := 0
    for i := 0; i < len(s1); i++ {
        if s1[i] != s2[i] {
            count++
        }
    }
    return count == 1
}

func ladderLength(beginWord string, endWord string, wordList []string) int {
    // 判断endWord是否在wordList中,并记录其位置
    e := -1
    for i, v := range wordList {
        if v == endWord {
            e = i
            break
        }
    }
    if e < 0 {
        return 0
    }
    e++ // 为0的特别标记为beginWord
    // 构建邻接表表示的无向图
    m := make([][]int, len(wordList)+1)
    for i := 0; i <= len(wordList); i++ {
        for j := 0; j <= len(wordList); j++ {
            var a, b string
            if i == 0 {
                a = beginWord
            } else {
              a = wordList[i-1]
            }
            if j == 0 {
                b = beginWord
            } else {
              b = wordList[j-1]
            }
            if distance1(a, b) {
                m[i] = append(m[i], j)
            }
        }
    }

    // 下标为0的为beginWord
    queue := make([]node, 0)
    queue = append(queue, node{0,1})
    visited := make(map[int]bool)
    visited[0] = true
    for len(queue) > 0 {
      n := queue[0]
      queue = queue[1:]
      word := n.word
      level := n.level
      for i := 0; i < len(m[word]); i++ {
        w := m[word][i]
        if w == e {
          return level+1
        }
        if visited[w] {
          continue
        }
        queue = append(queue, node{w, level+1})
        visited[w] = true
      }
    }
    return 0
}

总结:

勤思考。

结语

不管怎么样好好加油。