2024-5-1——雇佣 K 位工人的总代价

文章介绍了如何使用两个优先队列的方法解决LeetCode题目2462,根据候选数和costs数组,动态调整队列策略以优化求解总成本问题。时间复杂度为O((candidate+k)⋅logcandidate),空间复杂度为O(candidate)。
摘要由CSDN通过智能技术生成

题目来源

力扣每日一题;题序:2462

我的题解

方法一 优先队列

使用两个优先队列进行模拟
判断k是否等于costs的长度,若是则直接求costs的和返回就行了;否则判断candidates*2与sosts的长度的大小关系
若大于等于,则表示每次都在整个sosts上选择,只需要一个优先队列就行了;若小于,则需要两个优先队列,分别记录左侧和右侧。

时间复杂度:O((candidate+k)⋅log candidate)。
空间复杂度:O(candidate)

 public long totalCost(int[] costs, int k, int candidates) {
     int n=costs.length;
     if(k==n)
         return Arrays.stream(costs).asLongStream().sum();
     PriorityQueue<int[]> left=new PriorityQueue<>((a,b)->{
         if(a[0]==b[0]){
             return a[1]-b[1];
         }else{
             return a[0]-b[0];
         }
     });
     PriorityQueue<int[]> right=new PriorityQueue<>((a,b)->{
         if(a[0]==b[0]){
             return a[1]-b[1];
         }else{
             return a[0]-b[0];
         }
     });
     long res=0;
     
     if(candidates*2>=n){
         for(int i=0;i<n;i++){
             left.offer(new int[]{costs[i],i});
         }
         while(k>0){
             res+=left.poll()[0];
             k--;
         }
     }else{
         int lIndex=candidates;
         int rIndex=n-1-candidates;
         for(int i=0;i<candidates;i++){
             left.offer(new int[]{costs[i],i});
             right.offer(new int[]{costs[n-1-i],n-1-i});
         }
         while(k>0){
         	//这里要注意左侧或右侧优先队列为空的情况
             int l=left.isEmpty()?Integer.MAX_VALUE:left.peek()[0];
             int r=right.isEmpty()?Integer.MAX_VALUE:right.peek()[0];
             if(l<=r){
                 res+=left.poll()[0];
                 if(lIndex<=rIndex){
                     left.offer(new int[]{costs[lIndex++],lIndex-1});
                 }
             }else{
                 res+=right.poll()[0];
                 if(lIndex<=rIndex){
                     right.offer(new int[]{costs[rIndex--],rIndex+1});
                 }
             }   
             k--;
         }
     }
     return res;
 }

有任何问题,欢迎评论区交流,欢迎评论区提供其它解题思路(代码),也可以点个赞支持一下作者哈😄~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

菜菜的小彭

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

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

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

打赏作者

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

抵扣说明:

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

余额充值