题目描述
给定一个含有 M x N 个元素的矩阵(M 行,N 列),请以对角线遍历的顺序返回这个矩阵中的所有元素,对角线遍历如下图所示。
实例:
输入:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
输出: [1,2,4,7,5,3,6,8,9]
说明:
给定矩阵中的元素总数不会超过 100000 。
解题思路
- 在遍历二维数组中主要有两个方向变换,一个是右上,一个是左下。
- 右上:col++, row–; 左下:col–;row++;
- 本题的重点是:对于越界的处理,对于两种方向的遍历,都要进行边界的处理,当向右上时,row < 0 时,row 需要重置,当 col > n - 1 时,row 和 col 都需要重置。 当向左下时,col < 0 时, col 需要重置,当 row > m - 1时,row 和 col 都需要重置。当越到边界时,遍历的方向都会发生改变。
代码
解法一
public int[] findDiagonalOrder(int[][] matrix) {
// 空数组的判断
if(matrix.length == 0 || matrix[0].length == 0) {
return new int[]{};
}
// 行数
int row = matrix.length;
// 列数
int col = matrix[0].length;
// 保存结果
int[] result = new int[row * col];
// 当 每一行只有一个元素时。
// if (col == 1) {
// for (int l = 1; l < row; l++) {
// result[k++] = matrix[l][0];
// }
// return result;
// }
int x = 0, y = 0, k = 0;
result[k++] = matrix[y][x];
while(y != row - 1 || x != col - 1) {
// 右上
while(true) {
y--;
x++;
// 边界
if(y < 0 && x != col) {
y++;
result[k++] = matrix[y][x];
break;
}
// 边界
if(x == col) {
x--;
y += 2;
result[k++] = matrix[y][x];
break;
}
result[k++] = matrix[y][x];
}
if(!(y != row - 1 || x != col - 1)) {
break;
}
// 左下
while(true) {
x--;
y++;
if(x < 0 && y != row) {
x++;
result[k++] = matrix[y][x];
break;
}
if(y == row) {
y--;
x += 2;
result[k++] = matrix[y][x];
break;
}
result[k++] = matrix[y][x];
}
}
return result;
}
解法二
public static int[] findDiagonalOrder(int[][] matrix) {
if(matrix.length==0||matrix[0].length==0){
return new int[0];
}
int m = matrix.length;
int n = matrix[0].length;
int[] new_array = new int[m*n];
int row = 0;
int col = 0;
// 方向的变化标志
boolean flag = true;
for(int i = 0; i < new_array.length; i++){
new_array[i] = matrix[row][col];
if(flag) {
row--;
col++;
}else {
row ++;
col--;
}
if(col > n-1){
col = n-1;
row += 2;
flag = !flag;
}
if(row > m-1){
row = m-1;
col += 2;
flag = !flag;
}
if(col < 0){
col = 0;
flag = !flag;
}
if(row < 0){
row = 0;
flag = !flag;
}
}
return new_array;
}