Leetcode 127. Word Ladder

time limit exceeded

class Solution {
public:
    int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
        unordered_set<string> wordSet;
        for (auto word : wordList) {
            wordSet.insert(word);
        }
        return reSolver(beginWord, endWord, wordSet);
    }

private: 
    int reSolver(string beginWord, string endWord, unordered_set<string> & wordList) {
        if (beginWord == endWord) return 1;  // 第一个头未加所以这里用1;

        unordered_set<string> tmp(wordList);
        int step = wordList.size() + 1;

        for (auto word : tmp) {
            int count = 0;
            int i = 0; 
            for (; i != beginWord.size() && count <= 1; ++i) {
                if (beginWord[i] != word[i])
                    ++count;
            }

            if (i == beginWord.size() && count == 1) {
                wordList.erase(word);
                int n  = reSolver(word, endWord, wordList);
                if (n != 0) { // n == 0, 没找到
                    step = min(step, n);
                }

                wordList.insert(word);
            }

        }

        return step == wordList.size() + 1 ? 0 : step + 1;
    }
};
class Solution {
public:
    int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
        unordered_map<string, vector<string> > mp;
        unordered_map<string, int> flag;
        if (wordList.size() == 0) return 0;
        int wordLen = wordList[0].size();

        for (int i = 0; i != wordList.size(); ++i) {
            for (int j = i + 1; j != wordList.size(); ++j) {
                int count = 0;
                int k = 0;
                for (; k != wordLen; ++k) {

                    if (wordList[i][k] != wordList[j][k])
                        ++count;
                }
                if (k == wordLen && count == 1) {
                    mp[wordList[i]].emplace_back(wordList[j]);
                    mp[wordList[j]].emplace_back(wordList[i]);
                }
            }
            flag[wordList[i]] = 0;
        }
        if (mp.find(beginWord) == mp.end()) {
            for (int i = 0; i != wordList.size(); ++i) {
               int count = 0;
                int k =  0;
                for (; k != wordLen; ++k) {

                    if (wordList[i][k] != beginWord[k])
                        ++count;
                }

                if (k == wordLen && count == 1) {

                    mp[beginWord].emplace_back(wordList[i]);
                    mp[wordList[i]].emplace_back(beginWord);
                }
            }
            flag[beginWord] = 0;
        }

        return reSolver(mp, beginWord, endWord, flag);
    }

private:
    int reSolver(unordered_map<string, vector<string> >& mp, string beginWord, string endWord, unordered_map<string, int>& flag) {
        if (beginWord == endWord) return 1;
        int step = flag.size() + 2;

        for (auto word: mp[beginWord]) {
            if (flag[word] == 0) {
                flag[word] = 1;
                int tmp = reSolver(mp, word, endWord, flag);
                if (tmp !=  0) {
                    step = min(step, tmp);
                }
                flag[word] = 0;
            }                
        }
        return step == flag.size() + 2 ? 0 : step + 1;
    }

};

参考后
思维误区, 之前用广度优先搜索的时候保证每条路线有一个set记录哪些数据在这条路线中用过,其实没有必要因为如果第一层用过第二层再用那绝对不可能是最短的因为它从第一层那条过去会更短何必从第二层那条过去

class Solution {
public:
    int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
        unordered_set<string> wordSet(begin(wordList), end(wordList));


        deque<string> dq;
        dq.emplace_back(beginWord);
        wordSet.erase(beginWord);
        int ret = 0;

        while (!dq.empty()) {
            ++ret;
            int n = dq.size();
            for (int k = 0; k != n; ++k) {
                string wd = dq.front();
                for (int i = 0; i != beginWord.size(); ++i) {
                    char c = wd[i];                    
                    for (char j = 'a'; j <= 'z'; ++j) {

                        wd[i] = j;
                        auto it = wordSet.find(wd);
                        if (it == wordSet.end()) continue;
                        if (wd == endWord) return ret + 1; // plus endWord                    
                        wordSet.erase(it);
                        dq.emplace_back(wd);
                    }
                    wd[i] = c;                
                }
                dq.pop_front();
            }
        }

        return 0;

    }
};

当n < 26 的话这个应该会更快一些。

class Solution {
public:
    int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
        unordered_map<string, vector<string> > mp;
        unordered_set<string> wordSet;
        if (wordList.size() == 0) return 0;
        int wordLen = wordList[0].size();

        for (int i = 0; i != wordList.size(); ++i) {
            for (int j = i + 1; j != wordList.size(); ++j) {
                int count = 0;
                int k = 0;
                for (; k != wordLen; ++k) {

                    if (wordList[i][k] != wordList[j][k])
                        ++count;
                }
                if (k == wordLen && count == 1) {
                    mp[wordList[i]].emplace_back(wordList[j]);
                    mp[wordList[j]].emplace_back(wordList[i]);
                }
            }
            wordSet.insert(wordList[i]);
        }
        if (mp.find(beginWord) == mp.end()) {
            for (int i = 0; i != wordList.size(); ++i) {
               int count = 0;
                int k =  0;
                for (; k != wordLen; ++k) {

                    if (wordList[i][k] != beginWord[k])
                        ++count;
                }

                if (k == wordLen && count == 1) {

                    mp[beginWord].emplace_back(wordList[i]);
                    mp[wordList[i]].emplace_back(beginWord);
                }
            }
            wordSet.insert(beginWord);
        }   
        deque<string> dq;
        dq.emplace_back(beginWord);
        wordSet.erase(beginWord);
        int ret = 0;
        while(!dq.empty()) {
            ++ret;
            int n = dq.size();
            for (int i = 0; i != n; ++i) {
                string word = dq.front(); 
                for (int j = 0; j != mp[word].size(); ++j) {
                    string nextWord = mp[word][j];
                    if (wordSet.find(nextWord) == wordSet.end()) continue;
                    if (nextWord == endWord) return ret + 1;
                    dq.emplace_back(nextWord);
                    wordSet.erase(nextWord);
                }
                dq.pop_front();
            }
        }
        return 0;
    }
};

参考后
快到没女朋友


class Solution {
public:
    int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
        unordered_set<string> wordSet(begin(wordList), end(wordList));
        unordered_set<string> beginSet { beginWord };
        if (wordSet.find(endWord) == wordSet.end()) return 0;

        unordered_set<string> endSet { endWord };



        deque<string> dq;
        dq.emplace_back(beginWord);
        wordSet.erase(beginWord);
        int ret = 0;

        unordered_set<string> *pbeginSet = nullptr;
        unordered_set<string> *pendSet = nullptr;
        while (!beginSet.empty() && !endSet.empty()) {
            ++ret;

            if (beginSet.size() > endSet.size()) {
                pbeginSet = &endSet;
                pendSet = &beginSet;
            }  else {
                pbeginSet = &beginSet;
                pendSet = &endSet;
            }
            unordered_set<string> tmp;
            for (auto wd : (*pbeginSet)){

                for (int i = 0; i != beginWord.size(); ++i) {
                    char c = wd[i];                    
                    for (char j = 'a'; j <= 'z'; ++j) {
                        wd[i] = j;
                        if ((*pendSet).find(wd) != (*pendSet).end()) return ret + 1; 
                        auto it = wordSet.find(wd);
                        if (it == wordSet.end()) continue;
                       // plus endWord                    
                        wordSet.erase(it);
                        tmp.insert(wd);
                    }
                    wd[i] = c;                
                }
            }

            *pbeginSet = tmp;
        }

        return 0;

    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值