LeetCode 每日一题 2025/1/20-2025/1/26

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




1/20 2239. 找到最接近 0 的数字

遍历记录最小差值

def findClosestNumber(nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    ans = float("inf")
    for num in nums:
        if abs(num)<abs(ans) or (abs(num)==abs(ans) and num>ans):
            ans = num
    return ans



1/21 2218. 从栈中取出 K 个硬币的最大面值和

dp[i]表示i次操作可以得到的最大值
对于每个栈最多取k个数

def maxValueOfCoins(piles, k):
    """
    :type piles: List[List[int]]
    :type k: int
    :rtype: int
    """
    dp=[0]+[-1]*k
    for p in piles:
        for i in range(k,0,-1):
            v = 0
            for t in range(1,len(p)+1):
                v+=p[t-1]
                if i>=t and dp[i-t]!=-1:
                    dp[i]=max(dp[i],dp[i-t]+v)
    return dp[k]



1/22 1561. 你可以获得的最大硬币数目

每次选最大的两堆和最小的一堆 让自己可以拿到更多硬币
每个人取k个 从大到小排序 隔一个取一个取k个

def maxCoins(piles):
    """
    :type piles: List[int]
    :rtype: int
    """
    k = len(piles)//3
    piles.sort(reversed=True)
    return sum(piles[1:2*k:2])



1/23 2920. 收集所有金币可获得的最大积分

dfs 记录做了多少次减半操作
node为当前节点 p为父节点
f为之前已经做过减半操作的次数
ans0 ans1分别代表进行操作一、二的结果

def maximumPoints(edges, coins, k):
    """
    :type edges: List[List[int]]
    :type coins: List[int]
    :type k: int
    :rtype: int
    """
    n= len(coins)
    c = [[] for _ in range(n)]
    for x,y in edges:
        c[x].append(y)
        c[y].append(x)
        
    mem={}
    def dfs(node,p,f):
        if (node,p,f) in mem:
            return mem[(node,p,f)]
        ans0 = (coins[node]>>f)-k
        ans1 = coins[node]>>(f+1) if f+1<14 else 0
        for child in c[node]:
            if child==p:
                continue
            ans0 += dfs(child,node,f)
            if f+1<14:
                ans1+=dfs(child,node,f+1)
        ans=max(ans0,ans1)
        mem[(node,p,f)]=ans
        return ans
    return dfs(0,-1,0)



1/24 2944. 购买水果需要的最少金币数

单调队列
f[i]表示购买i的情况下 获取后面所有水果最少金币数

def minimumCoins(prices):
    """
    :type prices: List[int]
    :rtype: int
    """
    n=len(prices)
    l = [(n+1,0)]
    for i in range(n,0,-1):
        while l[-1][0]>i*2+1:
            l=l[:-1]
        f = prices[i-1]+l[-1][1]
        while f<=l[0][1]:
            l=l[1:]
        l = [(i,f)]+l
    return l[0][1]



1/25 2412. 完成所有交易的初始最少钱数

每次交易有两种情况 亏 或者 不亏
任意交易顺序都要能完成 最坏的情况就是最先遇到的都是亏的
total记录所有亏钱总和
对于赚钱的情况cost<=cashback 假设是第一笔赚钱 那么经过了所有亏钱交易 需要total+cost 初始钱数
对于亏钱的情况cost>cashback 假设是最后一笔亏钱 需要total+cashback 初始钱数
综上两种情况都是 total+min(cost,cashback)

def minimumMoney(transactions):
    """
    :type transactions: List[List[int]]
    :rtype: int
    """
    total = mx = 0
    for cst,back in transactions:
        total += max(cst-back,0)
        mx = max(mx,min(cst,back))
    return total+mx



1/26 40. 组合总和 II

递归
1.按顺序排序 记录使用过的位置loc 防止继续取到前面的数造成重复
因为有重复的数字 所以set要防重复
2.不用set防重复 直接排序后移动 并且判断当前是否已经有重复的了

def combinationSum2(candidates, target):
    """
    :type candidates: List[int]
    :type target: int
    :rtype: List[List[int]]
    """
    candidates = sorted(candidates)
    ans=set()
    def dfs(v,l,nums,loc):
        print(v,l,nums)
        if v==0:
            ans.add(tuple(l))
            return
        if not nums:
            print("empty")
            return
        for i in range(loc,len(nums)):
            tmpl = l[:]
            tmp = nums[:]
            c = tmp.pop(i)
            if c>v:
                return
            tmpl.append(c)
            dfs(v-c,tmpl,tmp,i)
            
    dfs(target,[],candidates,0)
    ret = [list(i) for i in ans]
    return ret
    print(ret)
    
    
def combinationSum22(candidates, target):
    """
    :type candidates: List[int]
    :type target: int
    :rtype: List[List[int]]
    """
    candidates = sorted(candidates)
    n = len(candidates)
    ret = []
    def dfs(v,l,loc):
        print(v,l,candidates)
        if v==0:
            ret.append(l)
            return
        for i in range(loc,n):
            value = candidates[i]
            if value>v: #有序排列 后面的都不符合
                return
            if  i>loc and candidates[i]==candidates[i-1]:
                continue
            tmp = l[:]
            tmp.append(candidates[i])
            dfs(v-value,tmp,i+1)
            
    dfs(target,[],0)
    return ret
    print(ret)



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值