力扣最热一百题——矩阵置零

news2024/12/23 0:13:33

目录

题目链接:73. 矩阵置零 - 力扣(LeetCode)

题目描述

示例

提示:

解法一:采用标记数组遍历处理

Java写法:

C++写法:

优化

解法二:优化解法之标记变量

Java写法:

总结


题目链接:73. 矩阵置零 - 力扣(LeetCode)

注:下述题目描述和示例均来自力扣

题目描述

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

示例

示例 1:

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

示例 2:

输入:matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]]
输出:[[0,0,0,0],[0,4,5,0],[0,3,1,0]]

提示:

  • m == matrix.length
  • n == matrix[0].length
  • 1 <= m, n <= 200
  • -2^{31} <= matrix[i][j] <= 2^{31} - 1


解法一:采用标记数组遍历处理

  1. 标记零的位置:首先遍历整个矩阵,找到所有为0的元素,并在辅助的标记数组中记录这些位置。这一步的作用是确保后续的置零操作不会影响还未检查到的位置。

  2. 执行置零操作:在标记完成后,再次遍历矩阵。对于标记数组中对应为0的位置,将原矩阵中该元素所在的整行和整列都置为0。

        整个过程的时间复杂度是O(MN),因为遍历了两次矩阵,而空间复杂度为O(MN),由于使用了额外的标记数组。

Java写法:

class Solution {
    public void setZeroes(int[][] matrix) {
        // 获取纵向的长度
        int lenY = matrix.length;
        // 获取横向的长度
        int lenX = matrix[0].length;
        // 定义标记数组用于标记0的位置
        int[][] isZero = new int[lenY][lenX];

        // 给标记数组赋值,寻找全部的0的位置
        for(int x=0;x < lenX; x++){
            for(int y=0;y < lenY;y++){
                if(matrix[y][x] == 0){
                    // 标记为0
                    isZero[y][x] = 1;
                }
            }
        }

        // 操作原数组,如果被标记数组标记为0的位置的xy方向全部置零
        for(int x=0;x < lenX; x++){
            for(int y=0;y < lenY;y++){
                if(isZero[y][x] == 1){
                    setXYZero(matrix,y,x);
                }
            }
        }
    }

    /**
     * 1 2 3
     * 4 0 6
     * 7 8 9
     * @param aimArr 置零方法,将x,y位置的横纵方向上的数全部置零
     * @param y
     * @param x
     */
    public void setXYZero(int[][] aimArr,int y,int x){
        for (int i = 0; i < aimArr[0].length; i++) {
            aimArr[y][i] = 0;
        }
        for (int i = 0; i < aimArr.length; i++) {
            aimArr[i][x] = 0;
        }
    }
}

C++写法:

class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        int lenY = matrix.size();            // 获取矩阵的行数
        int lenX = matrix[0].size();         // 获取矩阵的列数
        vector<vector<int>> isZero(lenY, vector<int>(lenX, 0)); // 定义标记数组

        // 标记数组赋值,寻找0的位置
        for(int x = 0; x < lenX; x++) {
            for(int y = 0; y < lenY; y++) {
                if(matrix[y][x] == 0) {
                    isZero[y][x] = 1; // 标记0
                }
            }
        }

        // 根据标记数组对矩阵进行置零操作
        for(int x = 0; x < lenX; x++) {
            for(int y = 0; y < lenY; y++) {
                if(isZero[y][x] == 1) {
                    setXYZero(matrix, y, x); // 置零
                }
            }
        }
    }

    // 将指定位置的行和列全部置零
    void setXYZero(vector<vector<int>>& aimArr, int y, int x) {
        for (int i = 0; i < aimArr[0].size(); i++) {
            aimArr[y][i] = 0; // 置零行
        }
        for (int i = 0; i < aimArr.size(); i++) {
            aimArr[i][x] = 0; // 置零列
        }
    }
};

优化

        但是我还看见了一种简化写法是官方给的我这里借着这个思路复写一下,大家可以去看官方题解。

class Solution {
    public void setZeroes(int[][] matrix) {
        int lenY = matrix.length;
        int lenX = matrix[0].length;

        // 使用第一行和第一列用于标记数组
        boolean[] isZeroX = new boolean[lenX];
        boolean[] isZeroY = new boolean[lenY];

        // 遍历数组寻找0的位置
        for(int i = 0; i < lenY; i++){
            for(int j = 0; j < lenX; j++){
                if(matrix[i][j] == 0){
                    // 找到了这个位置有0那么就设置标记数组
                    isZeroX[j] = true;
                    isZeroY[i] = true;
                }
            }
        }

        // 然后只要是发现位置上的行或列是包含0的那么就设置为0
        for(int i = 0; i < lenY; i++){
            for(int j = 0; j < lenX; j++){
                if(isZeroX[j] || isZeroY[i]){
                    matrix[i][j] = 0;
                }
            }
        }
    }
}


解法二:优化解法之标记变量

        如果优化,可以将空间复杂度降低到O(1),利用矩阵本身的某一行和某一列作为标记区域。

        优化后的算法不再使用额外的标记数组,而是通过矩阵的第一行和第一列来标记哪些行和列需要置零。具体优化步骤如下:

  1. 首先,检查矩阵的第一行和第一列是否有零,并记录下来。
  2. 然后,使用第一行和第一列作为标记区域,遍历其余部分矩阵,标记哪些行和列需要置零。
  3. 接着,根据第一行和第一列的标记信息,置零相应的行和列。
  4. 最后,检查第一行和第一列,必要时将它们置零。

Java写法:

class Solution {
    public void setZeroes(int[][] matrix) {
        // 获取矩阵的行列数
        int lenY = matrix.length;
        int lenX = matrix[0].length;

        // 标记第一行和第一列是否需要置零
        boolean firstRowZero = false;
        boolean firstColZero = false;

        // 检查第一列是否有零
        for (int y = 0; y < lenY; y++) {
            if (matrix[y][0] == 0) {
                firstColZero = true;
                break;
            }
        }

        // 检查第一行是否有零
        for (int x = 0; x < lenX; x++) {
            if (matrix[0][x] == 0) {
                firstRowZero = true;
                break;
            }
        }

        // 使用第一行和第一列作为标记
        for (int y = 1; y < lenY; y++) {
            for (int x = 1; x < lenX; x++) {
                if (matrix[y][x] == 0) {
                    matrix[y][0] = 0;
                    matrix[0][x] = 0;
                }
            }
        }

        // 置零操作(除去第一行和第一列)
        for (int y = 1; y < lenY; y++) {
            for (int x = 1; x < lenX; x++) {
                if (matrix[y][0] == 0 || matrix[0][x] == 0) {
                    matrix[y][x] = 0;
                }
            }
        }

        // 如果第一列需要置零
        if (firstColZero) {
            for (int y = 0; y < lenY; y++) {
                matrix[y][0] = 0;
            }
        }

        // 如果第一行需要置零
        if (firstRowZero) {
            for (int x = 0; x < lenX; x++) {
                matrix[0][x] = 0;
            }
        }
    }
}

        果然由于少了一次赋值为零的遍历,速度直接就上来了,加上用的也不是二维数组了,现在的速度更快了。


总结

哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈烦死了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2116909.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【鸿蒙HarmonyOS NEXT】UIAbility的生命周期

【鸿蒙HarmonyOS NEXT】UIAbility的生命周期 一、环境说明二、UIAbility的生命周期三、示例代码加以说明四、小结 一、环境说明 DevEco Studio 版本&#xff1a; API版本&#xff1a;以12为主 二、UIAbility的生命周期 概念&#xff1a; HarmonyOS中的UIAbility是一种包含…

入门pytorch

卷积神经网络模型 卷积神经网络&#xff08;简称 CNN&#xff09;是一种专为图像输入而设计的网络。它最明显的特征就是具有三个层次&#xff0c;卷积层&#xff0c;池化层&#xff0c;全连接层。 借用一张图&#xff0c;下图很好的表示了什么是卷积&#xff08;提取特征&…

机器学习:多种算法处理填充后的数据

在机器学习中&#xff0c;填充数据&#xff08;即处理缺失值&#xff09;后&#xff0c;选择合适的算法并优化模型以提高召回率是一个常见的任务。召回率是指模型正确识别的正例占所有实际正例的比例。 代码思路&#xff1a; 数据预处理&#xff1a; 导入填充后的数据 …

FastGPT自定义插件的icon

最近研究FastGPT的自定义插件&#xff0c;经过好几天的折磨&#xff0c;终于实现了一个简单的发送邮件功能&#xff0c;但是呢在使用的时候发现插件的icon是默认的fastgpt的logo&#xff0c;那肯定得自定义一个啊。直接说方法&#xff1a; 1、自定义插件下面的template.json文件…

zookeeper相关面试题

zk的数据同步原理&#xff1f;zk的集群会出现脑裂的问题吗&#xff1f;zk的watch机制实现原理&#xff1f;zk是如何保证一致性的&#xff1f;zk的快速选举leader原理&#xff1f;zk的典型应用场景zk中一个客户端修改了数据之后&#xff0c;其他客户端能够马上获取到最新的数据吗…

握 手 问 题

目录 一&#xff1a;问题描述 二&#xff1a;思路: 三&#xff1a;代码&#xff1a; 四&#xff1a;结果&#xff1a;1204 一&#xff1a;问题描述 小蓝组织了一场算法交流会议&#xff0c;总共有50 5050 人参加了本次会议。在会议上&#xff0c;大家进行了握手交流。按照…

excel如何删除某列或者某区域的重复数据

先&#xff0c;鼠标选中想要去除重复数据的某列或者某区域 然后&#xff0c;点击上方栏中的【数据】-【删除重复数据】&#xff1a; 之后&#xff0c;表格里只留下了无重复的数据

STM32(十一):ADC数模转换器实验

AD单通道&#xff1a; 1.RCC开启GPIO和ADC时钟。配置ADCCLK分频器。 2.配置GPIO&#xff0c;把GPIO配置成模拟输入的模式。 3.配置多路开关&#xff0c;把左面通道接入到右面规则组列表里。 4.配置ADC转换器&#xff0c; 包括AD转换器和AD数据寄存器。单次转换&#xff0c;连…

Kafka (快速)安装部署

文章目录 1、软件下载&配置环境1_JDK安装2_Zookeeper安装3_Kafka安装 2、单机安装1_配置主机名和IP映射2_单机Kafka配置 3、集群安装1_配置主机名和IP的映射关系2_时钟同步3_Zookeeper配置信息4_集群Kafka配置 4、kafka的其他脚本命令5、监控工具Kafka-eagle安装 1、软件下…

Java并发编程实战 07 | 如何正确停止线程

什么时候需要停止一个线程&#xff1f; 一个线程被创建并启动之后&#xff0c;大部分情况下都会自然运行至结束&#xff0c;但是也有一些情况需要主动停止线程&#xff0c;比如&#xff1a; 用户主动取消执行&#xff1a;用户可能会中止一个正在进行的操作&#xff0c;这时需…

Python系统教程004(字符串)

一、input函数的算术运算 一包奥特曼卡片卖0.5元&#xff0c;小华想编写一个只需要输入卡片的包数就能自动计算价格的程序&#xff0c;请你帮帮它。 解题 报出类型错误 注意&#xff1a; input函数接收到的键盘信息&#xff0c;默认都是字符串的数据类型。 字符串的数据类型…

书生浦语三期实战营 [进阶] LMDeploy 量化部署进阶实践

LMDeploy 量化部署进阶实践 1 配置LMDeploy环境 1.1 InternStudio开发机创建与环境搭建 在终端中&#xff0c;让我们输入以下指令&#xff0c;来创建一个名为lmdeploy的conda环境&#xff0c;python版本为3.10&#xff0c;创建成功后激活环境并安装0.5.3版本的lmdeploy及相关…

IM即时通讯,稳定可靠的即时通讯服务-WorkPlus

在现代企业日常工作中&#xff0c;即时通讯已成为了一种不可或缺的沟通工具。为了满足企业对稳定可靠的即时通讯服务的需求&#xff0c;WorkPlus提供了一款优秀的IM即时通讯平台&#xff0c;以满足企业高效沟通和协作的要求。本文将深入探讨IM即时通讯服务的重要性以及WorkPlus…

Linux下的RTC应用

RTC RTC基础知识 1. RTC简介 RTC 全称是 Real-Time clock&#xff0c;翻译过来是实时时钟。实时时钟在日常生活中的应用也比较泛&#xff0c;比如电子时钟。实时时钟可以为系统提供精确的实时时间&#xff0c;通常带有电池&#xff0c;可以保证系统断电时还可以正常工作&…

JVM虚拟机 - 基础篇

一、初始JVM 1. JVM是什么 2. JVM的三大核心功能是什么&#xff1f; 3. 常见的JVM虚拟机有哪些&#xff1f; 二、字节码文件详解 1. Java虚拟机的组成 2. 字节码文件的组成 &#xff08;1&#xff09;基本信息 Magic魔数 主副版本号 &#xff08;2&#xff09;常量池 &#…

RabbitMQ练习(AMQP 0-9-1 Overview)

1、What is AMQP 0-9-1 AMQP 0-9-1&#xff08;高级消息队列协议&#xff09;是一种网络协议&#xff0c;它允许遵从该协议的客户端&#xff08;Publisher或者Consumer&#xff09;应用程序与遵从该协议的消息中间件代理&#xff08;Broker&#xff0c;如RabbitMQ&#xff09;…

Day19_0.1基础学习MATLAB学习小技巧总结(19)——MATLAB绘图篇(2)

利用空闲时间把碎片化的MATLAB知识重新系统的学习一遍&#xff0c;为了在这个过程中加深印象&#xff0c;也为了能够有所足迹&#xff0c;我会把自己的学习总结发在专栏中&#xff0c;以便学习交流。 参考书目&#xff1a;《MATLAB基础教程 (第三版) (薛山)》 之前的章节都是…

H5漂流瓶社交系统源码

一个非常有创意的H5漂流瓶社交系统源码&#xff0c;带完整前端h5和后台管理系统。 环境&#xff1a;Nginx 1.20.1-MySQL 5.6.50-PHP-7.3 代码下载

python简单计算入门教程|加减法

python通过调用numpy模块&#xff0c;非常擅长数学计算。再通过调用matplotlib模块&#xff0c;可以自由自在地输出numpy计算的结果。 今天&#xff0c;我们就尝试一些基本计算。 下述是正弦函数和余弦函数的加法和减法计算结果。 图1 代码为&#xff1a; import matplotli…

【stata】处理城市名和城市代码

写了两个简单的外部命令&#xff0c;在这里分享一下&#xff0c;希望能帮到大家 1.citycode_mutate 第一个命令是citycode_mutate&#xff0c;用于识别字符串中可能存在的城市信息&#xff0c;并生成城市代码&#xff08;图1图2&#xff09;。 2.cityname_mutate 第二个命令…