目录
一、661. 图片平滑器
1.二维前缀和
cnt求法参考题解(. - 力扣(LeetCode))。
class Solution:
def imageSmoother(self, img: List[List[int]]) -> List[List[int]]:
# 二维前缀和
# 时复O(m * n),空复O(m * n)
m, n = len(img), len(img[0]) # m * n
# pad = 2
for i in range(m):
img[i] = [0, 0] + img[i] + [0, 0]
'''
# 错误写法
pad = [[0] * (n + 4) for _ in range(2)]
img = pad + img + pad
会导致两头关联在同一数组上,值一起改变
'''
img = [[0] * (n + 4) for _ in range(2)] + img + [[0] * (n + 4) for _ in range(2)]
m += 4
n += 4
# 求前缀和
for i in range(2, m):
for j in range(2, n):
img[i][j] += img[i][j - 1] + img[i - 1][j] - img[i - 1][j - 1]
# 对前缀和数组求平均值
newImg = [[0] * (n - 4) for _ in range(m - 4)]
for i in range(2, m - 2):
for j in range(2, n - 2):
total = img[i + 1][j + 1] - img[i - 2][j + 1] - img[i + 1][j - 2] + img[i - 2][j - 2]
a, b = max(i - 1, 2), max(j - 1, 2)
c, d = min(i + 1, m - 3), min(j + 1, n - 3)
cnt = (c - a + 1) * (d - b + 1)
newImg[i - 2][j - 2] = total // cnt
# # 处理掉pad
# img = img[2:-2]
# for i in range(len(img)):
# img[i] = img[i][2:-2]
return newImg
2.模拟
class Solution:
def imageSmoother(self, img: List[List[int]]) -> List[List[int]]:
# 模拟
# 时复O(m * n * (C ^ 2)),空复O(m * n)
m, n = len(img), len(img[0]) # m * n
newImg = [[0] * n for _ in range(m)]
for i in range(m):
for j in range(n):
total, cnt = 0, 0
for x in range(max(i - 1, 0), min(i + 1, m - 1) + 1):
for y in range(max(j - 1, 0), min(j + 1, n - 1) + 1):
total += img[x][y]
cnt += 1
newImg[i][j] = total // cnt
return newImg
二、598. 区间加法 II
数学
class Solution:
def maxCount(self, m: int, n: int, ops: List[List[int]]) -> int:
# 数学
# 求最小重叠区域
'''
原理:二维前缀和
差分数组元素全为0
# 二维前缀和
if not ops:
return m * n
# 差分数组
diff = [[0] * n for _ in range(m)]
for x, y in ops:
diff[x - 1][y - 1] += 1
# 寻找
cntX, cntY = m, n
for i in range(m):
for j in range(n):
if diff[i][j] != 0:
# 最小重叠区域的个数即为最大元素的个数
cntX = min(cntX, i + 1)
cntY = min(cntY, j + 1)
return cntX * cntY
本质上ops出现的位置即为重叠区域
即不用使用差分数组,直接求最小区域即可
'''
cntX, cntY = m, n
for x, y in ops:
cntX = min(cntX, x)
cntY = min(cntY, y)
return cntX * cntY
三、419. 甲板上的战舰
模拟,一次扫描
class Solution:
def countBattleships(self, board: List[List[str]]) -> int:
# 模拟,一次扫描
# 时复O(m * n),空复O(1)
cnt = 0
m, n = len(board), len(board[0])
for i in range(m):
for j in range(n):
ship = board[i][j]
if ship == '.':
continue
if (i == 0 or board[i - 1][j] == '.') and (j == 0 or board[i][j - 1] == '.'):
# 取决于左边和上面是不是'X'
cnt += 1
return cnt
完
感谢你看到这里!一起加油吧!