# 力扣-二维数组的变换

力扣-二维数组的变换

  1. 对于原地工作的算法,很重要的一个思想是,用标志位来表示我们进行的操作,例如289生命游戏,用一个标志来表示更改前后的两种状态,这样既保留了之前的数据,又保留了更改后的数据。
  2. 还可以用相反数来标记该数,但其实不改变他所含有的数据,例如442重复的数据。

重塑矩阵(566)

思路: 先判断 重塑后的矩阵和原来矩阵的元素是否相等,不相等则返回原矩阵。
随后遍历原矩阵,用 count 来记录是否遍历完一个 c 的长度,也就是重塑后矩阵的列数,当count==c 时,将刚刚遍历的元素作为重塑后的第一行,再令 count = 0,重复 上述操作,即可得到重塑后的每一行。

class Solution:
    def matrixReshape(self, mat: List[List[int]], r: int, c: int) -> List[List[int]]:
        h = len(mat)
        w = len(mat[0])
        result=[]
        if r*c!=h*w:
            return mat
        temp=[]
        count=0
        for i in range(h):
            for j in range(w):
                temp.append(mat[i][j])
                count+=1
                if count==c:
                    result.append(temp)
                    temp=[]
                    count=0
        return result

旋转图像(48)

思路: 以示例1为例,修改(0,0)的位置需要改变其余三个位置的值(0,2)、(2,2)、(2,0),只需要修改(0,0)和(0,1)就可以更新完全部位置(也就是进行了旋转)。
第一行从第一个起,到倒数第二个
第二行从第二个其,到倒数第三个
以此类推
总共执行 n//2 行

class Solution:
    def rotate(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        n=len(matrix)
        p=0
        k=n-1
        for i in range(n//2):
            for j in range(p,k): 
                x=i
                y=j
                pre=matrix[x][y]
                for q in range(4):
                    matrix[y][n-x-1],pre=pre,matrix[y][n-x-1]
                    x,y=y,n-x-1
            p+=1
            k-=1

矩阵置零(73)

思路一: 用set集合来记录需要置零的行和列,最后统一进行置零,时间复杂度为 O(m+n)。

class Solution:
    def setZeroes(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        m=len(matrix)
        n=len(matrix[0])
        row=set()
        col=set()
        for i in range(m):
            for j in range(n):
                if matrix[i][j]==0:
                    row.add(i)
                    col.add(j)
        for y in row:
            for j in range(n):
                matrix[y][j]=0
        for x in col:
            for i in range(m):
                matrix[i][x]=0

思路二: 用第一行和第一列来记录该行和该列有没有0,然后还需要用两个标志来记录第一行和第一列是否有0,因为第一行有0,需要把该行都置零,第一列同理。
除去第一行第一列进行一个遍历,matrix[i][j]=0,则置第一行和第一列的标志为0。
最后再除去第一行第一列进行一个遍历,如果该行或者该列标志为0,则该位置置0。
最后再对第一行和第一列进行判断是否置零。

class Solution:
    def setZeroes(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        m = len(matrix)
        n = len(matrix[0])
        row_flag=False
        col_flag=False
        # 找第一行是否有0,以便后面处理第一行
        for i in range(n):
            if matrix[0][i]==0:
                row_flag=True
        # 找第一列是否有0,以便后面处理第一列
        for j in range(m):
            if matrix[j][0]==0:
                col_flag=True
        for i in range(1,m):
            for j in range(1,n):
                if matrix[i][j]==0:
                    matrix[i][0]=matrix[0][j]=0
        # 置零操作
        for i in range(1,m):
            for j in range(1,n):
                if matrix[i][0]==0 or matrix[0][j]==0:
                    matrix[i][j]=0
        if row_flag==True:
            for j in range(n):
                matrix[0][j]=0
        if col_flag==True:
            for i in range(m):
                matrix[i][0]=0     

生命游戏 (289)

方法一思路: 将原数组进行一个复制,然后再复制的数组上去判断规则,在原数组上进行更改。

class Solution:
    def gameOfLife(self, board: List[List[int]]) -> None:
        """
        Do not return anything, modify board in-place instead.
        """
        m=len(board)
        n=len(board[0])
        result=[[0 for i in range(n)] for j in range(m)]
        for i in range(m):
            for j in range(n):
                result[i][j]=board[i][j]
        for i in range(m):
            for j in range(n):
                live=0
                for x in range(i-1,i+2):
                    for y in range(j-1,j+2):
                        if 0<=x<m and 0<=y<n and result[x][y]==1:
                            live+=1
                if result[i][j]==1:
                    live-=1
                
                if result[i][j]==1 and live<2:
                    board[i][j]=0
                elif result[i][j]==1 and (live==2 or live==3):
                    board[i][j]=1
                elif result[i][j]==1 and live>3:
                    board[i][j]=0
                elif result[i][j]==0 and live==3:
                    board[i][j]=1

方法二思路: 在原数组上进行更改,更改时用 2 来表示细胞从1到0,用 -1表示细胞从0变1,这样既能表示修改前的值又能表示修改后的值。

class Solution:
    def gameOfLife(self, board: List[List[int]]) -> None:
        """
        Do not return anything, modify board in-place instead.
        """
        m=len(board)
        n=len(board[0])
        # 更新每一个元素
        for i in range(m):
            for j in range(n):
                # 统计每一个元素周围存活的细胞
                live=0
                for x in range(i-1,i+2):
                    for y in range(j-1,j+2):
                        if 0<=x<m and 0<=y<n and (board[x][y]==1 or board[x][y]==-1):
                            live+=1
                # 排除该细胞本身
                if board[i][j]==1:
                    live-=1
                # 根据符合标志(0->1为2,1->0 为-1)更新数组
                if board[i][j]==1 and live<2:
                    board[i][j]=-1
                elif board[i][j]==1 and (live==2 or live==3):
                    pass
                elif board[i][j]==1 and live>3:
                    board[i][j]=-1
                elif board[i][j]==0 and live==3:
                    board[i][j]=2
        # 再遍历一次数组将2和-1分别再转为1和0
        for i in range(m):
            for j in range(n):
                if board[i][j]==2:
                    board[i][j]=1
                elif board[i][j]==-1:
                    board[i][j]=0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

徐小磊xl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值