Imagine that you are pouring water into an icebox.
What is the movement of water ?
Maybe some blockes which have already
| B | B | B | B | B |
|---|---|---|---|---|
| B | O | O | O | |
| B | O | |||
| B | O | |||
| B |
| B | B | B | ||
| B | B | B | ||
| B | B | B | ||
Naïve idea: Check every block and make them "flood" to the neighboring blocks.
suppose n*m ice box, it takes O(nm) per check
It takes a most O(n+m) rounds. (why?)
time complexity O(nm (n + m))
Spend to much time at "searching 'flooding' blocks"
| 1 | ||||
| 2 | ||||
| 3 | 1 | 5 | ||
| 4 | ||||
| 6 | ||||
|---|---|---|---|---|
| 7 | 2 | 8 | ||
| 9 | 3 | 1 | 5 | |
| 10 | 4 | |||
| 6 | ||||
|---|---|---|---|---|
| 7 | 2 | 8 | ||
| 9 | 3 | 1 | 5 | 13 |
| 10 | 4 | 12 | ||
| 11 |
Observe elements in the queue, the level of ring is non-decreasing.
ex. start at (2,2), (4,5), (10,3)
for convenience, assume spread in for direction
pre-elements in the queue
(2, 2), (4, 5), (10, 3),
(2, 3), (2,1), (1,2), (3,2), (4,6), (4,4), (3,5), (5,5), (10,4), (10,2), (9,3), (11,3)
(2,4), (1,3), (3,3), ……
So all we need to do is record the "level" of each block, and process the same "level" elements at the same round.
Why? And what if the cost of one step is not 1? Suppose each block has height, and the cost from one block to another is the difference of height.
| 1 | ||||
| 2 | ||||
| 4 | 1 | 5 | ||
| 3 | ||||
| 2 | 6 | |||
| 4 | 1 | 5 | 8 | |
| 3 | 7 | |||
| 2 | 6 | 9 | ||
| 4 | 1 | 5 | 8 | |
| 3 | 7 | 10 | ||
If the map is large, we will see that water keeps going in some direction until it meets the end. And it comes back and goes in another direction.
| 1 | ||||
| 2 | ||||
| 4 | 1 | 5 | ||
| 3 | ||||
| 2 | 6 | |||
| 4 | 1 | 5 | 8 | |
| 3 | 7 | |||
| 2 | 6 | 9 | ||
| 4 | 1 | 5 | 8 | |
| 3 | 7 | 10 | ||
we don't have to store 2, 3, 4, 5 at the same time.
Push one, and we just process it at the next time.
Just use recursion
void dfs(int x, int y, int cur_dist){
dist[x][y] = cur_dist;
if(map[x+1][y] != '#' && dist[x+1][y] > cur_dist + 1)
dfs(x+1, y, cur_dist + 1);
if(map[x][y+1] != '#' && ....)
}(x, y) current coordinate
cur_dist = current steps
dist[x][y] is the shortest path length to (x,y)
call dfs(x_start, y_start, 0) call solve shortest path
(x_start, y_start) is where the cat is
Can we use DFS for problem 1?
Or Can we use DFS for problem 2?
What are the pros and cons ? Time Complexity ?
A problem:
each block has a height, if height is less than a certain value, it flooded.
Asking how many flooded at the end?
Is BFS/DFS both applicable?