这一题本质上是bfs的问题,我们要考虑的部分就是找响相邻节点的问题,我们对于每一位从a变到来看是不是在dict里,在的话就是相邻的节点,其他部分和bfs是一样的,我们记录一下扫到哪里碰到目标节点就行了,代码如下:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Solution { | |
public int ladderLength(String start, String end, Set<String> dict) { | |
if (start == null || end == null || end == null) | |
return 0; | |
LinkedList<String> queue = new LinkedList<String>(); | |
HashSet<String> visited = new HashSet<String>(); | |
queue.add(start); | |
visited.add(start); | |
int count = 1; | |
while (!queue.isEmpty()) { | |
int size = queue.size(); | |
for (int i = 0; i < size; i++) { | |
String curr = queue.removeFirst(); | |
if (curr.equals(end)) | |
return count; | |
ArrayList<String> neighbors = adj(curr, dict); | |
for (int j = 0; j < neighbors.size(); j++) { | |
String temp = neighbors.get(j); | |
if (!visited.contains(temp)) { | |
visited.add(temp); | |
queue.add(temp); | |
} | |
} | |
} | |
count++; | |
} | |
return 0; | |
} | |
public ArrayList<String> adj(String s, Set<String> dict) { | |
ArrayList<String> res = new ArrayList<String>(); | |
char[] chars = s.toCharArray(); | |
int len = chars.length; | |
for (int i = 0; i < len; i++) { | |
char copy = chars[i]; | |
for (int j = 0; j < 26; j++) { | |
char replace = (char)('a' + j); | |
if (replace == copy) | |
continue; | |
chars[i] = replace; | |
String temp = new String(chars); | |
if (dict.contains(temp)) | |
res.add(temp); | |
} | |
chars[i] = copy; | |
} | |
return res; | |
} | |
} |
另外这一题如果要优化的话,可以考虑双向bfs,时间和空间都可以优化到O(b^(d / 2)),b是branch factor,d是起点和目标的距离。我们就在起点和终点一起开始bfs就行,起点一圈,终点一圈,直到
- 起点bfs访问到了到了终点bfs访问过的节点(终点的visited set)
- 终点bfs访问到了到了起点bfs访问过的节点(起点的visited set)
- 终点或者起点的queue为空(注意如果两个node真的是联通的,那么在check到相交的部分之前不会为空)
优化的部分就考虑可以先继续搜queue size较小的那边,这样可以更节省空间,时间上也会一定程度优化,不过这只是有限的优化,不会影响时间复杂度,代码如下:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Solution { | |
public: | |
int ladderLength(string beginWord, string endWord, vector<string>& wordList) { | |
//bidirectional BFS | |
queue<string> q1, q2; | |
unordered_set<string> visited1, visited2; | |
unordered_set<string> words; | |
for (auto& word : wordList)words.insert(word); | |
if(words.find(endWord) == words.end())return 0; | |
q1.push(beginWord); | |
q2.push(endWord); | |
int layer1 = 0, layer2 = 0; | |
while (q1.size() && q2.size()) | |
{ | |
int len1 = q1.size(), len2 = q2.size(); | |
++layer1; | |
for (int i = 0; i < len1; ++i) | |
{ | |
auto curr = q1.front(); | |
q1.pop(); | |
if (visited1.find(curr) != visited1.end())continue; | |
if (visited2.find(curr) != visited2.end())return layer1 + layer2 - 1; | |
visited1.insert(curr); | |
for (auto& next : adj(curr, words)) | |
q1.push(next); | |
} | |
++layer2; | |
for (int i = 0; i < len2; ++i) | |
{ | |
auto curr = q2.front(); | |
q2.pop(); | |
if (visited2.find(curr) != visited2.end())continue; | |
if (visited1.find(curr) != visited1.end())return layer1 + layer2 - 1; | |
visited2.insert(curr); | |
for (auto& next : adj(curr, words)) | |
q2.push(next); | |
} | |
} | |
return 0; | |
} | |
private: | |
vector<string> adj(string word, unordered_set<string>& list) | |
{ | |
vector<string> res; | |
for (int i = 0; i < word.size(); ++i) | |
{ | |
string tmp = word; | |
for (int j = 0; j < 26; ++j) | |
{ | |
char c = 'a' + j; | |
if (c == word[i])continue; | |
tmp[i] = c; | |
if (list.find(tmp) != list.end()) | |
res.push_back(tmp); | |
} | |
} | |
return res; | |
} | |
}; |
No comments:
Post a Comment