【排序-中等】948. 令牌放置

【题目】
你的初始 能量 为 P,初始 分数 为 0,只有一包令牌 tokens 。其中 tokens[i] 是第 i 个令牌的值(下标从 0 开始)。
令牌可能的两种使用方法如下:
如果你至少有 token[i] 点 能量 ,可以将令牌 i 置为正面朝上,失去 token[i] 点 能量 ,并得到 1 分 。
如果我们至少有 1 分 ,可以将令牌 i 置为反面朝上,获得 token[i] 点 能量 ,并失去 1 分 。
每个令牌 最多 只能使用一次,使用 顺序不限 ,不需 使用所有令牌。
在使用任意数量的令牌后,返回我们可以得到的最大 分数 。
【示例 1】
输入:tokens = [100], P = 50
输出:0
解释:无法使用唯一的令牌,因为能量和分数都太少了。
【示例 2】
输入:tokens = [100,200], P = 150
输出:1
解释:令牌 0 正面朝上,能量变为 50,分数变为 1 。不必使用令牌 1 ,因为你无法使用它来提高分数。
【示例 3】
输入:tokens = [100,200,300,400], P = 200
输出:2
解释:按下面顺序使用令牌可以得到 2 分:

  1. 令牌 0 正面朝上,能量变为 100 ,分数变为 1
  2. 令牌 3 正面朝下,能量变为 500 ,分数变为 0
  3. 令牌 1 正面朝上,能量变为 300 ,分数变为 1
  4. 令牌 2 正面朝上,能量变为 0 ,分数变为 2
    提示
    0 <= tokens.length <= 1000
    0 <= tokens[i], P < 104
    【代码】
    【Python】
class Solution:
    def bagOfTokensScore(self, tokens: List[int], P: int) -> int:
        tokens.sort()
        #目标:更多的分数
        #1分可以换取一个令牌的能量,将该令牌反面向上
        #分数尽可能换成右侧的,翻令牌得分尽可能使用左侧的
        cnt,maxcnt=0,0
        l,r=0,len(tokens)-1

        #特殊情况预处理流程
        if l==r and P>=tokens[0]:
            return 1
        elif tokens and  P<tokens[0]:
            return 0

        #一般情况处理流程
        while l<r:
            while P>=tokens[l]:
                P-=tokens[l]
                l+=1        #下标+1
                cnt+=1      #分数+1
            #能量不够了 退出循环
            #用一分换取能量,先判断是否有分数可换取
            if cnt:
                maxcnt=max(maxcnt,cnt)
                P+=tokens[r]
                r-=1
                cnt-=1
            else:
                break
            print(P,l,r)
        return maxcnt

【方法2】

class Solution(object):
    def bagOfTokensScore(self, tokens, P):
        tokens.sort()
        deque = collections.deque(tokens)
        ans = bns = 0
        while deque and (P >= deque[0] or bns):
            while deque and P >= deque[0]:
                P -= deque.popleft()
                bns += 1
            ans = max(ans, bns)

            if deque and bns:
                P += deque.pop()
                bns -= 1

        return ans
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值