前言
算法题的训练方面,1-提取,将核心内容提取,联系已学知识;2-问题转换,根据提取的问题个性,进行问题转换解决;3-自我进阶,将一些规则抽象,考虑解决方案。
一、距离顺序排列矩阵单元格
二、朴素bfs
package everyday.simple;
import java.util.LinkedList;
import java.util.Queue;
// 距离顺序排列矩阵单元格。
public class AllCellsDistOrder {
// 层序遍历即可,没多一层,距离就会变远。
public int[][] allCellsDistOrder(int rows, int cols, int rCenter, int cCenter) {
// 采用队列来进行层遍历。
Queue<int[]> que = new LinkedList<>();
que.add(new int[]{rCenter, cCenter});
// 标记位置已经被访问。
boolean[][] isMark = new boolean[rows][cols];
isMark[rCenter][cCenter] = true;
// 层次遍历,收集每层的坐标。
int[][] rs = new int[rows * cols][2];
int idx = 0;
while (!que.isEmpty()) {
int[] pos = que.poll();
int i = pos[0], j = pos[1];
// 将坐标收集起来。
rs[idx][0] = i;
rs[idx++][1] = j;
// 防止重复访问,做上标记。
isMark[i][j] = true;
// 将下一层加入队列。
for (int[] gap : gaps) {
int ni = gap[0] + i, nj = gap[1] + j;
if (ni != -1 && -1 != nj && nj != cols && ni != rows && !isMark[ni][nj]) {
que.add(new int[]{ni, nj});
// bug1:加入队列时,就应该标记,否则会重复加入。
isMark[ni][nj] = true;
}
}
}
return rs;
}
static int[][] gaps = new int[][]{{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
// review:如果不是这么朴素的距离,而是将它抽象,如下一步的距离是下一格的数字之和,则需要用到优先队列,每次取元素O(LogN)
}
总结
1)每天一道算法题,养成勤思考,勤训练的习惯。而且可加强对一类问题的理解,通过不断的排除bug,提升自己的严谨性,考虑问题的全面能力。
2)对于一个算法,最后锻炼到自己的提取问题&问题转换&自我进阶的能力。而这些能力与大量算法题的积累紧密相关。