zoukankan      html  css  js  c++  java
  • LeetCode Word Ladder

    Given two words (beginWord and endWord), and a dictionary, 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 dictionary

    For example,

    Given:
    start = "hit"
    end = "cog"
    dict = ["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.

    这道题一直以为是自己做过的,不过看了下提交记录,发现不过是直接修改了别人的代码,有点浮躁。1.5年前提交的,失去很多,得到的却寥寥无几。还是看了一些解答自己先写个BFS的:

    class Solution {
    public:
        int ladderLength(string beginWord, string endWord, unordered_set<string>& wordDict) {
            queue<string> que;
            que.push(beginWord);
            wordDict.insert(endWord);
            int level = 0;
            while (!que.empty()) {
                level++;
                int size = que.size();
                for (int i=0; i<size; i++) {
                    string str = que.front();
                    que.pop();
                    
                    if (str == endWord) {
                        return level;
                    }
                    
                    int len = str.size();
                    for (int k=0; k<len; k++) {
                        for (char ch='a'; ch <= 'z'; ch++) {
                            if (str[k] == ch) {
                                continue;
                            }
                            char t = str[k];
                            str[k] = ch;
                            if (wordDict.count(str) > 0) {
                                wordDict.erase(str);
                                que.push(str);
                            }
                            str[k] = t;
                        }
                    }
                }
            }
            return 0;
        }
    };

    没什么优化的地方,240+ms

    另外从discuss里找了个递归的解法,60ms

    class Solution {
    public:
        int ladderLength(string beginWord, string endWord, unordered_set<string>& wordDict) {
            unordered_set<string> s1 = {beginWord}; // Front end
            unordered_set<string> s2 = {endWord}; // Back end
            wordDict.erase(beginWord);
            wordDict.erase(endWord);
    
            return ladderLength(s1, s2, wordDict, 1);
        }
    
    private:
        int ladderLength(unordered_set<string>& s1, unordered_set<string>& s2, unordered_set<string>& wordDict, int level) {
            if (s1.empty()) // We can't find one.
                return 0;
    
            unordered_set<string> s3; // s3 stores all words 1 step from s1.
            for (auto word : s1) {
    
                for (auto& ch : word) {
                    auto originalCh = ch;
    
                    for (ch = 'a'; ch <= 'z'; ++ ch) {
    
                        if (ch != originalCh) {
    
                            if (s2.count(word))  // We found one.
                                return level + 1;
    
                            if (wordDict.count(word)) {
                                wordDict.erase(word); // Avoid duplicates.
                                s3.insert(word);
                            }
                        }
                    }
    
                    ch = originalCh;
                }
            }
            // Continue with the one with smaller size.    
            return (s2.size() <= s3.size()) ? ladderLength(s2, s3, wordDict, level + 1) : ladderLength(s3, s2, wordDict, level + 1);
        }
    };

    如果最后一个return中的判断不加的花,时间在340+ms。这个解法不是单向的从start往end走,他们的关系是对等的,可以根据需要进行双向的靠近。它会根据两者集合数量选择较少的那个来生成相差一次字母转换的一个集合来替换自己,进行下一步运算。如果发现本集合中有可以通过一次转换到另外一个集合中,则当前所进行过的转换次数即为最少转换次数。

  • 相关阅读:
    《SQL 基础教程》第五章:复杂查询
    Ruby on Rails Tutorial 第一章笔记
    《Practical Vim》第十章:复制和粘贴
    《Practical Vim》第五章:命令行模式
    《SQL 基础教程》第四章:数据更新
    用户的三次登录验证及进度条
    socket模块开启一个永久性服务
    TCP协议实现切换目录
    爬取好友微信信息
    TCP协议中传输系统命令及上传下载文件
  • 原文地址:https://www.cnblogs.com/lailailai/p/4574371.html
Copyright © 2011-2022 走看看