通过一道面试题对于BFS,DFS的简单思考

Topic:面经

题目:

给定一个二维数组,可以看做其中的1被0包围,求数组中有几堆1?


Code:

class Test{
    public static void main(String[] args){
		int[][] matrix = {
			{1, 1, 0, 1},
			{0, 1, 1, 0},
			{0, 0, 0, 1},
			{0, 1, 1, 1}
		};
		int m = matrix.length, n = matrix[0].length;
		
		//bfs方法:
		// int[][] dir = {
			// {0, 1},
			// {1, 0},
			// {0, -1},
			// {-1, 0}
		// };
		// int res = 0;
		// Queue<Position> q = new LinkedList<Position>();
		// for(int i=0; i<m; i++){
			// for(int j=0; j<n; j++){
				// if(matrix[i][j] == 1){
					// res++;
					// Position pos = new Position(i, j);
					// q.add(pos);
					// while(!q.isEmpty()){
						// Position x = q.poll();
						// matrix[x.r][x.c] = 2;
						// for(int k=0; k<dir.length; k++){
							// int r = x.r + dir[k][0];
							// int c = x.c + dir[k][1];
							// if(r>=0 && r<m && c>=0 && c<n && matrix[r][c]==1){
								// Position tmp = new Position(r, c);
								// q.add(tmp);
							// }
						// }
					// }
				// }
			// }
		// }
		// System.out.println(res);
		
		
		//dfs方法:
		Solution sol = new Solution();
		for(int i=0; i<m; i++){
			for(int j=0; j<n; j++){
				if(matrix[i][j] == 1){
					sol.res++;
					sol.dfs(matrix, i, j);
				}
			}
		}
		System.out.println(sol.res);
    }
}

class Solution{
	int res;
	Solution(){
		res = 0;
	}
	
	public void dfs(int[][] matrix, int row, int col){
		int m = matrix.length, n = matrix[0].length;
		int[][] dir = {
			{0, 1},
			{1, 0},
			{0, -1},
			{-1, 0}
		};
		matrix[row][col] = 2;
		for(int i=0; i<dir.length; i++){
			int r = row + dir[i][0];
			int c = col + dir[i][1];
			if(r>=0 && r<m && c>=0 && c<n && matrix[r][c]==1){
				dfs(matrix, r, c);
			}
		}
	}
}

class Position{
	int r, c;
	Position(int r, int c){
		this.r = r;
		this.c = c;
	}
}


小结:

这里BFS和DFS的Runtime应该都是O(4mn),如果不对请纠正,space是O(mn),一个用了递归(DFS),一个由于Queue的存在是顺序的,但是两者除了便利方式外,其实原理、运行方式都非常接近。

DFS之所以使用递归,因为内存本身就是一个Stack,我们只是加以利用罢了。换句话说,如果我们像BFS那样,手动建立一个Stack,也可以完成顺序的DFS。

下面这个图的DFS和BFS的例子是个很好的印证:

	public void bfs(){
		Queue<Integer> q = new Queue<Integer>();
		q.enque(0);
		display(0);
		list[0].wasVisited = true;
		
		while(!q.isEmpty()){
			int x1 = q.deque();
			int x2;
			while((x2 = getAdjUnvisited(x1)) != -1){
				q.enque(x2);
				display(x2);
				list[x2].wasVisited = true;
			}
		}
		
		for(int i=0; i<cnt; i++)
			list[i].wasVisited = false;
	}
	
	public void dfs(){
		Stack<Integer> s= new Stack<Integer>();
		s.push(0);
		display(0);
		list[0].wasVisited = true;
		
		while(!s.isEmpty()){
			int x = getAdjUnvisited(s.peek());
			if(x != -1){
				s.push(x);
				display(x);
				list[x].wasVisited = true;
			}
			else
				s.pop();
		}
		
		for(int i=0; i<cnt; i++)
			list[i].wasVisited = false;
	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值