Leetcode 73. Set Matrix Zeroes [medium][java]

本文介绍了一种高效的矩阵置零算法,当矩阵中的元素为0时,将整个行和列设置为0。提供了三种解决方案:暴力法、使用额外内存的方法和利用矩阵自身作为标记的最优解。最优解的时间复杂度为O(m*n),空间复杂度仅为O(1)。

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

Example
在这里插入图片描述

Solution 1: brute force
Consideration

  1. Use a boolean matrix to mark if the element has been set to 0.
  2. We iterate through the matrix. if the element is 0, we iterate the row and column. If the number in this row/column is not 0 and has not been set, we set it as 0 and mark it.

Time complexity:O(mnm) or O(mnn) depending on whether m or n is bigger, space complexity: O(m*n).

class Solution {
    public void setZeroes(int[][] matrix) {
        int rows = matrix.length;
        int cols = matrix[0].length;
        boolean[][] sets = new boolean[rows][cols];
        
        for(int i = 0; i < rows; i++)
            for(int j = 0; j < cols; j++) {
                if(sets[i][j])
                    continue;
                if(matrix[i][j] == 0) {
                    for(int k = 0; k < rows; k++) {
                        if(k != i && matrix[k][j] != 0 && !sets[k][j]) {
                            matrix[k][j] = 0;
                            sets[k][j] = true;
                        }
                    }
                    for(int k = 0; k < cols; k++) {
                        if(k != j && matrix[i][k] != 0 && !sets[i][k]) {
                            matrix[i][k] = 0;
                            sets[i][k] = true;
                        }
                    }
                }
            }
        
    }
}

Solution 2: Additional Memory Approach

  1. Iterate through the matrix. If the number is 0, we add its row index and column index to the rows set and cols set.
  2. We iterate through the rows set and cols set separately to set whole row/column to be 0.

Time Complexity: O(3mn), space complexity: O(m+n)

class Solution {
    public void setZeroes(int[][] matrix) {
        int rows = matrix.length;
        int cols = matrix[0].length;
        Set<Integer> rowSets = new HashSet();
        Set<Integer> colSets = new HashSet();
        
        for(int i = 0; i < rows; i++)
            for(int j = 0; j < cols; j++) {
                if(matrix[i][j] == 0) {
                    rowSets.add(i);
                    colSets.add(j);
                }
            }
        Iterator<Integer> ite = rowSets.iterator();
        while(ite.hasNext()) {
            int index = ite.next();
            for(int i = 0; i < cols; i++) {
                matrix[index][i] = 0;
            }
        }
        
        ite = colSets.iterator();
        while(ite.hasNext()) {
            int index = ite.next();
            for(int i = 0; i < rows; i++) {
                matrix[i][index] = 0;
            }
        } 
        
    }
}

Solution 3
Consideration

  1. We can use the first row and first column of the matrix as a flag. This flag would determine whether a row or column should beset to zero.
  2. The first cell of row and column for the first row and first column is the same i.e. matrix[0][0]. So we use matrix[0][0] to represent the first row flag and create a flag to represent the first column flag.
  3. We iterate through the whole matrix to mark the flags.
  4. Then, we start from the second row and second column to the end. If the row flag or column flag is set, change the element to be 0.
  5. We then check if matrix[0][0] == 0. If yes, we set the first row elements.
  6. Finally, we check the first column flag. If yes, we set the first column elements.

Time complexity: O(m*n), space complexity: O(1)

class Solution {
    public void setZeroes(int[][] matrix) {
        int rows = matrix.length;
        int cols = matrix[0].length;
        Boolean setFirstCol = false;
        
    
        // use the first row and first column as a flag to indidate if the row/column should be set as 0
        for(int i = 0; i < rows; i++) {
            //check first column
            if(matrix[i][0] == 0)
                setFirstCol = true;
            
            for(int j = 1; j < cols; j++) {
                if(matrix[i][j] == 0) {
                    matrix[i][0] = 0;
                    matrix[0][j] = 0;
                }
            }
        }
            
        //iterate over the matrix again, if the row/column should be set, set the element to 0    
        for(int i = 1; i < rows; i++)
            for(int j = 1; j < cols; j++) {
                if(matrix[i][0] == 0 || matrix[0][j] == 0)
                    matrix[i][j] = 0;
            }

        //check if the first row should be set as 0
        if(matrix[0][0] == 0) {
            for(int j = 1; j < cols; j++)
                matrix[0][j] = 0;
        }
        
        //check if the first column should be set as 0
        if(setFirstCol) {
            for(int i = 0; i < rows; i++) 
                matrix[i][0] = 0;
        }
        
    }
}

Reference

  1. https://leetcode.com/problems/set-matrix-zeroes/solution/
代码下载地址: https://pan.quark.cn/s/a4b39357ea24 在当代Web开发领域中,前后端分离的架构模式已广泛普及,这种模式有助于提升开发效能,清晰界定工作职责,并支持前后端独立地进行开发与部署工作。当前项目借助Spring Boot框架构建了后端服务接口,并搭配Vue.js技术完成前端界面呈现,同时运用axios工具应对跨域通信挑战,从而形成一个完整的前后端分离实践范例。 1. **Spring Boot**: Spring Boot可视为Spring框架的一个精简版本,其旨在简化Spring应用的初始构建及开发流程。在Spring Boot环境下,开发者能够迅速构建出具备生产环境要求水准的Spring应用程序。该框架整合了众多常用第三方库的配置选项,例如数据库连接管理、模板引擎应用、安全机制设定等,显著降低了标准配置的复杂程度。 2. **后端接口开发**: 在`springBoot实现后端接口.zip`文件中,主要包含了基于Spring Boot的后端服务功能实现。通常情况下,我们会设计RESTful风格的API,通过HTTP协议的CRUD操作(即创建、读取、更新、删除)来响应前端发起的请求。这些接口多采用Spring MVC的注解方式,如`@GetMapping`, `@PostMapping`, `@PutMapping`, `@DeleteMapping`等来定义,并借助Spring Data JPA或MyBatis等数据持久化框架与数据库进行数据交互。 3. **Vue.js**: Vue.js是一款轻量级的前端JavaScript框架,专注于用户界面的开发。它具备响应式的数据绑定机制和组件化的架构设计,使得开发者能够高...
打开链接下载源码: https://pan.quark.cn/s/a4b39357ea24 直方图双峰法是一种以图像直方图为基础的阈值分割技术,其核心原理在于借助图像直方图中存在的两个显著峰值(双峰)来确定分割阈值,进而将图像有效地区分为前景与背景两个区域。该方法在处理二值化图像时展现出卓越的性能,特别是在图像的亮度分布呈现明显分离特征的场景下。为了深入掌握该方法,首先需要明确图像直方图的概念。图像直方图是一种用于表征图像像素强度分布特性的统计图表,它通过将图像中所有像素的灰度值按照其出现频率进行绘制,其中横轴表示灰度级别,纵轴则代表像素数量或频率。当图像的背景与前景具有显著的亮度对比时,直方图上通常能够观察到两个清晰的峰值,这两个峰值分别对应着背景和前景像素的集中区域。 在直方图双峰法的实践过程中,关键环节在于如何准确识别并选取这两个峰值作为阈值。通常情况下,我们会倾向于选择距离较远且峰值较高的两个峰,因为这样的配置往往意味着它们分别代表了图像中的两种主要类别。一种普遍采用的技术是通过计算相邻灰度级之间的梯度,从而定位梯度最大值的位置,该位置可以被视作两个峰值之间的谷底,随后取这两个峰值的平均值或中点作为最终的阈值。 在提供的代码实例中,首先加载了一个名为coins.png的图像,并利用`imshow`函数展示了原始图像。紧接着,绘制了该图像的直方图,参数`axis([0 255 0 4000])`用于设定直方图的显示范围,确保能够清晰地观察到图像的亮度分布情况。随后,选择了一个具体的阈值`th=97`,并通过`im2bw`函数将图像转换为二值图像,同时展示了分割后的结果。 阈值`th`的选取具有决定性作用,因为它直接关联到分割的最终效果。若阈值选取不当,可能会导...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值