链接:LeetCode
[Leetcode]5376. 非递增顺序的最小子序列
给你一个数组 nums,请你从中抽取一个子序列,满足该子序列的元素之和 严格 大于未包含在该子序列中的各元素之和。如果存在多个解决方案,只需返回 长度最小 的子序列。如果仍然有多个解决方案,则返回 元素之和最大 的子序列。
与子数组不同的地方在于,「数组的子序列」不强调元素在原数组中的连续性,也就是说,它可以通过从数组中分离一些(也可能不分离)元素得到。
注意,题目数据保证满足所有约束条件的解决方案是 唯一 的。同时,返回的答案应当按 非递增顺序 排列。
排序不解释。
class Solution:
def minSubsequence(self, nums: List[int]) -> List[int]:
if len(nums)<2:
return nums
nums.sort(reverse=True)
sum_ = sum(nums)
res = []
cur = 0
for num in nums:
res.append(num)
cur += num
if cur > sum_-cur:
break
return res
[Leetcode]5377. 将二进制表示减到 1 的步骤数
给你一个以二进制形式表示的数字 s 。请你返回按下述规则将其减少到 1 所需要的步骤数:
如果当前数字为偶数,则将其除以 2 。
如果当前数字为奇数,则将其加上 1 。
题目保证你总是可以按上述规则将测试用例变为 1 。
直接对二进制数组进行操作
偶数时,最后一位是'0',除以2即去掉最后一位,整体右移一个单位
奇数时,二进制加法,注意首位进位的问题
class Solution:
def numSteps(self, s: str) -> int:
tmp = 0
while s != '1':
if s[-1] == '0':
s = s[:-1]
tmp += 1
else:
tmp += 1
ans = 1
s = '0'+ s
for i in range(len(s)-1,-1,-1):
if ans==1 and s[i]=='1':
s = s[:i]+'0'+s[i+1:]
ans = 1
elif ans==1 and s[i]=='0':
s = s[:i]+'1'+s[i+1:]
ans = 0
elif ans==0:
break
if s[0] == '0':
s = s[1:]
return tmp
[Leetcode]5195. 最长快乐字符串
如果字符串中不含有任何 'aaa','bbb' 或 'ccc' 这样的字符串作为子串,那么该字符串就是一个「快乐字符串」。
给你三个整数 a,b ,c,请你返回 任意一个 满足下列全部条件的字符串 s:
s 是一个尽可能长的快乐字符串。
s 中 最多 有a 个字母 'a'、b 个字母 'b'、c 个字母 'c' 。
s 中只含有 'a'、'b' 、'c' 三种字母。
如果不存在这样的字符串 s ,请返回一个空字符串 ""。
贪心,每一轮放置字符时优先先放剩余次数最多的, 如果上次放的2个字符和剩余个数最多的字符相同,则放置次多的字符
class Solution:
def longestDiverseString(self, a: int, b: int, c: int) -> str:
d = {'a':min(a,2*(b+c+1)),'b':min(b,2*(a+c+1)),'c':min(c,2*(b+a+1))}
n = sum(d.values())
res = []
for i in range(n):
cand = set(['a','b','c'])
if len(res)>1 and res[-1]==res[-2]:
cand.remove(res[-1])
tmp = max(cand,key=lambda x:d[x])
res.append(tmp)
d[tmp] -= 1
return ''.join(res)
[Leetcode]5379. 石子游戏 III
Alice 和 Bob 用几堆石子在做游戏。几堆石子排成一行,每堆石子都对应一个得分,由数组 stoneValue 给出。
Alice 和 Bob 轮流取石子,Alice 总是先开始。在每个玩家的回合中,该玩家可以拿走剩下石子中的的前 1、2 或 3 堆石子 。比赛一直持续到所有石头都被拿走。
每个玩家的最终得分为他所拿到的每堆石子的对应得分之和。每个玩家的初始分数都是 0 。比赛的目标是决出最高分,得分最高的选手将会赢得比赛,比赛也可能会出现平局。
假设 Alice 和 Bob 都采取 最优策略 。如果 Alice 赢了就返回 "Alice" ,Bob 赢了就返回 "Bob",平局(分数相同)返回 "Tie" 。
一开始,Alice 面临取1、2、3 堆的抉择,Alice 此刻总共能拿多少分,取决于取完 1 or 2 or 3 堆之后面对剩下的这堆石子精分出来的 Bob能拿多少分,因为剩下的分就是 Alice 的。
也就是 dp[i]=Max(sum-dp[i+1],sum-dp[i+2],sum-dp[i+3])dp[i]=Max(sum−dp[i+1],sum−dp[i+2],sum−dp[i+3]) ,dp[i]为石碓 i……n 得最高分数,sum 为 i……n 的石碓分数之和。
那 Alice 的得分即为:dp[0] ,Bob 得分为 sumAll-dp[0]。
这其实是个非常简单的动规。
class Solution:
def stoneGameIII(self, stoneValue: List[int]) -> str:
s = stoneValue
su = 0
dp = [0]*(len(s)+1)+[10000000]*4
for i in range(len(s)-1, -1, -1):
su += s[i]
cho = min(dp[i+1],dp[i+2],dp[i+3])
dp[i] = su - cho
if dp[0]+dp[0]<su:
return "Bob"
elif dp[0]+dp[0]>su:
return "Alice"
return "Tie"
参考:
leetcode