[LeetCode解题报告] 498. 对角线遍历

一、 题目

1. 题目描述

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

 

示例 1:

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

示例 2:

输入:mat = [[1,2],[3,4]]
输出:[1,2,3,4]

 

提示:

  • m == mat.length
  • n == mat[i].length
  • 1 <= m, n <= 104
  • 1 <= m * n <= 104
  • -105 <= mat[i][j] <= 105
Related Topics
  • 数组
  • 矩阵
  • 模拟

  • 👍 330
  • 👎 0

2. 原题链接

链接: 498. 对角线遍历

二、 解题报告

1. 思路分析

  1. 下标直接模拟,我们发现一共有m+n-1条对角线,处理每条对角线时计算初始端点的i,j,然后让他们移动即可。
  2. 下标搜索:
    • 从(0,0)开始,方向一共有右上左下两个方向;
    • 向右上搜索若出界:坐标向下移动1格,方向调转,继续搜索。
    • 向左下收缩若出界:坐标向右移动1格,方向调转,继续搜索。
    • 直到到达(m-1,n-1)。
      在这里插入图片描述

2. 复杂度分析

时间复杂度O(nm)

3. 代码实现

下标模拟

class Solution:
    def findDiagonalOrder(self, mat: List[List[int]]) -> List[int]:
        m,n = len(mat),len(mat[0])
        ans = []
        for k in range(m+n-1):  # 处理第k条对角线
            if k&1 == 0:
                i = k if k < m else m-1
                j = 0 if k < m else k-m+1 
                while i>=0 and j < n:
                    ans.append(mat[i][j])
                    i -= 1
                    j += 1
            else:
                i = 0 if k < n else k - n + 1
                j = k if k < n else n-1
                while i<m and j>=0:
                    ans.append(mat[i][j])
                    i += 1
                    j -= 1
        return ans

搜索

class Solution:
    def findDiagonalOrder(self, mat: List[List[int]]) -> List[int]:
        m,n = len(mat),len(mat[0])
        ans = []
        dirs = [(-1,1),(1,-1)]  # 向右上,向左下
        change = [(1,0),(0,1)]  # 向下,向右
        d = 0
        x,y = 0,0
        def in_bound(x,y):
            return 0<=x<m and 0<=y<n
        while not (x == m-1 and y == n-1):
            if in_bound(x,y):
                ans.append(mat[x][y])
            x += dirs[d][0]
            y += dirs[d][1]
            if not in_bound(x,y):
                x += change[d][0]
                y += change[d][1]
                d ^=1
        ans.append( mat[m-1][n-1])
        return ans

三、 本题小结

  1. 几乎是对角线搜索的模板

四、 参考链接

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值