记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
BFS 模拟
搜索所有区域 遇到病毒后
广搜并将连在一起的病毒打上相同的标签-tag
同时统计这片区域下一步会影响到的邻居数量
def containVirus(isInfected):
"""
:type isInfected: List[List[int]]
:rtype: int
"""
ans = 0
m,n = len(isInfected),len(isInfected[0])
while True:
neighbors = []
firewalls = []
for i in range(m):
for j in range(n):
if isInfected[i][j]== 1:
l = [(i,j)]
tag = len(neighbors)+1
neighbor = set()
fw = 0
isInfected[i][j] = -tag
while l:
tmp = []
for x,y in l:
for mx,my in [(0,1),(1,0),(0,-1),(-1,0)]:
nx,ny = x+mx,y+my
if 0<=nx<m and 0<=ny<n:
if isInfected[nx][ny]==1:
tmp.append((nx,ny))
isInfected[nx][ny] = -tag
elif isInfected[nx][ny]==0:
fw +=1
neighbor.add((nx,ny))
l = tmp[:]
neighbors.append(neighbor)
firewalls.append(fw)
if not neighbors:
break
tag = 0
for i in range(1,len(neighbors)):
if len(neighbors[i])>len(neighbors[tag]):
tag = i
ans += firewalls[tag]
for i in range(m):
for j in range(n):
if isInfected[i][j]<0:
if isInfected[i][j]==-tag-1:
isInfected[i][j] = 2
else:
isInfected[i][j] = 1
for i,nb in enumerate(neighbors):
if i!=tag:
for x,y in nb:
isInfected[x][y] = 1
if len(neighbors)==1:
break
return ans
线段树 动态开点
val记录各节点已有次数
lazy懒标记 记录该节点内子节点已有次数未下发
class MyCalendarTwo(object):
def __init__(self):
self.val = {}
self.lazy = {}
def update(self,start,end,l,r,idx,val):
if start>r or end<l:
return
if start<=l and r<=end:
self.val[idx] = self.val.get(idx,0)+val
self.lazy[idx] = self.lazy.get(idx,0)+val
return
mid = (l+r)>>1
self.update(start,end,l,mid,2*idx,val)
self.update(start,end,mid+1,r,2*idx+1,val)
v = max(self.val.get(2*idx,0),self.val.get(2*idx+1,0))
self.val[idx] = self.lazy.get(idx,0)+v
def book(self, start, end):
"""
:type start: int
:type end: int
:rtype: bool
"""
self.update(start,end-1,0,10**9,1,1)
if self.val.get(1,0)>2:
self.update(start,end-1,0,10**9,1,-1)
return False
return True
mn 对于grid[i][j] 标记为in+j
每个数移动k次 找到移动后的标记位
def shiftGrid(grid, k):
"""
:type grid: List[List[int]]
:type k: int
:rtype: List[List[int]]
"""
m,n = len(grid),len(grid[0])
ans = [[0]*n for _ in range(m)]
total = m*n
for i in range(m):
for j in range(n):
loc = (i*n+j+k)%total
x = loc//n
y = loc%n
ans[x][y] = grid[i][j]
return ans
dfs 检查两个子树
如果子树都为0 并且自身为0 返回true
class TreeNode(object):
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def pruneTree(root):
"""
:type root: Optional[TreeNode]
:rtype: Optional[TreeNode]
"""
def check(node):
if not node:
return True
l = check(node.left)
if l:
node.left = None
r = check(node.right)
if r:
node.right = None
if l and r and node.val==0:
return True
return False
if check(root):
return None
return root
将intervals排序 按x[0]升序 x[1]降序
确保x[0]相同时 靠后的x[1]被前一个包含
从后往前考虑
对于排在后面的区间来说 为了和前面的区间有更多的交集
取最前面的两个数为好
使用last1,last2记录当前最靠前的两个数
对于当前的区间x来说
如果last2<=x[1]说明已有的两个数在x内 不必再添加
如果last1<=x[1]说明一个数在x内 需要添加一个 此时添加x第一个数x[0]最优 其最有可能在前一个区间内
否则 说明没有数在当前x内 需要添加两个 x[0],x[0]+1
def intersectionSizeTwo(intervals):
"""
:type intervals: List[List[int]]
:rtype: int
"""
intervals.sort(key=lambda x: (x[0], -x[1]))
ans, n = 0, len(intervals)
last1,last2 = intervals[-1][0],intervals[-1][0]+1
ans = 2
for i in range(n-2,-1,-1):
if intervals[i][1]>=last2:
continue
elif intervals[i][1]>=last1:
last1,last2 = intervals[i][0],last1
ans +=1
else:
last1,last2 = intervals[i][0],intervals[i][0]+1
ans +=2
return ans
将每个子序列内相邻两个点看作一条边
将所有入度为0的加入队列 拓扑排序
如果队列内节点大于一个 则说明不唯一
如果队列元素为1个 则取出 将数字指向的每个节点入度-1
def sequenceReconstruction(nums, sequences):
"""
:type nums: List[int]
:type sequences: List[List[int]]
:rtype: bool
"""
from collections import defaultdict
n = len(nums)
inD = [0]*n
m = defaultdict(list)
for s in sequences:
for i in range(len(s)-1):
x,y = s[i],s[i+1]
m[x].append(y)
inD[y-1]+=1
l = [i for i,v in enumerate(inD) if v==0]
while l:
tmp = []
if len(l)>1:
return False
for x in l:
for y in m[x+1]:
inD[y-1]-=1
if inD[y-1]==0:
tmp.append(y)
l = tmp
return True
先求总和total
从start向右到dest距离可以遍历得到x 从start向左到dest可以total-x
def distanceBetweenBusStops(distance, start, destination):
"""
:type distance: List[int]
:type start: int
:type destination: int
:rtype: int
"""
n = len(distance)
total = sum(distance)
x = 0
while start!=destination:
x += distance[start]
start = (start+1)%n
return min(x,total-x)