力扣每日一题+python知识点回顾(一)
力扣题目:执行 K 次操作后的最大分数(题号:2530)
给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。你的 起始分数 为 0 。
在一步 操作 中:
- 选出一个满足 0 <= i < nums.length 的下标 i ,
- 将你的 分数 增加 nums[i] ,并且
- 将 nums[i] 替换为 ceil(nums[i] / 3) 。
- 返回在 恰好 执行 k 次操作后,你可能获得的最大分数。
向上取整函数 ceil(val) 的结果是大于或等于 val 的最小整数。
示例 1:
输入:nums = [10,10,10,10,10], k = 5
输出:50
解释:对数组中每个元素执行一次操作。最后分数是 10 + 10 + 10 + 10 + 10 = 50 。
示例 2:
输入:nums = [1,10,3,3,3], k = 3
输出:17
解释:可以执行下述操作:
第 1 步操作:选中 i = 1 ,nums 变为 [1,4,3,3,3] 。分数增加 10 。
第 2 步操作:选中 i = 1 ,nums 变为 [1,2,3,3,3] 。分数增加 4 。
第 3 步操作:选中 i = 2 ,nums 变为 [1,1,1,3,3] 。分数增加 3 。
最后分数是 10 + 4 + 3 = 17 。
编程思路:贪婪算法+大根堆调整
注意:python中没有自带的大根堆只有小根堆,所以需要使用负号取反,再在加上结果时取反。
python小根堆:
小根堆模块:heapq
函数:
1.heapq.heapify(x):创建堆,将list x 转换称堆,时间复杂度线性,空间复杂度原地。
示例:
import heapq
H = [21,1,45,78,3,5] #Use heapify to rearrange the elements
heapq.heapify(H)
print(H)
结果:
[1, 3, 5, 78, 21, 45]
2.heapq.heappush(heap, item):将item的值加入heap中,保持堆的不变性。
示例:
heapq.heappush(H,8)
print(H)
结果:
[1, 3, 5, 78, 21, 45, 8]
3.heapq.heappop(heap):弹出并返回 heap 的最小的元素,保持堆的不变性。如果堆为空,抛出 IndexError 。使用 heap[0] ,可以只访问最小的元素而不弹出它。
示例:
heapq.heappop(H)
print(H)
结果(相比初始堆栈)
[3, 21, 5, 78, 45]
4.heapq.heapreplace(x):总是删除堆中最小的元素,并在未被任何顺序修复的地方插入新的传入元素
示例:
heapq.heapreplace(H,6)
print(H)
结果(相比初始堆栈)
[3, 6, 5, 78, 21, 45]
5.heapq.heappushpop(heap, item):将 item 放入堆中,然后弹出并返回 heap 的最小元素。该组合操作比先调用 heappush() 再调用 heappop() 运行起来更有效率。
enumerate函数
enumerate(sequence, [start=0])
用于将一个可遍历的数据对象(如列表,元组或者字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中
参数:
sequence -- 一个序列、迭代器或其他支持迭代对象。
start -- 下标起始返回值
示例:
nums = [5,7,9]
for t in enumerate(nums):
print(t)
for index,num in enumerate(nums):
print(index,num)
print(list(enumerate(nums)))
print(tuple(enumerate(nums)))
结果
(0, 5)
(1, 7)
(2, 9)
0 5
1 7
2 9
[(0, 5), (1, 7), (2, 9)]
((0, 5), (1, 7), (2, 9))
贪婪算法
要使得分数最大化,我们需要在每一步操作中,选择元素值最大的元素进行操作。因此,我们可以使用优先队列(大根堆)来维护当前元素值最大的元素。
先化成小根堆,即先迭代将nums中元素全部取反,创建小根堆,然后每次取出小根堆里最小的数,并将最小的数先取反,再后取ceil值,再取反,再加入到小根堆中,重复k次,将答案返回即可。
编程代码:
解题代码:
class Solution:
def maxKelements(self, nums: List[int], k: int) -> int:
for i in range(len(nums)) :
nums[i] = -nums[i]
heapify(nums)
ans = 0
while k > 0 :
h = -heappop(nums)
ans += h
print(h)
heappush(nums, -(ceil(h / 3)))
k -= 1
return ans
此处for循环处也可采用enumerate函数
进阶代码:
class Solution:
def maxKelements(self, nums: List[int], k: int) -> int:
for i, v in enumerate(nums):
nums[i] = -v
heapify(nums)
ans = 0
while k > 0 :
h = -heappop(nums)
ans += h
print(h)
heappush(nums, -(ceil(h / 3)))
k -= 1
return ans