第一个想到的就是一层层遍历
class Solution {
public int[][] allCellsDistOrder(int R, int C, int r0, int c0) {
int[][] result=new int[R*C][2];
int index=0;
boolean[][] visited=new boolean[R][C];//是否访问
Queue<int[]> queue=new LinkedList<int[]>(); //存储每一层
queue.offer(new int[]{r0,c0}); //加入根节点
visited[r0][c0]=true;
while(!queue.isEmpty()){ //层次遍历
int[] root=queue.poll();
result[index++]=root;
int i=root[0] ,j=root[1];
if(isLegal(R,C,i-1,j) && !visited[i-1][j]){ //上
queue.offer(new int[]{i-1,j}); //加入访问过的节点
visited[i-1][j]=true;
}
if(isLegal(R,C,i+1,j) && !visited[i+1][j]){//下
queue.offer(new int[]{i+1,j});
visited[i+1][j]=true;
}
if(isLegal(R,C,i,j-1) && !visited[i][j-1]){//左
queue.offer(new int[]{i,j-1});
visited[i][j-1]=true;
}
if(isLegal(R,C,i,j+1) && !visited[i][j+1]){//右
queue.offer(new int[]{i,j+1});
visited[i][j+1]=true;
}
}
return result;
}
private boolean isLegal(int R, int C ,int i, int j){ //检查下标是否合法
return i>=0 && i<R && j>=0 && j<C;
}
}
不去记录是否访问,提前规定好定义域
class Solution {
public int[][] allCellsDistOrder(int R, int C, int r0, int c0) {
int[][] result=new int[R*C][2];
int index=0;
Queue<int[]> queue=new LinkedList<int[]>();
queue.offer(new int[]{r0,c0}); //加入根节点
while(!queue.isEmpty()){ //层次遍历
int[] root=queue.poll();
result[index++]=root;
int i=root[0] ,j=root[1];
//提前规定好边界
if(i<=r0 && i-1>=0) queue.offer(new int[]{i-1,j});
if(i>=r0 && i+1<R) queue.offer(new int[]{i+1,j});
if(i==r0 && j<=c0 && j-1>=0 ) queue.offer(new int[]{i,j-1});
if(i==r0 && j>=c0 && j+1<C) queue.offer(new int[]{i,j+1});
}
return result;
}
}
时间短了很多
桶排序
遍历所有坐标,按照距离的大小分组,每组的距离相等(即放入一个桶中)
按照距离从小到大的原则,遍历所有桶,并输出结果
本解法关键在于求得可能的最大距离,即行距离和列距离都最大时:max(r0, R - 1 - r0) + max(c0, C - 1 - c0)
import java.util.ArrayList;
import java.util.LinkedList;
class Solution {
public int[][] allCellsDistOrder(int R, int C, int r0, int c0) {
int[][] re = new int[R * C][2];
int maxDist = Math.max(r0, R - 1 - r0) + Math.max(c0, C - 1 - c0);
ArrayList<LinkedList<Pos>> bucket = new ArrayList<>(maxDist + 1);
for (int i = 0; i <= maxDist; i++) {
bucket.add(new LinkedList<>());
}
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
int d = dist(i, j, r0, c0);
LinkedList<Pos> list = bucket.get(d);
list.add(new Pos(i,j));
}
}
int cnt = 0;
for (int i = 0; i <= maxDist; i++) {
LinkedList<Pos> list = bucket.get(i);
if (list.isEmpty()) continue;
for (Pos p : list) {
re[cnt][0] = p.r;
re[cnt][1] = p.c;
cnt++;
}
}
return re;
}
private int dist(int r1,int c1,int r2,int c2) {
return Math.abs(r1 - r2) + Math.abs(c1 - c2);
}
private static class Pos {
int r;
int c;
public Pos(int r, int c) {
this.r = r;
this.c = c;
}
}
}