LeetCode[Hard]------803. Bricks Falling When Hit

問題描述

We have a grid of 1s and 0s; the 1s in a cell represent bricks. A brick will not drop if and only if it is directly connected to the top of the grid, or at least one of its (4-way) adjacent bricks will not drop.

We will do some erasures sequentially. Each time we want to do the erasure at the location (i, j), the brick (if it exists) on that location will disappear, and then some other bricks may drop because of that erasure.

Return an array representing the number of bricks that will drop after each erasure in sequence.

Example 1:

Input:
grid = [[1,0,0,0],[1,1,1,0]]
hits = [[1,0]]
Output: [2]
Explanation:
If we erase the brick at (1, 0), the brick at (1, 1) and (1, 2) will drop. So we should return 2.

Example 2:

Input:
grid = [[1,0,0,0],[1,1,0,0]]
hits = [[1,1],[1,0]]
Output: [0,0]
Explanation:
When we erase the brick at (1, 0), the brick at (1, 1) has already disappeared due to the last move. So each erasure will cause no bricks dropping. Note that the erased brick (1, 0) will not be counted as a dropped brick.

Note:

  1. The number of rows and columns in the grid will be in the range [1, 200].
  2. The number of erasures will not exceed the area of the grid.
  3. It is guaranteed that each erasure will be different from any other erasure, and located inside the grid.
  4. An erasure may refer to a location with no brick - if it does, no bricks drop.

簡單翻譯一下,有一個包含0和1的二維數組,1表示bricks。第一行的bricks是不會掉落的,與其想聯通的bricks都不會掉落。現在我要打碎一些bricks,問會有多少bricks drop。

思路:

思路:這是DFS中較難的一道題。首先我們要明白brick drop的條件:

  1. grid中刪除的節點爲1。
  2. 刪除位置的節點必須和top(grid[0][])相連。
  3. 刪除節點的周圍的brick 節點必須不能通過其他brick到達top。

所以只有同時滿足以上3個條件,brick纔會drop。我們先把所有要brick的節點置爲0,第一行的所有brick標記爲TOP(2),然後用DFS,順藤摸瓜找到所有與TOP聯通的grid。

下一步我們恢復hits節點到1,isConnected(x, y, grid)方法用來判斷第二個條件,dfs方法返回的就是因爲hits的原因與TOP 斷開連接的grid的個數。減一是因爲要減去hit本身。

代碼:

	private static final int TOP = 2;
	private static final int BRICK = 1;
	private static final int EMPTY = 0;
	private static final int[][] DIRS = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } };

	public int[] hitBricks(int[][] grid, int[][] hits) {
		int[] res = new int[hits.length];
		// Think backwards: remove all of the hits and then add them back;
		for (int[] hit : hits) {
			grid[hit[0]][hit[1]]--;
		}

		// Flood all the grids connecting to top with 2;
		for (int i = 0; i < grid[0].length; i++) {
			dfs(0, i, grid);
		}

		// Add back the hited Bricks
		for (int i = hits.length - 1; i >= 0; i--) {
			int x = hits[i][0], y = hits[i][1];
			grid[x][y]++;
			if (grid[x][y] == BRICK && isConnected(x, y, grid)) {
				res[i] = dfs(x, y, grid) - 1;
			}
		}

		return res;
	}

	private int dfs(int i, int j, int[][] grid) {
		if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] != BRICK) {
			return 0;
		}
		grid[i][j] = 2;
		return dfs(i + 1, j, grid) + dfs(i - 1, j, grid) + dfs(i, j + 1, grid) + dfs(i, j - 1, grid) + 1;
	}

	private boolean isConnected(int i, int j, int[][] grid) {
		if (i == 0) {
			return true;
		}
		for (int[] d : DIRS) {
			int x = i + d[0], y = j + d[1];
			if (x >= 0 && x < grid.length && y >= 0 && y < grid[0].length && grid[x][y] == TOP) {
				return true;
			}
		}
		return false;
	}

僅用於個人的學習理解,如需轉載,請標明出處:
https://blog.csdn.net/sc19951007/article/details/83771000

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章