美团二面:498. 对角线遍历

498. 对角线遍历

题目描述:给你一个大小为 m x n 的矩阵 mat ,请以对角线遍历的顺序,用一个数组返回这个矩阵中的所有元素。

在这里插入图片描述

思路分析

思路分析

在这里插入图片描述

从上图可以得知:

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

    第一趟:1 的坐标(0, 0)。x + y == 0。
    第二趟:2 的坐标(1, 0),4 的坐标(0, 1)。x + y == 1。
    第三趟:7 的坐标(0, 2), 5 的坐标(1, 1),3 的坐标(2, 0)。第三趟 x + y == 2。
    第四趟:……

  • 每一趟都是 x 或 y 其中一个从大到小(每次减 1),另一个从小到大(每次加 1)。

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

    第二趟:2 的坐标(1, 0),4 的坐标(0, 1)。x + y == 1,x 初始值取 1,y 取 0。
    第四趟:6 的坐标(2, 1),8 的坐标(1, 2)。x + y == 3,x 初始值取 2,剩下的加到 y上,y 取 1。

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

    第二趟:2 的坐标(1, 0),4 的坐标(0, 1)。x 减到 0 为止。
    第四趟:6 的坐标(2, 1),8 的坐标(1, 2)。x 虽然才减到 1,但是 y 已经加到上限了。

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

代码实现

public int[] findDiagonalOrder(int[][] mat) {
    
    
    int m = mat.length,n = mat[0].length;
    List<Integer> temp = new ArrayList<>();

    int i = 0; // i = x + y
    while (i < m + n) {
    
    
        // 第 1,3,5... 趟
        int x1 = i < m ? i : m - 1;
        int y1 = i - x1;
        while (x1 >= 0 && y1 < n) {
    
    
            temp.add(mat[x1][y1]);
            x1--;
            y1++;
        }
        i++;
        if (i >= m + n) break;
        // 第 2,4,6... 趟
        int y2 = i < n ? i : n - 1;
        int x2 = i - y2;
        while (y2 >= 0 && x2 < m) {
    
    
            temp.add(mat[x2][y2]);
            x2++;
            y2--;
        }
        i++;
    }
    int[] result = new int[temp.size()];
    for (int j = 0; j < result.length; j++) {
    
    
        result[j] = temp.get(j);
    }
    return result;
}

猜你喜欢

转载自blog.csdn.net/qq_36389060/article/details/124253303
今日推荐