1962. 移除石子使总数最小
难度: 中等
题目大意:
给你一个整数数组 piles
,数组 下标从 0 开始 ,其中 piles[i]
表示第 i
堆石子中的石子数量。另给你一个整数 k
,请你执行下述操作 恰好 k
次:
- 选出任一石子堆
piles[i]
,并从中 移除floor(piles[i] / 2)
颗石子。
**注意:**你可以对 同一堆 石子多次执行此操作。
返回执行 k
次操作后,剩下石子的 最小 总数。
floor(x)
为 小于 或 等于 x
的 最大 整数。(即,对 x
向下取整)。
提示:
1 <= piles.length <= 10^5
1 <= piles[i] <= 10^4
1 <= k <= 10^5
思路
这题思路很明确,贪心思想,我们每次取出最大的那一堆石子,然后将这一堆石子减半,执行k
次,最终返回剩余的石子总和即可,每次取最大值,这不是堆的性质吗,我们可以使用优先队列
代码实现(C++)
class Solution {
public:
int minStoneSum(vector<int>& piles, int k) {
priority_queue<int> q;
int n = piles.size();
int sum = 0;
for (int i = 0; i < n; i ++) q.push(piles[i]), sum += piles[i];
int res = 0;
while (k --) {
int t = q.top(); q.pop();
res += t / 2;
q.push(t - t / 2);
}
return sum - res;
}
};
python3 代码实现
class Solution:
def minStoneSum(self, piles: List[int], k: int) -> int:
heap = [-i for i in piles]
heapify(heap)
for i in range(k) :
heapreplace(heap, heap[0] // 2)
return -sum(heap)
时间复杂度 : O ( k ∗ l o g n + n ) O(k * logn + n) O(k∗logn+n) 主要时间的消耗在建堆或执行操作上面
总结
- 要了解堆这个数据结构,C++中的优先队列
- 勤于思考
【微语】: 加油
结束了