如题只要发现一个元素为0,那么它所在的行和列都要置零。
方法一:使用两个数组只要发现某个元素为0,就将这一行或这一列的头元素置true,然后再遍历矩阵,只要某个元素对应的行或列头元素为true,那么对应元素就应该置换为0。//时间复杂度为o(mn),空间复杂度o(m+n);优点代码简短,缺点空间复杂度略高。
方法二:我们首先预处理出两个标记变量,用它们来标记第一行和第一列是否有0元素,接着遍历(1:m-1:1:n-1)元素如果出现零元素,那么将矩阵对应这一列和行头元素同时置0;再接着遍历1:m-1:1:n-1)一次,发现某个元素所对应的行或列头元素为0时,该元素就应该置0;最后在判断是否将第一行或者第一列元素置0/时间复杂度为o(mn),空间复杂度o(1);优点代码空间复杂度低,缺点代码冗杂。
方法三:只用一个变量,用它来标记第一列是否有0元素,接着遍历(0:m-1:1:n-1),同样的如果出现零元素,那么将矩阵对应这一列和行头元素同时置0;再接着遍历1:m-1:1:n-1)一次,不同的是这种方法第二次遍历置换元素需要从最后一行开始倒着置换,因为为了防止第一行元素被提前置换使得后续元素受到影响,最后再判断第一列元素是否全置0./时间复杂度为o(mn),空间复杂度o(1);为方法二的进一步优化

#include <iostream>
#include<vector>
using namespace std;
class Solution {//方法一
public:void setZeroes(vector<vector<int>>& matrix) {vector<bool> t1(matrix.size());//只要发现那个元素为0,就将这一行或这一列的头元素置truevector<bool> t2(matrix[0].size());for (int i = 0; i < matrix.size(); i++) {for (int j = 0; j < matrix[i].size(); j++) {if (matrix[i][j] == 0) {t1[i] = t2[j] = true;}}}for (int i = 0; i < matrix.size(); i++) {for (int j = 0; j < matrix[i].size(); j++) {if (t1[i] || t2[j]) {//判断这一行或者这一列头元素如果为true,那么这个元素一定为0matrix[i][j] = 0;}}}}
};//时间复杂度为o(mn),空间复杂度o(m+n);
class Solution1 {//方法二
public:void setZeroes(vector<vector<int>>& matrix) {bool dyh = false;bool dyl = false;for (int i = 0; i < matrix.size(); i++) {if (matrix[i][0] == 0) {dyl = true;}}for (int i = 0; i < matrix[0].size(); i++) {if (matrix[0][i] == 0) {dyh = true;}}for (int i = 1; i < matrix.size(); i++) {for (int j = 1; j < matrix[0].size(); j++) {if (matrix[i][j] == 0) {matrix[i][0] = matrix[0][j] = 0; //只要发现那个元素为0,就将这一行或这一列的头元素置true}}}for (int i = 1; i < matrix.size(); i++) {for (int j = 1; j < matrix[0].size(); j++) {if (matrix[i][0] == 0 || matrix[0][j] == 0) {matrix[i][j] = 0;}}}if (dyl) {for (int i = 0; i < matrix.size(); i++) {matrix[i][0] = 0;}}if (dyh) {for (int i = 0; i < matrix[0].size(); i++) {matrix[0][i] = 0;}}}
};//时间复杂度:O(mn),其中 mm 是矩阵的行数,nn 是矩阵的列数。我们至多只需要遍历该矩阵两次。
//空间复杂度:O(1),我们只需要常数空间存储若干变量。
class Solution2 {//方法三
public:void setZeroes(vector<vector<int>>& matrix) {bool dyl = false;for (int i = 0; i < matrix.size(); i++) {if (matrix[i][0] == 0) {dyl = true;}}for (int i = 0; i < matrix.size(); i++) {for (int j = 1; j < matrix[0].size(); j++) {if (matrix[i][j] == 0) {matrix[i][0] = matrix[0][j] = 0; //只要发现那个元素为0,就将这一行或这一列的头元素置true}}}for (int i = matrix.size() - 1; i >= 0; i--) {for (int j = 1; j < matrix[0].size(); j++) {if (matrix[i][0] == 0 || matrix[0][j] == 0) {//防止第一行元素被提前置0,所以从最后一行开始替换matrix[i][j] = 0;}}}if (dyl) {for (int i = 0; i < matrix.size(); i++) {matrix[i][0] = 0;}}}
};//时间复杂度:O(mn),其中 mm 是矩阵的行数,nn 是矩阵的列数。我们至多只需要遍历该矩阵两次。
//空间复杂度:O(1),我们只需要常数空间存储若干变量。

下附测试代码:

int main()
{vector<vector<int>> matrix1 = { {1, 1, 1} ,{1, 0, 1},{1, 1, 1} };vector<vector<int>> matrix2 = { {1, 1, 1} ,{1, 0, 1},{1, 1, 1} };vector<vector<int>> matrix3 = { {1, 1, 1} ,{1, 0, 1},{1, 1, 1} };Solution* x1 = new Solution;Solution1* x2 = new Solution1;Solution2* x3 = new Solution2;x1->setZeroes(matrix1);x2->setZeroes(matrix2);x3->setZeroes(matrix3);for (int i = 0; i < matrix1.size(); i++) {for (int j = 0; j < matrix1[0].size(); j++) {cout << matrix1[i][j] << " ";//cout << matrix2[i][j] << " ";//cout << matrix3[i][j] << " ";if (j == matrix1[0].size() - 1) {cout << endl;}}}system("pause");
}

测试结果:

C++矩阵置零---原地算法(附三种解法)相关推荐

  1. Leetcode算法Java全解答--73. 矩阵置零

    Leetcode算法Java全解答–73. 矩阵置零 文章目录 Leetcode算法Java全解答--73. 矩阵置零 题目 想法 结果 总结 代码 我的答案 大佬们的答案 测试用例 其他 题目 给定 ...

  2. leetcode 73 矩阵置零 Python

    矩阵置零 给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0.请使用原地算法. 示例 1: 输入: [[1,1,1],[1,0,1],[1,1,1] ] 输出: [ ...

  3. LeetCode 73矩阵置零74搜素二维矩阵75颜色分类

    新人公众号(求支持):bigsai 专注于Java.数据结构与算法,一起进大厂不迷路! 算法文章题解全部收录在github仓库bigsai-algorithm,求star! 关注回复进群即可加入力扣打 ...

  4. Java实现 LeetCode 73 矩阵置零

    73. 矩阵置零 给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0.请使用原地算法. 示例 1: 输入: [ [1,1,1], [1,0,1], [1,1,1] ...

  5. LeetCode 73. 矩阵置零(两个标记变量)

    73. 矩阵置零 我们可以用矩阵的第一行和第一列作为两个标记数组,以达到 O(1)O(1) 的额外空间. 但这样会导致原数组的第一行和第一列被修改,无法记录它们是否原本包含 0.因此我们需要额外使用两 ...

  6. leetcode(js)-每日一练之 矩阵置零 题库编号 73

    leetcode(js)-每日一练之 矩阵置零 1.检查并标记第一行和第一列是否有0 (firstColHasZero和firstRowHasZero) 2.忽略第一行第一列,若其余行列含有0,将其所 ...

  7. K-means聚类算法的三种改进(K-means++,ISODATA,Kernel K-means)介绍与对比

    原文:http://www.cnblogs.com/yixuan-xu/p/6272208.html K-means聚类算法的三种改进(K-means++,ISODATA,Kernel K-means ...

  8. js实现阶乘算法的三种方法

    js实现阶乘算法的三种方法 // 非递归写法 function f(n) {if (0 === n) {return 1;}let res = 1;for (let i = 1; i <= n; ...

  9. ML之R:通过数据预处理利用LiR/XGBoost等(特征重要性/交叉训练曲线可视化/线性和非线性算法对比/三种模型调参/三种模型融合)实现二手汽车产品交易价格回归预测之详细攻略

    ML之R:通过数据预处理利用LiR/XGBoost等(特征重要性/交叉训练曲线可视化/线性和非线性算法对比/三种模型调参/三种模型融合)实现二手汽车产品交易价格回归预测之详细攻略 目录 三.模型训练 ...

最新文章

  1. Redis 高级特性(5)— 集群模式(主从模式、哨兵模式、cluster 集群模式)
  2. 浏览器同源策略以及跨域请求时可能遇到的问题
  3. 读书笔记之MySQL技术内幕
  4. matplotlib.pyplot中add_subplot方法参数111的含义
  5. java处理XSS过滤的方法
  6. java restful_Java EE中的RESTful计时器
  7. 后端视角下的前端框架之Vue.js初探
  8. js控制scss的变量_web前端:js如何操作sass里的变量及calc 使用sass变量
  9. Kafka、 RabbitMQ、Redis、 ZeroMQ、 ActiveMQ、 Kafka/Jafka 对比
  10. python判断文件格式_Python判断上传文件类型
  11. VBA代码自动缩进排版-VBA代码助手一键排版功能
  12. php发送curl最快方式,使用PHP cURL发送短信的简单GET请求
  13. IP-Guard使用中63个常见问题
  14. [蛋蛋无厘头日记]收到礼物喵~o(∩_∩)o
  15. Centos7.X修改hostname立刻生效-修改/etc/hostname后立刻生效-Centos7.x修改hostname永久生效
  16. 2021-11-06 ompl运动规划库的规划算法
  17. 群晖NAS 7.X版搭建博客网站,并内网穿透发布公网可访问 8-8
  18. html大作业展示个人风采,个人风采展示自我介绍精选模板
  19. HTML5——如何在网页中加入图片和超链接。
  20. 全国青少年软件编程等级考试--scratch-三级-真题-五彩糖葫芦

热门文章

  1. java 获取 知乎 热搜 给自己网站加上知乎热搜模块
  2. 使用Xshell部署网页
  3. 看过来看过来,快去看看这个网站!!!
  4. 【python+SQLAlchemy】
  5. web课程设计网页规划与设计~时尚服装购物商城模板html源码(HTML+CSS+JS)
  6. 每次开机Edge浏览器自动启动怎么办
  7. Linux系统文本三剑客之grep使用方法
  8. 网络安全比赛知识点梳理小记
  9. 传说她是海洋大学校花
  10. 视通科技科技法庭解决方案