126. Word Ladder II(js)

126. Word Ladder II

Given two words (beginWord and endWord), and a dictionary‘s word list, find all shortest transformation sequence(s) from beginWord to endWord, such that:

  1. Only one letter can be changed at a time
  2. Each transformed word must exist in the word list. Note that beginWord is not a transformed word.

Note:

  • Return an empty list 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.

Example 1:

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

Output:
[
  ["hit","hot","dot","dog","cog"],
  ["hit","hot","lot","log","cog"]
]

Example 2:

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

Output: []

Explanation: The endWord "cog" is not in wordList, therefore no possible transformation.题意:给出开始单词和结束单词,从单词列表中找出单词使得从开始单词到结束单词形成接龙,每次只允许替换一个字符,求出所有情况代码如下:
‘use strict‘;
var findLadders = function(start, end, dict) {
  // 常量
  var A_CODE = ‘a‘.charCodeAt(0);
  var WORD_COUNTS = 26;
  var wordLength = start.length;
  var results;
  var currents, next;
  var isFounded = false;
  var dictSet = new Set(dict);

  // 判断一次字符转换是否有效
  var isValid = function(from, to) {
    var i = 0, c = 0;
    while (i < wordLength) {
      if (from.charCodeAt(i) !== to.charCodeAt(i)) {
        ++c;
      }
      ++i;
    }

    return (c === 1);
  };

  // 字符替换
  var replacedWord = function(word, idx, chCode) {
    var newStr =
      word.substr(0, idx) + String.fromCharCode(chCode) + word.substr(idx + 1);
    return newStr;
  };

  // If its only one step from start to end.
  if (start === end || isValid(start, end)) {
    return [[start, end]];
  } else if (!dictSet.has(end)) {
    return [];
  }

  results = [];
  var startSet = new Set([start]);
  var endSet = new Set([end]);
  var startPath = [[start]];
  var endPath = [[end]]

  var isReversing = false;
  var isConnected = false;

  // Use to decide whether use all word possible or use all dice word.
  var wordCombinations = WORD_COUNTS * wordLength;
  var dictComputations;

  // Determine current paths.
  var currentPaths;
  var currentLength;
  var currentSet;
  var pathLength;

  var nextPaths;

  var currentPath, currentWord, targets, target, tmpPath;

  var i, j, k;

  // 初始化
  currentPaths = startPath;
  currentSet = startSet;
  currentLength = currentPaths.length;

  while (currentLength > 0) {
    nextPaths = [];
    // 从currentSet中删除key
    targets = currentSet.keys();
    for (target of targets) {
      dictSet.delete(target);
    }
    currentSet.clear();
    dictComputations = dictSet.size * wordLength;
    // Decide whether to use dict iteration of word replaces.
    if (dictComputations < wordCombinations) {
      // If iteration though dict needs less compares, iterate it.
      for (i = 0; i < currentLength; ++i) {
        currentPath = currentPaths[i];
        currentWord = currentPath[currentPath.length - 1];
        targets = dictSet.keys();
        for (target of targets) {
          if (isValid(currentWord, target)) {
            tmpPath = currentPath.slice();
            tmpPath.push(target);
            nextPaths.push(tmpPath);
            currentSet.add(target);
          }
        }
      }
    } else {

      for (i = 0; i < currentLength; ++i) {
        currentPath = currentPaths[i];
        currentWord = currentPath[currentPath.length - 1];
        for (j = 0; j < wordLength; ++j) {
          for (k = 0; k < WORD_COUNTS; ++k) {
            target = replacedWord(currentWord, j, A_CODE + k);
            if (dictSet.has(target)) {
              tmpPath = currentPath.slice();
              tmpPath.push(target);
              nextPaths.push(tmpPath);
              currentSet.add(target);
            }
          }
        }
      }
    }
    if (isReversing) {
      endPath = nextPaths;
    } else {
      startPath = nextPaths;
    }

    if (startSet.size > endSet.size) {
      targets = endSet.keys();
      currentSet = startSet;
    } else {
      targets = startSet.keys();
      currentSet = endSet;
    }

    for (target of targets) {
      if (currentSet.has(target)) {
        isConnected = true;
        break;
      }
    }
    if (isConnected) {
      break;
    } else {
      // 取小
      isReversing = startPath.length > endPath.length ? true : false;
      currentSet = isReversing ? endSet : startSet;
      currentPaths = isReversing ? endPath : startPath;
      currentLength = currentPaths.length;
    }
  }

  if (isConnected) {
    currentLength = startPath.length;
    pathLength = endPath.length;
    // Reverse endPaths.
    for (j = 0; j < pathLength; ++j) {
      endPath[j].reverse();
    }
    for (i = 0; i < currentLength; ++i) {
      currentPath = startPath[i];
      currentWord = currentPath[currentPath.length - 1];
      if (!endSet.has(currentWord)) {
        continue;
      }
      for (j = 0; j < pathLength; ++j) {
        target = endPath[j];
        if (currentWord === target[0]) {
          tmpPath = currentPath.concat(target.slice(1));
          results.push(tmpPath);
        }
      }
    }
  }
  return results;
};

参考链接:https://leetcode.com/problems/word-ladder-ii/discuss/40606/Share-my-javascript-solution-with-2-way-BFS-cost-about-250ms.

原文地址:https://www.cnblogs.com/xingguozhiming/p/10909234.html

时间: 2024-10-11 21:48:05

126. Word Ladder II(js)的相关文章

【leetcode】126. Word Ladder II

题目如下: 解题思路:DFS或者BFS都行.本题的关键在于减少重复计算.我采用了两种方法:一是用字典dic_ladderlist记录每一个单词可以ladder的单词列表:另外是用dp数组记录从startword开始到wordlist每一个word的最小转换次数,这一点非常重要,可以过滤很多无效的运算. 代码如下: class Solution(object): def getLadderList(self, w,d): l = [] r = [] for i in xrange(26): l.a

leetcode 126. Word Ladder II

1 import string 2 import collections 3 4 class Solution(object): 5 def findLadders(self, begin, end, words_list): 6 '''删除起至单词''' 7 words_list.discard(begin) 8 words_list.discard(end) 9 10 '''根据tree递归构造路径''' 11 def construct_paths(source, dest, tree):

Java for LeetCode 126 Word Ladder II

Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from start to end, such that: Only one letter can be changed at a time    Each intermediate word must exist in the dictionary For example, Given:start = "

45. Jump Game II(js)

45. Jump Game II Given an array of non-negative integers, you are initially positioned at the first index of the array. Each element in the array represents your maximum jump length at that position. Your goal is to reach the last index in the minimu

63. Unique Paths II(js)

63. Unique Paths II A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (

82. Remove Duplicates from Sorted List II(js)

82. Remove Duplicates from Sorted List II Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list. Example 1: Input: 1->2->3->3->4->4->5 Output: 1->2->5 Example

80. Remove Duplicates from Sorted Array II(js)

80. Remove Duplicates from Sorted Array II Given a sorted array nums, remove the duplicates in-place such that duplicates appeared at most twice and return the new length. Do not allocate extra space for another array, you must do this by modifying t

137. Single Number II(js)

137. Single Number II Given a non-empty array of integers, every element appears three times except for one, which appears exactly once. Find that single one. Note: Your algorithm should have a linear runtime complexity. Could you implement it withou

126. Word Ladder II

class StringWithLevel { String str; int level; public StringWithLevel(String str, int level) { this.str = str; this.level = level; } } public ArrayList<ArrayList<String>> findLadders(String start, String end, HashSet<String> dict) { Arra