54. 螺旋矩阵
思路:把矩阵螺旋输出。
做法也很简单,我们只需要每次输出一圈后更新横排的左右边界和竖排的上下边界即可,但是要保证左边界小于等于右边界,上边界小于等于下边界:
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> res = new ArrayList<>();
if(matrix.length == 0 || matrix[0].length == 0) return res;
int l = 0;
int r = matrix[0].length - 1;
int u = 0;
int d = matrix.length - 1;
while(l <= r && u <= d){
for(int i=l;i<=r;i++){
res.add(matrix[u][i]);
}
u++;
for(int i=u;i<=d;i++){
res.add(matrix[i][r]);
}
r--;
for(int i=r;i>=l;i--){
res.add(matrix[d][i]);
}
d--;
for(int i=d;i>=u;i--){
res.add(matrix[i][l]);
}
l++;
}
return res;
}
这样写看似没有问题了,实际上还是不对,因为上面两个循环结束后存在u++和r–,这导致u<=d和l<=r此时可能已经无法满足了,如果此时无法满足,最后两个循环应该无需执行(执行就错了重复了!!),所以最后两个循环里应该加上u<=d和l<=r两个判断条件!!!
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> res = new ArrayList<>();
if(matrix.length == 0 || matrix[0].length == 0) return res;
int l = 0;
int r = matrix[0].length - 1;
int u = 0;
int d = matrix.length - 1;
while(l <= r && u <= d){
for(int i=l;i<=r;i++){
res.add(matrix[u][i]);
}
u++;
for(int i=u;i<=d;i++){
res.add(matrix[i][r]);
}
r--;
for(int i=r;i>=l&&u<=d;i--){
res.add(matrix[d][i]);
}
d--;
for(int i=d;i>=u&&l<=r;i--){
res.add(matrix[i][l]);
}
l++;
}
return res;
}
498. 对角线遍历
思路:
同样也是矩阵的遍历,但是这里需要利用一个规律,图中的各个箭头的横纵坐标之和是相等的!利用这一点就可以以和的奇偶区箭头的方向啦:
public int[] findDiagonalOrder(int[][] matrix) {
if (matrix == null || matrix.length == 0) {
return new int[]{};
}
int r = 0, c = 0;
int row = matrix.length, col = matrix[0].length;
int[] res = new int[row * col];
for (int i = 0; i < res.length; i++) {
res[i] = matrix[r][c];
// r + c 即为遍历的层数,偶数向上遍历,奇数向下遍历
if ((r + c) % 2 == 0) {
if (c == col - 1) {
// 往右移动一格准备向下遍历
r++;
} else if (r == 0) {
// 往下移动一格准备向下遍历
c++;
} else {
// 往上移动
r--;
c++;
}
} else {
if (r == row - 1) {
// 往右移动一格准备向上遍历
c++;
} else if (c == 0) {
// 往上移动一格准备向上遍历
r++;
} else {
// 往下移动
r++;
c--;
}
}
}
return res;
}