按照对角线的方式遍历矩阵 Diagonal Traverse

问题:

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:

 

10003729_kVOC.png

Note:

  1. The total number of elements of the given matrix will not exceed 10,000.

 解决:

① 

移动的方向不再是水平或竖直方向,而是对角线方向,那么每移动一次,横纵坐标都要变化,向右上移动的话要坐标加上[-1, 1],向左下移动的话要坐标加上[1, -1],那么难点在于我们如何处理越界情况,越界后遍历的方向怎么变换。

向右上和左下两个对角线方向遍历的时候都会有越界的可能,但是除了左下角和右上角的位置越界需要改变两个坐标之外,其余的越界只需要改变一个。

那么我们就先判断要同时改变两个坐标的越界情况,即在右上角和左下角的位置。如果在右上角位置还要往右上走时,那么要移动到它下面的位置的,那么如果col超过了n-1的范围,那么col重置为n-1,并且row自增2,然后改变遍历的方向。同理如果row超过了m-1的范围,那么row重置为m-1,并且col自增2,然后改变遍历的方向。然后我们再来判断一般的越界情况,如果row小于0,那么row重置0,然后改变遍历的方向。同理如果col小于0,那么col重置0,然后改变遍历的方向。

class Solution { //10ms
    public int[] findDiagonalOrder(int[][] matrix) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return new int[]{};
        int m = matrix.length;
        int n = matrix[0].length;
        int row = 0;
        int col = 0;
        int k = 0;
        int[] res = new int[m * n];
        int[][] dirs = {{-1,1},{1,-1}};
        for (int i = 0;i < m * n;i ++){
            res[i] = matrix[row][col];
            row += dirs[k][0];
            col += dirs[k][1];
            if (row >= m){
                row = m - 1;
                col += 2;
                k = 1 - k;
            }
            if (col >= n){
                col = n - 1;
                row += 2;
                k = 1 - k;
            }
            if (row < 0){
                row = 0;
                k = 1 - k;
            }
            if (col < 0){
                col = 0;
                k = 1 - k;
            }
        }
        return res;
    }
}

② 根据横纵坐标之和的奇偶性来判断遍历的方向,然后对于越界情况再单独处理即可。

class Solution { //8ms
    public int[] findDiagonalOrder(int[][] matrix) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return new int[]{};
        int m = matrix.length;
        int n = matrix[0].length;
        int row = 0;
        int col = 0;
        int[] res = new int[m * n];
        for (int i = 0;i < m * n;i ++){
            res[i] = matrix[row][col];
            if ((row + col) % 2 == 0){
                if (col == n - 1){
                    row ++;
                }else if (row == 0){
                    col ++;
                }else {
                    row --;
                    col ++;
                }
            }else{
                if (row == m - 1) {
                    col++;
                }else if (col == 0){
                    row ++;
                }else {
                    row ++;
                    col --;
                }
            }
        }
        return res;
    }
}

转载于:https://my.oschina.net/liyurong/blog/1603740

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值