最初的思路(TLE,最大数据集wordList约2800个词):
维护两个集合,分别代表beginWord的n级关系和endWord的n级关系;
若beginSet和endSet在第n级关系的交集为空,则beginSet和endSet分别去wordList中扩展下一级关系。
若beginSet和endSet在第n级关系的交集不为空,则返回关系级数。
代码如下:
public class Solution {
public int countDiffCh(String word1, String word2){
int count = 0;
for(int i = 0; i < word1.length(); i ++){
if (word1.charAt(i) != word2.charAt(i))
count ++;
}
return count;
}
//add the next level neighbor into set, and remove them from the wordList
//return true: changed, false otherwise;
public boolean addNewNeighbor(Set<String> set, LinkedList<String> wordList){
boolean flag = false;
Set<String> newSet = new HashSet<String>();
for(String wordInSet : set){
int p = 0;
while(p < wordList.size()){
if (countDiffCh(wordInSet, wordList.get(p)) == 1){
newSet.add(wordList.get(p));
wordList.remove(p);
flag = true;
}else{
p ++;
}
}
if (wordList.size() == 0)
break;
}
set.addAll(newSet);
return flag;
}
public int ladderLength(String beginWord, String endWord, Set<String> wordList) {
Set<String> beginSet = new HashSet<String>();
beginSet.add(beginWord);
Set<String> endSet = new HashSet<String>();
endSet.add(endWord);
LinkedList<String> beginList = new LinkedList<String>();//lengths of words in the wordList should be all the same
LinkedList<String> endList = new LinkedList<String>();
for (String word : wordList){
if (! word.equals(beginWord))
beginList.add(word);
if (! word.equals(endWord))
endList.add(word);
}
int pathLen = 1;
Set<String> tmp;
while(true){
tmp = new HashSet(beginSet);
tmp.retainAll(endSet);
if (tmp.size() != 0){
break;
}
if ((beginList.size() == 0 && endList.size() == 0) ||
(addNewNeighbor(beginSet, beginList) == false && addNewNeighbor(endSet, endList) == false)){
pathLen = 0;
break;
}
pathLen ++;
}
return pathLen;
}
}
解决办法:
把wordList中的词和Set中的词一一比较太费时,可以用wordList中的词去产生所有相差一个字母的情况,然后判断Set.contains(word),不超时
https://discuss.leetcode.com/topic/64729/share-my-easy-bfs-solution-java
这个代码实现更简洁:https://discuss.leetcode.com/topic/17890/another-accepted-java-solution-bfs/2
改写如下,大数据还是TLE:
public class Solution {
//add the next level neighbor into set, and remove them from the wordList
//return true: changed, false otherwise;
public boolean addNewNeighbor(Set<String> set, LinkedList<String> wordList){
boolean flagNewNeighbor = false;
int p = 0;
boolean flag = false; // cur word is a new neighbor;
Set<String> newSet = new HashSet<String>();
while(p < wordList.size()){
flag = false;
for (int i = 0; i < wordList.get(p).length(); i ++){
char[] chs = wordList.get(p).toCharArray();
for (char ch = 'a'; ch <= 'z'; ch ++){
if (ch == wordList.get(p).charAt(i))
continue;
else
chs[i] = ch;
String newWord = new String(chs);
if (set.contains(newWord)){
newSet.add(wordList.get(p));
wordList.remove(p);
flag = true;
break;
}
}
if (flag == true)
break;
}
if (flag == false)
p ++;
else
flagNewNeighbor = true;
}
set.addAll(newSet);
return flagNewNeighbor;
}
public int ladderLength(String beginWord, String endWord, Set<String> wordList) {
Set<String> beginSet = new HashSet<String>();
beginSet.add(beginWord);
LinkedList<String> beginList = new LinkedList<String>();//lengths of words in the wordList should be all the same
for (String word : wordList){
if (! word.equals(beginWord))
beginList.add(word);
}
int pathLen = 1;
while(true){
if (beginSet.contains(endWord)){
break;
}
if (beginList.size() == 0 || addNewNeighbor(beginSet, beginList) == false){
pathLen = 0;
break;
}
pathLen ++;
}
return pathLen;
}
}