题意:

image.png

解题思路:

  1. 思路:双向BFS
  2. 1. begin: [hit] -> [hot] + 1 -> [dot, lot] + 1, end: [cog];
  3. 2. begin: [cog] -> [cog, dog, log] + 1, end: [dot, lot];
  4. 3. begin: [dot, log] -> dog + 1, end: [cog, dog, log];
  5. 4. 由于dogend[cog, dog, log]中有交集,故找到相交点;

PHP代码实现:

  1. class Solution {
  2. /**
  3. * @param String $beginWord
  4. * @param String $endWord
  5. * @param String[] $wordList
  6. * @return Integer
  7. */
  8. function swap(&$s1, &$s2) {
  9. $temp = $s1;
  10. $s1 = $s2;
  11. $s2 = $temp;
  12. }
  13. function ladderLength($beginWord, $endWord, $wordList) {
  14. if (!in_array($endWord, $wordList)) return 0;
  15. $wordList = array_flip($wordList);
  16. $s1[] = $beginWord;
  17. $s2[] = $endWord;
  18. $n = strlen($beginWord);
  19. $step = 0;
  20. while (!empty($s1)) {
  21. $step++;
  22. if (count($s1) > count($s2)) {
  23. $this->swap($s1, $s2);
  24. }
  25. $s = [];
  26. foreach ($s1 as $wordstr) {
  27. for ($i = 0; $i < $n; $i++) {
  28. $word = $wordstr;
  29. for ($ch = ord('a'); $ch <= ord('z'); $ch++) {
  30. $word[$i] = chr($ch);
  31. if (in_array($word, $s2)) {
  32. return $step + 1;
  33. }
  34. if (!array_key_exists($word, $wordList)) {
  35. continue;
  36. }
  37. unset($wordList[$word]);
  38. $s[] = $word;
  39. }
  40. }
  41. }
  42. $s1 = $s;
  43. }
  44. return 0;
  45. }
  46. }

GO代码实现:

  1. func ladderLength(beginWord string, endWord string, wordList []string) int {
  2. dict := make(map[string]bool) // 把word存入字典
  3. for _, word := range wordList {
  4. dict[word] = true // 可以利用字典快速添加、删除和查找单词
  5. }
  6. if _, ok := dict[endWord]; !ok {
  7. return 0
  8. }
  9. s1 := make(map[string]bool)
  10. s2 := make(map[string]bool)
  11. s1[beginWord] = true // 头
  12. s2[endWord] = true // 尾
  13. l := len(beginWord)
  14. steps := 0
  15. for len(s1) > 0 && len(s2) > 0 { // 当两个集合都不为空,执行
  16. steps++
  17. // Always expend the smaller queue first
  18. if len(s1) > len(s2) {
  19. s1, s2 = s2, s1
  20. }
  21. q := make(map[string]bool) // 临时set
  22. for k := range s1 {
  23. chs := []rune(k)
  24. for i := 0; i < l; i++ {
  25. ch := chs[i]
  26. for c := 'a'; c <= 'z'; c++ { // 对每一位从a-z尝试
  27. chs[i] = c // 替换字母组成新的单词
  28. t := string(chs)
  29. if _, ok := s2[t]; ok { // 看新单词是否在s2集合中
  30. return steps + 1
  31. }
  32. if _, ok := dict[t]; !ok { // 看新单词是否在dict中
  33. continue // 不在字典就跳出循环
  34. }
  35. delete(dict, t) // 若在字典中则删除该新的单词,表示已访问过
  36. q[t] = true // 把该单词加入到临时队列中
  37. }
  38. chs[i] = ch // 新单词第i位复位,还原成原单词,继续往下操作
  39. }
  40. }
  41. s1 = q // s1修改为新扩展的q
  42. }
  43. return 0
  44. }