498#對角線遍歷
阿新 • • 發佈:2018-08-28
find 思路 pre nal system 再次 void lse 方法
題目描述
給定一個含有 M x N 個元素的矩陣(M行,N列),請以對角線遍歷的順序返回這個矩陣中的所有元素,對角線遍歷如下圖所示。
示例:
輸入:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
輸出: [1,2,4,7,5,3,6,8,9]
說明:
- 給定矩陣中的元素總數不會超過 100000 。
分析
分析一下遍歷順序的特點,可以看出,對角線的方向跟索引和(行的索引值+列的索引值)的奇偶性有關,然後加上邊界情況,遍歷的路線大概就出來了。
具體可以分為以下幾種情況:
- 索引和為偶數:
- 元素在第一行,往右走
- 元素在最後一列,往下走
- 其他情況,往右上走
- 索引和為奇數:
- 元素在第一列,往下走
- 元素在最後一行,往右走
- 其他情況,往左下走
按照這個思路,寫出的方法如下:
public class DiagonalTraverse { public int[] findDiagonalOrder(int[][] matrix) { if (matrix.length == 0) return new int[0]; int m = matrix.length; // 待處理的矩陣有M行、N列 int n = matrix[0].length; int[] result = new int[m * n]; // 用來存放遍歷的結果 int r = 0; int c = 0; for (int i = 0; i < result.length; i++) { result[i] = matrix[r][c]; if ((r + c) % 2 == 0) { if (r == 0) { //元素在第一行,往右走 c++; } else if (c == n - 1) { // 元素在最後一列,往下走 r++; } else { //其他情況,往右上走 r--; c++; } } else { if (c == 0) { //元素在第一列,往下走 r++; } else if (r == m -1) { //元素在最後一行,往右走 c++; } else { //其他情況,往左下走 r++; c--; } } } return result; } }
測試用例
public static void main(String[] args)
{
DiagonalTraverse dt = new DiagonalTraverse();
int[][] a = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int[] b = dt.findDiagonalOrder(a);
System.out.println(Arrays.toString(b));
}
運行以下,發現出錯了,報的是數組索引越界了
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
用IDE單步執行調試發現,問題出在邊界的元素上,比如這個例子中的元素3,它的索引和是偶數,在第一行,最後一列,在程序的判斷流程中,會先判定它在第一行,所以就會往右走,數組索引就越界了。同理,最左下角(第一列,最後一行)的那個元素同樣有這種越界的隱患,需要將相應的判斷語句的順序調整一下。
修改後判斷流程如下:
if ((r + c) % 2 == 0) {
if (c == n - 1) { // 元素在最後一列,往下走
r++;
} else if (r == 0) { // 元素在第一行,往右走
c++;
} else { // 其他情況,往右上走
r--;
c++;
}
} else {
if (r == m - 1) { //元素在最後一行,往右走
c++;
} else if (c == 0) { // //元素在第一列,往下走
r++;
} else { //其他情況,往左下走
r++;
c--;
}
}
再次測試,可以通過了。
498#對角線遍歷