leetcode刷题记录-498. 对角线遍历

115 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第18天,点击查看活动详情

前言

今天的题目为中等,简单的模拟题,主要是要搞懂题目要求的模拟顺序,在搞清楚顺序的规律之后,也就是一道简单的模拟题罢了。

每日一题

今天的题目是 498. 对角线遍历,难度为中等

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

示例 1:

image.png

输入: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

题解

数学规律

题目看似很有难度,但是我们要学会寻找其中的规律。

首先第一次遍历就只有 (0,0) 这一个点

第二次有 (0,1) 和 (1,0) 两个点

第三次有 (2,0),(1,1),(0,2) 三个点

我们会发现,每一次的点相加刚好就是这一趟的次数减一,然后根据题目中示例的循环规律,能够看出来区分奇数和偶数趟,

所以我们只需要确定题目给的这个长方形是多大的,通过长方形的边长去判断需要模拟几次,然后每一次的模拟的规律就都是按照上面说的那个样子。

做题的时候我们需要循环 正方形的 长加宽减一 次,因为我们需要的循环次数是长方形的对角线,然后每一次循环判断现在是奇数次还是偶数次,对此再去做单独的计算

对于奇数次,我们是从左下往上开始计算,要注意在对角线经过另一条对角线之后,x y 的取值方式也是不一样的,所以也需要做出判断。

对于偶数次也是如此,

综上,我们就能够模拟出这道题的一个循环情况。

function findDiagonalOrder(mat: number[][]): number[] {
  const m = mat.length;
  const n = mat[0].length;
  const ans = new Array();
  for (let i = 0; i < m + n - 1; i++) {
    if (i % 2 === 0) {
      let x = i < m ? i : m - 1;
      let y = i < m ? 0 : i - m + 1;
      while (x >= 0 && y < n) {
        ans.push(mat[x][y]);
        x--;
        y++;
      }
    } else {
      let x = i < n ? 0 : i - n + 1;
      let y = i < n ? i : n - 1;
      while (x < m && y >= 0) {
        ans.push(mat[x][y]);
        x++;
        y--;
      }
    }
  }
  return ans;
}

image.png