zoukankan      html  css  js  c++  java
  • [LeetCode] 127 Word Ladder

    原题地址:

    https://leetcode.com/problems/word-ladder/description/

    题目:

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

    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.
      • You may assume no duplicates in the word list.
      • You may assume beginWord and endWord are non-empty and are not the same.

    解法:

    这道题目给定一个开始的单词和一个结束的单词,然后给了一个单词的数组,每次能变换单词的一个字母,要求由开始单词变换到结束单词的最短路径的长度。看似是字符串的题目,但涉及到最短路径,就知道是使用BFS进行解决。

    准备一个队列,先把开始单词放进队列里面,每次从队列中拿出一个单词,我们把它称为“当前单词”。当“当前单词”与结束单词一样时,返回当前遍历到的层数。否则,把搜索到与当前单词相差一个字母的单词放进队列里面。每次把一个单词放进队列里面时,把这个单词从单词数组里面删除掉,以防形成环路。

    具体实现代码如下:

    class Solution {
    public:
       bool isConnected(string a, string b) {
           int num = 0;
           for (int i = 0; i < a.size(); i++) {
               if (a[i] != b[i]) num++;
           }
           return num == 1;
      }
       int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
            int res = 1;
            queue<string> q;
            q.push(beginWord);
            int count = 1;
            while (!q.empty()) {
                string str = q.front();
                q.pop();
                count--;
                if (str == endWord) return res;
                for (vector<string>::iterator iter = wordList.begin(); iter != wordList.end();) {
                    if (isConnected(str, *iter)) {
                        q.push(*iter);
                        iter = wordList.erase(iter);
                    }
                    else {
                        iter++;
                    }
                }
                if (count == 0) {
                    count = q.size();
                    res++;
                }
            }
            return 0;
        }
    };

    上面的代码有两点值得去研究的:
    (1)

    count变量的使用:这是用来计算当前层数的,每当count为0,表明已经把一层的单词都访问过了,层数res加1,然后再把新的一层的单词个数赋给count。这是需要理解一下的地方。

    (2)

    把单词放进队列时,要把这个单词从原来的数组里面erase掉,避免出现环路。但现在erase掉的单词,为什么就不会在后面使用到呢(不同的路径)?这个我刚做完的时候百思不得其解,后来一想,假如后面使用到了,它也不会是最短的路径(使用到的那一条路径的后半部分和当前路径一模一样),因此可以直接erase掉。

  • 相关阅读:
    dockerk个人学习(0)
    ubuntu编译python源码的坑
    查找大目录
    ubuntu 远程gui显示
    paramiko模块
    python open和file的区别
    python type metaclass
    python 生成器 迭代器 yiled
    博客暂停更新,请移步新主页
    win10禁用自动更新服务
  • 原文地址:https://www.cnblogs.com/fengziwei/p/7656464.html
Copyright © 2011-2022 走看看