LeetCode 每日一题 2024/6/3-2024/6/9

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




6/3 1103. 分糖果 II

base记录当前已经完成了几轮
cur为当前轮需要消耗的总糖果数
当无法完全分一轮时结束 完成了base轮
此时对于i位置(从1开始)的人分到了
i+(i+n)+(i+n2)+…+(i+n(base-1))
=i*base+(base-1)base/2n 个糖果
最后将剩余糖果分一遍即可

def distributeCandies(candies, num_people):
    """
    :type candies: int
    :type num_people: int
    :rtype: List[int]
    """
    n=num_people
    s = (1+n)*n//2
    base = 0
    cur = s
    while candies>=cur:
        candies -= cur
        base +=1
        cur += n*n
    ans = [0]*n
    if base>0:
        ans = [base*(base-1)//2*n+(i+1)*(base) for i in range(n) ]
    for i in range(n):
        v = base*n+i+1
        if v>candies:
            v = candies
        candies-=v
        ans[i]+=v
        if candies==0:
            break
    return ans



6/4 3067. 在带权树网络中统计可连接服务器对数目

g[x]存储节点x的邻居节点
pre记录已经处理过的节点中满足条件的个数
cnt为当前节点满足的个数 相乘即为总对数

def countPairsOfConnectableServers(edges, signalSpeed):
    """
    :type edges: List[List[int]]
    :type signalSpeed: int
    :rtype: List[int]
    """
    n=len(edges)+1
    g = [[] for _ in range(n)]
    for u,v,w in edges:
        g[u].append((v,w))
        g[v].append((u,w))
    
    def dfs(p,root,cur):
        ans = 0
        if cur==0:
            ans+=1
        for v,cost in g[p]:
            if v!=root:
                ans += dfs(v,p,(cur+cost)%signalSpeed)
        return ans
    
    ans = [0]*n
    for i in range(n):
        pre = 0
        for v, cost in g[i]:
            cnt = dfs(v,i,cost%signalSpeed)
            ans[i]+=pre*cnt
            pre+=cnt
    return ans



6/5 3072. 将元素分配到两个数组中 II

假设nums中有m个不同的数值
将数组中的数从小到大离散到[1,m]
利用树状数组查询大于val的元素数量

def resultArray(nums):
    """
    :type nums: List[int]
    :rtype: List[int]
    """
    class Tree:
        def __init__(self,n):
            self.v = [0]*n
        def add(self,i):
            while i<len(self.v):
                self.v[i]+=1
                i += i&-i
        def get(self,i):
            ans = 0
            while i>0:
                ans += self.v[i]
                i&=i-1
            return ans
    n=len(nums)
    snums = sorted(nums)
    ind ={}
    for i,v in enumerate(snums):
        ind[v]=i+1
    arr1 = [nums[0]]
    arr2 = [nums[1]]
    t1 = Tree(n+1)
    t2 = Tree(n+1)
    t1.add(ind[nums[0]])
    t2.add(ind[nums[1]])
    for i in range(2,n):
        cnt1 = len(arr1)-t1.get(ind[nums[i]])
        cnt2 = len(arr2)-t2.get(ind[nums[i]])
        if cnt1>cnt2 or (cnt1==cnt2 and len(arr1)<=len(arr2)):
            arr1.append(nums[i])
            t1.add(ind[nums[i]])
        else:
            arr2.append(nums[i])
            t2.add(ind[nums[i]])
    return arr1+arr2



6/6 2938. 区分黑球与白球

将白球0移到左侧 黑球1移到右侧
对于每一个0 对于它左侧的所有1都需要交换一次
从头遍历 记录遇到的1的个数cnt
没遇到一个0都需要移动cnt次

def minimumSteps(s):
    """
    :type s: str
    :rtype: int
    """
    ans=cnt=0
    for c in s:
        if c=='1':
            cnt +=1
        else:
            ans += cnt
    return ans



6/7 3038. 相同分数的最大操作数目 I

依次判断

def maxOperations(nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    ans = 0
    v = 0
    while len(nums)>=2:
        if v==0:
            v = nums[0]+nums[1]
        elif v!=nums[0]+nums[1]:
            break
        ans+=1
        nums = nums[2:]
    return ans



6/8 3040. 相同分数的最大操作数目 II

共有三种情况考虑
func考虑从[i,j]区间内 分数为target能得到的操作数

def maxOperations(nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    mem={}
    def func(i,j,target):
        if (i,j,target) in mem:
            return mem[(i,j,target)]
        ans = 0
        if j-i>=1:
            if nums[i]+nums[i+1]==target:
                ans = max(ans,1+func(i+2,j,target))
            if nums[i]+nums[j]==target:
                ans = max(ans,1+func(i+1,j-1,target))
            if nums[j]+nums[j-1]==target:
                ans = max(ans,1+func(i,j-2,target))
        mem[(i,j,target)] = ans
        return ans
    ans = 0
    n=len(nums)
    if len(nums)>=2:
        ans = max(ans,1+func(2,n-1,nums[0]+nums[1]),1+func(1,n-2,nums[0]+nums[-1]),1+func(0,n-3,nums[-1]+nums[-2]))
    return ans



6/9 312. 戳气球

动态规划
分别在前后加一个1方便计算
dp[i][j]表示区间i,j内气球能够得到最多硬币数
假设i,j内的k是最后一个被戳破的气球
状态转移为
dp[i][j]=max(dp[i][j],dp[i][k]+dp[k][j]+arr[i]*arr[k]*arr[j])

def maxCoins(nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    n=len(nums)
    arr = [1]+nums+[1]
    dp=[[0]*(n+2) for _ in range(n+2)]
    for i in range(n-1,-1,-1):
        for j in range(i+2,n+2):
            for k in range(i+1,j):
                dp[i][j] = max(dp[i][j],dp[i][k]+dp[k][j]+arr[i]*arr[k]*arr[j])
    return dp[0][-1]



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值