[Leetcode] 498. Diagonal Traverse

本文提供两种解决方案,实现对二维矩阵的对角线遍历。第一种方法直接遍历,第二种方法通过暂存列表实现统一的上右遍历方式。详细解析了遍历逻辑与时间、空间复杂度。

Link: https://leetcode.com/problems/diagonal-traverse/

Solution 1:
矩阵最外围的数字是每一次traverse slices的head
偶数位的traverse方向是up right
奇数位的方向是down left
重点是要找到最外围数字的遍历方法

class Solution {
    public int[] findDiagonalOrder(int[][] matrix) {
        if(matrix.length == 0 || matrix[0].length == 0){
            return new int[0];
        }
        
        int rows = matrix.length; 
        int cols = matrix[0].length;
        int r,c;
        int scan = rows+cols-1; // head of slices
        int index = 0;
        int[] res = new int[rows*cols];
        for(int i=0; i<scan; i++){
            if(i%2 == 0){ // up right
            // 矩阵的左边和下边
                r = i < rows ? i : rows - 1;
                c = i < rows ? 0 : i - (rows - 1);
                while(r >= 0 && c < cols){
                    res[index++] = matrix[r--][c++];
                }
            }else{ // down left
            // head在矩阵的上边和右边
                r = i < cols ? 0 : i - (cols - 1);
                c = i < cols ? i : cols - 1;
                while(r < rows && c >= 0){
                    res[index++] = matrix[r++][c--];
                }
            }
        }
        return res;
    }
}

TC: O(rows * cols)
SC: O(1) (没有使用extra space)

Solution 2:
统一使用up-right对矩阵进行遍历,将slice暂存在list中,偶数位直接存入res,奇数位reserve后存入

class Solution {
    public int[] findDiagonalOrder(int[][] matrix) {
        if(matrix.length == 0 || matrix[0].length == 0){
            return new int[0];
        }
        
        int rows = matrix.length; 
        int cols = matrix[0].length;
        int r,c;
        int scan = rows+cols-1; // head of slices
        int index = 0;
        int[] res = new int[rows*cols];
        
        // 全体up right的方式遍历,奇数列倒序存入res
        List<Integer> temp = new ArrayList<>();
        for(int i=0; i<scan; i++){
            // 遍历左边和下边, 统一用up right的方式存入temp
            // 每一次遍历后temp内的数字都要清空
            temp.clear();
            r = i < rows ? i : rows - 1;
            c = i < rows ? 0 : i - (rows - 1);
            while(r >= 0 && c < cols){
                temp.add(matrix[r--][c++]);
            }
            if(i%2 == 0){
                for(int j=0; j<temp.size(); j++){
                    res[index++] = temp.get(j);
                }
            } else {
                for(int j=temp.size()-1; j>=0; j--){
                    res[index++] = temp.get(j);
                }
            }
        }
        return res;
    }
}

TC: O(rows * cols)
SC: O(min(rows, cols)) (temp存储的最长个数)

方法二TC复杂度不如方法一:

  1. 在reverse奇数slice的时候会touch每个数字两次
  2. 在每次清空temp的时候还会用到O(temp.size())的时间
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值