本次刷题日记的第 65 篇,力扣题为:498. 对角线遍历,中等
一、题目描述:
对角线遍历,在网格的对接线上进行遍历,可以来尝试一波,有点意思
二、这道题考察了什么思想?你的思路是什么?
摘取一下题目中的重点信息:
- 题目给出一个表格,咱们需要找到题目中要求的对角线
- 然后按照对角线的顺序将遍历到到的数据存储,并有序输出
分析
题目看上去还是比较清晰明确的,读完题之后我们其实就能够很明确的知道,这个题肯定要在格子的坐标上做文章
那么我么按照思路,来看一下题目所说的对角线是啥样子的
咱们稍微画一个简图,就能很清晰的知道,对角线的条数,和具体的表格行列有密不可分的关系,且满足如下关系
对角线条数 = m+n −1对角线条数 = m+n -1 对角线条数=m+n−1
另外仔细看上图,咱们对角线的方向还是有不同的,奇数条对角线是从下到上的,偶数条对角线是从上到下的
如果咱们对角线的索引从 0 开始的话,那么就是 偶数条对角线是从下到上的,例如这样
到这里,我们知道了对角线的条数如何计算,另外对角线的方向我们也明确了如何处理
那么我们如何找到每条对角的起点格子和终点格子呢?
我们可以清晰的看到每一条对角线的顺序,已经途径的格子,仔细观察一下,如何计算每一条对角线的其实坐标呢?
观察后我们可以知道,对于偶数的的由下至上的对角线有这样的规律:
x=min(i,m−1)x = min(i, m-1) x=min(i,m−1)
y=max(i−m+1,0)y = max(i-m+1, 0) y=max(i−m+1,0)
例如上图左边的第 2 条线 起点为 :
x = min(i,m−1) = min(2,3−1) = 2x = min(i, m-1) = min(2, 3-1) = 2 x=min(i,m−1)=min(2,3−1)= 2
y = max(2−3+1,0) = 0y = max(2-3+1,0) = 0 y=max(2−3+1,0)= 0
同理,我们可以得到 奇数对角线的时候的规律:
x=max(i−n+1,0)x = max(i-n+1, 0) x=max(i−n+1,0)
y=min(i,n−1)y = min(i, n-1) y=min(i,n−1)
既然规律找到了,那么接下来就是编码实现的问题了,注意哦,我们找到了对角线的起点还不够,我们还要知道如何去遍历这一条对角线上的值,其实看到上图,我们就已经知道了,
在遍历以内的情况下:
对角线由下往上的,x 不停的向右扩展,所以需要加 1, y 不停的向上扩展,所以要 减 1
同理,对角线由上往下的,x 不停的向左扩展,所以需要减 1, y 不停的向下扩展,所以要 加 1
三、编码
根据上述逻辑和分析,我们就可以翻译成如下代码
此处需要注意表格的边界值,以及需要区分好对角线的顺序,别弄反了
编码如下:
func findDiagonalOrder(mat [][]int) []int { m, n := len(mat), len(mat[0]) ans := make([]int, 0, m*n) for i := 0; i < m+n-1; i++ { // 由上到下 if i%2 == 1 { x := max(i-n+1, 0) y := min(i, n-1) for x < m && y >= 0 { ans = append(ans, mat[x][y]) x++ y-- } } else { // 由下到上 x := min(i, m-1) y := max(i-m+1, 0) for x >= 0 && y < n { ans = append(ans, mat[x][y]) x-- y++ } } } return ans } func min(a, b int) int { if a > b { return b } return a } func max(a, b int) int { if b > a { return b } return a }
四、总结:
本题的处理方式时间复杂度为相当于咱们遍历了一遍题目给出的所有格子,令 表格的行为 n, 列为 m ,那么时间复杂度为 O(nm)
空间复杂度是 O(1) ,咱们没有引入其他额外的空间消耗
原题地址:498. 对角线遍历
今天就到这里,学习所得,若有偏差,还请斧正
欢迎点赞,关注,收藏
朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力
好了,本次就到这里
技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。
我是阿兵云原生,欢迎点赞关注收藏,下次见~