zoukankan      html  css  js  c++  java
  • [Leetcode Week5]Word Ladder II

    Word Ladder II 题解

    原创文章,拒绝转载

    题目来源:https://leetcode.com/problems/word-ladder-ii/description/


    Description

    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 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

    class Solution {
    private:
        map<string, int> isVisited;
        map<string, vector<string>> preVertex;
    public:
        bool canTrans(string a, string b) {
            int count = 0;
            for (int i = 0; i < a.length(); i++)
                if (a[i] != b[i]) {
                    if (count == 0)
                        count++;
                    else
                        return false;
                }
            return count == 1;
        }
    
        vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) {
            vector<vector<string>> resultLists;
            vector<string> adjacentWordOfEnd;
            if (wordList.size() == 0)
                return resultLists;
    
            bool endWordExist = false;
            for (auto& w: wordList)
                if (w == endWord) {
                    endWordExist = true;
                    break;
                }
            if (!endWordExist)
                return resultLists;
    
            isVisited[beginWord] = 0;
            queue<string> vq;
            vq.push(beginWord);
            string qfront;
    
            bool flag = false;
            while (!vq.empty()) {
                qfront = vq.front();
                vq.pop();
                if (qfront == endWord)
                    break;
                if (canTrans(qfront, endWord)) {
                    adjacentWordOfEnd.push_back(qfront);
                    flag = true;
                    continue;
                }
                if (flag)
                    continue;
    
                int curLevel = isVisited[qfront];
                for (auto& w: wordList) {
                    if (canTrans(qfront, w)) {
                        if (isVisited.count(w) == 0) {
                            isVisited[w] = curLevel + 1;
                            vq.push(w);
                            preVertex[w].push_back(qfront);
                        } else if (isVisited[w] == 1 + curLevel) {
                            preVertex[w].push_back(qfront);
                        }
                    }
                }
            }
    
            if (adjacentWordOfEnd.empty())
                return resultLists;
    
            queue< stack<string> > pathQueue;
            for (auto& w: adjacentWordOfEnd) {
                stack<string> path;
                path.push(endWord);
                path.push(w);
                pathQueue.push(path);
            }
    
            while (!pathQueue.empty()) {
                stack<string> curPath(pathQueue.front());
                pathQueue.pop();
                string curVertex = curPath.top();
                if (curVertex == beginWord) {
                    insertPath(resultLists, curPath);                
                } else if (preVertex[curVertex].size() == 1 && preVertex[curVertex].back() == beginWord) {
                    curPath.push(beginWord);
                    insertPath(resultLists, curPath);
                } else {
                    for (int i = 1; i < preVertex[curVertex].size(); i++) {
                        stack<string> newPath(curPath);
                        newPath.push(preVertex[curVertex][i]);
                        pathQueue.push(newPath);
                    }
                    curPath.push(preVertex[curVertex][0]);
                    pathQueue.push(curPath);
                }
            }
    
            return resultLists;
        }
    
    
        void insertPath(vector<vector<string>>& resultLists, stack<string>& reversePath) {
            vector<string> path;
            while (!reversePath.empty()) {
                path.push_back(reversePath.top());
                reversePath.pop();
            }
            resultLists.push_back(path);
        }
    };
    

    解题描述

    这道题是在leetcode上AC的第一道hard的题,花了一天。一开始想到的还是BFS,在Word Ladder的基础上,多记录下完整的路径。但是实际并没有这么简单。这道题要多考虑相同长度的所有路径的情况。所以我起初想到的解决的办法就是通过记录BFS树中所求路径上每一个点的父节点,然后通过获取endWord的所有父节点来向上回溯直到达到beginWord。但是这里我想少了一点,就是其实路径中间的节点也可以和endWord一样拥有多个父节点。解决了这个问题之后,没有过的测例表明,对于endWord同层节点的排除还没有做。所以就另外加了一个flag来标记以排除与endWord同层的点,这才最终AC。

  • 相关阅读:
    地址SQL文件
    SpringBoot webjars 映射
    Maven 阿里镜像
    Log4j输出的日志乱码问题
    Redis Client 官方下载地址
    SpringBoot连接Oracle报错,找不到驱动类,application.properties文件中驱动类路径为红色
    Linux Ubuntu 默认root密码
    Java 格式化字符串
    Linux Ubuntu 常见的压缩命令
    使用MD5比较两个文件是否相同
  • 原文地址:https://www.cnblogs.com/yanhewu/p/7657843.html
Copyright © 2011-2022 走看看