leetcode 498. Diagonal Traverse

257 篇文章 17 订阅

Given a matrix of M x N elements (M rows, N columns), return all elements of the matrix in diagonal order as shown in the below image.

Example:

Input:
[
 [ 1, 2, 3 ],
 [ 4, 5, 6 ],
 [ 7, 8, 9 ]
]
Output:  [1,2,4,7,5,3,6,8,9]
Explanation:

Note:

  1. The total number of elements of the given matrix will not exceed 10,000.
这一题我用的方法不怎么好,只打败了0.72%的人,差点就TLE了。。。

我是写出结果中元素的x,y坐标,找规律。

       0     1     2

0     1     2     3

1     4     5     6

2     7     8     9

3    10   11   12


0,0     0,1    1,0    2,0    1,1    0,2    1,2     2,1     3,0      3,1      2,2      3,2

1        2        4      7        5       3       6       8        10        11       9         12

发现每一道对角线上,x+y的和都是固定的,并且随着不断画对角线,x+y的和每次都加一。而且要么是以x=0为对角线开始,或者以y=0为对角线开始,是轮流来的。

package leetcode;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Diagonal_Traverse_498 {

	public int[] findDiagonalOrder(int[][] matrix) {
		if(matrix.length==0){
			return new int[]{};
		}
		List<Integer> list=new ArrayList<Integer>();
		int m=matrix.length;
		int n=matrix[0].length;
		int sum=0;
		int x=0,y=0;
		boolean isOdd=false;
		while(sum<=(m-1+n-1)){
			if (isOdd == true) {
				x = 0;
				if(sum-x>=n){
					y=n-1;
					x=sum-(n-1);
				}
				else{
					y=sum-x;
				}
			}
			else{
				y=0;
				if(sum-y>=m){
					x=m-1;
					y=sum-(m-1);
				}
				else{
					x=sum-y;
				}
			}
			while(x>=0&&y>=0){
				if(x<m&&y<n){
					list.add(matrix[x][y]);
				}
				if(isOdd==true){
					x++;	
				}
				else{
					x--;
				}
				y=sum-x;
			}
			if(isOdd==true){
				isOdd=false;
			}
			else{
				isOdd=true;
			}
			sum++;
		}
		int[] result=new int[list.size()];
		for(int i=0;i<list.size();i++){
			result[i]=list.get(i);
		}
		return result;
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Diagonal_Traverse_498 d=new Diagonal_Traverse_498();
		int[][] matrix=new int[][]{
				{1,2,3},
				{4,5,6},
				{7,8,9},
				{10,11,12}
		};
		System.out.println(Arrays.toString(d.findDiagonalOrder(matrix)));
	}

}

下面看大神的方法:
I don't think this is a hard problem. It is easy to figure out the walk pattern. Anyway...
Walk patterns:

  • If out of bottom border (row >= m) then row = m - 1; col += 2; change walk direction.
  • if out of right border (col >= n) then col = n - 1; row += 2; change walk direction.
  • if out of top border (row < 0) then row = 0; change walk direction.
  • if out of left border (col < 0) then col = 0; change walk direction.
  • Otherwise, just go along with the current direction.

Time complexity: O(m * n), m = number of rows, n = number of columns.
Space complexity: O(1).

public class Solution {
    public int[] findDiagonalOrder(int[][] matrix) {
        if (matrix == null || matrix.length == 0) return new int[0];
        int m = matrix.length, n = matrix[0].length;
        
        int[] result = new int[m * n];
        int row = 0, col = 0, d = 0;
        int[][] dirs = {{-1, 1}, {1, -1}};
        
        for (int i = 0; i < m * n; i++) {
            result[i] = matrix[row][col];
            row += dirs[d][0];
            col += dirs[d][1];
            
            if (row >= m) { row = m - 1; col += 2; d = 1 - d;}
            if (col >= n) { col = n - 1; row += 2; d = 1 - d;}
            if (row < 0)  { row = 0; d = 1 - d;}
            if (col < 0)  { col = 0; d = 1 - d;}
        }
        
        return result;
    }
}
以例子来演示这段程序:

       0     1     2

0     1     2     3

1     4     5     6

2     7     8     9

3    10   11   12


matrix[0][0]=1放到result,row=-1,col=1,row=0,d=1

matrix[0][1]=2放到result,row=1,col=0

matrix[1][0]=4放到result,row=2,col=-1,col=0,d=0

matrix[2][0]=7放到result,row=1,col=1

matrix[1][1]=5放到result,row=0,col=2

matrix[0][2]=3放到result中,row=-1,col=3,col=2,row=1,d=1

matrix[2][1]=6放到result中,row=2,col=1

matrix[1][2]=8放到result中,row=3,col=0

matrix[3][0]=10放到result中,row=4,col=-1,row=3,col=1,d=0

matrix[3][1]=11放到result中,row=2,col=2

matrix[2][2]=9放到result中,row=1,col=3,col=2,row=3,d=1

matrix[3][2]=12放到result中,row=4,col=1,row=3,col=3,d=0



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值