记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
dp[i][j]表示节点i的第2^j个祖先
对于dp[i][j] 可以先得到2^(j-1)的祖先dp[i][j-1]
然后再找这个祖先的2^(j-1)祖先 及dp[dp[i][j-1]][j-1]
class TreeAncestor(object):
def __init__(self, n, parent):
"""
:type n: int
:type parent: List[int]
"""
self.dp = [[] for _ in range(n)]
for i in range(n):
self.dp[i].append(parent[i])
j=1
while True:
tag = True
for i in range(n):
v = -1
if self.dp[i][j-1]!=-1:
v = self.dp[self.dp[i][j-1]][j-1]
self.dp[i].append(v)
if v!=-1:
tag = False
if tag:
break
j+=1
def getKthAncestor(self, node, k):
"""
:type node: int
:type k: int
:rtype: int
"""
ans = node
pos = 0
while k and ans!=-1:
if pos>=len(self.dp[ans]):
return -1
if k&1:
ans = self.dp[ans][pos]
k = k>>1
pos+=1
return ans
统计每个整数出现次数
def unequalTriplets(nums):
"""
:type nums: List[int]
:rtype: int
"""
from collections import defaultdict
m = defaultdict(int)
for num in nums:
m[num]+=1
n = len(nums)
l = 0
ans = 0
for v in m.value():
ans += l*v*(n-l-v)
l+=v
return ans
记录翻转最大位置
如果最大位置等于翻转次数 说明满足
def numTimesAllBlue(flips):
"""
:type flips: List[int]
:rtype: int
"""
ans,r = 0,0
for i,v in enumerate(flips):
r = max(r,v)
if r==i+1:
ans +=1
return ans
可以重新排列 所以最多一个字符出现奇数次可以构成回文串
用26位二进制来表示字符串每个字母的奇偶性 m用来存储前缀
getnum用来获取字符串中有多少个奇数次的字母
def canMakePaliQueries( s, queries):
"""
:type s: str
:type queries: List[List[int]]
:rtype: List[bool]
"""
def getnum(v):
num = 0
while v>0:
if v!=0:
v = v&(v-1)
num+=1
return num
n = len(s)
m = [0]*(n+1)
for i in range(n):
m[i+1] = m[i]^(1<<(ord(s[i])-ord('a')))
ans = []
for l,r,k in queries:
total = getnum(m[r+1]^m[l])
ans.append(total<=k*2+1)
return ans
pre[x]用一个n位的二进制 来存储课程x的先修课
dp[i]表示上完i中课程最少需要的学期
def minNumberOfSemesters(n, relations, k):
"""
:type n: int
:type relations: List[List[int]]
:type k: int
:rtype: int
"""
if len(relations)==0:
return (n+k-1)//k
pre = [0]*n
for x,y in relations:
pre[y-1] |= 1<<(x-1)
u=(1<<n)-1
dp = [float("inf")]*(1<<n)
dp[0]=0
for i in range(1,1<<n):
c = u^i
num = 0
for j,p in enumerate(pre):
if i>>j&1 and p|c==c:
num |=1<<j
if num.bit_count() <=k:
dp[i] =dp[i^num]+1
continue
j=num
while j:
if j.bit_count()<=k:
dp[i]=min(dp[i],dp[i^j]+1)
j=(j-1)&num
return dp[u]
n等分 最多n次切割
每个扇形角度为x=360/n 如果角度x为180因数
说明有两次切割能合并为一次 即n为偶数
def numberOfCuts(n):
"""
:type n: int
:rtype: int
"""
if n==1:
return 0
if n%2==0:
return n//2
return n