首页 > 其他分享 >力扣-498. 对角线遍历

力扣-498. 对角线遍历

时间:2024-04-27 17:01:01浏览次数:22  
标签:cnt 遍历 优先级 mat dy 力扣 498 dx 对角线

1.题目

题目地址(498. 对角线遍历 - 力扣(LeetCode))

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

题目描述

给你一个大小为 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

2.题解

2.1 模拟

注意一下向右是y+1, 向下是x+1, 最开始弄反了, 导致我弄了好久没弄出来!!!
这里关键点是知道一条对角线触碰到边界后, 下一次的起始点!!! 通过下图我们能发现规律

  1. 如果上一次是向右上截止(本次是左下方向), 那么优先级是首先找是否有(x,y+1), 如果没有选择(x+1, y)
  2. 如果上一次是向左下截止(本次是右上方向), 那么优先级是首先找是否有(x+1,y), 如果没有选择(x, y+1)

对角线方向遍历, 我们设置一个方向数组dir即可{{-1, 1}(右上), {1, -1}(左下)}
对于碰壁后出发点转变, 我们新设置一个出发点变更数组 trans(按上方的优先级即可) 即可; 这里要判断两次, 第一次是判断按对角线方向走是否碰壁, 第二次是判断高优先级出发点是否存在,不存在就选择次级优先级出发点.

代码

  • 语言支持:C++

C++ Code:

class Solution {
	public:
		vector<int> findDiagonalOrder(vector<vector<int>>& mat) {
			int row = mat.size(), col = mat[0].size();
			vector<pair<int, int>> dir{{-1, 1},{1, -1}}; // 分别对应右上, 左下方向
			vector<pair<int, int>> trans{{0, 1},{1, 0}}; // cnt=0(右上方向时,下次左下), 优先{0, 1}; cnt=1(左上方向时,下次右上), 优先 {1, 0}; (cnt+1)%2表示次级优先
			vector<int> ans;
			int cnt = 0, x = 0, y = 0;
			for(int i = 0; i < row * col; i++) {
				ans.push_back(mat[x][y]);
                // 按对角线方向行走
				int dx = x + dir[cnt].first; 
				int dy = y + dir[cnt].second;
                // 按对角线走碰壁
				if(dx < 0 || dx >= row || dy < 0 || dy >= col) {
					dx = x + trans[cnt].first;
					dy = y + trans[cnt].second;
                    // 高优先级出发点不存在, 选择次级优先级出发点
					if(dx < 0 || dx >= row || dy < 0 || dy >= col) {
						dx = x + trans[(cnt+1)%2].first;
						dy = y + trans[(cnt+1)%2].second;
					}
					cnt = (cnt+1) % 2; // 转变对角线行走方向
				}
                // 更新 x, y值
				x = dx;
				y = dy;
			}
			return ans;
		}
};

复杂度分析

令 n 为数组长度。

  • 时间复杂度:\(O(n)\)
  • 空间复杂度:\(O(n)\)

标签:cnt,遍历,优先级,mat,dy,力扣,498,dx,对角线
From: https://www.cnblogs.com/trmbh12/p/18162238

相关文章

  • 力扣-520. 检测大写字母
    1.题目题目地址(520.检测大写字母-力扣(LeetCode))https://leetcode.cn/problems/detect-capital/题目描述我们定义,在以下情况时,单词的大写用法是正确的:全部字母都是大写,比如"USA"。单词中所有字母都不是大写,比如"leetcode"。如果单词不只含有一个字母,只有首字母大写......
  • 力扣-59. 螺旋矩阵 II
    1.题目题目地址(59.螺旋矩阵II-力扣(LeetCode))https://leetcode.cn/problems/spiral-matrix-ii/题目描述给你一个正整数 n,生成一个包含1到 n2 所有元素,且元素按顺时针顺序螺旋排列的 nxn正方形矩阵matrix。 示例1:输入:n=3输出:[[1,2,3],[8,9,4],[7,6,5]......
  • 力扣-54. 螺旋矩阵
    1.题目题目地址(54.螺旋矩阵-力扣(LeetCode))https://leetcode.cn/problems/spiral-matrix/题目描述给你一个m行n列的矩阵 matrix,请按照顺时针螺旋顺序,返回矩阵中的所有元素。 示例1:输入:matrix=[[1,2,3],[4,5,6],[7,8,9]]输出:[1,2,3,6,9,8,7,4,5]示例2:......
  • 力扣-419. 甲板上的战舰
    1.题目题目地址(419.甲板上的战舰-力扣(LeetCode))https://leetcode.cn/problems/battleships-in-a-board/题目描述给你一个大小为mxn的矩阵board表示甲板,其中,每个单元格可以是一艘战舰'X'或者是一个空位'.',返回在甲板board上放置的战舰的数量。战舰只能水平......
  • 力扣-598. 区间加法 II
    1.题目题目地址(598.区间加法II-力扣(LeetCode))https://leetcode.cn/problems/range-addition-ii/题目描述给你一个mx n的矩阵 M和一个操作数组op。矩阵初始化时所有的单元格都为0。ops[i]=[ai,bi]意味着当所有的0<=x<ai和0<=y<bi时,M[x][y]应......
  • 力扣-LCR 126. 斐波那契数
    1.题目题目地址(LCR126.斐波那契数-力扣(LeetCode))https://leetcode.cn/problems/fei-bo-na-qi-shu-lie-lcof/题目描述斐波那契数(通常用F(n)表示)形成的序列称为斐波那契数列。该数列由0和1开始,后面的每一项数字都是前面两项数字的和。也就是:F(0)=0,F(1)=1F(n......
  • TODO-力扣-707. 设计链表
    1.题目题目地址(707.设计链表-力扣(LeetCode))https://leetcode.cn/problems/design-linked-list/题目描述你可以选择使用单链表或者双链表,设计并实现自己的链表。单链表中的节点应该具备两个属性:val和next。val是当前节点的值,next是指向下一个节点的指针/引用。如果......
  • 力扣-118. 杨辉三角
    1.题目介绍题目地址(118.杨辉三角-力扣(LeetCode))https://leetcode.cn/problems/pascals-triangle/题目描述给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。在「杨辉三角」中,每个数是它左上方和右上方的数的和。 示例1:输入:numRows=5输出:[[1],......
  • 关于双向循环列表的插入、删除、遍历
    目录双向循环链表公式初始化双向循环链表构建双向循环链表结构体//双向循环链表节点定义typedefstructdouble_loop_node{chardata[DATA_LEN];//数据域,存储数据长度structdouble_loop_node*next;......
  • 力扣-442. 数组中重复的数据
    1.题目介绍题目地址(442.数组中重复的数据-力扣(LeetCode))https://leetcode.cn/problems/find-all-duplicates-in-an-array/题目描述给你一个长度为n的整数数组nums,其中nums的所有整数都在范围[1,n]内,且每个整数出现一次或两次。请你找出所有出现两次的整数,......