首页 > 编程语言 >【Java完整版 面试必备】Leetcode Top100题目和答案-矩阵篇

【Java完整版 面试必备】Leetcode Top100题目和答案-矩阵篇

时间:2024-07-03 12:00:16浏览次数:20  
标签:layer Java matrix int 元素 矩阵 length 完整版 Top100

目录

以下摘自leetcode Top100精选题目-矩阵篇​

矩阵置零

螺旋矩阵

旋转图像

搜索二维矩阵II


以下摘自leetcode Top100精选题目-矩阵篇

矩阵置零

给定一个 m x n 的矩阵,如果一个元素为 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法

示例:

输入:matrix = [[1,1,1],[1,0,1],[1,1,1]]
输出:[[1,0,1],[0,0,0],[1,0,1]]

Solution:

    先遍历矩阵,记录下需要置零的行和列,再遍历一遍矩阵,根据记录的信息来决定哪些元素需要置零。这种方法避免了重复遍历矩阵中的每个元素来检查其行或列是否需要置零。

public void setZeroes(int[][] matrix) {
    int m = matrix.length; // 矩阵的行数
    int n = matrix[0].length; // 矩阵的列数
    
    // 使用布尔数组标记哪些行和列需要置零
    boolean[] rowFlags = new boolean[m];
    boolean[] colFlags = new boolean[n];
    
    // 遍历矩阵,标记需要置零的行和列
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            if (matrix[i][j] == 0) {
                rowFlags[i] = true;
                colFlags[j] = true;
            }
        }
    }
    
    // 根据标记的信息,将对应行和列置零
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            if (rowFlags[i] || colFlags[j]) {
                matrix[i][j] = 0;
            }
        }
    }
}

先通过两个布尔数组rowFlagscolFlags来分别标记哪些行和列需要被置零。在第一遍遍历中,如果发现某个元素为0,就将其所在的行和列对应的标记设为true。在第二遍遍历时,检查每个元素所在行和列的标记,如果任一标记为true,则将该元素置为0。

螺旋矩阵

给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。

示例:

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]

Solution:

要按顺时针螺旋顺序打印矩阵中的所有元素,可以使用四个指针分别跟踪当前层的上、下、左、右边界的移动。

public List<Integer> spiralOrder(int[][] matrix) {
    List<Integer> result = new ArrayList<>();
    if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
        return result;
    }
    int rows = matrix.length, columns = matrix[0].length;
    int top = 0, bottom = rows - 1, left = 0, right = columns - 1;

    while (top <= bottom && left <= right) {
        // 从左到右打印顶部一行
        for (int i = left; i <= right; i++) {
            result.add(matrix[top][i]);
        }
        top++; // 缩小顶部边界

        // 从上到下打印右侧一列
        for (int i = top; i <= bottom; i++) {
            result.add(matrix[i][right]);
        }
        right--; // 缩小右侧边界

        if (top <= bottom) { // 防止只有单行或单列时重复打印
            // 从右到左打印底部一行
            for (int i = right; i >= left; i--) {
                result.add(matrix[bottom][i]);
            }
            bottom--; // 缩小底部边界
        }

        if (left <= right) { // 同样防止只有单行或单列时重复打印
            // 从下到上打印左侧一列
            for (int i = bottom; i >= top; i--) {
                result.add(matrix[i][left]);
            }
            left++; // 缩小左侧边界
        }
    }
    return result;
}

先检查输入矩阵是否为空或无元素,初始化四个边界指针。进入一个循环,只要顶部边界不大于底部边界且左边界不大于右边界,就继续执行。在循环内部,按照顺时针顺序遍历当前层的四个边,并在遍历完每一侧后相应地调整边界。当所有层遍历完毕,返回结果列表,其中包含矩阵中所有元素的顺时针螺旋顺序。 

旋转图像

给定一个 × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。

你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。

示例:

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[[7,4,1],[8,5,2],[9,6,3]]

Solution:

要原地旋转一个n×n的二维矩阵90度,可以遵循以下步骤:

  1. 按照层来进行操作,首先处理最外层(即第一行到最后一行,但不包括第一列和最后一列)。
  2. 对于每层中的每个元素,将其与它所要交换到的位置的元素进行交换。具体来说,假设当前处理的元素坐标为(x, y),那么它将被交换到(y, n-x-1)位置,其中n是矩阵的边长。
public void rotate(int[][] matrix) {
    int n = matrix.length;
    // 层数,最外层是0层,向内依次递增
    for (int layer = 0; layer < n / 2; layer++) {
        // 每一层需要交换的元素个数,注意排除边界
        int len = n - 2 * layer - 1;
        for (int i = 0; i < len; i++) {
            // 保存左上角的元素,用于后续的交换
            int temp = matrix[layer][layer + i];
            // 左上 -> 右上
            matrix[layer][layer + i] = matrix[n - 1 - layer - i][layer];
            // 右上 -> 右下
            matrix[n - 1 - layer - i][layer] = matrix[n - 1 - layer][n - 1 - layer - i];
            // 右下 -> 左下
            matrix[n - 1 - layer][n - 1 - layer - i] = matrix[layer + i][n - 1 - layer];
            // 左下 -> 左上
            matrix[layer + i][n - 1 - layer] = temp;
        }
    }
}

     先计算出需要交换的层数(矩阵半径),然后对于每一层,计算出需要交换的元素个数,并执行旋转交换。通过这种方式,矩阵可以在原地完成90度的顺时针旋转。 

搜索二维矩阵II

编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:

  • 每行的元素从左到右升序排列。
  • 每列的元素从上到下升序排列

示例:

输入:matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]], target = 5
输出:true

Solution:

在有序的二维矩阵中搜索目标值,可以利用矩阵的有序特性,从矩阵的右上角或左下角开始搜索,这样每次比较都可以排除一行或一列。

public boolean searchMatrix(int[][] matrix, int target) {
    if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
        return false;
    }
    
    int rows = matrix.length;
    int cols = matrix[0].length;
    int row = 0; // 起始行
    int col = cols - 1; // 起始列(右上角)
    
    while (row < rows && col >= 0) {
        if (matrix[row][col] == target) {
            return true; // 找到目标值
        } else if (matrix[row][col] < target) {
            row++; // 目标值更大,移动到下一行
        } else {
            col--; // 目标值更小,移动到左一列
        }
    }
    
    return false; // 没有找到目标值
}

先检查矩阵是否为空或无列,初始化行和列的指针,从矩阵的右上角开始。在循环中,如果找到了目标值,直接返回true。如果当前元素小于目标值,则向下移动到下一行(因为同一列的元素从上到下是递增的)。如果当前元素大于目标值,则向左移动到前一列(因为同一行的元素从左到右是递增的)。如果循环结束还没有找到目标值,则返回false。 

标签:layer,Java,matrix,int,元素,矩阵,length,完整版,Top100
From: https://blog.csdn.net/weixin_43298211/article/details/140101879

相关文章

  • JAVA妇产科专科电子病历系统源码,前端框架:Vue,ElementUI
    JAVA妇产科专科电子病历系统源码,前端框架:Vue,ElementUI孕产妇健康管理信息管理系统是一种将孕产妇健康管理信息进行集中管理和存储的系统。通过建立该系统,有助于提高孕产妇健康管理的效率和质量,减少医疗事故发生的可能性,管理医疗资源,保证孕产妇得到及时、准确的医疗服务。该系......
  • java的常用技术
    1、java集合(Iterable、List、Set、Map,JUC安全性集合)2、hashmap(原理,延申)、ConcurrentHashMap(锁:1.8是synchronized+node,1.7是segment)3、乐观锁(比较/交换)AtomicInteger是Java中的一个原子类4、悲观锁synchronized5、线程池运行状态运行过程其他......
  • Java中semaphore的具体解释产生原因和使用场景
    Semaphore(信号量)信号量(Semaphore)是一种用于控制多个线程对共享资源访问的同步机制。它实质上是一个计数器,可以用来限制能够访问某些资源的线程数量。信号量可以是二进制的(只允许一个线程访问)或计数的(允许多个线程访问,具体数目由信号量的值决定)。信号量产生的原因信号量最......
  • Java基础——常用类库
    在Java编程的世界里,掌握并熟练使用类库是提高开发效率和代码质量的关键。本文将深入探讨几个常用的Java类库,包括它们的功能、应用场景以及如何有效利用它们来优化你的项目。1. CollectionsFramework简介:Java的集合框架(CollectionsFramework)提供了实现数据结构如列表、集......
  • Java基础——线程
    在当今的软件开发中,多线程技术是提升程序性能、实现并发处理的关键所在。Java作为一款广泛应用的编程语言,其内置的多线程支持为开发者提供了强大的工具箱。本文将深入探讨Java中的线程概念,包括线程的创建、生命周期、同步机制以及一些常见的问题和解决方案。1.线程的基本概念......
  • Java基础——日期操作类
    在Java中,处理日期和时间一直是一个复杂但又至关重要的任务。从早期的java.util.Date和java.util.Calendar,到Java8引入的java.time包,我们见证了日期和时间API的显著改进。本文将带你深入了解这些变化,并重点介绍如何使用java.time包中的类进行高效、准确的日期操作。1.回顾过......
  • redis - [05] Java & Redis
    题记部分 一、准备工作下载jedis.jar或者在maven配置文件中配置jar包依赖 二、连接redisimportredis.clients.jedis.Jedis;publicclassRedisJava{publicstaticvoidmain(String[]args){//连接本地的Redis服务Jedisjedis=newJed......
  • 55、Flink 中使用 Java Lambda 表达式详解
    1)概述1.注意Flink支持对JavaAPI的所有算子使用Lambda表达式,但是,当Lambda表达式使用Java泛型时,需要显式地声明类型信息。2.示例和限制示例:map()函数使用Lambda表达式计算输入值的平方。不需要声明map()函数的输入i和输出参数的数据类型,因为Java编......
  • 用JavaScript来优化数独验证的过程
    问题陈述给定一个9x9数独棋盘,确定它是否有效。棋盘由一个二维数组表示,其中空单元格用表示'.'。有效的数独棋盘满足以下规则:每行必须包含数字1–9,且不能重复。每列必须包含数字1–9,且不能重复。九个3x3子网格中的每一个都必须包含数字1–9,且不能重复。初步方法一种简......
  • 有手就会的 Java 处理压缩文件
    @目录前言背景第一步:编写代码1.1请求层1.2业务处理层1.3新增配置第二步:解压缩处理2.1引入依赖2.2解压缩工具类总结前言请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i、提示:以下是本篇文章正文内容,下面案例可供参考背景在项目出现上传文件,其中文件包含压缩包,......