leetcode: Word Ladder II

來源:互聯網
上載者:User

標籤:leetcode   遞迴   bfs   

Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from start to end, such that:

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

For example,

Given:
start = "hit"
end = "cog"
dict = ["hot","dot","dog","lot","log"]

Return

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

本題5星難度,和I一樣用bfs,但是因為要輸出,所以時間不夠

先遍曆找到每個詞的前驅詞,用兩個隊列儲存當前層和之前層的詞,一個是正在處理,一個是下次需要處理

得到前驅詞表後,從end往前遞迴列印路徑

AC代碼

class Solution {public:    vector< vector< string> > res;    vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {        dict.insert(start);        dict.insert(end);        unordered_map< string, vector< string> > precursor;//儲存每個詞對應的前驅詞        for( unordered_set< string>::const_iterator citer = dict.begin(); citer != dict.end(); ++citer)//初始化            precursor.insert( make_pair( *citer, vector< string>()));        vector< unordered_set< string> >layers(2);//分別用來儲存當前層的詞和之前層的詞        layers[0].insert(start);        int cur = 0;        int pre = 1;        while(true){            cur = !cur;//兩層互換            pre = !pre;            for( unordered_set< string>::const_iterator citer = layers[pre].begin(); citer != layers[pre].end(); ++citer)                dict.erase(*citer);//刪除之前層裡出現在字典裡的詞            layers[cur].clear();            //bfs搜尋之前層裡每個詞通過一次變換可以達到的詞,該詞如果在字典裡就放入當前層            for( unordered_set< string>::const_iterator citer = layers[pre].begin(); citer != layers[pre].end(); ++citer){                string str = *citer;                for( int i = 0; i < str.size(); ++i){                    for( int j = 'a'; j <= 'z'; ++j){                        if( str[i] == j)                            continue;                        string tmp = str;                        tmp[i] = j;                        if( dict.count(tmp)){                            precursor[tmp].push_back(str);                            layers[cur].insert(tmp);                        }                    }                }            }            if( layers[cur].empty())//如果當前層空,說明無法從start到end,結束                return res;            if( layers[cur].count(end))//如果當前層出現end,說明已經找到了轉換,而且因為是根據層數來的,所以都是shortest                break;        }        vector< string> path;        generatePath( precursor, path, end);        return res;    }    //從end開始從後往前遞迴    void generatePath( unordered_map< string, vector< string> > &precursor, vector< string> &path, string end){        if( precursor[end].size() == 0){//沒有前驅詞說明已經到了start            path.push_back(end);            vector< string> tmp = path;            reverse( tmp.begin(), tmp.end());//反轉次序            res.push_back(tmp);            path.pop_back();        }        path.push_back(end);        for( vector< string>::const_iterator citer = precursor[end].begin(); citer != precursor[end].end(); ++citer){            generatePath( precursor, path, *citer);        }        path.pop_back();    }};


TLE得一塌糊塗,還是不能用遞迴的

class Solution {public:        vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {        vector< vector< string> > res;        vector< string> cur;        cur.push_back(start);        dict.insert(end);        unordered_set< string> tmp = dict;        int length = ladderLength(start, end, tmp);        core( res, cur, start, end, dict, length);        return res;    }    void core( vector< vector< string> > &res, vector< string> &cur, string start, string end, unordered_set< string> &dict, int l){        if( cur.size() > l)            return;        if( start == end){            res.push_back(cur);            return;        }        for( int i = 0; i < start.size(); ++i){            for( int j = 'a'; j <= 'z'; ++j){                if( start[i] == j)                    continue;                else{                    string tmp = start;                    tmp[i] = j;                    if( dict.count(tmp)){                        cur.push_back(tmp);                        dict.erase(tmp);                        core( res, cur, tmp, end, dict, l);                        cur.pop_back();                        dict.insert(tmp);                    }                }            }        }    }    int ladderLength(string start, string end, unordered_set<string> &dict) {        int shortest = INT_MAX;        dict.insert(end);        queue< pair< string, int> > q;        q.push( pair< string, int>( start, 1));        while( !q.empty()){            pair< string, int> cur = q.front();            q.pop();            if( cur.first == end){                shortest = shortest < cur.second ? shortest : cur.second;                continue;            }            string str = cur.first;            for( int i = 0; i < str.size(); ++i){                for( int j = 'a'; j <= 'z'; ++j){                    if( str[i] == j)                        continue;                    string tmp = str;                    tmp[i] = j;                    if( dict.count(tmp)){                        q.push( make_pair( tmp, cur.second+1));                        dict.erase(tmp);                    }                }            }        }        if( shortest == INT_MAX)            return 0;        return shortest;    }};


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.