Matrix Zigzag Traversal

Question

  1. Given a matrix of m x n elements (m rows, n columns),
  2. return all elements of the matrix in ZigZag-order.
  3. Example
  4. Given a matrix:
  5. [
  6. [1, 2, 3, 4],
  7. [5, 6, 7, 8],
  8. [9,10, 11, 12]
  9. ]
  10. return [1, 2, 5, 9, 6, 3, 4, 7, 10, 11, 8, 12]

题解

按之字形遍历矩阵,纯粹找下标规律。以题中所给范例为例,设(x, y)为矩阵坐标,按之字形遍历有如下规律:

  1. (0, 0)
  2. (0, 1), (1, 0)
  3. (2, 0), (1, 1), (0, 2)
  4. (0, 3), (1, 2), (2, 1)
  5. (2, 2), (1, 3)
  6. (2, 3)

可以发现其中每一行的坐标之和为常数,坐标和为奇数时 x 递增,为偶数时 x 递减。

Java - valid matrix index second

  1. public class Solution {
  2. /**
  3. * @param matrix: a matrix of integers
  4. * @return: an array of integers
  5. */
  6. public int[] printZMatrix(int[][] matrix) {
  7. if (matrix == null || matrix.length == 0) return null;
  8. int m = matrix.length - 1, n = matrix[0].length - 1;
  9. int[] result = new int[(m + 1) * (n + 1)];
  10. int index = 0;
  11. for (int i = 0; i <= m + n; i++) {
  12. if (i % 2 == 0) {
  13. for (int x = i; x >= 0; x--) {
  14. // valid matrix index
  15. if ((x <= m) && (i - x <= n)) {
  16. result[index] = matrix[x][i - x];
  17. index++;
  18. }
  19. }
  20. } else {
  21. for (int x = 0; x <= i; x++) {
  22. if ((x <= m) && (i - x <= n)) {
  23. result[index] = matrix[x][i - x];
  24. index++;
  25. }
  26. }
  27. }
  28. }
  29. return result;
  30. }
  31. }

Java - valid matrix index first

  1. public class Solution {
  2. /**
  3. * @param matrix: a matrix of integers
  4. * @return: an array of integers
  5. */
  6. public int[] printZMatrix(int[][] matrix) {
  7. if (matrix == null || matrix.length == 0) return null;
  8. int m = matrix.length - 1, n = matrix[0].length - 1;
  9. int[] result = new int[(m + 1) * (n + 1)];
  10. int index = 0;
  11. for (int i = 0; i <= m + n; i++) {
  12. int upperBoundx = Math.min(i, m); // x <= m
  13. int lowerBoundx = Math.max(0, i - n); // lower bound i - x(y) <= n
  14. int upperBoundy = Math.min(i, n); // y <= n
  15. int lowerBoundy = Math.max(0, i - m); // i - y(x) <= m
  16. if (i % 2 == 0) {
  17. // column increment
  18. for (int y = lowerBoundy; y <= upperBoundy; y++) {
  19. result[index] = matrix[i - y][y];
  20. index++;
  21. }
  22. } else {
  23. // row increment
  24. for (int x = lowerBoundx; x <= upperBoundx; x++) {
  25. result[index] = matrix[x][i - x];
  26. index++;
  27. }
  28. }
  29. }
  30. return result;
  31. }
  32. }

源码分析

矩阵行列和分奇偶讨论,奇数时行递增,偶数时列递增,一种是先循环再判断索引是否合法,另一种是先取的索引边界。

复杂度分析

后判断索引是否合法的实现遍历次数为 1 + 2 + … + (m + n) = O((m+n)^2), 首先确定上下界的每个元素遍历一次,时间复杂度 O(m \cdot n). 空间复杂度都是 O(1).

Reference