leetcode刷题:对角线遍历

本文介绍了如何解决LeetCode中的二维数组对角线遍历问题,提供了两种解法:一种是使用大量ifelse进行条件判断,另一种是利用坐标和的变化规律进行遍历。通过对角线的递增和坐标调整,实现了从大到小和从小到大的遍历策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

二维数组对角线遍历对角线遍历

问题描述

给定二维数组,然后按照对角线折返遍历。

解法一

通过大量的ifelse对情况进行分类,最无脑的做法:

class Solution {
public:
	vector<int> findDiagonalOrder(vector<vector<int>>& matrix) {
		int row = matrix.size();
		if (row == 0)  return{};
		int col = matrix[0].size();
		vector<int> diagonal;
		if (row == 1) {
			for (int i = 0; i < col; i++) {
				diagonal.push_back(matrix[0][i]);
			}
			return diagonal;
		}
		if(col == 1) {
			for (int i = 0; i < row; i++) {
				diagonal.push_back(matrix[i][0]);
			}
			return diagonal;
		}
		int i = 0, j = 0;
		int upOrDown = 0;
		diagonal.push_back(matrix[0][0]);
		while (i < row - 1 || j < col - 1)
		{
			if (i == 0 && j != col - 1) {
				if (upOrDown == 0) { j++; upOrDown = 1; }
				else { i++; j--; }
			}
			else if (j == col - 1) {
				if (upOrDown == 0) { i++; upOrDown = 1; }
				else { i++; j--; }
			}
			else if (i != 0 && j == 0 && i != row - 1) {
				if (upOrDown == 0) { i--; j++; }
				else { i++; upOrDown = 0; }
			}
			else if (i == row - 1 && j != col - 1) {
				if (upOrDown == 0) { i--; j++; }
				else { j++; upOrDown = 0; }
			}
			else {
				if (upOrDown == 0) { i--; j++; }
				else { i++; j--; }
			}
			diagonal.push_back(matrix[i][j]);
		}
		return diagonal;
	}
};

解法二

1.每一趟对角线中元素的坐标(x, y)相加的和是递增的。

2.每一趟都是 x 或 y 其中一个从大到小(每次-1),另一个从小到大(每次+1)。

3.确定初始值。例如这一趟是 x 从大到小, x 尽量取最大,当初始值超过 x 的上限时,不足的部分加到 y 上面。

4.确定结束值。例如这一趟是 x 从大到小,这一趟结束的判断是, x 减到 0 或者 y 加到上限。

5.这一趟是 x 从大到小,那么下一趟是 y 从大到小,循环进行。 并且方向相反时,逻辑处理是一样的,除了x,y和他们各自的上限值是相反的。

class Solution {
public:
	vector<int> findDiagonalOrder(vector<vector<int>>& matrix) {
		int row = matrix.size();
		if (row == 0)  return{};
		int col = matrix[0].size();
		vector<int> diagonal;
		//diagonal.push_back(matrix[0][0]);
		bool upOrDown = true;
		for (int i = 0; i < row + col; i++) {
			int pm = upOrDown ? row : col;
			int pn = upOrDown ? col : row;
			int x = (pm > i) ? i : pm - 1;
			int y = i - x;
			while (x >= 0 && y < pn) {
				diagonal.push_back(upOrDown ? matrix[x][y] : matrix[y][x]);
				x--;
				y++;
			}
			upOrDown = !upOrDown;
		}
		return diagonal;
	}
};

作者:ikaruga
链接:https://leetcode-cn.com/problems/diagonal-traverse/solution/dui-jiao-xian-bian-li-fen-xi-ti-mu-zhao-zhun-gui-l/

自己的代码:

class Solution {
public:
	vector<int> findDiagonalOrder(vector<vector<int>>& matrix) {
		int row = matrix.size();
		if (row == 0)  return{};
		int col = matrix[0].size();
		if (col == 0)  return{};
		vector<int> diagonal;
		//diagonal.push_back(matrix[0][0]);
		bool upOrDown = true;      //true=up
		for (int i = 0; i < row + col -1; i++) {
			int x = (i > (row-1)) ? row-1 : i;
			int y = i - x;
			while (!(x<0||y>(col-1))) {
				diagonal.push_back(matrix[x][y]);
				x--; y++;
			}
			i++;
			y = (i > (col-1)) ? col-1 : i;
			x = i - y;
			//while (y >= 0 && x <= row - 1) {
			while(!(y<0||x>(row-1))){
				diagonal.push_back(matrix[x][y]);
				x++; y--;
			}
			//i++;
		}
		return diagonal;
	}
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值