Java中的字梯

时间:2015-04-18 01:06:28

标签: java

我在解决许多人可能知道的WordLadder问题时遇到了一些麻烦。

Word ladder(也称为Doublets,word-links或Word golf)是由Lewis Carroll发明的文字游戏。字梯拼图以两个单词开头,为了解决这个难题,必须找到一系列其他单词链接两个单词,其中两个相邻的单词(即连续步骤中的单词)相差一个字母。

示例将来自 - >猫,罐头,骗子,齿轮,狗

我在网上找到了一个教程,附带下面的代码。我理解先呼吸搜索是如何工作的,但是我很难弄清楚如何找到从起始单词到结束单词的实际路径。作者只是试图找到最短的阶梯长度,而我想知道实际上与该阶梯路径对应的字。

public int ladderLength(String start, String end, HashSet<String> dict) {
    if (dict.size() == 0)
        return 0;

    dict.add(end);

    LinkedList<String> wordQueue = new LinkedList<String>();
    LinkedList<Integer> distanceQueue = new LinkedList<Integer>();

    wordQueue.add(start);
    distanceQueue.add(1);

    //track the shortest path
    int result = Integer.MAX_VALUE;
    while (!wordQueue.isEmpty()) {
        String currWord = wordQueue.pop();
        Integer currDistance = distanceQueue.pop();

        if (currWord.equals(end)) {
            result = Math.min(result, currDistance);
        }

        for (int i = 0; i < currWord.length(); i++) {
            char[] currCharArr = currWord.toCharArray();
            for (char c = 'a'; c <= 'z'; c++) {
                currCharArr[i] = c;

                String newWord = new String(currCharArr);
                if (dict.contains(newWord)) {
                    wordQueue.add(newWord);
                    distanceQueue.add(currDistance + 1);
                    dict.remove(newWord);
                }
            }
        }
    }

    if (result < Integer.MAX_VALUE)
        return result;
    else
        return 0;
}

感谢您以后的任何帮助!

1 个答案:

答案 0 :(得分:1)

如果性能不是问题,这可能适合您。

public static LinkedList<String> ladderLength(String start, String end, HashSet<String> dict) {
    if (dict.size() == 0)
        return new LinkedList<String>();

    dict.add(end);

    LinkedList<String> wordQueue = new LinkedList<String>();
    LinkedList<Integer> distanceQueue = new LinkedList<Integer>();
    LinkedList<LinkedList<String>> pathsQueue = new LinkedList<LinkedList<String>>();
    LinkedList<String> solution = new LinkedList<String>();

    wordQueue.add(start);
    distanceQueue.add(1);
    dict.remove(start);
    LinkedList<String> path = new LinkedList<String>();
    path.add(start);
    pathsQueue.add(path);

    //track the shortest path
    int result = Integer.MAX_VALUE;
    while (!wordQueue.isEmpty()) {
        String currWord = wordQueue.pop();
        Integer currDistance = distanceQueue.pop();
        LinkedList<String> currentPathQueue = pathsQueue.pop();

        if (currWord.equals(end)) {
            if (currDistance < result)
            {
                result = currDistance;
                solution = currentPathQueue;
            }
        }

        for (int i = 0; i < currWord.length(); i++) {
            char[] currCharArr = currWord.toCharArray();
            for (char c = 'A'; c <= 'Z'; c++) {
                currCharArr[i] = c;
                LinkedList<String> currentPathQueueTemp = new LinkedList<String>(currentPathQueue);

                String newWord = new String(currCharArr);
                if (dict.contains(newWord)) {
                    wordQueue.add(newWord);
                    distanceQueue.add(currDistance + 1);
                    currentPathQueueTemp.add(newWord);
                    pathsQueue.add(currentPathQueueTemp);
                    dict.remove(newWord);
                }
            }
        }
    }

    if (result < Integer.MAX_VALUE)
        return solution;
    else
        return new LinkedList<String>();
}

基本上,我所做的就是快速添加所采用路径的队列。因此,当我们将长度添加到队列时,我们还将当前路径添加到另一个队列。通过这种方式,我们可以跟踪路径。这绝对没有优化,但它确实有效。