题目要求:
分析:
第一反应永远是暴力法……
遍历矩阵,设置一个二维数组用来存放结果,用数组中的sort方法进行排序,具体方式为:重写sort()方法中的compare方法。
注:在compare(int[] a, int[]b)中,
如果前者 - 后者,则是升序排序;
如果后者 - 前者,则是降序排序。
具体代码如下:
class Solution {
public int[][] allCellsDistOrder(int R, int C, int r0, int c0) {
int[][] matrix = new int[R*C][2];
for(int i = 0; i < R; i++) {
for(int j = 0; j < C; j++) {
matrix[i*C+j][0] = i;
matrix[i*C+j][1] = j;
}
}
Arrays.sort(matrix, new Comparator<int[]>() {
public int compare(int[] a, int[] b) {
return (Math.abs(a[0]-r0) + Math.abs(a[1]-c0)) - (Math.abs(b[0]-r0) + Math.abs(b[1]-c0));
}
});
return matrix;
}
}
唉,这个方法性能真的不行。。。
其实是可以用BFS来做的,路径从小到大排序嘛,在这里的话,一个点与它边上的点的距离都是1,连排序都不用排,等我有空了补上吧。
我来补用BFS方法做的步骤了
首先复习一下BFS:
BFS就是广度优先遍历,类似于树的层序遍历,将最先访问的顶点放在最上面第一层,相邻的点放在第二层,与第二层相关的点放在第三层,以此类推。
BFS
这个博客写得很清楚。
为了更清晰、更直观地明白是怎么一回事,将其搜索过程写成伪代码,如下所示:
void BFS() {
//将最初的顶点放入到队列中
queue.add(顶点);
//标记最初的顶点已被访问
visited = true;
while(!queue.isEmpty) {
/*
做相应操作
将队列首元素弹出
queue.poll();
*/
//遍历所有相邻节点
for(所有相邻的点) {
if(该点合法 && 未被访问) {
//将该点加入队列末尾
queue.add(该点);
//标记为已访问
visited = true;
}
}
}
//如果不是void,则需要return
}
所以,对于本题,利用BFS的方法如下:
//用BFS方法来完成
class Solution {
public int[][] allCellsDistOrder(int R, int C, int r0, int c0) {
Queue<int[]> queue = new LinkedList<>();
queue.add(new int[]{r0,c0});
boolean[][] visited = new boolean[R][C];
visited[r0][c0] = true;
int[][] matrix = new int[R*C][2];
int i = 0;
while(!queue.isEmpty()) {
List<int[]> list = new ArrayList<>();
while(!queue.isEmpty()) {
int[] node = queue.poll();
matrix[i++] = node;
list.add(node);
}
for(int[] k:list) {
int row = k[0];
int col = k[1];
//上
if(row > 0 && !visited[row-1][col]) {
queue.add(new int[]{row-1,col});
visited[row-1][col] = true;
}
//下
if(row < R-1 && !visited[row+1][col]) {
queue.add(new int[]{row+1,col});
visited[row+1][col] = true;
}
//左
if(col > 0 && !visited[row][col-1]) {
queue.add(new int[]{row,col-1});
visited[row][col-1] = true;
}
//右
if(col < C-1 && !visited[row][col+1]) {
queue.add(new int[]{row,col+1});
visited[row][col+1] = true;
}
}
}
return matrix;
}
}