滑动窗口
乘积小于 k 的连续的子数组
给定一个正整数数组 nums和整数 k ,请找出该数组内乘积小于 k 的连续的子数组的个数
思想:关键的点在于记录个数的时候,某个窗口内的子数组个数大小 right-left+1,是因为我们需要从右边开始数,如果从左边开始就有重复。
比如某次遍历符合题意的子数组为 ABCX,那么在该条件下符合条件的有X,CX,BCX,ABCX共四个(可以进行多个例子,发现个数符合right-left+1)
class Solution:
def numSubarrayProductLessThanK(self, nums: List[int], k: int) -> int:
left, res = 0, 0
total = 1
for right,num in enumerate(nums):
total *= num
while left <= right and total >= k:
total //= nums[left] ### key point
left += 1
if left <= right:
res += right-left+1 ### key point
return res
前缀和
和为 k 的连续子数组
给定一个整数数组和一个整数 k ,请找到该数组中和为 k 的连续子数组的个数。
思想:前缀和+哈希。求数组前缀和,并且将当前的前缀和存到哈希表中,每次求出一个前缀和只需要判断preSum[i] - k在没在前面出现过即可
class Solution:
def subarraySum(self, nums: List[int], k: int) -> int:
presum_map = defaultdict(int)
presum_map[0] = 1
presum, ans = 0, 0
for i in range(len(nums)):
presum += nums[i]
target = presum - k
if target in presum_map:
ans += presum_map[target]
presum_map[presum] += 1
return ans
ascii码
码与数字的转换
ord('a')
chr(65)
0--48
A--65
a--97
最小公倍数
在最大的数的倍数里面去找能整除另一个数的数就是最小公倍数,按照大的数来找来降低循环的次数
while True:
try:
a, b = list(map(int, input().split()))
if a < b:
a,b = b,a
for i in range(a, a*b+1, a):
if i % b == 0:
print(i)
break
except:
break
岛屿问题
岛屿数量
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
row, col, ret = len(grid), len(grid[0]), 0
def dfs(x,y):
grid[x][y] = '0' # 遍历过的标记为 0
for c in [[0,1], [0,-1], [-1,0], [1,0]]:
nx, ny = x+c[0], y+c[1]
if 0 <= nx < row and 0 <= ny < col and grid[nx][ny] == '1':
dfs(nx, ny)
for i in range(row):
for j in range(col):
if grid[i][j] == '1':
dfs(i,j)
ret += 1
return ret
岛屿的周长
遇到边界或者是水的话就+1
class Solution:
def islandPerimeter(self, grid: List[List[int]]) -> int:
row, col = len(grid), len(grid[0])
def dfs(grid, i, j):
if not 0 <= i < row or not 0 <= j < col: # 边界
return 1
if grid[i][j] == 0: # 水
return 1
if grid[i][j] != 1: # 已经遍历过
return 0
grid[i][j] = 2 # 标记已经遍历过的
return dfs(grid, i-1, j) + dfs(grid, i, j-1) + dfs(grid, i+1, j) + dfs(grid, i, j+1)
for i in range(row):
for j in range(col):
if grid[i][j] == '1':
return dfs(grid, i, j)
岛屿的最大面积
想法就是每找到一个岛,数一数里边1的个数
class Solution:
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
row, col, max_ = len(grid), len(grid[0]), 0
def dfs(grid, i, j):
if not 0 <= i < row or not 0 <= j < col or not grid[i][j]:
return
grid[i][j] = 0
self.res += 1
dfs(grid, i, j+1)
dfs(grid, i, j-1)
dfs(grid, i-1, j)
dfs(grid, i+1, j)
return self.res
for i in range(row):
for j in range(col):
if grid[i][j] == 1:
self.res = 0
max_ = max(max_, dfs(grid, i ,j))
return max_
统计子岛屿
有两个岛屿,如果 grid2 的一个岛屿,被 grid1 的一个岛屿 完全 包含,也就是说 grid2 中该岛屿的每一个格子都被 grid1 中同一个岛屿完全包含,那么我们称 grid2 中的这个岛屿为 子岛屿 。
class Solution:
def countSubIslands(self, grid1: List[List[int]], grid2: List[List[int]]) -> int:
row, col = len(grid1), len(grid1[0])
def dfs(grid, i, j):
grid[i][j] = 0 # 将搜索过的岛屿置0,防止重复搜索
for c in [[-1,0], [1,0], [0,-1], [0,1]]:
n_i, n_j = i+c[0], j+c[1]
if 0<= n_i < row and 0 <= n_j < col and grid[n_i][n_j] == 1: # 搜索点符合要求且为陆地
dfs(grid, n_i, n_j)
# 首先将2中岛屿不被1中包含的剔除掉
for i in range(row):
for j in range(col):
if grid2[i][j] == 1 and grid1[i][j] == 0:
dfs(grid2, i, j)
res = 0
for i in range(row):
for j in range(col):
if grid2[i][j] == 1:
dfs(grid2, i, j)
res += 1
return res