leetcode简单题,将数组和减半的最少操作次数

给你一个正整数数组 nums 。每一次操作中,你可以从 nums 中选择 任意 一个数并将它减小到 恰好 一半。(注意,在后续操作中你可以对减半过的数继续执行操作)

请你返回将 nums 数组和 至少 减少一半的 最少 操作数。

看到这里的时候,我自己想的就是用贪心算法,每次选中数组中的最大值,再将最大值放回数组,然后搞了一堆,写完提交肯定是超出编译时间的,看了别人的发现可以用优先队列,然后自己又去把队列的知识恶补了一下。

首先是我们要用到的优先队列,直接创建优先队列的话,队列是按顺序排列的。

PriorityQueue<>  pq = new PriorityQueue<>();

 但是我们要找最大值,又因为PriorityQueue中有一个取顶部值的方法poll(),所以我们给它换一个排序方法。

PriorityQueue<>  pq = new PriorityQueue<>((a,b)->b.compareTo(a);

说一下相关要用的方法

poll(),取顶部值,并删除顶部元素,队列中没有元素返回null。

offer(E e),插入指定元素,不能为null。

class Solution {
    public int halveArray(int[] nums) {
        // PriorityQueue本身是顺序排列,下面我们要用的是最大值,所以直接把队列弄成倒序
        PriorityQueue<Double> pq = new PriorityQueue<Double>((a,b)->b.compareTo(a));
        
        int count = 0;
        double sum =  0; // 这里sum的数据类型一定要是double,因为sum和sum1在比较的时候有可能出错
        for(int num:nums){
            sum += num;
            //把数组中的元素添加到优先队列中
            pq.offer((double)num);
        }
        
        double sum1 = 0.0;
        //当被减去值的总和sum1大于等于原队列总和时,退出循环
        while(sum1<sum/2){
            //取到并删除堆顶元素
            double n = pq.poll();
            sum1 += n/2;
            //将元素减半之后重新放入队列
            pq.offer(n/2);
            count++;
        }

        return count;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值