98.对角线遍历

一、题目描述

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

二、解题思路

对角线遍历:根据题目给定一个矩阵(如下),
在这里插入图片描述
在这里插入图片描述
我们可以发现遍历的顺序分为斜上走斜下走,分别有不同的特点:
在这里插入图片描述
考虑边界条件

条件一:假如,下面这个先斜上走,遍历完1之后,下一个遍历的元素根据上面斜上走的条件,发现超出边界,此时应该调转方向:row<0:row=0,col不变,换方向表示当row小于0时,将row设置为0,col不变,换方向。
在这里插入图片描述

条件二:同理,斜下走满足条件也要换方向:col<0:row不变,col=0,换方向表示此时row保持不变,col设置为0,换方向:
在这里插入图片描述
条件三:一直到主对角线下面的斜下走遍历完,此时的位置处于第一列元素9的下面,此时换方向从最后一行元素11开始,需要新的边界条件,那么这时你会发现超出边界的条件是row>=m:row=m-1,col+=2,换方向意思是,当row大于等于行数m时,此时row从m-1开始,col从col+=2列开始:
在这里插入图片描述
条件四:继续斜上走,此时斜上走当col大于等于n列时,位置在第一行4的后面,此时也要换方向:col>=n:row+=2,col=n-1,换方向
在这里插入图片描述
最终:

在这里插入图片描述
特殊条件一:此时边界条件还没有考虑完,斜上和斜下也有可能同时存在两个边界条件,假如有一个n*n的矩阵:当走到主对角线时,发现条件一和条件四都符合,此时该怎么重新换方向走呢,使用哪个条件的逻辑呢?
在这里插入图片描述
这种情况,此时先执行条件四的逻辑,主对角线走完3之后再往上走,此时坐标应该是(-1,3)col>=n,先将row+=2,col=n-1,这时下一个遍历的元素就跑到了6这个位置:
在这里插入图片描述
特殊情况二:再来看下面这种情况,发现越界符合条件二和三,这时怎么继续遍历执行呢?
在这里插入图片描述

此时执行条件三,row>=m,row = m-1,col+=2,就来到我想要的位置,也就是斜上走的位置:
在这里插入图片描述

三、代码演示

class Solution {
    public int[] findDiagonalOrder(int[][] mat) {
        //假设矩阵元素个数为0的话,返回一个空数组
        if (mat.length==0){
            return new int[0];
        }

        //求出行列的长度
        int m = mat.length;
        int n = mat[0].length;

        //定义一个二维数组来确定是往斜上还是斜下走,斜上:row-1,col+1;斜下:row+1,col-1
        int[][] dirs = {{-1,1},{1,-1}};
        //存放结果集
        int[] result = new int[m*n];

        //di是用来标识方向的
        int row = 0, col = 0, di=0;
        for (int i=0; i<m*n; i++){
            result[i] = mat[row][col];

            row = row + dirs[di][0];
            col = col + dirs[di][1];

            /**
             * 这里先考虑同时满足两个越界条件的情况,最开始是斜上走,假如最开始的斜上走就出现了特殊情况一呢?
             * 这时解决特殊情况一的情况(执行条件四)
             */
            if (col>=n){
                col = n-1;
                row += 2;
                //换方向,di取0和1,0是斜上,1是斜下,通过下面的公式计算下一个方向
                di = 1-di;

            }

            //特殊情况二(执行条件三)
            if (row>=m){
                row = m-1;
                col += 2;
                di = 1-di;
            }

            //条件二
            if (col<0){
                col = 0;
                di = 1-di;
            }

            //条件一
            if (row<0){
                row = 0;
                di = 1-di;
            }

        }
    return result;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值