[LeetCode] BFS解决的题目

一.130  Surrounded Regions(https://leetcode.com/problems/surrounded-regions/description/)

题目:

解法:

这道题的意思是将所有被X包围的O都变为X(边缘的不算),我们可以维护一个队列,先把四周的O的位置放进队列中,并把这个位置的值变为Y。然后每次从队列中拿出一个位置,把这个位置四周为O的位置的值变为Y,再把这个位置放进队列(为什么要先变值再进队列呢?在下一道题中会说)。一直到队列为空时,我们就成功地把所有直接或间接地与边缘的O相连的其他O变为了Y,剩余的O就是被X包围的了。然后遍历一遍,把为O的位置变为X,为Y的位置变为O,就得出结果了。

这道题利用到了BFS(宽度优先搜索)的思想,那么用深度优先是否可以呢?据说会TLE,因为图可能很大,递归会导致栈溢出。但是,我认为分别用这两种不同的方法思考一下这道题,可以锻炼利用bfs和dfs解题的思想。

下面是代码:

class Solution {
public:
    void solve(vector<vector<char>>& board) {
        queue<int> x;
        queue<int> y;
        for (int i = 0; i < board.size(); i++) {
            for (int j = 0; j < board[i].size(); j++) {
                if ((i == 0 || i == board.size() - 1 ||
                    j == 0 || j == board[i].size() - 1) &&
                    board[i][j] == ‘O‘) {
                    x.push(i);
                    y.push(j);
                    board[i][j] = ‘Y‘;
                }
            }
        }
        while (!x.empty() && !y.empty()) {
            int i = x.front();
            int j = y.front();
            x.pop();
            y.pop();
            if (i - 1 >= 0 && board[i - 1][j] == ‘O‘) {
                x.push(i - 1);
                y.push(j);
                board[i - 1][j] = ‘Y‘;
            }
            if (i + 1 < board.size() && board[i + 1][j] == ‘O‘) {
                x.push(i + 1);
                y.push(j);
                board[i + 1][j] = ‘Y‘;
            }
            if (j - 1 >= 0 && board[i][j - 1] == ‘O‘) {
                x.push(i);
                y.push(j - 1);
                board[i][j - 1] = ‘Y‘;
            }
            if (j + 1 < board[0].size() && board[i][j + 1] == ‘O‘) {
                x.push(i);
                y.push(j + 1);
                board[i][j + 1] = ‘Y‘;
            }
        }
        for (int i = 0; i < board.size(); i++) {
            for (int j = 0; j < board[i].size(); j++) {
                if (board[i][j] == ‘Y‘) {
                    board[i][j] = ‘O‘;
                }
                else {
                    board[i][j] = ‘X‘;
                }
            }
        }
    }
};

二. 200  Number of Islands(https://leetcode.com/problems/number-of-islands/description/)

题目:

解法:

这道题的基本思想跟上面一道差不多,也是用bfs,维护一个队列:
当遇到1的时候,把它改为0,进队列;(每次遇到新的island时)

每次把一个位置出队列,并把这个位置四周为1的位置改为0,然后把这些位置放入队列中。当队列为空时,代表已经找到一个island的所有1了,结果+1。

解法是简单的,但我做题的时候还是踩了不少坑:
(1)我用了三层循环去写,因为我想着要判断什么时候所有位置都为0,但其实是多此一举,只需要遍历每一个位置就行了。

(2)我一开始是先把位置放进队列,在出队列的时候才把这个位置的值变为0,但这是不对的:这样会造成一个位置的多次进队列(细想一下吧,出队列的时候才变为0,那在进队列到出队列的过程中这个位置的值还是1,还是会被其他位置检测到,多次加进队列),肯定会TLE。因此一定要先把值变为0,再加进队列。

代码如下:

class Solution {
public:
    int numIslands(vector<vector<char> >& grid) {
        int ans = 0;
        queue<int> x, y;
        for (int i = 0; i < grid.size(); i++ ) {
            for (int j = 0; j < grid[0].size(); j++) {
                if (grid[i][j] == ‘1‘) {
                    x.push(i);
                    y.push(j);
                    grid[i][j] = ‘0‘;
                    while (!x.empty() && !y.empty()) {
                        int i = x.front();
                        int j = y.front();
                        x.pop();
                        y.pop();
                        if (i - 1 >= 0 && grid[i - 1][j] == ‘1‘) {
                            x.push(i - 1);
                            y.push(j);
                            grid[i - 1][j] = ‘0‘;
                        }
                        if (i + 1 < grid.size() && grid[i + 1][j] == ‘1‘) {
                            x.push(i + 1);
                            y.push(j);
                            grid[i + 1][j] = ‘0‘;
                        }
                        if (j - 1 >= 0 && grid[i][j - 1] == ‘1‘) {
                            x.push(i);
                            y.push(j - 1);
                            grid[i][j - 1] = ‘0‘;
                        }
                        if (j + 1 < grid[0].size() && grid[i][j + 1] == ‘1‘) {
                            x.push(i);
                            y.push(j + 1);
                            grid[i][j + 1] = ‘0‘;
                        }
                    }
                    ans++;
                }
            }
        }
        return ans;
    }
};

或者:

class Solution {
public:
    int numIslands(vector<vector<char> >& grid) {
        int ans = 0;
        for (int i = 0; i < grid.size(); i++ ) {
            for (int j = 0; j < grid[0].size(); j++) {
                if (grid[i][j] == ‘1‘) {
                    bfs(grid, i, j);
                    ans++;
                }
            }
        }
        return ans;
    }
    void bfs(vector<vector<char> >& grid, int i, int j) {
        grid[i][j] = ‘0‘;
        if (i - 1 >= 0 && grid[i - 1][j] == ‘1‘) {
            bfs(grid, i - 1, j);
        }
        if (i + 1 < grid.size() && grid[i + 1][j] == ‘1‘) {
            bfs(grid, i + 1, j);
        }
        if (j - 1 >= 0 && grid[i][j - 1] == ‘1‘) {
            bfs(grid, i, j - 1);
        }
        if (j + 1 < grid[0].size() && grid[i][j + 1] == ‘1‘) {
            bfs(grid, i, j + 1);
        }
    }
};

LeetCode上面还有其他一些用BFS解决的问题,比如Word Ladder,但在前面已经写过了。

时间: 2024-11-09 02:16:32

[LeetCode] BFS解决的题目的相关文章

每天刷个算法题20160526:BFS解决八数码问题(九宫格问题)

版权所有.所有权利保留. 欢迎转载,转载时请注明出处: http://blog.csdn.net/xiaofei_it/article/details/51524864 为了防止思维僵化,每天刷个算法题.已经刷了几天了,现在发点代码. 我已经建了一个开源项目,每天的题目都在里面: https://github.com/Xiaofei-it/Algorithms 绝大部分算法都是我自己写的,没有参考网上通用代码.读者可能会觉得有的代码晦涩难懂,因为那是我自己的理解. 最近几天都是在写一些原来的东西

有关dfs、bfs解决迷宫问题的个人见解

可以使用BFS或者DFS方法解决的迷宫问题! 题目如下: kotori在一个n*m迷宫里,迷宫的最外层被岩浆淹没,无法涉足,迷宫内有k个出口.kotori只能上下左右四个方向移动.她想知道有多少出口是她能到达的,最近的出口离她有多远? 输入描述: 第一行为两个整数n和m,代表迷宫的行和列数 (1≤n,m≤30) 后面紧跟着n行长度为m的字符串来描述迷宫.'k'代表kotori开始的位置,'.'代表道路,'*'代表墙壁,'e'代表出口.保证输入合法. 输出描述: 若有出口可以抵达,则输出2个整数,

解决一个题目。关于结构体与链表的操作

有初学者给我发了一个题目,求助我解决. 题目如下: 其实哥也不会C,但就是有一颗热心肠.于是果断研究起. 最后解决如下: 先上效果图 附上代码 : // LinkListDemo.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <STDLIB.H> # define LEN sizeof(struct examinee) //结构体长度 //

BFS解决九宫重排问题

问题 1426: [蓝桥杯][历届试题]九宫重排 时间限制: 1Sec 内存限制: 128MB 提交: 215 解决: 47 题目描述 如下面第一个图的九宫格中,放着  1~8  的数字卡片,还有一个格子空着.与空格子相邻的格子中的卡片可以移动到空格中.经过若干次移动,可以形成第二个图所示的局面. 我们把第一个图的局面记为:12345678. 把第二个图的局面记为:123.46758 显然是按从上到下,从左到右的顺序记录数字,空格记为句点. 本题目的任务是已知九宫的初态和终态,求最少经过多少步的

leetcode 锁掉的题目清单

也刷leetcode, 先把锁掉的题目留备份好了: 156 Binary Tree Upside Down  [1] Problem: Given a binary tree where all the right nodes are either leaf nodes with a sibling (a left node that shares the same parent node) or empty, flip it upside down and turn it into a tre

POJ 2049-Finding Nemo(三维bfs解决类迷宫问题)

Finding Nemo Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 7902   Accepted: 1827 Description Nemo is a naughty boy. One day he went into the deep sea all by himself. Unfortunately, he became lost and couldn't find his way home. Therefo

动态规划学习之LeetCode分割整数相关题目(第343、279、91题)

题目:给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化. 返回你可以获得的最大乘积. 示例: 输入: 10 输出: 36 解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36. 说明: 你可以假设 n 不小于 2 且不大于 58. 分析: 1.定义一个状态转移数组dp,dp[i]表示数字i拆分为至少两项之和后,拆分后的数字之间的最大乘积. 2.寻找关系式,那么如何确定dp[i]的最大值呢?首先我们要确定它有哪些取值的可能,对于拆分之和的数字的乘积,这个乘

leetcode上面的一个题目,求Largest Number

原题如下: Given a list of non negative integers, arrange them such that they form the largest number. For example, given [3, 30, 34, 5, 9], the largest formed number is 9534330. Note: The result may be very large, so you need to return a string instead o

用BFS解决迷宫问题

在一个n*n的矩阵里走,从原点(0,0)开始走到终点(n-1,n-1),只能上下左右4个方向走,只能在给定的矩阵里走,求最短步数.n*n是01矩阵,0代表该格子没有障碍,为1表示有障碍物. int mazeArr[maxn][maxn]; //表示的是01矩阵 int stepArr[4][2] = {{-1,0},{1,0},{0,-1},{0,1}}; //表示上下左右4个方向 int visit[maxn][maxn]; //表示该点是否被访问过,防止回溯,回溯很耗时. 解题思路: BFS