LintCode 794: Sliding Puzzle II (BFS和A*经典题)

  1. Sliding Puzzle II

On a 3x3 board, there are 8 tiles represented by the integers 1 through 8, and an empty square represented by 0.

A move consists of choosing 0 and a 4-directionally adjacent number and swapping it.

Given an initial state of the puzzle board and final state, return the least number of moves required so that the initial state to final state.

If it is impossible to move from initial state to final state, return -1.

Example
Example 1:

Input:
[
[2,8,3],
[1,0,4],
[7,6,5]
]
[
[1,2,3],
[8,0,4],
[7,6,5]
]
Output:
4

Explanation:
[ [
[2,8,3], [2,0,3],
[1,0,4], --> [1,8,4],
[7,6,5] [7,6,5]
] ]

[ [
[2,0,3], [0,2,3],
[1,8,4], --> [1,8,4],
[7,6,5] [7,6,5]
] ]

[ [
[0,2,3], [1,2,3],
[1,8,4], --> [0,8,4],
[7,6,5] [7,6,5]
] ]

[ [
[1,2,3], [1,2,3],
[0,8,4], --> [8,0,4],
[7,6,5] [7,6,5]
] ]
Example 2:

Input:
[[2,3,8],[7,0,5],[1,6,4]]
[[1,2,3],[8,0,4],[7,6,5]]
Output:
-1
Challenge
How to optimize the memory?
Can you solve it with A* algorithm?

解法1:BFS
注意:这种棋盘类的题目用BFS都要把状态转换为一维来方便处理。
代码如下:

class Solution {
public:
    /**
     * @param init_state: the initial state of chessboard
     * @param final_state: the final state of chessboard
     * @return: return an integer, denote the number of minimum moving
     */
    int minMoveStep(vector<vector<int>> &init_state, vector<vector<int>> &final_state) {
        string beginStr = getStr(init_state);
        string endStr = getStr(final_state);
        if (beginStr == endStr) return 0;
        
        unordered_set<string> visited;
        queue<pair<string, int>> q; //string, pos
        //pair<string, int> node = make_pair(beginStr, getZeroPos(init_state));
        //pair<string, int> node(beginStr, getZeroPos(init_state));
         pair<string, int> node = {beginStr, getZeroPos(init_state)};
        q.push(node);
        vector<int> dx = {1, -1, 0, 0};
        vector<int> dy = {0, 0, 1, -1};
        int step = 1;
        
        while(!q.empty()) {
            int qSize = q.size();
            for (int i = 0; i < qSize; ++i) {
                node = q.front();
                string frontStr = node.first;
                q.pop();
                int x = node.second / 3;
                int y = node.second % 3;
                
                for (int j = 0; j < 4; ++j) {
                    int newX = x + dx[j];
                    int newY = y + dy[j];
                    if (newX >= 0 && newX < 3 && newY >= 0 && newY < 3) {
                        int newPos = newX * 3 + newY;
                        swap(frontStr[node.second], frontStr[newPos]);
                        if (visited.find(frontStr) == visited.end()) {
                            if (frontStr == endStr) {
                                return step;
                            } else {
                                visited.insert(frontStr);
                                q.push({frontStr, newPos});
                            }
                        }
                        frontStr = node.first;
                    }
                }
            }
            step++;
        }
        return -1;
    }

private:
   string getStr(vector<vector<int>> &vv) {
       string str = "";
       for (int i = 0; i < 3; ++i) {
           for (int j = 0; j < 3; ++j) {
               str.push_back('0' + vv[i][j]);
           }
       }
       return str;
   }
   
   int getZeroPos(vector<vector<int>> &vv) {
       int pos = 0;
       for (int i = 0; i < 3; ++i) {
           for (int j = 0; j < 3; ++j) {
               if (vv[i][j] == 0) {
                   return i * 3 + j;
               }
           }
       }
       return -1;
   }
   
};

二刷:

class Solution {
public:
    /**
     * @param initState: the initial state of chessboard
     * @param finalState: the final state of chessboard
     * @return: return an integer, denote the number of minimum moving
     */
    int minMoveStep(vector<vector<int>> &initState, vector<vector<int>> &finalState) {
        int nRow = initState.size(), nCol = initState[0].size();
        string srcState = matrix2Str(initState);
        string destState = matrix2Str(finalState);
        queue<string> stateQueue;
        set<string> visited;
        stateQueue.push(srcState);
        visited.insert(srcState);
        int dx[4] = {1, -1, 0, 0};
        int dy[4] = {0, 0, 1, -1};
        int step = 0;
        while (!stateQueue.empty()) {
            int qSize = stateQueue.size();
            for (int i = 0; i < qSize; i++) {
                string frontState = stateQueue.front();
                stateQueue.pop();
                if (frontState == destState) return step;
                int pos0 = frontState.find('0');
                int x = pos0 / 3, y = pos0 % 3;
            
                for (int j = 0; j < 4; j++) {
                    int newX = x + dx[j];
                    int newY = y + dy[j];
                    
                    if (newX >= 0 && newX < 3 && newY >= 0 && newY < 3) {
                        string newState = frontState;
                        swap(newState[pos0], newState[newX * 3 + newY]);
                        if (visited.find(newState) == visited.end()) {
                            stateQueue.push(newState);
                            visited.insert(newState);
                        }
                    }
                }
            }
            step++;
        }
        return -1;
    }
private:
    string matrix2Str(vector<vector<int>> &initState) {
        string str = "";
        int nRow = initState.size(), nCol = initState[0].size();
        for (int i = 0; i < nRow; i++) {
            for (int j = 0; j < nCol; j++) {
                str += '0' + initState[i][j];
            }
        }
        return str;
    }
};

解法2:A*算法。
TBD。

解法3:DFS

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值