(二维数组)leetcode498. 对角线遍历

一、题目

1、题目描述

给你一个大小为 m x n 的矩阵 mat ,请以对角线遍历的顺序,用一个数组返回这个矩阵中的所有元素。

2、基础框架

  • C++版本给出的基础框架如下:

3、原题链接

https://leetcode.cn/problems/diagonal-traverse/

二、解题报告

1、思路分析

   ( 1 ) (1) (1)对角线遍历和普通遍历的区别在于遍历指针的变化方式不同。
   ( 2 ) (2) (2)可以观察,对角线遍历存在两个方向,所以要考虑方向变化,可以设置一个变量来控制方向。
   ( 3 ) (3) (3)斜上方向,指针变化方式为i-1,j+1。斜下方向指针的变化方式为i+1,j-1。
   ( 4 ) (4) (4)最大的难点在于边界条件的判断,二维数组可以看做矩形,有四条边,4个顶点,所以总共有8个边界,但由于遍历方向为2,4象限,所以只考虑2个顶点,所以总共需要考虑6个边界。
   ( 5 ) (5) (5)第一行边界(除去顶点情况),当i<0时,发生越界,此时要调转方向,i+1,j不变。第一列边界(除去顶点情况),当j<0时,发生越界,此时要调转方向,i不变,j+1。最后一行边界(除去顶点情况),当i=m时,发生越界,此时要调转方向,i-1,j+2;最后一列边界(除去顶点情况),当j=n时,发生越界,此时要调转方向,i+2,j-1。右上顶点,当i<0并且j=n时,右上顶点越界,此时要调转方向,i+2,j-1。左下顶点,当j<0并且i=m时,左下顶点越界,此时要调转方向,i-1,j+2。

2、时间复杂度

时间复杂度O(mn),
空间复杂度O(mn)

3、代码详解

class Solution {
public:
    vector<int> findDiagonalOrder(vector<vector<int>>& mat) {
        vector<int> re;
        int flag = 0;
        int m = mat.size();
        int n = mat[0].size();
        int i = 0;
        int j = 0;
        while(1) {
            re.push_back(mat[i][j]);
            if (i == m-1 && j == n-1) break;
            if (flag == 0) {
                i = i - 1;
                j = j + 1;
                if (i < 0 && j >= n) {
                    i = i + 2;
                    j = j - 1;
                    flag = 1;
                }
                else if (i < 0 || j >= n) {
                    if (i < 0) {
                        i = i + 1;
                    }
                    if (j >= n) {
                        i = i + 2;
                        j = j - 1;
                    }
                    flag = 1;
                }
            }
            else {
                i = i + 1;
                j = j - 1;
                if (i >= m && j < 0) {
                    i = i - 1;
                    j = j + 2;
                    flag = 0;
                }
                else if (i >= m || j < 0) {
                    if (j < 0) {
                        j = j + 1;
                    } 
                    if (i >= m) {
                        i = i - 1;
                        j = j + 2;
                    }
                    flag = 0;
                }
            }
        }
        return re;
    }
};

三、本题小知识

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值