数组—对角线遍历数组

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

示例:

[
 [ 1, 2, 3 ],
 [ 4, 5, 6 ],
 [ 7, 8, 9 ]
]

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

说明:给定矩阵中的元素总数不会超过 100000 。

思路:对于对角线上的元素,仔细观察可以发现规律,如果我们设行和列对应的下标是m和n,对角线上的元素向上走是m--,n++

向下走是m++,n--;

根据元素的索引的座标和(数组元素的两个下标和)我们可以发现一些规律:和为偶数像上遍历,和为奇数向下遍历。

下标和为偶数时,如果到了第一行就让列加1向右移动,如果到了最后一列就让行加1向下移动。

下标和为奇数时:如果到了第一列就让行加1向下移动,如果到了最后一行就让列加1向右移动。

这样完成对角的转换。

所以综合上面的分析可以得到结果:

    public int[] findDiagonalOrder(int[][] matrix) {

        if (matrix == null) {
            return null;
        }
        if (matrix.length == 0) {
            int result[] = {};
            return result;
        }

        int m = matrix.length;
        int n = matrix[0].length;

        int r = 0;
        int c = 0;
        int result[] = new int[m * n];

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

对于以上代码输入数据{{1, 2, 3},{4, 5, 6},{7, 8, 9}}异常提示:

debug发现:对于上面的代码:对于下标和是偶数的元素3,由于先判断了元素在第一行就会向右导致列索引加1越界;同样对于最后一列的最后一行也可能出现数组越界。因此修改这两个地方的判断顺序。

最后结果如下:

  public int[] findDiagonalOrder(int[][] matrix) {
        
        if (matrix == null) {
            return null;
        }
        if (matrix.length == 0) {
            int result[] = {};
            return result;
        }

        int m = matrix.length;
        int n = matrix[0].length;

        int r = 0;
        int c = 0;
        int result[] = new int[m * n];

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

输出结果:

输入数据:

int matric[][] = {{1, 2, 3,10}, {4, 5, 6,11}, {7, 8, 9,12}};

输出结果:

总结:对于数组的问题,不会有其他的操作,找出下标变换的规律是关键;同时要处理好下标变换的边界。

参考实现:https://www.cnblogs.com/yuzhenzero/p/9550938.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章