【Leetcode】top 100 矩阵

73 矩阵置零

给定一个 mxn 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法**。**

**方法一:**拷贝出一个同样大小的矩阵,根据拷贝矩阵在原矩阵上修改元素; 空间复杂度O(mn)

**方法二:**第一次遍历用row记录第几行需要被改变,用column记录第几列需要被改变;第二次遍历再修改,若当前行需要被改变,直接全置零,若当前行不需要被改变,再改变当前行中被列上的0影响的元素; 空间复杂度O(m+n),时间复杂度O(2mn)

因为第二次遍历时需要查找值,用了集合;

python 复制代码
class Solution(object):
    def setZeroes(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: None Do not return anything, modify matrix in-place instead.
        """
        row, column = set(), set()
        m, n = len(matrix), len(matrix[0])
        for i in range(m):
            for j in range(n):
                if matrix[i][j] == 0:
                    row.add(i)
                    column.add(j)        
        for i in range(m):
            if i in row:matrix[i] = [0] * n
            else:
                for j in column:
                    matrix[i][j] = 0
        return matrix

官方思路: 用第一行记录行改变情况(第一行为row),用第一列记录列改变情况(第一列为column)损失的第一行和第一列信息用变量储存;只需要记录第一行第一列是否有0即可,若有0,更新后的状态需要全0,即损失的初始状态不重要;若无0,更新后的状态只会受到该行或该列的影响,所以提前置零记录该行或该列情况不影响最终结果; 空间复杂度O(1)

python 复制代码
class Solution(object):
    def setZeroes(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: None Do not return anything, modify matrix in-place instead.
        """
        row, column = 1, 1
        m, n = len(matrix), len(matrix[0])
        for i in range(n):                   #第一行情况
            if matrix[0][i] == 0: row = 0
        for i in range(m):                   #第一列情况
            if matrix[i][0] == 0: column = 0

        for i in range(1,m):                 #记录需要改变的行和列
            for j in range(1,n):
                if matrix[i][j] == 0:
                    matrix[0][j] = 0
                    matrix[i][0] = 0
        
        for i in range(1,m):                 #根据记录修改行和列
            for j in range(1,n):
                if matrix[0][j] == 0 or matrix[i][0] == 0:
                    matrix[i][j] = 0

        if row == 0:                         #更新第一行
            for i in range(n):
                matrix[0][i] = 0
        if column == 0:                      #更新第一列
            for i in range(m):
                matrix[i][0] = 0

        return matrix
54 螺旋矩阵

给你一个 mn 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。

分析:一定会转满min(m//2, n//2)圈,最后不剩/剩一行/剩一列/剩一个中心元素;

思路一:直接模拟

python 复制代码
class Solution(object):
    def spiralOrder(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: List[int]
        """

        out = []
        n, m = len(matrix), len(matrix[0])
        up, left, down, right = 0, 0, n-1, m-1

        for i in range(min(m,n)//2):
            for j in range(left,right+1):
                out.append(matrix[up][j])
            up += 1

            for j in range(up,down+1):
                out.append(matrix[j][right])
            right -= 1

            for j in range(right,left-1,-1):
                out.append(matrix[down][j])
            down -= 1

            for j in range(down,up-1,-1):
                out.append(matrix[j][left])
            left += 1
        
        if min(m,n) % 2 != 0:
            if n > m:
                for j in range(up,down+1):
                    out.append(matrix[j][right])
            elif n < m:
                for j in range(left,right+1):
                    out.append(matrix[up][j])
            else:
                out.append(matrix[n//2][m//2])

        return out

思路二:循环用while true,直至指针交错(相等是允许的)才退出;

python 复制代码
class Solution(object):
    def spiralOrder(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: List[int]
        """
        res = []
        if matrix is None: return res
        top,bottom,left,right = 0, len(matrix) - 1, 0, len(matrix[0]) - 1
        while True:
            for i in range(left,right+1): #➡️
                res.append(matrix[top][i])
            top += 1 
            if top > bottom: break
            for i in range(top,bottom+1): #⬇️
                res.append(matrix[i][right])
            right -= 1
            if right < left: break
            for i in range(right,left-1,-1): #⬅️
                res.append(matrix[bottom][i])
            bottom -= 1
            if bottom < top: break
            for i in range(bottom,top-1,-1): #⬆️
                res.append(matrix[i][left])
            left += 1
            if left > right: break
        return res

思路三利用zip和*的搭配实现行列的转换; 原第一行取完后,将列转行再倒序,就能取到原最后一列;由于倒序操作改变了原行内的相对位置,恰好满足原最后一行的倒序输出;

这是真牛!!!

python 复制代码
class Solution(object):
    def spiralOrder(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: List[int]
        """

        out = []
        while matrix:
            out += matrix.pop(0)
            matrix = list(zip(*matrix))[::-1]   
        return out
48 旋转图像

给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。

分析:观察旋转图像发现,其实就是转置再翻转

转置:list(zip(*)) [( )( )( )]

list(map(list, zip(*matrix))) == list(row) for row in zip(*matrix) [[ ][ ][ ]]

翻转:[::-1]

python 复制代码
class Solution(object):
    def rotate(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: None Do not return anything, modify matrix in-place instead.
        """
        matrix[:] = [row[::-1] for row in zip(*matrix)]
240 搜索二维矩阵II

编写一个高效的算法来搜索 m xn 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:每行的元素从左到右升序排列;每列的元素从上到下升序排列。

分析:利用 matrix 特性减少搜索时间:

小于当前行起始值,就不可能再在后续中找到;

大于当前行终止值,该行不遍历;

在当前行的范围内,小于当前列值,后续就只能在较小的列中寻找;大于当前列值,继续遍历;

python 复制代码
class Solution(object):
    def searchMatrix(self, matrix, target):
        """
        :type matrix: List[List[int]]
        :type target: int
        :rtype: bool
        """
        if target < matrix[0][0] or target > matrix[-1][-1]:
            return False
        
        m, n = len(matrix), len(matrix[0])

        for i in range(m):
            if target < matrix[i][0]:return False
            elif target > matrix[i][-1]:continue
            else:
                for j in range(n):
                    if target < matrix[i][j]:n = j
                    elif target == matrix[i][j]:return True
                    else:continue
        return False

官方思路 :从矩阵的右上角开始Z字遍历

当目标值大于这个值,目标值就不能在当前行被找到;

当目标值小于这个值,目标值就不能在当前列被找到;

python 复制代码
class Solution:
    def searchMatrix(self, matrix, target):
        m, n = len(matrix), len(matrix[0])
        i, j = m - 1, 0
        while i >= 0 and j < n:
            if matrix[i][j] == target:return True
            elif matrix[i][j] < target:j += 1
            else:i -= 1
        return False
相关推荐
菜鸟求带飞_9 分钟前
算法打卡:第十一章 图论part01
java·数据结构·算法
浅念同学10 分钟前
算法.图论-建图/拓扑排序及其拓展
算法·图论
是小Y啦27 分钟前
leetcode 106.从中序与后续遍历序列构造二叉树
数据结构·算法·leetcode
程序猿练习生32 分钟前
C++速通LeetCode中等第9题-合并区间
开发语言·c++·leetcode
liuyang-neu37 分钟前
力扣 42.接雨水
java·算法·leetcode
y_dd44 分钟前
【machine learning-12-多元线性回归】
算法·机器学习·线性回归
m0_6312704044 分钟前
标准c语言(一)
c语言·开发语言·算法
万河归海42844 分钟前
C语言——二分法搜索数组中特定元素并返回下标
c语言·开发语言·数据结构·经验分享·笔记·算法·visualstudio
小周的C语言学习笔记1 小时前
鹏哥C语言36-37---循环/分支语句练习(折半查找算法)
c语言·算法·visual studio
y_dd1 小时前
【machine learning-七-线性回归之成本函数】
算法·回归·线性回归