美团二面算法题:沿对角线遍历二维数组

美团二面的时候面试官出了这道题,一起来看下:

实现一个函数,沿对角线遍历二维数组

例如:
[
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
打印输出:
[3, 2, 6, 1, 5, 9, 4, 8, 7]

之前没碰到过对角线遍历的,只做过 Leetcode 48 旋转图像 这样找规律的题。当时没想出来,只写了个伪代码大致说了下思路(还望面试官手下留情 )。昨天在解 N皇后 问题的时候,需要遍历二维数组对角线上的元素,这道题突然来了思路,下面把解题思路跟大家分享下。

这道题的核心就是要实现一个函数 diagonalTraverse ,给定某个元素坐标,然后沿着右下角的方向进行遍历。例如给定的元素是 2 ,那就按 2 -> 6 的顺序进行遍历;给定的元素是 1 ,按 1 -> 5 -> 9 的顺序遍历。

美团二面算法题:沿对角线遍历二维数组_第1张图片

右下角方向遍历其实很简单,每次给当前元素的横坐标和纵坐标分别 + 1 ,就可以实现了, diagonalTraverse 函数的实现如下:

public List diagonalTraverse(int x, int y, int n, int m) {
    List list = new ArrayList<>();
    while (x <= n && y <= m) {
        list.add(arr[x][y]);
        x++;
        y++;
    }
    return list;
}
xy 表示当前元素的坐标, nm 分别代表 arr.length-1arr[0].length-1
在遍历的时候要注意不能越界

有了这个函数之后,我们只要按照下图从右到左,从上到下的顺序给它传入边界元素坐标,就可以实现题目要求的对角线遍历的效果了。

美团二面算法题:沿对角线遍历二维数组_第2张图片

从上图可以看出来,传入坐标的时候分两次比较好处理,第一次遍历水平方向(3 -> 2 -> 1),第二次遍历垂直方向(4 -> 7)。flatArray 函数的实现如下:

public List flatArray(int[][] matrix) {
    this.arr = matrix;
    final int n = arr.length - 1;
    final int m = arr[0].length - 1;
    List res = new ArrayList<>(); // 保存遍历结果
    
    for (int i=m; i>=0; i--) {
        // 遍历水平方向
        List list = diagonalTraverse(0, i, n, m);
        res.addAll(list);
    }
    
    for (int i=1; i<=n; i++) {
        // 遍历垂直方向
        List list = diagonalTraverse(i, 0, n, m);
        res.addAll(list);
    }
    
    return res;
}

今天的文章就到这里,完整代码可以看我的 GitHub :

https://github.com/Jiacheng78...

你可能感兴趣的:(前端算法-数据结构)