59. 螺旋矩阵 II

本题并不涉及到什么算法,就是模拟过程

这里使用一个左闭右开区间
使用四个边界去逐步缩小矩阵范围
image.png

  1. int[][] generateMatrix(int n) {
  2. int[][] matrix = new int[n][n];
  3. int upper_bound = 0, lower_bound = n - 1;
  4. int left_bound = 0, right_bound = n - 1;
  5. // 需要填入矩阵的数字
  6. int num = 1;
  7. while (num <= n * n) {
  8. if (upper_bound <= lower_bound) {
  9. // 在顶部从左向右遍历
  10. for (int j = left_bound; j <= right_bound; j++) {
  11. matrix[upper_bound][j] = num++;
  12. }
  13. // 上边界下移
  14. upper_bound++;
  15. }
  16. if (left_bound <= right_bound) {
  17. // 在右侧从上向下遍历
  18. for (int i = upper_bound; i <= lower_bound; i++) {
  19. matrix[i][right_bound] = num++;
  20. }
  21. // 右边界左移
  22. right_bound--;
  23. }
  24. if (upper_bound <= lower_bound) {
  25. // 在底部从右向左遍历
  26. for (int j = right_bound; j >= left_bound; j--) {
  27. matrix[lower_bound][j] = num++;
  28. }
  29. // 下边界上移
  30. lower_bound--;
  31. }
  32. if (left_bound <= right_bound) {
  33. // 在左侧从下向上遍历
  34. for (int i = lower_bound; i >= upper_bound; i--) {
  35. matrix[i][left_bound] = num++;
  36. }
  37. // 左边界右移
  38. left_bound++;
  39. }
  40. }
  41. return matrix;
  42. }

出错的地方

  • matrix[][]总是写错
  • 要明确left; right; up; down 的含义 他们是用来当界限逐渐去缩小区间范围的,就比如当left到rigth的过程中,我们让left自增,条件是left<=right 当我们for循环后需要让上边界缩小就是up++

54. 螺旋矩阵

按照59题的思路书写超出时间限制 (我写错了而已….太菜了)

  1. class Solution {
  2. public List<Integer> spiralOrder(int[][] matrix) {
  3. int m = matrix.length, n = matrix[0].length;
  4. int up= 0, down = m - 1;
  5. int left = 0, right = n - 1;
  6. List<Integer> res = new LinkedList<>();
  7. //当res.size==m*n时说明遍历完整个数组
  8. while (res.size() < m*n){
  9. if(up <= down) {
  10. for (int i = left; i <= right; i++) {
  11. res.add(matrix[up][i]);
  12. }
  13. up++;
  14. }
  15. if(left<=right) {
  16. for (int i = up; i <= down; i++) {
  17. res.add(matrix[i][right]);
  18. }
  19. right--;
  20. }
  21. if (up <= down) {
  22. for (int i = right; i >= left; i--) {
  23. res.add(matrix[down][i]);
  24. }
  25. down--;
  26. }
  27. if (left<=right) {
  28. for (int i = down; i >= up; i--) {
  29. res.add(matrix[i][left]);
  30. }
  31. left++;
  32. }
  33. }
  34. return res;
  35. }
  36. }

48. 旋转图像(此题并非螺旋矩阵,只是一个二维数组的旋转)

反转二维数组90°

先沿着对角线反转
image.png
然后每一行反转
image.png

class Solution {
    public void rotate(int[][] matrix) {
        int n = matrix.length;
        // 先沿对角线反转二维矩阵
        for (int i = 0; i < n; i++) {
            for (int j = i; j < n; j++) {
                // swap(matrix[i][j], matrix[j][i]);
                int temp = matrix[i][j];
                matrix[i][j] = matrix[j][i];
                matrix[j][i] = temp;
            }
        }
        // 然后反转二维矩阵的每一行
        for (int[] row : matrix) {
            reverse(row);
        }
    }

    // 反转一维数组
    void reverse(int[] arr) {
        int i = 0, j = arr.length - 1;
        while (j > i) {
            // swap(arr[i], arr[j]);
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
            i++;
            j--;
        }
    }
}

同样的逆时针旋转90°只要通过另一条对角线镜像对称矩阵,然后再反转每一行,就得到了逆时针旋转矩阵的结果:
image.png
翻译成代码如下:

// 将二维矩阵原地逆时针旋转 90 度
void rotate2(int[][] matrix) {
    int n = matrix.length;
    // 沿左下到右上的对角线镜像对称二维矩阵
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n - i; j++) {
            // swap(matrix[i][j], matrix[n-j-1][n-i-1])
            int temp = matrix[i][j];
            matrix[i][j] = matrix[n - j - 1][n - i - 1];
            matrix[n - j - 1][n - i - 1] = temp;
        }
    }
    // 然后反转二维矩阵的每一行
    for (int[] row : matrix) {
        reverse(row);
    }
}

void reverse(int[] arr) { /* 见上文 */}