数据结构--对角线遍历

数据结构–对角线遍历

给一个M x N的矩阵,请按图完成其对角线的遍历,返回一个存储其遍历值的一维数组
在这里插入图片描述

分析

我们可以知道如下的规律

  1. 我们要返回的数组的长度为M x N
  2. 对角线有两种方向,在索引为偶数时是右上方向(行减列增),在索引为奇数时是左下方向(行增列减)
  3. 一共需要遍历的对角线次数为 M + N - 1
  4. 每条对角线上的横纵坐标的和为定值,就是第几条对角线索引(从0开始)

代码

我的代码

class Solution {
    public static int[] findDiagonalOrder(int[][] mat) {
        int total = mat.length + mat[0].length - 1;
        int rowOrigin = mat.length - 1;
        int columnOrigin = mat[0].length - 1;
        int row = 0;
        int column = 0;
        List <Integer> list = new ArrayList();
        for(int sum = 0;sum < total;++sum){
            if(sum % 2 == 1){// 行增列减
                if (sum > columnOrigin){
                    row = sum - columnOrigin;
                }
                column = sum - row;
                while (true){
                    list.add(mat[row++][column--]);
                    if (row > rowOrigin || column < 0){
                        break;
                    }
                }
                column = 0;
            }else{// 行减列增
                if (sum > rowOrigin){
                    column = sum - rowOrigin;
                }
                row = sum - column;
                while (true){
                    list.add(mat[row--][column++]);
                    if (row < 0 || column > columnOrigin){
                        break;
                    }
                }
                row = 0;
            }
        }
        int length = list.size();
        int [] array = new int[length];
        for(int i = 0;i < length;i++){
            array[i] = list.get(i);
        }
        return array;
    }
}

简介版代码

在处理右上时,行减列增
循环遍历对角线的条件:
因为行减到0,或者列增到边界时,就不能再遍历,所以遍历条件是其补集

边界判断:

当达到边界上的最后一个数时,还要进行一次行减列增(因为循环变量迭代),此时我们需要判断列是否越界,如果没有,则把行加1(满足行列之和加1,开启下一条线的遍历),如果越界了,行加2,列减1(满足行列之和加1,开启下一条线的遍历),说明列达到边界,下一条对角线的起始遍历位置加了一行

对于左下(行增列减),也是一样的分析方式

    public static int[] findDiagonalOrder(int[][] matrix) {
        if (matrix.length == 0) {
            return new int[0];
        }
        int m = matrix.length;// 得到行数
        int n = matrix[0].length; // 得到列数
        //存放数组
        int[] ans = new int[m * n];
        //对角线方向次数
        int count = n + m - 1;
        //定义初始化 行标记,列标记,存放数组索引
        int row = 0, col = 0, Index = 0;
        //开始对角线循环
        for (int i = 0; i < count; i++) {
            //判断对角线方向(因题目初始从右上(即i=0)开始):偶数右上,奇数左下
            if (i % 2 == 0) {
                //右上操作
                while (row >= 0 && col < n) {// 因为行在减,列在增,所以行判断和0,列判断越界
                    //将矩阵数存入存放数组
                    ans[Index] = matrix[row][col];
                    //索引后移
                    Index++;
                    //右上规律:行减一,列加一
                    row--;
                    col++;
                }
                //判断是否为越界情况:不越界正常行加一,越界行加二,列减一;
                //(此处不理解的拿张草稿纸将循环中row和col的值遍历写一下对照矩阵图就明白了)
                if (col < n) {// 执行完上面,行为-1,判断列是否越界
                    row++;// 列没越界,行加回到0
                }
                else { // 越界,行加2(即在原来得行的基础上再加1),列减一
                    row += 2;
                    col--;
                }// 始终保证了行列之和加1
            }
            //左下操作:按规律与右上相反即可
            else {
                while (row < m && col >= 0) {
                    ans[Index] = matrix[row][col];
                    Index++;
                    row++;
                    col--;
                }
                if (row < m) {
                    col++;

                } else {
                    row--;
                    col += 2;
                }
            }
        }
        // 返回存放数组
        return ans;
    }
}
  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

挽天技术

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值