【力扣hot100】刷题笔记Day7

前言

  • 身边同学已经陆陆续续回来啦,舍友都开始投简历了,我也要加油啦!刷完hot100就投!

73. 矩阵置零 - 力扣(LeetCode)

  • 标记数组:空间复杂度O(m+n)

    • 行数组和列数组分别记录该行/列有没有0,再根据数组置0
    • class Solution:
          def setZeroes(self, matrix: List[List[int]]) -> None:
              m, n = len(matrix), len(matrix[0])
              row, col = [False] * m, [False] * n  # 标记数组
              # 遍历一次,标记对应的行列为0
              for i in range(m):
                  for j in range(n):
                      if matrix[i][j] == 0:
                          row[i] = col[j] = True
              # 遍历二次,根据标记修改对应行列
              for i in range(m):
                  for j in range(n):
                      if row[i] or col[j]:
                          matrix[i][j] = 0
  • 两个标记变量:空间复杂度O(1)

    • 思路参考题解,先记录首行首列有无0,遍历非首行第一次,遇到0就向首行首列汇集,遍历非首行第二次置0,最后再把首行首列置0
    • class Solution:
          def setZeroes(self, matrix: List[List[int]]) -> None:
              m, n = len(matrix), len(matrix[0])
              # 如果可迭代对象中有任何一个元素为 True,则 any 函数返回 True;否则返回 False
              flag_col0 = any(matrix[i][0] == 0 for i in range(m))  # 判断首列是否有0
              flag_row0 = any(matrix[0][j] == 0 for j in range(n))  # 判读首行是否有0
              # 迭代非首行非首列,遇到0就把置0指令放在首行首列
              for i in range(1, m):
                  for j in range(1, n):
                      if matrix[i][j] == 0:
                          matrix[i][0] = matrix[0][j] = 0
              # 迭代非首行非首列,根据指令置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
              # 首列有0,则全置0
              if flag_col0:
                  for i in range(m):
                      matrix[i][0] = 0
              # 首行有0,则全置0
              if flag_row0:
                  for j in range(n):
                      matrix[0][j] = 0
  • 一个标记变量:空间复杂度O(1)

    • 参考题解,保存首行,但是要全部倒序遍历,防止提前更新,太难想仅作参考
    • class Solution:
          def setZeroes(self, matrix: List[List[int]]) -> None:
              m = len(matrix)
              n = len(matrix[0])
              first_row = False   # 标记首行是否有0元素
              for i, row in enumerate(matrix):
                  for j, item in enumerate(row):
                      if i == 0 and item == 0:
                          first_row = True    # 首行出现0元素,用标志位标记
                      elif item == 0:
                          matrix[i][0] = 0    # 非首行出现0元素,将对应的列首置为0,说明该列要置为0
                          matrix[0][j] = 0    # 将对应的行首置为0,说明该行要置为0
              for i in range(m - 1, -1, -1):
                  for j in range(n - 1, -1, -1):
                      # 从最后一个元素反向遍历,避免行首和列首的信息被篡改
                      if i == 0 and first_row:
                          matrix[i][j] = 0    # 首行元素是否置为0看标志位
                      elif i != 0 and (matrix[i][0] == 0 or matrix[0][j] == 0):
                          matrix[i][j] = 0    # 非首行元素是否置为0看行首和列首是否为0

54. 螺旋矩阵 - 力扣(LeetCode)

  • 边界模拟

    • 类似之前C++版本,设置边界,依次循环模拟输出,边界溢出则跳出循环
    • class Solution:
          def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
              res = []
              l, r, u, d = 0, len(matrix[0])-1, 0, len(matrix)-1
              while True:
                  # 向右
                  for i in range(l, r+1): res.append(matrix[u][i])
                  u += 1
                  if u > d: break
                  # 向下
                  for i in range(u, d+1): res.append(matrix[i][r])
                  r -= 1
                  if r < l: break
                  # 向左
                  for i in range(r, l-1, -1): res.append(matrix[d][i])
                  d -= 1
                  if d < u: break
                  # 向上
                  for i in range(d, u-1, -1): res.append(matrix[i][l])
                  l += 1
                  if l > r: break
              return res

 48. 旋转图像 - 力扣(LeetCode)

  • 辅助数组

    • class Solution:
          def rotate(self, matrix: List[List[int]]) -> None:
              n = len(matrix)
              matrix_new = [[0] * n for _ in range(n)]  # 新的n*n的矩阵
              for i in range(n):
                  for j in range(n):
                      # matrix[row][col]旋转到matrix_new[col][n−row−1]
                      matrix_new[j][n-i-1] = matrix[i][j]
              # 不能写成 matrix = matrix_new
              matrix[:] = matrix_new
  •  原地旋转

    • class Solution:
          def rotate(self, matrix: List[List[int]]) -> None:
              n = len(matrix)
              for i in range(n // 2):  # 偶数n/2,奇数(n-1)/2
                  for j in range((n + 1) // 2):  # 偶数n/2,奇数(n+1)/2
                      matrix[i][j], matrix[n-j-1][i], matrix[n-i-1][n-j-1], matrix[j][n-i-1] \
                      = matrix[n-j-1][i], matrix[n-i-1][n-j-1], matrix[j][n-i-1], matrix[i][j]
  •  两次翻转

    • class Solution:
          def rotate(self, matrix: List[List[int]]) -> None:
              n = len(matrix)
              # 上下翻转:只遍历上半部
              for i in range(n // 2):
                  for j in range(n):
                      matrix[i][j], matrix[n-i-1][j] = matrix[n-i-1][j], matrix[i][j]
              # 对角翻转:只遍历下三角
              for i in range(n):
                  for j in range(i):
                      matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]

 240. 搜索二维矩阵 II - 力扣(LeetCode)

  • 直接搜索:N(mn)

    • 就不用传统的遍历写法了,这里记录两种仅用一行就可以实现的搜索算法
    • class Solution:
          def searchMatrix(self, M: List[List[int]], target: int) -> bool:
          # chain()函数于将多个可迭代对象连接成一个单独的迭代器
          # 这里用于连接多个被*M解包得到的多个一维列表   
          return target in chain(*M)
          # 直接利用sum函数转化为一个一维列表
          return target in sum(M,[])
  • 二分查找:N(m*logn))

    • 先写二分查找函数(数组,target)返回True/Fasle,遍历每一个行进行二分查找
    • class Solution:
          def searchMatrix(self, M: List[List[int]], target: int) -> bool:
              def bin_search(arr,target):
                  l,r = 0,len(arr)-1
                  while l <= r:
                      mid = (l+r) // 2
                      if arr[mid] == target:
                          return True
                      elif arr[mid] < target:
                          l = mid + 1
                      else:
                          r = mid - 1
                  return False
              m = len(M)
              # 逐行进行二分查找
              for i in range(m):
                  if bin_search(M[i], target):
                      return True
              return False
  • 贪心BST

    • 也叫折线搜索,来源于题解,图画的很清晰,从右上角出发进行搜索
    • class Solution:
          def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
              row, col = 0, len(matrix[0]) - 1
              # 右上角出发进行搜索
              while row <= len(matrix) - 1 and col >= 0:
                  if target < matrix[row][col]:
                      col -= 1  # 往左移,排除一列
                  elif target > matrix[row][col]:
                      row += 1  # 往下移,排除一行
                  else:
                      return True
              return False

 后言

  • 一题多解的还是尽量每个解都弄懂,前期基础打好点,后面能快速写出最简单的就好啦
  • 23
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值