之字形打印矩阵
一、题目
给你一个大小为 m x n
的矩阵 mat
,请以对角线遍历的顺序,用一个数组返回这个矩阵中的所有元素。
也就是按照 “之” 字形的方式打印这个矩阵
1 2
| mat = [[1,2,3],[4,5,6],[7,8,9]] 输出:[1,2,4,7,5,3,6,8,9]
|
二、思路
我们可以看到其实就是按照对角线来打印。我们选取两个坐标。
第一个坐标从 (0,0)
位置,先遍历行,到达行结尾了再遍历列。如下:
1
| (0,0) -> (0,1) -> (0,2) -> (0,3) -> (1,3) -> (2,3) -> (3,3)
|
第二个坐标从 (0,0)
位置,先遍历列,达到列结尾了再遍历行。如下:
1
| (0,0) -> (1,0) -> (2,0) -> (3,0) -> (3,1) -> (3,2) -> (3,3)
|
我们只需要每次读取两个坐标之间的元素,这两个坐标之间的元素就是对角线之间的元素。遍历顺序我们可以使用一个 bool 值来区分,每次取反就可以了
三、代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| #include <vector> #include <iostream>
class Solution { public: std::vector<int> findDiagonalOrder(const std::vector<std::vector<int>>& mat) { std::vector<int> res; if (mat.empty()) { return res; } int row = mat.size() - 1, line = mat[0].size() - 1; int tr = 0, tc = 0; int dr = 0, dc = 0; bool flag = true; for (; tr <= row && tc <= line && dr <= row && dc <= line;) { int i = flag ? dr : tr; int j = flag ? dc : tc; for (;;) { res.push_back(mat[i][j]); if (flag) { i--, j++; if (i < tr && j > tc) { break; } } else { i++, j--; if (i > dr && j < dc) { break; } } } if (tc == line) { tr++; } else { tc++; } if (dr == row) { dc++; } else { dr++; } flag = !flag; } return res; } };
void print_vec(const std::vector<int>& res) { for (const auto& x : res) { std::cout << x << " "; } std::cout << std::endl; }
int main() { Solution s; std::vector<std::vector<int>> mat{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; auto res = s.findDiagonalOrder(mat); print_vec(res); return 0; }
|
时间复杂度:O(N*N)
,空间复杂度:O(N*N)