LeetCode刷题篇——矩阵篇

旋转矩阵

题目

不使用额外空间,将二维矩阵顺时针旋转90度
链接

思路

先将矩阵中的元素左右交换,再沿着对角线交换

class Solution {
    
    
    public void rotate(int[][] matrix) {
    
    
        int len = matrix.length;
        if (len == 1) {
    
    
            return;
        }
        for (int i = 0; i < len; i++) {
    
    
            for (int j = 0; j < len / 2; j++) {
    
    
                swap(matrix, i, j, i, len - j - 1);
            }
        }
        for (int i = 0; i < len; i++) {
    
    
            for (int j = 0; j < len - i; j++) {
    
    
                swap(matrix, i, j, len - j - 1, len - i -1);
            }
        }
    }

  	// 交换矩阵中的两个元素
    private void swap(int[][] matrix, int x1, int y1, int x2, int y2) {
    
    
        int tmp = matrix[x1][y1];
        matrix[x1][y1] = matrix[x2][y2];
        matrix[x2][y2] = tmp;
    }
}

螺旋矩阵(顺时针打印矩阵)

题目

顺时针获取矩阵中的元素,返回一个list
链接

思路

定义上下左右四个分割线,当走完一行或者一列对应的分割线就移动,当两个分割线相撞时就表示遍历结束了

class Solution {
    
    
    public List<Integer> spiralOrder(int[][] matrix) {
    
    
        int rows = matrix.length;
        int cols = matrix[0].length;
      	// 定义上、左、右、下四条分割线
        int below = 0, left = 0, right = cols - 1, bottom = rows - 1;
        List<Integer> list = new ArrayList<>();
        while (true) {
    
    
          	// 从左到右遍历
            for (int i = left; i <= right; i++) {
    
    
                list.add(matrix[below][i]);
            }
            if (below++ == bottom) {
    
    
                break;
            }
          	// 从上到下遍历
            for (int i = below; i <= bottom; i++) {
    
    
                list.add(matrix[i][right]);
            }
            if (right-- == left) {
    
    
                break;
            }
          	// 从右到左遍历
            for (int i = right; i >= left; i--) {
    
    
                list.add(matrix[bottom][i]);
            }
            if (bottom-- == below) {
    
    
                break;
            }
          	// 从下到上遍历
            for (int i = bottom; i >= below; i--) {
    
    
                list.add(matrix[i][left]);
            }
            if (left++ == right) {
    
    
                break;
            }
        }
        return list;
    }
}

矩阵中的路径

题目

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

链接

思路

深度优先遍历,对矩阵中的每个元素上下左右四个方向依次尝试

class Solution {
    
    
    public boolean exist(char[][] board, String word) {
    
    
        char[] words = word.toCharArray();
        for (int i = 0; i < board.length; i++) {
    
    
            for (int j = 0; j < board[0].length; j++) {
    
    
                if (dfs(board, words, i, j, 0)) {
    
    
                    return true;
                }
            }
        }
        return false;
    }
	
	// k记录成功匹配的字母个数
    private boolean dfs(char[][] board, char[] words, int i, int j, int k) {
    
    
    	// 数组越界或当前字符不在目标字符串内,直接返回false
        if (i < 0 || i >= board.length || j < 0 || j >= board[0].length || board[i][j] != words[k]) {
    
    
            return false;
        }
        if (words.length == k + 1) {
    
    
            return true;
        }
        // 更改值表示当前位置已访问过
        board[i][j] = '\0';
        boolean res = dfs(board, words, i + 1, j, k + 1) || dfs(board, words, i - 1, j, k + 1) || dfs(board, words, i, j + 1, k + 1) || dfs(board, words, i, j - 1, k + 1);
        // 恢复为初始值
        board[i][j] = words[k];
        return res;
    }
}

搜索二维矩阵

题目

判断二维矩阵中是否存在目标值,该矩阵每行递增,每列递增
链接

思路

每次将矩阵右上角的值与目标值比较,若该值大于目标值,表示目标值在该行中;若该值小于目标值,则排除当前行,重复操作直至找到目标值

class Solution {
    
    
    public boolean searchMatrix(int[][] matrix, int target) {
    
    
        int row = matrix.length;
        int col = matrix[0].length;
        int r = 0, c = col - 1;
        while (r < row && c >= 0) {
    
    
            if (matrix[r][c] == target) {
    
    
                return true;
            } else if (matrix[r][c] > target) {
    
    
                c--;
            } else {
    
    
                r++;
            }
        }
        return false;
    }
}

矩阵置零

题目

给定一个二维矩阵,若某元素为0,则对应的行和列的全部元素都要改为0,请原地修改矩阵
链接

思路

遍历矩阵除第一行第一列以外的所有元素,若某元素为0,则将其对应的第一行和第一列位置的值改为0,相当于一个标记,表示对应的行和列后续都要改为0;但第一行和第一列可能原本就存在0,会和标记冲突,因此要先遍历第一行和第一列,用两个布尔型变量记录第一行和第一列是否要置零

class Solution {
    
    
    public void setZeroes(int[][] matrix) {
    
    
    	// 记录第一行和第一列是否要置为0
        boolean rowZero = false;
        boolean colZero = false;
        int i = 0, j = 0;
        for (i = 0; i < matrix[0].length; i++) {
    
    
            if (matrix[0][i] == 0) {
    
    
                rowZero = true;
                break;
            }
        }
        for (j = 0; j < matrix.length; j++) {
    
    
            if (matrix[j][0] == 0) {
    
    
                colZero = true;
                break;
            }
        }
        for (i = 1; i < matrix.length; i++) {
    
    
            for (j = 1; j < matrix[0].length; j++) {
    
    
            	// 若某元素为0,将第一行和第一列的对应位置置为0,相当于标记
                if (matrix[i][j] == 0) {
    
    
                    matrix[i][0] = 0;
                    matrix[0][j] = 0;
                }
            }
        }
        for (i = 1; i < matrix.length; i++) {
    
    
            for (j = 1; j < matrix[0].length; j++) {
    
    
            	// 根据标记对相应的行和列置零
                if (matrix[i][0] == 0 || matrix[0][j] == 0) {
    
    
                    matrix[i][j] = 0;
                }
            }
        }
        // 根据布尔变量决定第一行和第一列是否置零
        if (rowZero) {
    
    
            for (i = 0; i < matrix[0].length; i++) {
    
    
                matrix[0][i] = 0;
            }
        }
        if (colZero) {
    
    
            for (j = 0; j < matrix.length; j++) {
    
    
                matrix[j][0] = 0;
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/wzc3614/article/details/129570411