Question
给一个矩阵,其中 0 代表海洋,其他数字代表高度,秉着水往低处流的原则,求出能够流向任意海洋的点。 比如说
0 0 0 1 2 3 0
0 1 2 2 4 3 2
2 1 1 3 3 2 0
0 3 3 3 2 3 3
那么就要给出 第二行的 4 (这有这点出发,能够找到连通道四个 0 的区域的一条非递增
路线),当然也有可能找不到这样的点,或者找到多个点。
Solution
I read online and the best solution I come up with is Brute Force. I did not really understand the online discussions.
So if you are reading this and want to discuss with me, kindly leave me a comment!
Code
brute force
public void findSuperPeak(int[][] map) {
int m = map.length;
int n = map[0].length;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (check(map, new Pair(i, j), m, n)) {
System.out.println("Found point (" + i + ", " + j
+ ") with height of " + map[i][j]);
}
}
}
}
private boolean check(int[][] originalMap, Pair p, int m, int n) {
// check if point can flow to all oceans
if (originalMap[p.x][p.y] == 0) {
return false;
}
int[][] map = new int[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
map[i][j] = originalMap[i][j];
}
}
Queue<Pair> q = new LinkedList<Pair>();
q.offer(p);
while (!q.isEmpty()) {
Pair top = q.poll();
int x = top.x;
int y = top.y;
if (map[x][y] == -1) {
continue;
}
// add neighbor nodes who are visitable from here
if (x - 1 >= 0 && map[x - 1][y] <= map[x][y]) {
// water can flow from:
// 1. high altitude to lower
// 2. from ocean to ocean
q.offer(new Pair(x - 1, y));
}
if (x + 1 < m && map[x + 1][y] <= map[x][y]) {
q.offer(new Pair(x + 1, y));
}
if (y - 1 >= 0 && map[x][y - 1] <= map[x][y]) {
q.offer(new Pair(x, y - 1));
}
if (y + 1 < n && map[x][y + 1] <= map[x][y]) {
q.offer(new Pair(x, y + 1));
}
// visit this point
map[x][y] = -1;
}
// now we finished BFS and the entire map with lower altitude is visited
// (including all ocean points). We now check if there exists a 0 in map
for (int[] arr : map)
for (int i : arr)
if (i == 0) // found an unvisited ocean point
return false;
return true;
}