leetcode 752. 打开转盘锁


题目

你有一个带有四个圆形拨轮的转盘锁。每个拨轮都有10个数字: ‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’ 。每个拨轮可以自由旋转:例如把 ‘9’ 变为 ‘0’,‘0’ 变为 ‘9’。每次旋转都只能旋转一个拨轮的一位数字。

锁的初始数字为 ‘0000’ ,一个代表四个拨轮的数字的字符串。

列表 deadends 包含了一组死亡数字,一旦拨轮的数字和列表里的任何一个元素相同,这个锁将会被永久锁定,无法再被旋转。

字符串 target 代表可以解锁的数字,你需要给出解锁需要的最小旋转次数,如果无论如何不能解锁,返回 -1 。

来源:力扣(LeetCode)
链接:752. 打开转盘锁
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


一、BFS

太懒了,直接改了改127. 单词接龙

class Solution {
public:
    int openLock(vector<string>& deadends, string endWord) {
        // 将vector转成unordered_set,提高查询速度
        unordered_set<string> wordset(deadends.begin(), deadends.end());
        // 如果endWord在wordSet出现,直接返回0
        if(wordset.find(endWord)!=wordset.end()||wordset.find("0000")!=wordset.end())return -1;
        if(endWord=="0000")return 0;
        // 记录word是否访问过
        unordered_map<string,int>umap;// <word, 查询到这个word路径长度>
        queue<string>que;
        que.push("0000");
        umap["0000"]=0;
        while(!que.empty())
        {
            string word=que.front();
            que.pop();
            int path=umap[word];
            for(int i=0;i<word.size();i++)
            {
                int num=word[i]-'0';
                int up=(num+1)%10;
                int down=(num+10-1)%10;
                string neword1 = word; 
                string neword2 = word;
                neword1[i]=up+'0';
                neword2[i]=down+'0';
                if(endWord==neword1||endWord==neword2)return path+1;
                // wordSet不出现newWord,并且newWord没有被访问过
                if(wordset.find(neword1)==wordset.end()&&umap.find(neword1)==umap.end())
                {
                    umap[neword1]=path+1;
                    que.push(neword1);
                }
                if(wordset.find(neword2)==wordset.end()&&umap.find(neword2)==umap.end())
                {
                    umap[neword2]=path+1;
                    que.push(neword2);
                }
            }
        }
        return -1;
    }
};

二、双向BFS

可以参考题解的解释,其实差不多

class Solution {
public:
int bfs(queue<string>& que, unordered_map<string, int>& umap1, unordered_map<string, int>& umap2, unordered_set<string>& wordset)
{
    string word=que.front();
    que.pop();
    int path=umap1[word];
    for(int i=0;i<4;i++)
    {
        int num=word[i]-'0';
        int up=(num+1)%10;
        int down=(num+10-1)%10;
        string neword1 = word; 
        string neword2 = word;
        neword1[i]=up+'0';
        neword2[i]=down+'0';
       
        /*if(wordset.find(neword1)!=wordset.end()||umap1.find(neword1)!=umap1.end()||wordset.find(neword2)!=wordset.end()||umap1.find(neword2)!=umap1.end())
        {
            continue
        }*/
        if(umap2.find(neword1)!=umap2.end())
        {
            return path+1+umap2[neword1];
        }
        if(umap2.find(neword2)!=umap2.end())
        {
            return path+1+umap2[neword2];
        }
        // wordSet不出现newWord,并且newWord没有被访问过
         if(wordset.find(neword1)==wordset.end()&&umap1.find(neword1)==umap1.end())
        {
            if(umap2.find(neword1)!=umap2.end())
            {
                return path+1+umap2[neword1];
            }
            umap1[neword1]=path+1;
            que.push(neword1);
        }
        if(wordset.find(neword2)==wordset.end()&&umap1.find(neword2)==umap1.end())
        {
            if(umap2.find(neword2)!=umap2.end())
            {
                return path+1+umap2[neword2];
            }
            umap1[neword2]=path+1;
            que.push(neword2);
        }
    }
    return -1;
}
    int openLock(vector<string>& deadends, string endWord) {
        // 将vector转成unordered_set,提高查询速度
        unordered_set<string> wordset(deadends.begin(), deadends.end());
        // 如果endWord在wordSet出现,直接返回0
        if(wordset.find(endWord)!=wordset.end()||wordset.find("0000")!=wordset.end())return -1;
        if(endWord=="0000")return 0;//注意
        // 记录word是否访问过
        unordered_map<string,int>mp1;// <word, 查询到这个word路径长度>
        unordered_map<string,int>mp2;// <word, 查询到这个word路径长度>
        queue<string>que1;
        queue<string>que2;
        que1.push("0000");
        mp1["0000"]=0;
        que2.push(endWord);
        mp2[endWord]=0;
        int res=-1;
        while(!que1.empty()&&!que2.empty())
        {
            //选择一个容量更少的队列进行BFS搜索
            if (que1.size() <= que2.size()) 
            {
                res = bfs(que1, mp1, mp2, wordset);
            } 
            else 
            {
                res = bfs(que2, mp2, mp1, wordset);
            }
            if (res != -1) return res;
        }
        return -1;
    }
};

总结

码一个BFS模板(这种还有点不太熟

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值