127. Word Ladder

2018/07/02 leetcode 共 3389 字,约 10 分钟

title

problem link

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:

Only one letter can be changed at a time.

Each transformed word must exist in the word list. Note that beginWord is not a transformed word.

Note:

  • Return 0 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"]

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.

solution

有待优化,速度太慢了


class Solution {
public:
	bool isconnect(string a, string b) {
		int diff = 0;
		for (int i = 0; i < a.length(); i++) {
			if (a[i] != b[i]) {
				diff++;
			}
		}
		return diff == 1;
	}
	void build(vector<vector<int>> &v, vector<string>& worldList) {
		for (int i = 0; i < worldList.size(); i++) {
			for (int j = 0; j < worldList.size(); j++) {
				if (isconnect(worldList[i], worldList[j])) {
					v[i].push_back(j);
				}
			}
		}
	}
	int getShortestPath(int start,int end,vector<vector<int>> &v,int n) {
		int len = 1;
		bool *visit = new bool[n + 1];
		fill(visit, visit + n + 1, false);
		visit[start] = true;
		queue<int> q;
		q.push(start);
		while (!q.empty()) {
			len++;
			int size = q.size();
			while (size--) {
				int p = q.front();
				q.pop();
				for (auto next : v[p]) {
					if (next == end) {
						return len;
					}
					if (!visit[next]) {
						q.push(next);
						visit[next] = true;
					}
				}
			}
		}
		return 0;
	}
	int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
		wordList.push_back(beginWord);
		vector<vector<int>> v(wordList.size());
		int start = wordList.size()-1, end = -1, n = wordList.size();
		for (int i = 0; i < n; i++) {
			if (wordList[i] == endWord) {
				end = i;
			}
		}
		if (end == -1) {
			return 0;
		}
		cout << start << " " << end << endl;
		build(v, wordList);
		return getShortestPath(start, end, v, n);
	}
};

java

public int ladderLength(String beginWord, String endWord, List<String> wordList) {
    wordList.add(beginWord);
    int N = wordList.size();
    int start = N - 1;
    int end = 0;
    while (end < N && !wordList.get(end).equals(endWord)) {
        end++;
    }
    if (end == N) {
        return 0;
    }
    List<Integer>[] graphic = buildGraphic(wordList);
    return getShortestPath(graphic, start, end);
}

private List<Integer>[] buildGraphic(List<String> wordList) {
    int N = wordList.size();
    List<Integer>[] graphic = new List[N];
    for (int i = 0; i < N; i++) {
        graphic[i] = new ArrayList<>();
        for (int j = 0; j < N; j++) {
            if (isConnect(wordList.get(i), wordList.get(j))) {
                graphic[i].add(j);
            }
        }
    }
    return graphic;
}

private boolean isConnect(String s1, String s2) {
    int diffCnt = 0;
    for (int i = 0; i < s1.length() && diffCnt <= 1; i++) {
        if (s1.charAt(i) != s2.charAt(i)) {
            diffCnt++;
        }
    }
    return diffCnt == 1;
}

private int getShortestPath(List<Integer>[] graphic, int start, int end) {
    Queue<Integer> queue = new LinkedList<>();
    boolean[] marked = new boolean[graphic.length];
    queue.add(start);
    marked[start] = true;
    int path = 1;
    while (!queue.isEmpty()) {
        int size = queue.size();
        path++;
        while (size-- > 0) {
            int cur = queue.poll();
            for (int next : graphic[cur]) {
                if (next == end) {
                    return path;
                }
                if (marked[next]) {
                    continue;
                }
                marked[next] = true;
                queue.add(next);
            }
        }
    }
    return 0;
}

Search

    Table of Contents