记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
2/26 938. 二叉搜索树的范围和
dfs 判断节点值是否在区间内
class TreeNode(object):
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def rangeSumBST(root, low, high):
"""
:type root: TreeNode
:type low: int
:type high: int
:rtype: int
"""
def dfs(node):
ret = 0
if node.val>low:
if node.left:
ret = dfs(node.left)
if node.val>=low and node.val<=high:
ret+=node.val
if node.val<high:
if node.right:
ret += dfs(node.right)
return ret
return dfs(root)
2/27 2867. 统计树中的合法路径数目
欧拉筛筛选质数
以质数节点为根 深搜所有非质数的子树
求字数大小 任意两个不同子树节点 路径都通过质数根节点
只有一个节点为质数 符合题意
def countPaths(n, edges):
"""
:type n: int
:type edges: List[List[int]]
:rtype: int
"""
prime=[]
isprime = [True]*(n+1)
isprime[1]=False
for i in range(2,n+1):
if isprime[i]:
prime.append(i)
for p in prime:
if p*i>n:
break
isprime[p*i]=False
if i%p==0:
break
m=[[] for _ in range(n+1)]
for i,j in edges:
m[i].append(j)
m[j].append(i)
global seen
def dfs(i,pre):
global seen
seen.append(i)
for j in m[i]:
if j!=pre and not isprime[j]:
dfs(j,i)
ans = 0
cnt=[0]*(n+1)
for i in range(1,n+1):
if not isprime[i]:
continue
cur = 0
for j in m[i]:
if isprime[j]:
continue
if cnt[j]==0:
seen = []
dfs(j,0)
for k in seen:
cnt[k] = len(seen)
ans+=cnt[j]*cur
cur+=cnt[j]
ans+=cur
return ans
2/28 2673. 使二叉树所有路径值相等的最小代价
满二叉树有n个节点 那么存在(n+1)//2个叶子节点
对于两个兄弟叶子节点 除了改变其自身 无法改变两个节点路径和的差值
所以将小的叶子节点增加到大的即可
改完叶子节点 将叶子节点的值增加到父节点中 依旧考虑父节点和叔节点的情况
def minIncrements(n, cost):
"""
:type n: int
:type cost: List[int]
:rtype: int
"""
ans=0
for i in range(n-2,0,-2):
ans += abs(cost[i]-cost[i+1])
cost[i//2] += max(cost[i],cost[i+1])
return ans
2/29 2581. 统计可能的树根数目
首先计算以0位根节点时猜对的个数cnt
当根节点从0换到其某个子节点x时
除了0,x的父子关系发生变化 其他没有变化
所以如果此时(0,x)在猜测中 则cnt-1
如果(x,0)在猜测中 则cnt+1
遇到cnt>=k 则ans+1
def rootCount(edges, guesses, k):
"""
:type edges: List[List[int]]
:type guesses: List[List[int]]
:type k: int
:rtype: int
"""
g=[[] for _ in range(len(edges)+1)]
for x,y in edges:
g[x].append(y)
g[y].append(x)
s = {(x,y) for x,y in guesses}
global cnt,ans
ans = 0
cnt = 0
def dfs(x,p):
global cnt
for y in g[x]:
if y!=p:
cnt += (x,y) in s
dfs(y,x)
dfs(0,-1)
def reroot(x,p,cnt):
global ans
if cnt>=k:
ans+=1
for y in g[x]:
if y!=p:
reroot(y,x,cnt-((x,y) in s) +((y,x) in s))
reroot(0,-1,cnt)
return ans
3/1 2369. 检查数组是否存在有效划分
dp[i+1]判断是否能够有效划分0~i
def validPartition(nums):
"""
:type nums: List[int]
:rtype: bool
"""
n=len(nums)
dp=[False]*(n+1)
dp[0]=True
for i,x in enumerate(nums):
if (i>0 and dp[i-1] and x==nums[i-1]) or (i>1 and dp[i-2] and (x==nums[i-1]==nums[i-2] or x==nums[i-1]+1==nums[i-2]+2)):
dp[i+1]=True
return dp[n]
3/2 2368. 受限条件下可到达节点的数目
不考虑受限的节点 建图
DFS搜索
def reachableNodes(n, edges, restricted):
"""
:type n: int
:type edges: List[List[int]]
:type restricted: List[int]
:rtype: int
"""
s = set(restricted)
m = [[] for _ in range(n)]
for x,y in edges:
if x not in s and y not in s:
m[x].append(y)
m[y].append(x)
def dfs(x,f):
cnt = 1
for y in m[x]:
if y!=f:
cnt += dfs(y,x)
return cnt
return dfs(0,-1)
3/3 225. 用队列实现栈
队列先进先出 模拟栈从后出即可
class MyStack(object):
def __init__(self):
"""
Initialize your data structure here.
"""
self.stack=[]
def push(self, x):
"""
Push element x onto stack.
:type x: int
:rtype: void
"""
self.stack.append(x)
def pop(self):
"""
Removes the element on top of the stack and returns that element.
:rtype: int
"""
return self.stack.pop()
def top(self):
"""
Get the top element.
:rtype: int
"""
return self.stack[-1]
def empty(self):
"""
Returns whether the stack is empty.
:rtype: bool
"""
return len(self.stack)==0