题目描述:
给两个单词和一个单词列表,每次转换只能改变一个字母,且只能变为在单词列表里的单词。问最少变换多少次,beginword能变为endword。
思路:
bfs。对单词的每个字母尝试26种变换,如果该单词在列表里,加入队列。
一直超时,把vector改为set以后,对于每次出现过的单词都直接删除。可以节省查找时间,然后就过了。
代码:
class Solution {
public:
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
auto it = find(wordList.begin(), wordList.end(), endWord);
if (it == wordList.end()) return 0;
set<string> st(wordList.begin(), wordList.end());
return bfs(beginWord, endWord, st);
}
private:
int bfs(string st, string ed, set<string>& words) {
queue<string> que;
que.push(st);
int step = 1;
while(!que.empty()) {
int size = que.size();
while(size--) {
string cur = que.front();
que.pop();
for (int i=0; i<cur.length(); ++i) {
string ts = cur;
for (int j=0; j<26; ++j) {
char tmp = j + 'a';
if (tmp == cur[i]) continue;
ts[i] = tmp;
if (!words.count(ts)) continue;
if (ts == ed) return step+1;
words.erase(ts);
que.push(ts);
}
}
}
step++;
}
return 0;
}
};
这周将是bfs周。
其实想做用队列和栈实现bfs和dfs的题。
#############################################
第二次写。常规想法 n*n,也能过。
又重新写了上边的实现。
有点恶心。
class Solution {
public:
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
wordList.insert(wordList.begin(), beginWord);
n = wordList.size();
vis = vector<int> (n, 0);
auto it = find(wordList.begin(), wordList.end(), endWord);
int end;
if (it == wordList.end()) return 0;
else end = it - wordList.begin();
return bfs(0, end, wordList);
}
private:
vector<int> vis;
int n;
int bfs(int st, int ed, vector<string>& words) {
queue<int> que;
que.push(st);
int step = 1;
while(!que.empty()) {
int size = que.size();
while(size--) {
int cur = que.front();
que.pop();
for (int i=1; i<words.size(); ++i) {
if (vis[i]) continue;
if (dis(i, cur, words) != 1) continue;
if (i == ed) return step+1;
vis[i] = 1;
que.push(i);
}
}
step++;
}
return 0;
}
int dis(int a, int b, vector<string>& words) {
int len = words[a].length();
int res = 0;
for (int i=0; i<len; ++i) {
if (words[a][i] != words[b][i]) res++;
}
return res;
}
};