127. 126. Word Ladder *HARD* -- 单词每次变一个字母转换成另一个单词

127. 

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:

  1. Only one letter can be changed at a time
  2. Each intermediate word must exist in the word list

For example,

Given:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

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.
class Solution {
public:
    int ladderLength(string beginWord, string endWord, unordered_set<string>& wordList) {
        int l = beginWord.length(), n = wordList.size(), i;
        if(l <= 0 || n <= 0 || beginWord == endWord)
            return 0;
        queue<string> q;
        q.push(beginWord);
        map<string, int> m;
        m[beginWord] = 1;
        while(!q.empty())
        {
            string s = q.front();
            q.pop();
            for(i = 0; i < l; i++)
            {
                for(char c = 'a'; c <= 'z'; c++)
                {
                    string t = s;
                    t[i] = c;
                    if(wordList.find(t) != wordList.end() && m.find(t) == m.end())
                    {
                        m[t] = m[s] + 1;
                        if(t == endWord)
                            return m[t];
                        q.push(t);
                    }
                }
            }
        }
        return 0;
    }
};
// --------------------------- 
//  BFS non-recursive method
// ---------------------------
//
//    Using BFS instead of DFS is becasue the solution need the shortest transformation path.
//  
//    So, we can change every char in the word one by one, until find all possible transformation.
//
//    Keep this iteration, we will find the shorest path.
//
// For example:
//   
//     start = "hit"
//     end = "cog"
//     dict = ["hot","dot","dog","lot","log","dit","hig", "dig"]
//
//                      +-----+                  
//        +-------------+ hit +--------------+   
//        |             +--+--+              |   
//        |                |                 |   
//     +--v--+          +--v--+           +--v--+
//     | dit |    +-----+ hot +---+       | hig |
//     +--+--+    |     +-----+   |       +--+--+
//        |       |               |          |   
//        |    +--v--+         +--v--+    +--v--+
//        +----> dot |         | lot |    | dig |
//             +--+--+         +--+--+    +--+--+
//                |               |          |   
//             +--v--+         +--v--+       |   
//        +----> dog |         | log |       |   
//        |    +--+--+         +--+--+       |   
//        |       |               |          |   
//        |       |    +--v--+    |          |   
//        |       +--->| cog |<-- +          |   
//        |            +-----+               |   
//        |                                  |   
//        |                                  |   
//        +----------------------------------+   
//     
//     1) queue <==  "hit"
//     2) queue <==  "dit", "hot", "hig"
//     3) queue <==  "dot", "lot", "dig"
//     4) queue <==  "dog", "log" 

 

126.

Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that:

  1. Only one letter can be changed at a time
  2. Each intermediate word must exist in the word list

For example,

Given:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

Return

  [
    ["hit","hot","dot","dog","cog"],
    ["hit","hot","lot","log","cog"]
  ]

 

Note:

  • All words have the same length.
  • All words contain only lowercase alphabetic characters.
class Solution {
public:
void buildTree(string beginWord, string endWord, unordered_set<string> &wordList, map<string, unordered_set<string>> &m)
{
    map<string, int> level;
    level[beginWord] = 1;
    queue<string> q;
    q.push(beginWord);
    int lvl = 0;
    while (!q.empty())
    {
        string s = q.front();
        q.pop();
        if (lvl && level[s] > lvl)
            break;
        bool found = false;
        int l = s.length(), i;
        for (i = 0; i < l; i++)
        {
            string t = s;
            for (char c = 'a'; c <= 'z'; c++)
            {
                t[i] = c;
                if (t == endWord)
                {
                    m[s].clear();
                    m[s].insert(endWord);
                    lvl = level[s];
                    found = true;
                    break;
                }
                else if (wordList.find(t) != wordList.end())
                {
                    if (level.find(t) == level.end())
                    {
                        level[t] = level[s] + 1;
                        m[s].insert(t);
                        q.push(t);
                    }
                    else if (level[t] == level[s] + 1)
                    {
                        m[s].insert(t);
                    }
                }
            }
            if (found)
                break;
        }
    }
}
int countnum = 0;
void dfs(string endWord, vector<vector<string>> &ans, vector<string> &v, map<string, unordered_set<string>> &m, string s)
{
    if (m.find(s) == m.end() && s == endWord)
    {
        ans.push_back(v);
        return;
    }
    for (unordered_set<string>::iterator it = m[s].begin(); it != m[s].end(); it++)
    {
        v.push_back(*it);
        dfs(endWord, ans, v, m, *it);
        v.pop_back();
    }
}

vector<vector<string>> findLadders(string beginWord, string endWord, unordered_set<string> &wordList) {
    vector<vector<string>> ans;
    int l = beginWord.length(), n = wordList.size();
    if (l <= 0 || n <= 0 || beginWord == endWord)
        return ans;
    map<string, unordered_set<string>> m;
    buildTree(beginWord, endWord, wordList, m);

    vector<string> v;
    v.push_back(beginWord);
    map<string, bool> visit;
    dfs(endWord, ans, v, m, beginWord);
    return ans;
}


};
// Solution
//
//      1) Using BSF algorithm build a tree like below
//      2) Using DSF to parse the tree to the transformation path.
//
// For example:
//
//     start = "hit"
//     end = "cog"
//     dict = ["hot","dot","dog","lot","log","dit","hig", "dig"]
//
//                      +-----+
//        +-------------+ hit +--------------+
//        |             +--+--+              |
//        |                |                 |
//     +--v--+          +--v--+           +--v--+
//     | dit |    +-----+ hot +---+       | hig |
//     +--+--+    |     +-----+   |       +--+--+
//        |       |               |          |
//        |    +--v--+         +--v--+    +--v--+
//        +----> dot |         | lot |    | dig |
//             +--+--+         +--+--+    +--+--+
//                |               |          |
//             +--v--+         +--v--+       |
//        +----> dog |         | log |       |
//        |    +--+--+         +--+--+       |
//        |       |               |          |
//        |       |    +--v--+    |          |
//        |       +--->| cog |<-- +          |
//        |            +-----+               |
//        |                                  |
//        |                                  |
//        +----------------------------------+

 

转载于:https://www.cnblogs.com/argenbarbie/p/5463232.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值