• 773. 滑动谜题 力扣(困难) bfs状态改变,写了一个下午


    题目描述:

    在一个 2 x 3 的板上(board)有 5 块砖瓦,用数字 1~5 来表示, 以及一块空缺用 0 来表示.

    一次移动定义为选择 0 与一个相邻的数字(上下左右)进行交换.

    最终当板 board 的结果是 [[1,2,3],[4,5,0]] 谜板被解开。

    给出一个谜板的初始状态,返回最少可以通过多少次移动解开谜板,如果不能解开谜板,则返回 -1 。

    示例:

    输入:board = [[1,2,3],[4,0,5]]
    输出:1
    解释:交换 0 和 5 ,1 步完成
    输入:board = [[1,2,3],[5,4,0]]
    输出:-1
    解释:没有办法完成谜板

    题源:https://leetcode-cn.com/problems/sliding-puzzle/

    题解:https://michael.blog.csdn.net/article/details/104118648

    利用字符串压缩状态,用map作hash,看是否有重复。

    学点:

    1. stoi() 对单个字符不适用,报错,对整串字符符合。( 区别于atoi(string.c_str())  )
    2. string类型,如果在末尾加一个字符,可以用push_back(),删除末尾一个字符可以用:pop_back()
    3. 在函数类型后加“&“,表示引用,也就是在函数中值变化,对应主代码中变量值也随之改变。
    4. string拆单个字符出来,比较是用单引号‘’,而不是双引号“”

    代码:

    class Solution {
    public:
        string vtos(vector<vector<int>> k)
        {
            string s;
            for(int i=0;i<2;i++)
              for(int j=0;j<3;j++)
                s.push_back(k[i][j]+'0'); // 或者 s=s+to_string(b[i][j]);
            return s;
        }
    
        void stov(string &s,int &x0,int &y0,vector<vector<int>>& k)
        {
            for(int i=0;i<2;i++)
                for(int j=0;j<3;j++)
                {
                    k[i][j]=s[i*3+j]-'0';
                    if( k[i][j]==0 ) { x0=i; y0=j; }   // 正确:if (s[i*3+j=='0')   错误:if(s[i*3+j]=="0)
                }
            return;
        }
    
        int slidingPuzzle(vector<vector<int>>& board) {
         int d[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
         map<string,int> mp;
         bool flag=0;
         queue<string> Q;
         
        string s=vtos(board);
        Q.push(s);
        mp[s]=0;
        while(!Q.empty())
        {
            string p=Q.front();
            Q.pop();
            int x0,y0;
            stov(p,x0,y0,board);  //得到0点坐标,并且形成矩阵
            
            for(int i=0;i<4;i++)
            {
                int x=x0+d[i][0];
                int y=y0+d[i][1];
                if(!((x>=0 && x<2) && (y>=0 && y<3)) ) continue;
                swap(board[x0][y0],board[x][y]);
    
                string s;
                for(int ii=0;ii<2;ii++)
                   for(int jj=0;jj<3;jj++)
                     s=s+to_string(board[ii][jj]); // 或 s.push_back(board[ii][jj]+'0');
                if(mp.find(s)==mp.end())
                {
                     mp[s]=mp[p]+1;
                     Q.push(s);
                }
                if(s=="123450") {flag=1; break;}
                swap(board[x0][y0],board[x][y]);           
            }
            if(flag) break;
        }
        if(flag) return mp["123450"];
           else return -1;
        }
    };
  • 相关阅读:
    6月16日
    9月15日
    9月14日
    9月13日
    9月12日
    6月11日
    梦断代码阅读笔记
    11周总结
    梦断代码阅读笔记
    10第一阶段意见评论
  • 原文地址:https://www.cnblogs.com/stepping/p/14938993.html
Copyright © 2020-2023  润新知