对角线遍历

题目描述

给定一个含有 M x N 个元素的矩阵(M 行,N 列),请以对角线遍历的顺序返回这个矩阵中的所有元素,对角线遍历如下图所示。

实例:

输入:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
输出: [1,2,4,7,5,3,6,8,9]
在这里插入图片描述

说明:

给定矩阵中的元素总数不会超过 100000 。

解题思路

  1. 在遍历二维数组中主要有两个方向变换,一个是右上,一个是左下。
  2. 右上:col++, row–; 左下:col–;row++;
  3. 本题的重点是:对于越界的处理,对于两种方向的遍历,都要进行边界的处理,当向右上时,row < 0 时,row 需要重置,当 col > n - 1 时,row 和 col 都需要重置。 当向左下时,col < 0 时, col 需要重置,当 row > m - 1时,row 和 col 都需要重置。当越到边界时,遍历的方向都会发生改变。

代码

解法一

public int[] findDiagonalOrder(int[][] matrix) {
// 空数组的判断
	if(matrix.length == 0 || matrix[0].length == 0) {
		return new int[]{};
	}
	// 行数
	int row = matrix.length;
	// 列数
	int col = matrix[0].length;
	// 保存结果
	int[] result = new int[row * col];
	//  当 每一行只有一个元素时。
	//	        if (col == 1) {
//	            for (int l = 1; l < row; l++) {
//	                result[k++] = matrix[l][0];
//	            }
//	            return result;
//	        }
	int x = 0, y = 0, k = 0;  
	result[k++] = matrix[y][x]; 
	while(y != row - 1 || x != col - 1) {
		// 右上
		while(true) {
			y--;
			x++;
			// 边界
			if(y < 0 && x != col) {
				y++;
				result[k++] = matrix[y][x];
				break;
			}
			// 边界
			if(x == col) {
				x--;
				y += 2;
				result[k++] = matrix[y][x];
				break;
			}
			result[k++] = matrix[y][x];
		} 
		if(!(y != row - 1 || x != col - 1)) {
			break;
		}
		// 左下
		while(true) {
			x--;
			y++;
			if(x < 0 && y != row) {
				x++;
				result[k++] = matrix[y][x];
				break;
			}
			if(y == row) {
				y--;
				x += 2;
				result[k++] = matrix[y][x];
				break;
			}
		result[k++] = matrix[y][x];
		}
	}
	return result;
}

解法二

public static int[] findDiagonalOrder(int[][] matrix) {
		 if(matrix.length==0||matrix[0].length==0){
	            return new int[0];
	        }
	        int m = matrix.length;
	        int n = matrix[0].length;
	        int[] new_array = new int[m*n];
	        int row = 0;
	        int col = 0;
	        // 方向的变化标志
	        boolean flag = true;
	        for(int i = 0; i < new_array.length; i++){
	            new_array[i] = matrix[row][col];
	            
	            if(flag) {
	            	row--;
	            	col++;
	            }else {	
	            	row ++; 
	            	col--;
	           }
	            
	            if(col > n-1){
	                col = n-1;
	                row += 2;
	                flag = !flag;
	            }
	            if(row > m-1){
	            	row = m-1;
	                col += 2;
	                flag = !flag;
	            }
	            if(col < 0){
	                col = 0;
	                flag = !flag;
	            }
	            if(row < 0){
	            	row = 0;
	                flag = !flag;
	            }
	            
	        }
	        return new_array;
	 }
	 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值