参考灵神和闫总的讲解和代码:
https://www.bilibili.com/video/BV1rP411s7Z5
https://space.bilibili.com/206214
7006. 销售利润最大化
https://leetcode.cn/problems/maximize-the-profit-as-the-salesman/
Solution
动态规划 + 哈希表
首先按照 end
的顺序分组,每个组记录所有以 end
为终点的区间。
f[i+1]
表示不超过 i
的房屋的最大盈利。
- 若编号
i
的房屋不卖,从上一个编号转移过来,f[i + 1] = f[i]
- 若卖,需要遍历所有以
i
为终点的区间,找出最大的f[s] + g
- 取最大即可
class Solution:
def maximizeTheProfit(self, n: int, offers: List[List[int]]) -> int:
groups = [[] for _ in range(n)]
for s, e, g in offers:
groups[e].append((s, g))
# f[i+1] 表示编号不超过 i 的房屋的最大盈利
f = [0] * (n + 1)
for end, group in enumerate(groups):
# 不选
f[end + 1] = f[end]
for s, g in group:
# 选
f[end + 1] = max(f[end + 1], f[s] + g)
return f[n]
6467. 找出最长等值子数组
https://leetcode.cn/problems/find-the-longest-equal-subarray/
Solution
同相双指针
class Solution:
def longestEqualSubarray(self, nums: List[int], k: int) -> int:
pos = [[] for _ in range(len(nums) + 1)]
for i, x in enumerate(nums):
pos[x].append(i)
ans = 0
for ps in pos:
left = 0
for right, p in enumerate(ps):
while p - ps[left] - (right - left) > k:
left += 1
ans = max(ans, right - left + 1)
return ans
Solution
暴力方法
class Solution:
def minimumOperations(self, nums: List[int]) -> int:
# 暴力方法
res = n = len(nums)
for i in range(n + 1):
for j in range(n - i + 1):
cnt = 0
for k in range(n):
t = -1
if k <= i - 1:
t = 1
elif k <= i + j - 1:
t = 2
else:
t = 3
# 有多少不同
if t != nums[k]:
cnt += 1
res = min(res, cnt)
return res
最长子序列
@https://leetcode.cn/u/xiongxyowo/
最长递增子序列。为了在最少操作次数内使得数组有序,我们只需要对不在最长递增子序列中的元素进行修改,使其满足递增要求即可。也就是求原数组长度减去最长递增子序列长度。
例如,[1,3,2,1,3,3]
的最长递增子序列为[1,-,2,-,3,3]
,我们只需要修改[-,3,-,1,-,-]
即可。代码如下:
class Solution:
def minimumOperations(self, nums: List[int]) -> int:
n = len(nums)
dp = [1] * n
for i in range(1, n):
for j in range(0, i):
if nums[i] >= nums[j]:
dp[i] = max(dp[i], dp[j] + 1)
return n - max(dp)
DP
最少修改多少个数字可以使数组非递减。定义 a, b, c
分别表示以 1, 2, 3
结尾的前缀数组需要修改的最小次数。
class Solution:
def minimumOperations(self, nums: List[int]) -> int:
a, b, c = 0, 0, 0
for x in nums:
aa, bb, cc = a, b, c
if x == 1:
a = aa # 因为本身就是 1,所以不用修改
b = min(aa, bb) + 1
c = min(aa, bb, cc) + 1
elif x == 2:
a = aa + 1
b = min(aa, bb)
c = min(aa, bb, cc) + 1
else:
a = aa + 1
b = min(aa, bb) + 1
c = min(aa, bb, cc)
return min(a, b, c)