【题目】
你的初始 能量 为 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 分:
- 令牌 0 正面朝上,能量变为 100 ,分数变为 1
- 令牌 3 正面朝下,能量变为 500 ,分数变为 0
- 令牌 1 正面朝上,能量变为 300 ,分数变为 1
- 令牌 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