Showing posts with label BFS. Show all posts
Showing posts with label BFS. Show all posts

Saturday, February 8, 2020

Leetcode 773 @ Sliding Puzzle

On a 2x3 board, there are 5 tiles represented by the integers 1 through 5, and an empty square represented by 0.
A move consists of choosing 0 and a 4-directionally adjacent number and swapping it.
The state of the board is solved if and only if the board is [[1,2,3],[4,5,0]].
Given a puzzle board, return the least number of moves required so that the state of the board is solved. If it is impossible for the state of the board to be solved, return -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我可以get大概idea, 但具体怎么实现,还是懵逼的,具体懵逼的点在于,怎么把这么一个二维矩阵转化为图和BFS的数据结构,也就是说,把具体问题建立模型的见多识广上还有点弱鸡。

先说解题思想,再说怎么用数据结构代入具体问题。

思路:0所在的地方就是出发点,0可以swap的邻居就是联通的边。0每swap一步,图的状态就改变一次,图有初始状态和目标状态。0每swap一次,就和目标状态对比一次,一旦匹配成功,既可以返回步数。此时如何让步数最小呢,那么就是BFS,这也很可以想,因为BFS把每一层的情况都遍历到了,但凡这一层有的就能够返回,说明步数是最少的。

数据结构:棋盘是一个二维数组,这一格二维数组就表示了一个状态。
set<vector<vector<int>>> visited : 用来记录所有访问过的状态
queue<pair<vector<vector<int>>, vector<int>>> q : 用来做BFS,pair里面存状态和"0"的对应坐标
int res 记录访问了几层
vector<vector<int>> dirs = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}} : 用来标记0可以走的方向,每次都用这几个值来计算新的0的坐标, int x = zero[0] + dir[0], int y = zero[1] + dir[1] 

随后就是BFS常规操作。
语法点:
1. q.front() 不是指针或者iterator,而是开头的元素,所以用 .first, .second, q.begin(), q.end() 是iterator
2. swap(a[i][j], b[i][j]), 原来可以直接swap 二维数组
3. q.push({board, {i,j}}), {board, {i, j}} 可以直接初始化pair, 而不需要pair(.....). 



class Solution {
public:
    int slidingPuzzle(vector<vector<int>>& board) {
        int res = 0;
        vector<vector<int>> target = {{1,2,3}, {4,5,0}};
        set<vector<vector<int>>> visited;
        queue<pair<vector<vector<int>>, vector<int>>> q;
        vector<vector<int>> dirs = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
        
        for (int i = 0; i<2; i++)
        { 
            for (int j = 0; j<3; j++)
            {
               if (board[i][j] == 0)
               {
                   q.push({board, {i,j}});
               }
            }
        }
        
        while(!q.empty())
        {
            // BFS finish visit one level, q size is changing, so 
            // take the initial one
            int size = q.size();
            for (int i = 0; i<size; i++)
            {
                auto cur = q.front().first;
                auto zero = q.front().second;
                q.pop();
                if (cur == target) return res;
                visited.insert(cur);
                for (auto dir : dirs)
                {
                    int x = zero[0] + dir[0], y = zero[1] + dir[1];
                    if (x < 0 || x >=2 || y < 0 || y >= 3) continue;
                    vector<vector<int>> tmp = cur;
                    swap(tmp[zero[0]][zero[1]], tmp[x][y]);
                    if (visited.count(tmp) > 0) continue;
                    q.push({tmp, {x,y}});
                }
            }
            ++res;
        }
        return -1;
    }
};

Sunday, September 8, 2013

Surrounded Region@leetcode

刷题必备书籍Cracking the Coding Interview: 150 Programming Questions and Solutions 

简历:The Google Resume: How to Prepare for a Career and Land a Job at Apple, Microsoft, Google, or any Top Tech Company
算法学习书籍:Introduction to Algorithms
编程珠玑:Programming Pearls (2nd Edition)
C++ 学习:The C++ Programming Language, 4th Edition
经典操作系统书籍,龙书:Operating System Concepts
创业:The Start-up of You: Adapt to the Future, Invest in Yourself, and Transform Your Career


Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'.
A region is captured by flipping all 'O's into 'X's in that surrounded region .
For example,
X X X X
X O O X
X X O X
X O X X
After running your function, the board should be:
X X X X
X X X X
X X X X
X O X X
» Solve this problem

这道题的关键是第一弄清楚:1。哪些o是需要被替代的,哪些不是。 2. 如何确定那些要被替代的。

思路1. dfs
不能被替代的o就是和边界相接的o,所以我们用dfs来搜索,只搜索边界,遇到边界的o mark为d,然后搜索和这个o相接的o,一直搜索到底。写一个单独的dfs的函数。这个可以在board上原地操作,不需要additional space.

大集合超时过不了。

2.bfs
需要用一个queue来存node。貌似有些复杂,就不写了



Friday, July 19, 2013

Symmetric Tree@leetcode

刷题必备书籍Cracking the Coding Interview: 150 Programming Questions and Solutions 

简历:The Google Resume: How to Prepare for a Career and Land a Job at Apple, Microsoft, Google, or any Top Tech Company
算法学习书籍:Introduction to Algorithms
编程珠玑:Programming Pearls (2nd Edition)
C++ 学习:The C++ Programming Language, 4th Edition
经典操作系统书籍,龙书:Operating System Concepts
创业:The Start-up of You: Adapt to the Future, Invest in Yourself, and Transform Your Career
Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).
For example, this binary tree is symmetric:
    1
   / \
  2   2
 / \ / \
3  4 4  3
But the following is not:
    1
   / \
  2   2
   \   \
   3    3
Note:
Bonus points if you could solve it both recursively and iteratively.
这题递归法比较简单,几行代码的事情。但是我在oj的时候老是不通过,逻辑很简单,而且我确定是对的,后来自己跑到emacs上面调试,发现有segmentation fault,原来是我做判断的时候的一句话
if(l->val==r->val&&!l&&!r)
这种情况下,l or r 有可能是null,那么就没有l->val or r->val, 就会出现问题,这样把空判断提前就可以了,细节,但一定要注意!
这题难的是iterative的解法,基本做法是BFS,一层一层看是否对称,然后用两个queue来存储结点。

Leetcode 316. Remove Duplicate Letters

 这道题表面问的是如何删除重复,实际在问如何从多个字符选取一个保留,从而让整个字符串按升序排列。那么策略就是对于高顺位的字符比如‘a',就要选靠前位置的保留,而低顺位字符如’z'则应该尽量选取靠后位置保留。 算法大概思路:每看到一个字符,我们要决定是否保留 1. ...