记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
对于一节node有两种情况 偷 或者 不偷
lrrob函数返回 偷这个node 和 不偷这个node 能够得到的最佳情况
如果这个点为空 那么 偷不偷的情况都是0
获得改点左右子节点的情况 lrob,lnot(偷/不偷左节点) rrob,rnot(偷/不偷右节点)
如果要偷 那么对于就不能偷他的左右子节点 得到 val+lnot+rnot
如果不偷 那么对于左右子节点可以选择偷或不偷 选最大值 max(lrob,lnot)+max(rrob,rnot)
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
def rob(root):
"""
:type root: TreeNode
:rtype: int
"""
def lrrob(node):
if not node:
return 0,0
lrob,lnot = lrrob(node.left)
rrob,rnot = lrrob(node.right)
return node.val+lnot+rnot, max(lrob,lnot)+max(rrob,rnot)
return max(lrrob(root))
二分 偷窃能力必定在min(nums),max(nums)的区间内
对与偷窃能力m
遍历所有房子
只关心偷或者不偷 所以遇到能偷的就偷 统计能偷的数量
def minCapability(nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
l,r = min(nums),max(nums)
while l<r:
m = (l+r)//2
pre,take=0,0
for num in nums:
if pre:
pre=0
continue
if num<=m:
take+=1
pre=1
if take>=k:
break
if take>=k:
r = m
else:
l = m+1
return l
减少次数 每次尽量拿两枚
对于一对n个硬币 需要拿取(n+1)//2次
def minCount(coins):
"""
:type coins: List[int]
:rtype: int
"""
ans = 0
for c in coins:
ans +=(c+1)//2
return ans
如果一个节点度数为1 即只有一个邻居 可以称作叶子节点
如果一个叶子节点没有金币 则这叶子节点可以直接去除
直至所有叶子节点都包含金币
由于可以直接收集距离为2以内的金币 所以我们只需要访问叶子节点的父节点的父节点
将所有叶子节点去除 再将新叶子节点去除 剩余的是我们必须要访问的节点
因为要回到出发点 所以每条边必定走两次
def collectTheCoins(coins, edges):
"""
:type coins: List[int]
:type edges: List[List[int]]
:rtype: int
"""
n= len(coins)
g = [[] for _ in range(n)]
for x,y in edges:
g[x].append(y)
g[y].append(x)
deg = list(map(len,g))
eg = n-1
l = []
for i,(d,c) in enumerate(zip(deg,coins)):
if d==1 and c==0:
l.append(i)
while l:
eg-=1
for y in g[l.pop()]:
deg[y]-=1
if deg[y]==1 and coins[y]==0:
l.append(y)
for i,(d,c) in enumerate(zip(deg,coins)):
if d==1 and c:
l.append(i)
eg -= len(l)
for x in l:
for y in g[x]:
deg[y]-=1
if deg[y]==1:
eg-=1
return max(eg*2,0)
如果钱少于儿童 则没有分配方案
先将每个儿童分配1元 然后查看还能分配出几个7元
处理特殊情况
def distMoney(money, children):
"""
:type money: int
:type children: int
:rtype: int
"""
if money<children:
return -1
left = money-children
ans = min(children,left//7)
if ans+1==children and ans*8+4==money:
ans-=1
if ans==children and ans*8!=money:
ans-=1
return ans
locked[i]用来记录节点i被哪一个用户上锁
parent[i]记录节点i的父节点
children[i] 记录节点i的子节点
dfs判断子孙节点是否由上锁的
class LockingTree(object):
def __init__(self, parent):
"""
:type parent: List[int]
"""
n=len(parent)
self.locked = [-1]*n
self.parent = parent
self.children = [[] for _ in range(n)]
for s,p in enumerate(parent[1:],1):
self.children[p].append(s)
def lock(self, num, user):
"""
:type num: int
:type user: int
:rtype: bool
"""
if self.locked[num]==-1:
self.locked[num]=user
return True
return False
def unlock(self, num, user):
"""
:type num: int
:type user: int
:rtype: bool
"""
if self.locked[num]==user:
self.locked[num]=-1
return True
return False
def upgrade(self, num, user):
"""
:type num: int
:type user: int
:rtype: bool
"""
global find
def dfs(x):
global find
for c in self.children[x]:
if self.locked[c]!=-1:
self.locked[c]=-1
find = True
dfs(c)
x=num
while x!=-1:
if self.locked[x]!=-1:
return False
x = self.parent[x]
find=False
dfs(num)
if not find:
return False
self.locked[num]=user
return True
fr存储最近是用过的key
kw存储key对应的value
from collections import defaultdict
class LRUCache:
def __init__(self, capacity: int):
self.cp = capacity
self.kw = defaultdict(int)
self.fr = []
def get(self, key: int) -> int:
if key in self.kw:
self.fr.remove(key)
self.fr.insert(0,key)
return self.kw[key]
else:
return -1
def put(self, key: int, value: int) -> None:
if key in self.kw or len(self.kw)<self.cp:
self.kw[key] = value
if key in self.fr:
self.fr.remove(key)
self.fr.insert(0,key)
else:
k = self.fr[-1]
print(k,key)
self.kw.pop(k)
self.kw[key] = value
self.fr.remove(k)
self.fr.insert(0,key)