498#对角线遍历(中等)

下面是我自己的分析:

代码:

public int[] findDiagonalOrder(int[][] matrix) {
        if (matrix.length == 0) return new int[0];
        int m = matrix.length;  //二维数组的行数
        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(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--;
                }
            }
        }
        return result;
    }

————————————————————————————————

题目描述

给定一个含有 M x N 个元素的矩阵(M行,N列),请以对角线遍历的顺序返回这个矩阵中的所有元素,对角线遍历如下图所示。

示例:

输入:
[
 [ 1, 2, 3 ],
 [ 4, 5, 6 ],
 [ 7, 8, 9 ]
]
输出:  [1,2,4,7,5,3,6,8,9]

说明:

  1. 给定矩阵中的元素总数不会超过 100000 。

分析

分析一下遍历顺序的特点,可以看出,对角线的方向跟索引和(行的索引值+列的索引值)的奇偶性有关,然后加上边界情况,遍历的路线大概就出来了。

具体可以分为以下几种情况:

  1. 索引和为偶数:
    • 元素在第一行,往右走
    • 元素在最后一列,往下走
    • 其他情况,往右上走
  2. 索引和为奇数:
    • 元素在第一列,往下走
    • 元素在最后一行,往右走
    • 其他情况,往左下走

按照这个思路,写出的方法如下:

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--;
    }
}

再次测试,可以通过了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值