leetcode刷题_OJ 73

本文介绍了一种高效的矩阵处理算法,即在不使用额外空间的情况下,将矩阵中为0的元素对应的行和列置零。文章详细阐述了算法的实现思路,并提供了一个具体的C++代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in-place.

Example 1:

Input: 
[
  [1,1,1],
  [1,0,1],
  [1,1,1]
]
Output: 
[
  [1,0,1],
  [0,0,0],
  [1,0,1]
]
Example 2:

Input: 
[
  [0,1,2,0],
  [3,4,5,2],
  [1,3,1,5]
]
Output: 
[
  [0,0,0,0],
  [0,4,5,0],
  [0,3,1,0]
]
Follow up:

A straight forward solution using O(mn) space is probably a bad idea.
A simple improvement uses O(m + n) space, but still not the best solution.
Could you devise a constant space solution?

题目主要的意思:输入一个m*n的矩阵,将矩阵为0位置的对应行、列都置为0后输出。

我本来的想法:将矩阵拷贝一份,在原矩阵中遍历到0,就在新矩阵中将该位置的对应行、列修改。完成对原矩阵的遍历后,将新矩阵覆盖原来的矩阵即可得到结果。但是这样带来的代价是:当矩阵非常大时,我们需要浪费想当大的一片空间来给新建的矩阵,这与题目中要求的尽量用O(m+n)的思想不符,所以以下是参考了其它博主的想法写出来的,无需额外开辟新空间的方法。
原文地址:http://blog.youkuaiyun.com/fly_yr/article/details/48499177

方法的具体思想:

利用矩阵的首行以及首列用来记录遍历除首行列外的部分时0出现的位置。具体步骤;

1、先遍历首行、首列,用一个boolean变量标记其中是否存在0。

2、对除首行、首列外的内容进行遍历,遇到0,则将首行、首列的对应两个位置标记为0,记录下0的位置。

3、对首行、首列进行处理。此时正是根据步骤2得到的记录,如果matrix[0][j]为0,则将j列对应的所有行置为0;反之亦然。

4、利用步骤1中我们得到的boolean变量对首行首列处理一下即可

class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {

    	if(matrix.empty())//处理矩阵为空的情况
    		return;
        
        int m=matrix.size();
        int n=matrix[0].size();
        //int n=matrix.front().size();
        bool m_row=false,m_col=false;

        //先确定首行首列中是否有0
        for(int i=0;i<m;i++){
        	if(matrix[i][0] == 0){
        		m_col=true;
        		break;
        	}
        }

        for(int i=0;i<n;i++){
        	if(matrix[0][i] == 0){
        		m_row=true;
        		break;
        	}
        }

        //然后去处理首行首列外的区域,如果有0,则将对应首行列上置为0,注意此时下标从1而不是0开始
        for(int i=1;i<m;i++){
        	for(int j=1;j<n;j++){
        		if(matrix[i][j] == 0){
        			matrix[0][j]=0;
        			matrix[i][0]=0;
        		}
        	}
        }

        //根据首行首列的值去修改矩阵的对应值为0
        for(int i=1;i<m;i++){
        	if(matrix[i][0] == 0){
        		for(int j=0;j<n;j++){
        			matrix[i][j]=0;
        		}
        	}
        }

        for(int i=1;i<n;i++){
        	if(matrix[0][i] == 0){
        		for(int j=0;j<m;j++){
        			matrix[j][i]=0;
        		}
        	}
        }

        //最后根据一开始对首行首列的遍历结果完成修改
        if(m_row){
        	for(int i=0;i<n;i++){
        		matrix[0][i]=0;
        	}
        }

        if(m_col){
        	for(int i=0;i<m;i++){
        		matrix[i][0]=0;
        	}
        }

    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值