773. Sliding Puzzle

问题:

滑动拼图。

给定2*3的一个拼图,有1~5代表每个格子的拼图,0代表空,其他位置的拼图可以滑动到这里。

求给定现在状态的拼图,是否最终能滑动到

1 2 3
4 5 0

的状态。

可以的话,需要最少多少步。

不可以的话,返回-1。

Examples:
Input: board = [[1,2,3],[4,0,5]]
Output: 1
Explanation: Swap the 0 and the 5 in one move.

Input: board = [[1,2,3],[5,4,0]]
Output: -1
Explanation: No number of moves will make the board solved.

Input: board = [[4,1,2],[5,0,3]]
Output: 5
Explanation: 5 is the smallest number of moves that solves the board.
An example path:
After move 0: [[4,1,2],[5,0,3]]
After move 1: [[4,1,2],[0,5,3]]
After move 2: [[0,1,2],[4,5,3]]
After move 3: [[1,0,2],[4,5,3]]
After move 4: [[1,2,0],[4,5,3]]
After move 5: [[1,2,3],[4,5,0]]

Input: board = [[3,2,4],[1,5,0]]
Output: 14

Note:
board will be a 2 x 3 array as described above.
board[i][j] will be a permutation of [0, 1, 2, 3, 4, 5].

  

解法:BFS

思路:将滑动后的每个状态作为一个node,进行queue横展开。

每个状态使用string记录。

例如:最终状态target就为:"123450"

当0在0~5位置上的时候,可以移动的选择有:

下图数字代表每个位置的index:

0 1 2
3 4 5

[0]->[1, 3]

[1]->[0,2,4]

[2]->[1,5]

[3]->[0,4]

[4]->[1,3,5] 例如上图表示

[5]->[2,4]

 

使用visited记录已经访问过的状态,若已经访问过,则不必再加入queue进行展开了。

代码参考:

 1 class Solution {
 2 public:
 3     int slidingPuzzle(vector<vector<int>>& board) {
 4         //for every cell i, can be move to dir[i]
 5         vector<vector<int>> dir={{1,3},{0,2,4},{1,5},{0,4},{1,3,5},{2,4}};
 6         string target("123450");
 7         string cur;
 8         //every condition would be a node for queue
 9         for(int i=0; i<2; i++) {
10             for(int j=0; j<3; j++) {
11                 cur.push_back('0'+board[i][j]);
12             }
13         }
14         //cout<< cur << endl;
15         queue<string> q;
16         unordered_set<string> visited;
17         q.push(cur);
18         int res = -1;
19         int pos_0=0;
20         string tmp;
21         while(!q.empty()) {
22             int sz=q.size();
23             res++;
24             for(int i=0; i<sz; i++) {
25                 cur = q.front();
26                 q.pop();
27                 if(cur==target) return res;
28                 pos_0=cur.find('0');
29                 for(auto d:dir[pos_0]) {
30                     tmp = cur;
31                     swap(tmp[pos_0], tmp[d]);
32                     if(visited.insert(tmp).second) {
33                         q.push(tmp);
34                     }
35                 }
36             }
37         }
38         return -1;
39     }
40 };

 

posted @ 2021-03-06 16:32  habibah_chang  阅读(61)  评论(0编辑  收藏  举报