1. 程式人生 > >【LeetCode】#127單詞接龍(Word Ladder)

【LeetCode】#127單詞接龍(Word Ladder)

【LeetCode】#127單詞接龍(Word Ladder)

題目描述

給定兩個單詞(beginWord 和 endWord)和一個字典,找到從 beginWord 到 endWord 的最短轉換序列的長度。轉換需遵循如下規則:
1.每次轉換隻能改變一個字母。
2.轉換過程中的中間單詞必須是字典中的單詞。
說明:
1.如果不存在這樣的轉換序列,返回 0。
2.所有單詞具有相同的長度。
3.所有單詞只由小寫字母組成。
4.字典中不存在重複的單詞。
5.你可以假設 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” 不在字典中,所以無法進行轉換。

Description

Given two words (beginWord and endWord), and a dictionary’s word list, find the length of shortest transformation sequence 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:
1.Return 0 if there is no such transformation sequence.
2.All words have the same length.
3.All words contain only lowercase alphabetic characters.
4.You may assume no duplicates in the word list.
5.You may assume beginWord and endWord are non-empty and are not the same.

Example

Example 1:

Input:
beginWord = “hit”,
endWord = “cog”,
wordList = [“hot”,“dot”,“dog”,“lot”,“log”,“cog”]
Output: 5
Explanation: As one shortest transformation is “hit” -> “hot” -> “dot” -> “dog” -> “cog”,
return its length 5.

Example 2:

Input:
beginWord = “hit”
endWord = “cog”
wordList = [“hot”,“dot”,“dog”,“lot”,“log”]
Output: 0
Explanation: The endWord “cog” is not in wordList, therefore no possible transformation.

解法

public class Solution {
    private boolean[][] graph;
    private int[] d;
    private final int INF = 1000000000;
    private int[] countInq;
    private boolean[] inq;
    private int size;
 
    public int ladderLength(String beginWord, String endWord, List<String> wordList) {
        HashSet<String> hashSet = new HashSet<>();
        hashSet.addAll(wordList);
        hashSet.add(beginWord);
        if(!hashSet.contains(endWord)){
            return 0;
        }
        List<String> list = new ArrayList<>();
        int index = 0;
        int start = 0, end = 0;
        for(String s : hashSet){
            list.add(s);
            if(s.equals(beginWord)){
                start = index;
            }
            if(s.equals(endWord)){
                end = index;
            }
            index++;
        }
        size = list.size();
        graph = new boolean[size][size];
        for(int i = 0; i < size; i++){
            for(int j = i + 1; j < size; j++){
                if(hashPath(list.get(i), list.get(j))){
                    graph[i][j] = graph[j][i] = true;
                }
            }
        }
        d = new int[size];
        Arrays.fill(d, INF);
        countInq = new int[size];
        Arrays.fill(countInq, 0);
        inq = new boolean[size];
        spfa(start);
        if(INF == d[end]){
            return 0;
        }
        return d[end] + 1;
    }
 
    private boolean hashPath(String s1, String s2){
        int count = 0;
        for(int i = 0; i < s1.length(); i++){
            if(s1.charAt(i) != s2.charAt(i)){
                count++;
            }
        }
        if(1 == count){
            return true;
        }
        return false;
    }
 
    private boolean spfa(int s){
        d[s] = 0;
        Queue<Integer> queue = new LinkedList<>();
        queue.add(s);
        countInq[s]++;
        inq[s] = true;
        while(!queue.isEmpty()){
            int u = queue.poll();
            inq[u] = false;
            for(int v = 0; v < size; v++){
                if(graph[u][v] && d[u] + 1 < d[v]){
                    d[v] = d[u] + 1;
                    if(!inq[v]){
                        queue.add(v);
                        countInq[v]++;
                        inq[v] = true;
                        if(countInq[v] > size - 1){
                            return false;
                        }
                    }
                }
            }
        }
        return true;
    }
}