LeetCode 127 Word Ladder (广度优先搜索)

最近重新捡起算法来看,发现广度优先搜索的代码不是很熟,就在leetcode上搜了一下,找到这道题练练,还是发现了很多问题的。

题目描述:
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:

Only one letter can be changed at a time
Each intermediate word must exist in the word list
For example,

Given:
beginWord = “hit”
endWord = “cog”
wordList = [“hot”,”dot”,”dog”,”lot”,”log”]
As one shortest transformation is “hit” -> “hot” -> “dot” -> “dog” -> “cog”,
return its length 5.

由于事先知道是广度搜索,这道题目大体思路还是比较明确的,字典里存储可能的状态,定义数据结构存储队列中的字符串和当前的路径。代码如下:

class Solution {
public:
    struct data
    {
        string s;
        int length;
    };
    bool compareWords(string word1,string word2)
    {
        int length=word1.length();
        int count=0;
        for(int i=0;i<length;i++)
        {
            if(word1[i]!=word2[i])
                count++;
        }
        return count==1;
    }
    int ladderLength(string beginWord, string endWord, unordered_set<string>& wordList) {
        queue<data>q;
        data beginData;
        unordered_set<string> wordListCopy;
        beginData.s=beginWord;beginData.length=0;
        int length=0;
        q.push(beginData);
        while(!q.empty())
        {
            data tempData;
            beginData=q.front();
            q.pop();
            if(compareWords(beginData.s,endWord))
                return beginData.length+1;
            for(auto &word :wordList)
                if(wordListCopy.find(word)==wordListCopy.end()&&compareWords(beginData.s,word))
                {
                    tempData.s=word;
                    tempData.length=beginData.length+1;
                    q.push(tempData);
                    wordListCopy.insert(word);
                }
        }
        return length;
    }
};

上述代码运行最后超时了,但是感觉思路是对的,上网看了下别人的思路后,主要是在判断两个字符串是否只相差一个字符的时候算法复杂度为 O(n2) 。一般别人采用的都是对原始字符串每个位置进行替换的策略,复杂度可以降到 O(n) ,同时利用两个全局变量分别保存状态转移的数目和每一个状态下的数目,这样就可以不用定义数据结构表示每一个状态了。代码如下

class Solution {
public:
    int ladderLength(string beginWord, string endWord, unordered_set<string>& wordList) {
        queue<string>q;
        q.push(beginWord);
        int length = beginWord.size();
        int count = 1, level = 0;
        string s;
        while (!q.empty())
        {
            s = q.front();
            q.pop();
            for (int i = 0; i < length;i++)
                for (char c = 'a'; c <= 'z'; c++)
                {
                    if (c == s[i]) continue;
                    swap(c, s[i]);
                    if (s == endWord)
                        return level+2;
                    if (wordList.find(s) != wordList.end())
                    {
                        q.push(s);
                        wordList.erase(s);
                    }
                    swap(c, s[i]);
                }
            count--;
            if (count == 0)
            {
                count = q.size();
                level++;
            }
        }
        return 0;
        }
};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值