当前位置:网站首页>LeetCode高频题73. 矩阵置零
LeetCode高频题73. 矩阵置零
2022-08-05 13:33:00 【冰露可乐】
LeetCode高频题73. 矩阵置零
提示:本题是系列LeetCode的150道高频题,你未来遇到的互联网大厂的笔试和面试考题,基本都是从这上面改编而来的题目互联网大厂们在公司养了一大批ACM竞赛的大佬们,吃完饭就是设计考题,然后去考应聘人员,你要做的就是学基础树结构与算法,然后打通任督二脉,以应对波云诡谲的大厂笔试面试题!你要是不扎实学习数据结构与算法,好好动手手撕代码,锻炼解题能力,你可能会在笔试面试过程中,连题目都看不懂!比如华为,字节啥的,足够让你读不懂题
题目
给定一个 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]]

输入: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
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/set-matrix-zeroes
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
最简单的就是外部辅助空间记录哪些行和列,需要变0
当然,你遍历过程中,遇到0,不能立马改整行和整列,否则你待会不知道遇到的0是怎么来的
用一个行哈希表,列哈希表,记录哪些行,哪些列应该直接变零
耗费额外空间的
代码也很简单
//复习:
public void setZeroesReview(int[][] matrix) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return;
int N = matrix.length;
int M = matrix[0].length;
//辅助
HashSet<Integer> rowSet = new HashSet<>();
HashSet<Integer> columnSet = new HashSet<>();
//遍历
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (matrix[i][j] == 0){
rowSet.add(i);
columnSet.add(j);
}
}
}
//再修改
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (rowSet.contains(i)) matrix[i][j] = 0;
if (columnSet.contains(j)) matrix[i][j] = 0;
}
}
}
测试;
public static void test(){
Solution solution = new Solution();
int[][] arr = {
{
1,1,2,4},
{
3,1,5,2},
{
0,3,1,1},
{
1,3,1,0}};
solution.setZeroes(arr);
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[0].length; j++) {
System.out.print(arr[i][j] +" ");
}
System.out.println();
}
System.out.println();
int[][] arr2 = {
{
1,1,2,4},
{
3,1,5,2},
{
0,3,1,1},
{
1,3,1,0}};
solution.setZeroesReview(arr2);
for (int i = 0; i < arr2.length; i++) {
for (int j = 0; j < arr2[0].length; j++) {
System.out.print(arr2[i][j] +" ");
}
System.out.println();
}
}
public static void main(String[] args) {
test();
}
结果:
0 1 2 0
0 1 5 0
0 0 0 0
0 0 0 0
0 1 2 0
0 1 5 0
0 0 0 0
0 0 0 0
LeetCode测试:

外部辅助首先耗费空间
其次时间也挺慢
题目说了用:原地算法 搞
咱们来一波节约空间和时间的做法
我们想干啥呢??
用第0行来记录,这一行,是否要整体变0???
用第0列来记录,这一列,是否要整体变0???
如果遍历过程中,发现某一行i需要变0,那i行0列这个格子就要记录
如果遍历过程中,发现某一列j需要变0,那0行j列这个格子就要记录
那注意了
你万一第0行,需要整体变0,怎么记录,单独拿一个变量row0来记录,
你万一第0列,需要整体变0,怎么记录,单独拿一个变量column0来记录,
咱们一开始就先遍历0行,如果遇到0,row0=true
咱们一开始就先遍历0列,如果遇到0,column0=true
然后遍历i=1–N-1行,遍历j=1–M-1列,用第0行和0列记录
用0记录,回头你检查,不是0的都不要动,是0的整行,或者整列都得变0
然后变的时候,当然是根据0行和0列先搞0–N-1行和0–M-1列【注意这可是整个矩阵的行列都变哦】
然后检查row0和column0,决定整个0行和0列要不要变
这就是原地算法的意思
手撕代码:
//如果遍历过程中,发现某一行i需要变0,那i行0列这个格子就要记录
//如果遍历过程中,发现某一列j需要变0,那0行j列这个格子就要记录
public void setZeroesSource(int[][] matrix) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return;
int N = matrix.length;
int M = matrix[0].length;
//俩变量记录
//咱们一开始就先遍历0行,如果遇到0,row0=true
//咱们一开始就先遍历0列,如果遇到0,column0=true
boolean row0 = false;
boolean column0 = false;
for (int i = 0; i < N; i++) {
if (matrix[i][0] == 0) column0 = true;
}
for (int j = 0; j < M; j++) {
if (matrix[0][j] == 0) row0 = true;
}
//然后遍历i=1--N-1行,遍历j=1--M-1列,用第0行和0列记录
//用2记录,回头你检查,不是2的都不要动,是2的整行,或者整列都得变0
for (int i = 1; i < N; i++) {
for (int j = 1; j < M; j++) {
if (matrix[i][j] == 0) {
matrix[i][0] = 0;
matrix[0][j] = 0;//对应俩格子记录0,代表这一行,这一列都得是0
}
}
}
//然后变的时候,当然是根据0行和0列先搞1--N-1行和1--M-1列
//然后检查row0和column0,决定整个0行和0列要不要变
for (int i = 1; i < N; i++) {
for (int j = 1; j < M; j++) {
if (matrix[i][0] == 0) matrix[i][j] = 0;//这一行都得是0
if (matrix[0][j] == 0) matrix[i][j] = 0;//这一列都得是0
}
}
if (row0)
for (int j = 0; j < M; j++) {
matrix[0][j] = 0;
}
if (column0)
for (int i = 0; i < N; i++) {
matrix[i][0] = 0;
}
}
测试
System.out.println();
int[][] arr3 = {
{
1,1,2,4},
{
3,1,5,2},
{
0,3,1,1},
{
1,3,1,0}};
solution.setZeroesSource(arr3);
for (int i = 0; i < arr3.length; i++) {
for (int j = 0; j < arr3[0].length; j++) {
System.out.print(arr3[i][j] +" ");
}
System.out.println();
}
很OK
0 1 2 0
0 1 5 0
0 0 0 0
0 0 0 0
LeetCode测试:

看看,整个空间,直接就大大地优化了
不过速度咋还慢呢???
不管,因为LeetCode有时候记录时间就是不准的,这已经是最好的算法了。
总结
提示:重要经验:
1)用辅助空间势必耗费额外空间
2)这种记录要变0或者1的事,可以原地记录,简单几个变量就行
3)笔试求AC,可以不考虑空间复杂度,但是面试既要考虑时间复杂度最优,也要考虑空间复杂度最优。
边栏推荐
- Matplotlib 使用指南
- 在线问题反馈模块实战(十九):实现数据批量导出到excel文件中功能
- 图扑软件数字孪生油气管道站,搭建油气运输管控平台
- 详解 SSL(一):网址栏的小绿锁有什么意义?
- 深度学习之 11 卷积神经网络实现
- 2022-08-04 clickhouse的join子句
- Mysql索引
- R语言patchwork包将多个可视化结果组合起来、plot_annotation函数以及tag_level参数将组合图用大写字母进行顺序编码、为组合图的标签添加自定义分割符号信息(separator
- 2022-08-04 顾宇佳 学习笔记
- R语言ggplot2可视化:使用ggpubr包的ggsummarytable函数可视化dataframe数据的描述性统计量、ggtheme参数设置可视化图像使用的主题
猜你喜欢

【时序数据库InfluxDB】Windows环境下配置InfluxDB+数据可视化,以及使用 C#进行简单操作的代码实例...

五、平衡二叉树——伸展树Splay

电脑端微信无法打开腾讯文档

【深度强化学习】MAPPO 代码学习

IIoT系统架构

【CC3200AI 实验教程2】疯壳·AI语音人脸识别(会议记录仪/人脸打卡机)-系统测试

115. In-depth explanation of the technical implementation of configuring the local SAP UI5 application to the local Fiori Launchpad

松翰烧录器在keil仿真时闪退,解决方法

链表面试题-刷题

内存问题难定位,那是因为你没用ASAN
随机推荐
Qt实现多国语言切换
DonkeyCar source code reading .4 (project file creation)
EAI X2(非订制版)50一个激光雷达?
TVS和ESD的区别
第三章 调度系统架构设计之获取集群资源信息
mmap内核实现及物理内存组织结构
华朗复读衔接营励志开营!全名师阵容护航 解读高考成功秘钥
施耐德电气庞邢健:以软件撬动可持续的未来工业
为什么设计思维是有用的?
What is the origin of an overnight flight tracking website?
每秒10亿次更新、实现秒级同步延迟,腾讯深度学习推荐系统首次入选OSDI顶会
【Sequel Pro】下载查询结果乱码问题处理方式
BOM学习
Matplotlib 使用指南
并发刺客(False Sharing)——并发程序的隐藏杀手
选择商城小程序源码的三个技巧!
【时序数据库InfluxDB】Windows环境下配置InfluxDB+数据可视化,以及使用 C#进行简单操作的代码实例...
2022-08-04 Brighthouse: An Analytic DataWarehouse for Ad-hoc Queries
Amazon Detective 支持 Amazon EKS 上的 Kubernetes 工作负载以进行安全调查
华为分析&联运活动,助您提升游戏总体付费