• 498#对角线遍历


    题目描述

    给定一个含有 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--;
        }
    }
    

    再次测试,可以通过了。

  • 相关阅读:
    论文阅读 | Generating Fluent Adversarial Examples for Natural Languages
    论文阅读 | BadNets: Identifying Vulnerabilities in the Machine Learning Model Supply Chain
    论文阅读 | Trojaning Attack on Neural Networks
    python copy与deepcopy (拷贝与深拷贝)
    论文阅读 | Real-Time Adversarial Attacks
    统计学习方法 | 第3章 k邻近法 | 补充
    统计学习方法 | 第3章 k邻近法
    统计学习方法 | 第2章 感知机 | 补充
    Gradle 如何打包 Spring Boot 可执行 JAR
    Gradle 发布 Jar 到 Archiva 时提示不能 Overwriting released artifacts is not allowed
  • 原文地址:https://www.cnblogs.com/yuzhenzero/p/9550938.html
Copyright © 2020-2023  润新知