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;
    }
};
原文地址:https://www.cnblogs.com/stepping/p/14938993.html