【力扣题解】2208. 将数组和减半的最少操作次数 - (贪心 + 优先队列)

Problem: 2208. 将数组和减半的最少操作次数

思路

题目说要最少操作次数,也就是说我们需要在每次操作时的收益最大,即每次都是对最大的数进行减半操作从而实现局部最优,进而做到全局最优。这里我们就很容易想到了 贪心 + 优先队列 的思想来解决这道题

解题方法

  1. 先构建一个大根堆,同时原数组的和
  2. 算出一半的数组和,也就是我们的贪心临界点
  3. 对构建的大根堆进行循环减半操作,每次循环时用 count 记录次数

复杂度

时间复杂度:

这里用了两个循环,所以时间复杂度为 O ( n ) O(n) O(n)

空间复杂度:

创建了一个大根堆, 空间复杂度为 O ( n ) O(n) O(n)

C++代码

class Solution {
public:
    int halveArray(vector<int>& nums) {
        priority_queue<double> heap; // 构建一个大根堆
        double sum = 0.0; // 计算数组和
        for(auto& x : nums) { // 将元素依次插入大根堆中
            sum += x;
            heap.push(x);
        }
        
        sum /= 2.0; // 计算数组的一半和
        int count = 0; // 创建变量记录操作次数
        while(sum > 0) { // 如果 sum > 0 循环就继续
            double t = heap.top() / 2.0; // 对最大的元素进行减半操作(局部最优进而达到全局最优)
            heap.pop(); // 删除堆顶元素
            sum -= t; 
            count++; // 操作次数 + 1
            heap.push(t); // 将减半后的元素重新插入到大根堆中
        }
        return count; // 返回最后结果
    }
};

Java代码

class Solution {
    public int halveArray(int[] nums) {
        // 创建⼀个⼤根堆
        PriorityQueue<Double> heap = new PriorityQueue<>((a, b) -> b.compareTo(a));
        double sum = 0.0;
        for (int x : nums) // 把元素都丢进堆中,并求出累加和
        {
            heap.offer((double) x);
            sum += x;
        }
        sum /= 2.0; // 先算出⽬标和

        int count = 0;
        while (sum > 0) // 依次取出堆顶元素减半,直到减到之前的⼀半以下
        {
            double t = heap.poll() / 2.0;
            sum -= t;
            count++;
            heap.offer(t);
        }
        return count;
    }
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

自然语言编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值