题目描述:
给定一个 m x n
的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 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
-231 <= matrix[i][j] <= 231 - 1
解决思路1:
朴素的思想是:遍历整个矩阵,碰到0,就将该行该列的数据都置为0。
不过这产生了问题:
1.后续的0,比如martix[0][0]是0,置0后,【0】【2】也是0,遍历到【0】【2】时,会产生错误。
2.覆盖的0,比如martix【0】【0】和【0】【1】都是0,置0后,【0】【1】的0被覆盖。
当然,很快就能想到解决方案:
1st.既然置0后,【0】【2】会是0产生错误,那么我们可以用一个boolean的矩阵,来处理这个问题,只要boolean【i】【j】 == true,就表示这个数据是改变过的(当然,遍历过了不必修改,毕竟只遍历矩阵行乘列,一共mn次)
2nd.对于原本就是0的【0】【1】,同样使用1st中的矩阵,只是提前判断一下,如果原来就是0,那么就不能使boolean【i】【j】 = true,这就Ok了。
这种方法相当朴素直观,就是效率又低(时间复杂度差不多O(n^3)吧),又不好写代码,写法如下:
解决思路2:
其实大可以从基本操作入手:先思考一下,改变这个矩阵需要哪些基本操作。
1.查找(遍历):无可置疑,无论是判断0,还是置0,都需要遍历矩阵数据。
2.修改:同理。
就目前来看,我们针对思路1提出两个问题:
1st.可不可以不用boolean数组,有点浪费空间。
2nd.可不可以不用统一置0,这样分散的置0,判断语句太多,绕昏头了。
对于一个数据结构(题目的输入),我们如果能不改变其原状,就不改变其原状,如果必须改变(比如本题的“原地”算法),那就尽量做到在一次基本操作内全部改变,这样能够最大限度地保证不出错,因为操作数据结构是个麻烦事。
既然这道题的数据结构是个矩阵,并且需要改变的是0所在的整行和整列,不妨记录一下这个行和这个列,在最末尾全部置0即可。
第一个解法:和思路1类似,采用boolean数组,有点浪费,不过很直观,在此不赘叙。
第二个解法:只用两个boolean数组,row[martix.length] col[martix[0].length]。
这个解法,通过行、列的角度定位需要改变的矩阵,浪费空间更少。
如图:
该图的意思,是指:既然【i】【j】是0,那么定下i,从第0列,到第martix【0】.length-1列,都得是0;;;同理,定下j,从第0行,到第martix.length-1行,都得是0。
那么记录i、j即可,之后,再依次遍历以i不动,以列动的数据。和以j不动,以行动的数据。
如图可解:
该题就此,另有更巧妙的解决方案,不过多是节约空间之流,因为无论如何,想找到矩阵中的0,至少需要mn次,也就是算法时间复杂度至少在O(n^2)及以上,加上其解决方案也没节约多少空间,故建议深入学习者再看。
以上内容即我想分享的关于力扣热题3的一些知识。
我是蚊子码农,如有补充,欢迎在评论区留言。个人也是初学者,知识体系可能没有那么完善,希望各位多多指正,谢谢大家。