題目描述
給定一個含有 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;
}