LeetCode 每日一题 2023/6/12-2023/6/18

记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步


目录

      • 6/12 1483. 树节点的第 K 个祖先
      • 6/13 2475. 数组中不等三元组的数目
      • 6/14 1375. 二进制字符串前缀一致的次数
      • 6/15 1177. 构建回文串检测
      • 6/16 1494. 并行课程 II
      • 6/17 2481. 分割圆的最少切割次数
      • 6/18


6/12 1483. 树节点的第 K 个祖先

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



6/13 2475. 数组中不等三元组的数目

统计每个整数出现次数

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



6/14 1375. 二进制字符串前缀一致的次数

记录翻转最大位置
如果最大位置等于翻转次数 说明满足

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



6/15 1177. 构建回文串检测

可以重新排列 所以最多一个字符出现奇数次可以构成回文串
用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



6/16 1494. 并行课程 II

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]



6/17 2481. 分割圆的最少切割次数

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




6/18





你可能感兴趣的:(Exercise,leetcode,算法,动态规划)