LeetCode 773 滑动谜题[BFS] HERODING的LeetCode之路

在这里插入图片描述解题思路:
这道题目的思路其实与1091题很像,都是从一个状态到另一个状态,如果能到最终状态则返回步数,如果所有状态都遍历了还是没有想要的状态,则返回-1,本题中,由于数组固定,不如换成一组连续的序列“123450”,此外要根据不同0位置所能交换的位置封装成数组(其实本质就是左右上下方向那样)。本题解题过程如下:

  1. 构建方向数组;
  2. 构建获取下一状态序列的函数;
  3. 将初始数组转换成类似“123450”的形式;
  4. 构建队列,步数,访问数组,并把初始位置放入队列中;
  5. 对于同一步数的状态,统一进行遍历,判断是否是想要的状态,不是则把状态记录到访问数组中;
  6. 所有状态都遍历过依然没有想要状态,返回-1。

代码如下:

class Solution {
private:
    vector<vector<int>> exchange = {{1, 3}, {0, 2, 4}, {1, 5}, {0, 4}, {1, 3, 5}, {2, 4}};
public:
    int slidingPuzzle(vector<vector<int>>& board) {
        string init;
        for(int i = 0; i < 2; i ++) {
            for(int j = 0; j < 3; j ++) {
                init += char(board[i][j] + '0');
            }
        }
        if(init == "123450") {
            return 0;
        }
        // 步数,状态队列,访问列表
        int step = 0;
        queue<string> q;
        unordered_set<string> visited = {init};
        q.push(init);
        while(!q.empty()) {
            step ++;
            int len = q.size();
            // 遍历同一步数的所有状态
            for(int i = 0; i < len; i ++) {
                string status = q.front();
                q.pop();
                // 获取所有下一状态
                vector<string> res = getStatus(status);
                for(auto& next_status : res) {
                    // 不能是经历过的状态
                    if(!visited.count(next_status)) {
                        if(next_status == "123450") {
                            return step;
                        }
                        q.push(next_status);
                        // move可以改善性能
                        visited.insert(move(next_status));
                    }
                }
            }
        } 
        return -1;
    }

    // 枚举status一次交换后所能获得的状态
    vector<string> getStatus(string& status) {
        vector<string> res;
        int index = status.find('0');
        for(int i : exchange[index]) {
            // 换一下
            swap(status[index], status[i]);
            res.push_back(status);
            // 换回来
            swap(status[index], status[i]);
        }
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HERODING77

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值