17. Letter Combinations of a Phone Number
Given a digit string, return all possible letter combinations that the number could represent.
A mapping of digit to letters (just like on the telephone buttons) is given below.
Input:Digit string "23" Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
Note:
Although the above answer is in lexicographical order, your answer could be in any order you want.
Solution: 对于每一位遍历每种可能性。
Code(递归):
class Solution {
public:
vector<string> letterCombinations(string digits) {
vector<string> ans;
if(digits.size()==0) return ans;
string path;
letterCombinations(0, digits, path, ans);
return ans;
}
private:
vector<string> m{"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
void letterCombinations(int index, string& digits, string& path, vector<string>& ans){
if(index==digits.size()){
ans.push_back(path);
return;
}
int number = digits[index]-'0';
for(int i=0; m[number][i]; i++){
path.push_back(m[number][i]);
letterCombinations(index+1, digits, path, ans);
path.pop_back();
}
}
};
Code(迭代):
class Solution {
public:
const vector<string> m{"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
vector<string> letterCombinations(string digits) {
vector<string> ans;
if(digits.size()==0) return ans;
ans.push_back("");
for(int i=0; i<digits.size(); i++){
int size = ans.size();
for(int j=0; j<size; j++){
string s = ans[0];
ans.erase(ans.begin());
int index = digits[i]-'0';
for(int t=0; m[index][t]; t++){
s.push_back(m[index][t]);
ans.push_back(s);
s.pop_back();
}
}
}
return ans;
}
};
127. Word Ladder
Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence frombeginWord 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.
For example,
Given:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log","cog"]
As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog"
,
return its length 5
.
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.
UPDATE (2017/1/20):
The wordList parameter had been changed to a list of strings (instead of a set of strings). Please reload the code definition to get the latest changes.
Solution: 广度优先搜索,一层层的搜索相邻单词,使用位向量visited记录访问过的单词去重。
Code:
class Solution {
public:
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
if(beginWord==endWord) return 1;
//广搜
vector<bool> visited;//不要使用vector<bool> visited(false, wordList.size*())的方式初始化,不知为何会出bug
for(int i=0; i<wordList.size(); i++) visited.push_back(false); //直接push_back
queue<pair<int,int>> q;//(wordIndex,step)
for(int t=0; t<wordList.size(); t++){
int count = 0;
for(int j=0; j<wordList[t].size(); j++){
if(beginWord[j]!=wordList[t][j]){
count++;
if(count>2) break;
}
}
if(count==1){
q.push(make_pair(t,2));
visited[t] = true;
}
}
while(!q.empty()){
if(wordList[q.front().first]==endWord){
return q.front().second;
}
for(int t=0; t<wordList.size(); t++){
if(visited[t]) continue;
int count = 0;
for(int j=0; j<wordList[t].size(); j++){
if(wordList[q.front().first][j]!=wordList[t][j]){
count++;
if(count>2) break;
}
}
if(count==1){
q.push(make_pair(t,q.front().second+1));
visited[t] = true;
}
}
q.pop();
}
return 0;
}
};
126. Word Ladder II
Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWordto 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.
For example,
Given:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log","cog"]
Return
[ ["hit","hot","dot","dog","cog"], ["hit","hot","lot","log","cog"] ]
Note:
- Return an empty list 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.
UPDATE (2017/1/20):
The wordList parameter had been changed to a list of strings (instead of a set of strings). Please reload the code definition to get the latest changes.
Solution: 这题解法思路跟上一题类似,只是注意三点:1、去重的方式必须要保留所有的最短路径;2、记录下路径的方式;3、退出循环的时机。
Code:
class Solution {
public:
vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) {
vector<vector<string>> ans;
if(beginWord==endWord){
ans.push_back(vector<string> {beginWord});
return ans;
}
//广搜
wordList.insert(wordList.begin(), beginWord);
vector<bool> visited;//不要使用vector<bool> visited(false, wordList.size*())的方式初始化,不知为何会出bug
for(int i=0; i<wordList.size(); i++) visited.push_back(false); //直接push_back
unordered_set<int> cur, next;//(wordIndex,step) //使用set去重
cur.insert(cur.end(), 0);
int level = 1;
bool found = false;
unordered_map<int,vector<int>> father;//记录全部的路径
int target = find(wordList.begin(), wordList.end(), endWord) - wordList.begin();
if(target==wordList.size()) return ans;
int k = 20;
while(!cur.empty() && !found){
for(auto i:cur) visited[i] = true;//防止指向同一层或者上一层的单词
while(!cur.empty()){
cout<<level<<' '<<wordList[*cur.begin()]<<": ";
for(int t=0; t<wordList.size(); t++){
if(visited[t]) continue;
int count = 0;
for(int j=0; j<wordList[t].size(); j++){
if(wordList[*cur.begin()][j]!=wordList[t][j]){
count++;
if(count>2) break;
}
}
if(count==1){
cout<<wordList[t]<<' ';
next.insert(next.end(),t);
father[t].push_back(*cur.begin());
if(t==target) found = true;
}
}
cout<<endl;
cur.erase(cur.begin());
}
level++;
swap(cur, next);
}
vector<string> path;
if(found) setPath(father, target, wordList, path, ans);
return ans;
}
private:
void setPath(unordered_map<int,vector<int>>& father, int target, vector<string>& wordList,
vector<string>& path, vector<vector<string>>& ans){
path.insert(path.begin(), wordList[target]);
if(target==0){
ans.push_back(path);
}else{
for(int i=0; i<father[target].size(); i++){
setPath(father, father[target][i], wordList, path, ans);
}
}
path.erase(path.begin());
return;
}
};