public static int[][] generateMatrix(int n) {
int[][] ints = new int[n][n];
int startx = 0, starty = 0, offset = 1;
int i = 0, j = 0, count = 1;
int rounds = n / 2;
while ((rounds--) > 0) {
for (i = starty, j = startx; j < n - offset; j++) {
ints[i][j] = count++;
}
for (; i < n - offset; i++) {
ints[i][j] = count++;
}
for (; j > startx; j--) {
ints[i][j] = count++;
}
for (; i > starty; i--) {
ints[i][j] = count++;
}
startx++;
starty++;
offset++;
}
if (n % 2 != 0) {
ints[startx][starty] = count;
}
return ints;
}
public static int[][] generateMatrix1(int n) {
int[][] matrix = new int[n][n];
int count = 1;
if (n == 0) return matrix;
int i_up = 0, i_down = n - 1, j_left = 0, j_right = n - 1;
while (true) {
for (int k = j_left; k <= j_right; k++) {
matrix[i_up][k] = count++;
}
if (++i_up > i_down) break;
for (int k = i_up; k <= i_down; k++) {
matrix[k][j_right] = count++;
}
if (--j_right < j_left) break;
for (int k = j_right; k >= j_left; k--) {
matrix[i_down][k] = count++;
}
if (--i_down < i_up) break;
for (int k = i_down; k >= i_up; k--) {
matrix[k][j_left] = count++;
}
if (++j_left > j_right) break;
}
return matrix;
}
第二种方法取消了循环不变量,思想更具有普适性,尤其是当矩形是m*n规模时,只需修改边界起始参数即可;第一种方法则需要考虑更多特殊情况。这一特点在下一题中将会得到体现。
public static List<Integer> spiralOrder(int[][] matrix) {
List<Integer> res = new ArrayList<>();
int startx = 0, starty = 0, offset = 1;
int i = 0, j = 0;
int m = matrix.length, n = matrix[0].length;
int min = Math.min(m, n), rounds = min / 2;
if (m == 1) {
for (int k = 0; k < n; k++) {
res.add(matrix[0][k]);
}
return res;
}
if (n == 1) {
for (int k = 0; k < m; k++) {
res.add(matrix[k][0]);
}
return res;
}
while ((rounds--) > 0) {
for (i = starty, j = startx; j < n - offset; j++) {
res.add(matrix[i][j]);
}
for (; i < m - offset; i++) {
res.add(matrix[i][j]);
}
for (; j > startx; j--) {
res.add(matrix[i][j]);
}
for (; i > starty; i--) {
res.add(matrix[i][j]);
}
startx++;
starty++;
offset++;
}
if (min % 2 == 1) {
if (m < n) {
for (i = starty, j = startx; j < n - offset + 1; j++) {
res.add(matrix[i][j]);
}
} else {
for (i = starty, j = startx; i < m - offset + 1; i++) {
res.add(matrix[i][j]);
}
}
}
return res;
public static List<Integer> spiralOrder1(int[][] matrix) {
List<Integer> res = new ArrayList<>();
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return res;
}
//以下变量分别表示纵坐标的左右界和横坐标的左右界
//遍历顺序为:右-下-左-上,每遍历完一条边将相应移动一条界线,比如左->右完成了最上面的一条边,随即将--i_up
//遍历结束的标志?上边界大于下边界,右边界小于左边界
int i_up = 0, i_down = matrix.length - 1, j_left = 0, j_right = matrix[0].length - 1;
while (true) {
for (int k = j_left; k <= j_right; k++) {
res.add(matrix[i_up][k]);
}
if (++i_up > i_down) break;
for (int k = i_up; k <= i_down; k++) {
res.add(matrix[k][j_right]);
}
if (--j_right < j_left) break;
for (int k = j_right; k >= j_left; k--) {
res.add(matrix[i_down][k]);
}
if (--i_down < i_up) break;
for (int k = i_down; k >= i_up; k--) {
res.add(matrix[k][j_left]);
}
if (++j_left > j_right) break;
}
return res;
}
本文章使用limfx的vscode插件快速发布