1、矩阵置 0

O(m+n)

定义长度分别为 m , n 的boolean数组,首次遍历时标记哪些数字为 0,第二次遍历时,如果辅助的数组为0,则第 i , j 为0.

  1. public void setZeroes(int[][] matrix) {
  2. int m = matrix.length, n = matrix[0].length;
  3. boolean[] row = new boolean[m];
  4. boolean[] col = new boolean[n];
  5. for (int i = 0; i < m; i++) {
  6. for (int j = 0; j < n; j++) {
  7. if (matrix[i][j] == 0) {
  8. row[i] = col[j] = true;
  9. // System.out.println("i: " + i);
  10. // System.out.println("j: " + j);
  11. }
  12. }
  13. }
  14. for (int i = 0; i < m; i++) {
  15. for (int j = 0; j < n; j++) {
  16. if (row[i] || col[j]) {
  17. matrix[i][j] = 0;
  18. }
  19. }
  20. }
  21. }

O(1)

复用原来二维数组的第一行和第一列,复用之前,先使用两个标记位判断第一行和第一列有没有为 0 的数字,其他逻辑与第一种方法类似,都是遍历然后根据标记位置0,最后根据标记位来处理第一行和第一列中 为0的元素。

  1. class Solution {
  2. public void setZeroes(int[][] matrix) {
  3. int m = matrix.length, n = matrix[0].length;
  4. boolean row0Flag = false, col0Flag = false;
  5. for (int i = 0; i < m; i++) {
  6. if (matrix[i][0] == 0) {
  7. col0Flag = true;
  8. break;
  9. }
  10. }
  11. for (int i = 0; i < n; i++) {
  12. if (matrix[0][i] == 0) {
  13. row0Flag = true;
  14. break;
  15. }
  16. }
  17. for (int i = 1; i < m; i++) {
  18. for (int j = 1; j < n; j++) {
  19. if (matrix[i][j] == 0) {
  20. matrix[i][0] = matrix[0][j] = 0;
  21. // System.out.println("i: " + i);
  22. // System.out.println("j: " + j);
  23. }
  24. }
  25. }
  26. for (int j = 1; j < n; j++) {
  27. if (matrix[0][j] == 0) {
  28. for (int i = 1; i < m; i++) {
  29. matrix[i][j] = 0;
  30. }
  31. }
  32. }
  33. for (int i = 0; i < m; i++) {
  34. if (matrix[i][0] == 0) {
  35. Arrays.fill(matrix[i], 0);
  36. }
  37. }
  38. if (col0Flag) {
  39. for (int j = 0; j < m; j++) {
  40. matrix[j][0] = 0;
  41. }
  42. }
  43. if (row0Flag) {
  44. Arrays.fill(matrix[0], 0);
  45. }
  46. }
  47. }

2、旋转图像

力扣

在矩阵中,可以使用矩阵的变换来解题,先以副对角线对称变换,然后再上下翻转,其次也可以主对角线翻转,然后左右翻转,本题按照副对角线进行反转

  1. class Solution {
  2. public void rotate(int[][] matrix) {
  3. int n = matrix.length;
  4. //副对角线变换
  5. for (int i = 0; i < n ; i++) {
  6. for (int j = 0; j < n-i; j++) { //
  7. int temp = matrix[i][j];
  8. matrix[i][j] = matrix[n - j - 1][n - i - 1]; //副对角线对称
  9. matrix[n - j -1][n - i - 1] = temp;
  10. }
  11. }
  12. // System.out.println(matrix[1][2]);
  13. //上限对折
  14. for (int i = 0; i < n / 2; i++) {
  15. for (int j = 0; j < n; j++) {
  16. int temp = matrix[i][j];
  17. matrix[i][j]=matrix[n - i-1][j];
  18. matrix[n - i-1][j] = temp;
  19. }
  20. }
  21. }
  22. }

3、搜索二维矩阵 ||

力扣

根据矩阵的每行每列都有顺序的特性,让起始数字放在数组的右上角,这样就可以根据大小限制方向:

  • 如果大于target — 下移
  • 小于 — 左移
  • 等于 返回true
  1. public boolean searchMatrix(int[][] matrix, int target) {
  2. int m = matrix.length, n = matrix[0].length;
  3. int x = 0, y = n - 1;
  4. while (x < m && y >= 0) {
  5. if (matrix[x][y] == target) {
  6. return true;
  7. }
  8. if (matrix[x][y] > target) {
  9. --y;
  10. }
  11. else {
  12. ++x;
  13. }
  14. }
  15. return false;
  16. }

image.png

image.png

4a00185f56be0a31c47c1373398b2f7.png