一种非递归实现广度优先搜索(BFS)的方法

在面对数据量大的情况下递归搜索的效率是必须要解决的问题,这也是递归的一个缺点。这里提供一种实现BFS的非递归解决方法。

为了方便,给出一道使用BFS的模板题,题目来自leetcode:

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


1 递归部分:

void bfs(vector<vector<char>>&board, int i, int j){
	typedef pair<int, int>stateT;
	queue<stateT>q;
	const int m = board.size();
	const int n = board.front().size();

	auto stateIsValid = [&](const stateT &s){
		const int x = s.first;
		const int y = s.second;

		if (x < 0 || x >= m || y < 0 || y >= n || board[x][y] != '0')
			return false;
		return true;
	};

	auto stateExend = [&](const stateT &s){
		vector<stateT>result;
		const int x = s.first;
		const int y = s.second;
		const stateT newStates[4] = { { x - 1, y }, { x + 1, y }, { x, y - 1 }, { x, y + 1 } };
		for (int k = 0; k < 4; ++k){
			if (stateIsValid(newStates[k])){
				board[newStates[k].first][newStates[k].second] = '+';
				result.push_back(newStates[k]);
			}
		}
		return result;
	};

	stateT start = { i, j };
	if (stateIsValid(start)){
		board[i][j] = '+';
		q.push(start);
	}

	while (!q.empty())
	{
		auto cur = q.front();
		auto newStates = stateExend(cur);
		for (auto s : newStates)q.push(s);
	}
}


2 主函部分:

void surroundedRegions(vector<vector<char>>& board){
	if (board.empty())return;

	const int m = board.size();
	const int n = board[0].size();

	for (int i = 0; i < n; ++i){
		bfs(board, 0, i);
		bfs(board, m - 1, i);
	}
	for (int j = 1; j < m - 1; ++j){
		bfs(board, j, 0);
		bfs(board, j, n - 1);
	}
	for (int i = 0; i < m; ++i){
		for (int j = 0; j < n; ++j){
			if (board[i][j] == '0')
				board[i][j] = 'X';
			else if (board[i][j] == '+')
				board[i][j] = '0';
		}
	}
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值