记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
7/22 2101. 引爆最多的炸弹
统计每个炸弹能够引爆的其他炸弹
l[i]记录第i个炸弹能够引爆的其他炸弹编号
BFS 广搜遍历第一个引爆炸弹的所有情况
mem记录当前已经爆炸的炸弹
li记录接下来可以被引爆的炸弹编号
def maximumDetonation(bombs):
"""
:type bombs: List[List[int]]
:rtype: int
"""
from collections import defaultdict
l = defaultdict(list)
n = len(bombs)
for i in range(n-1):
x,y,r = bombs[i]
for j in range(i+1,n):
xx,yy,rr = bombs[j]
d = (x-xx)**2+(y-yy)**2
if d<=r*r:
l[i].append(j)
if d<=rr*rr:
l[j].append(i)
ans = 1
for i in range(n):
mem = set()
li = [i]
cur = 0
while li:
tmp = []
for ind in li:
if ind in mem:
continue
mem.add(ind)
cur+=1
for nxt in l[ind]:
if nxt not in mem:
tmp.append(nxt)
li=tmp
ans = max(ans,cur)
return ans
7/23 3098. 求出所有子序列的能量和
排序 子序列能量为两两相邻元素的差值绝对值最小值
设dp[i][p][v]表示以i结尾时 有多少个长度为p 能量为v的子序列
从小到大枚举i为最后一个元素 再枚举j为i前一个元素 diff=|nums[i]-nums[j]|
def sumOfPowers(nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
from collections import defaultdict
inf = float("inf")
MOD=10**9+7
n=len(nums)
ans = 0
nums.sort()
d = [[defaultdict(int) for _ in range(k+1)] for _ in range(n)]
for i in range(n):
d[i][1][inf]=1
for j in range(i):
diff = abs(nums[i]-nums[j])
for p in range(2,k+1):
for v,cnt in d[j][p-1].items():
d[i][p][min(diff,v)]=(d[i][p][min(diff,v)]+cnt)%MOD
for v,cnt in d[i][k].items():
ans = (ans+v*cnt%MOD)%MOD
return ans
7/24 2766. 重新放置石块
使用map[x]记录位置x上有石块
依次判断移动操作 将移动from位置标记去除 新增to的标记
def relocateMarbles(nums, moveFrom, moveTo):
"""
:type nums: List[int]
:type moveFrom: List[int]
:type moveTo: List[int]
:rtype: List[int]
"""
m={}
for num in nums:
m[num]=1
for i in range(len(moveFrom)):
f,t=moveFrom[i],moveTo[i]
if f in m:
del m[f]
m[t]=1
return sorted(list(m.keys()))
7/25 2844. 生成特殊数字的最少操作
被25整除 结尾需要为25 50 75 00
从后往前寻找
f0,f5记录是否找到可以作为最后一位的0或者5
如果当前为0或5 且已经找到0 f0=True 说明此时已经可以满足条件 n-i-2个数即可
如果当前为2或7 且已经找到5 f5=True 同理
如果遍历完了没有成功 且找到有0 那么单独一个0也满足条件 删除n-1个字符
def minimumOperations(num):
"""
:type num: str
:rtype: int
"""
n=len(num)
f0,f5=False,False
for i in range(n-1,-1,-1):
if num[i] in ['0','5']:
if f0:
return n-i-2
if num[i]=='0':
f0=True
else:
f5=True
elif num[i] in ['2','7']:
if f5:
return n-i-2
if f0:
return n-1
return n
7/26 2740. 找出分区值
分区值为数组中两个数的
从小到大排序 最小差值必定产生在相邻的两个数中
求出相邻两数差值的最小情况即可
将左侧部分放入nums1 右侧部分放入nums2
def findValueOfPartition(nums):
"""
:type nums: List[int]
:rtype: int
"""
nums.sort()
n=len(nums)
ans = nums[-1]
for i in range(1,n):
ans = min(ans,nums[i]-nums[i-1])
return ans
7/27 3106. 满足距离约束且字典序最小的字符串
字典序最小为a 尽量变成a
从头开始判断能否能在剩余距离k内变成a 如果不行则变小
def getSmallestString(s, k):
"""
:type s: str
:type k: int
:rtype: str
"""
ans = list(s)
for i in range(len(ans)):
v = ord(ans[i])-ord('a')
dis = min(v,26-v)
print(dis,k)
if dis <=k:
ans[i] = 'a'
k-=dis
else:
ans[i] = chr(ord(ans[i])-k)
break
print(ans)
return ''.join(ans)
7/28 699. 掉落的方块
每个方块只需要考虑左右两侧的两个点
pos记录所有方块出现的左右两侧两点
将所有这些点从小到大排序 只需要考虑这些点上的高度
然后依次考虑各个方块
遍历方块所覆盖点最高高度加上方块边长即为 覆盖点的新高度
def fallingSquares(positions):
"""
:type positions: List[List[int]]
:rtype: List[int]
"""
pos = set()
for left,lg in positions:
pos.add(left)
pos.add(left+lg)
pos = sorted(pos)
ind = {}
for i,num in enumerate(pos):
ind[num] = i
li = [0]*len(pos)
ans = []
maxh = 0
for left,lg in positions:
idxl = ind[left]
idxr = ind[left+lg]
h = max(li[idxl:idxr])+lg
maxh = max(maxh,h)
ans.append(maxh)
for i in range(idxl,idxr):
li[i] = h
return ans