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 解释:没有办法完成谜板
输入:board = [[4,1,2],[5,0,3]] 输出:5 解释: 最少完成谜板的最少移动次数是 5 , 一种移动路径: 尚未移动: [[4,1,2],[5,0,3]] 移动 1 次: [[4,1,2],[0,5,3]] 移动 2 次: [[0,1,2],[4,5,3]] 移动 3 次: [[1,0,2],[4,5,3]] 移动 4 次: [[1,2,0],[4,5,3]] 移动 5 次: [[1,2,3],[4,5,0]]
输入:board = [[3,2,4],[1,5,0]] 输出:14
1 class Solution { 2 public: 3 int slidingPuzzle(vector<vector<int>>& board) { 4 queue<string> q; 5 unordered_set<string> visited; 6 string target = "123450"; 7 string label = ""; 8 for(int i = 0; i <2;i++) { 9 for(int a: board[i]) { 10 label+=(a+'0'); 11 } 12 } 13 14 vector<vector<int>> negbors = { 15 {1,3}, 16 {0,2,4}, 17 {1,5}, 18 {0,4}, 19 {1,3,5}, 20 {2,4}, 21 }; 22 23 int step=0; 24 q.push(label); 25 visited.insert(label); 26 27 28 while(!q.empty()) { 29 int sz = q.size(); 30 for (int k = 0;k < sz;k++) { 31 string cur = q.front();q.pop(); 32 if (cur == target) { 33 return step; 34 } 35 36 //find 0 and sawp 37 int idx = 0; 38 for(;cur[idx]!='0';idx++); 39 for( int negbor : negbors[idx]) { 40 //sawp 41 string newpath = cur; 42 swap(newpath[idx],newpath[negbor]); 43 if (!visited.count(newpath)) { 44 visited.insert(newpath); 45 q.push(newpath); 46 } 47 } 48 } 49 step++; 50 } 51 return -1; 52 53 } 54 };