【Python LeetCode 专题】每日一题
- 2025/03
- 2829. k-avoiding 数组的最小总和
- 2712. 使所有字符相等的最小成本
- 2716. 最小化字符串长度
2025/03
2829. k-avoiding 数组的最小总和
上 回溯,
class Solution:
def minimumSum(self, n: int, k: int) -> int:
# 思路:对任何一个正整数 x,不能同时存在 k-x
nums = []
ans = 2501
def backtrace(x):
nonlocal ans
if sum(nums) > ans: # 剪枝,比 ans 还大不需要考虑
return
if len(nums) == n: # 终止条件,数组塞满了
ans = min(sum(nums), ans)
return
for i in range(1, 80):
if i not in nums and (k - i) not in nums: # 当 k-i 不在数组中才可以选
nums.append(i) # 做选择
backtrace(x+1) # 递归
nums.pop() # 撤销选择
return
backtrace(1) # 从小的正整数开始
return ans
不出意外就会超时了!
上 贪心,举例来说, 假设不能选和为 4 的数对,肯定选 1 不选 3 啊! O ( n ) O(n) O(n),
class Solution:
def minimumSum(self, n: int, k: int) -> int:
# 思路:对任何一个正整数 x,不能同时存在 k-x
nums = []
sum = 0
for i in range(1, 100):
if len(nums) == n: # 如果够 n 个就退出循环
break
if (k-i) not in nums: # k-i 不在就塞进数组
nums.append(i)
sum += i
return sum
过了,但是还能优化,直接上数学公式, O ( 1 ) O(1) O(1),
class Solution:
def minimumSum(self, n: int, k: int) -> int:
# 思路:对任何一个正整数 x,不能同时存在 k-x
if 2 * n <= k:
return sum(range(1, n + 1)) # 注意 range 左闭右开
part_num = k - (k // 2 + 1)
return sum(range(1, k // 2 + 1)) + sum(range(k, n + part_num + 1))
2712. 使所有字符相等的最小成本
class Solution:
def minimumCost(self, s: str) -> int:
# 思路:反转为全 '0' 或全 '1',从中间往两边反转
n = len(s)
mid = n // 2
def reverse_to(to):
""" 反转为 to """
cost = 0
reverse = False
for i in range(mid, -1, -1):
if (s[i] != to and not reverse) or (s[i] == to and reverse):
cost += i + 1
reverse = not reverse
reverse = False
for j in range(mid + 1, n):
if (s[j] != to and not reverse) or (s[j] == to and reverse):
cost += n - j
reverse = not reverse
return cost
return min(reverse_to('0'), reverse_to('1'))
2716. 最小化字符串长度
说人话,不就是去重嘛!上 数据结构,
class Solution:
def minimizedStringLength(self, s: str) -> int:
return len(set(s))
散了散了。。。