分糖果问题-----medium

1、题目描述

力扣原题:原题链接

优秀题解:二分搜索类问题

力扣https://leetcode-cn.com/problems/maximum-candies-allocated-to-k-children/solution/by-relll-1037-dhhf/

2、代码:

class Solution {
    public int maximumCandies(int[] candies, long k) {

        //二分法 分糖果
        int max = candies[0];
        for(int candy:candies) max = Math.max(max,candy);

        //每个孩子最多能分max个糖果
        int left =0,right=max;
        while(left<right){
            //右边主动收缩应该主动偏右
            int mid = left+(right-left+1)/2;
            if(getkids(candies,mid)<k){
                //减治法  不行的先排除
                //不够分这么多孩子,那么每个孩子分少一点 向左查找
                right = mid-1;
            }else{
                //刚好够分或者分多了  向右查找  目的是找到每个孩子可以分到的最大糖果数目
                left=mid;
            }
        }

        return left;


    }

    //当 每个孩子分candiansNum颗糖果时,最多可以分给几个孩子
    private long getkids(int[] candies,int candiedNum){
        long count =0;
        for(int candy:candies){
            count += candy/candiedNum;
        }

        return count;
    }
}

优秀题解2

力扣https://leetcode-cn.com/problems/maximum-candies-allocated-to-k-children/solution/5219-mei-ge-xiao-hai-zui-duo-neng-fen-da-375p/解题思路
1.计算出总共有多少糖果
2.计算每个孩子理论上平均能分多少个糖果
3.遍历数组,找到满足条件的最大值
4.二分优化

class Solution {
  public int maximumCandies(int[] candies, long k) {
    long sum=0L;
    for(int i:candies){  //求和
      sum+=(long)(i);
    }
    if(sum<k){ 
      return 0;
    }
    if(sum==k){
      return 1;
    }
    long max=sum/k;  //求平均值

    for(long i=max;i>=0;i--){  //从最大值开始遍历,
      long cnt=0l;
      for(int num:candies){
        cnt+=(long)(num)/i;   //看num能分出几个i
      }
      if(cnt>=k){   //直到找到第一个满足条件的最大值,返回
        return (int)i;
      }
    }
    return 0;
  }
}

===================================================================》

分割线

=============================

类型题目2 : 完成旅行的最少时间

1、原题地址:

力扣原题链接https://leetcode-cn.com/problems/minimum-time-to-complete-trips/

2、解题思路

怎么想到二分法的!!!!!
        对花费的时间进行二分查找
        初始最小时间为0,最大时间为只用一辆速度最快的车跑完所有旅途花费的时间
        取中间时间mid,求mid内能完成得旅途数目trips
        1.若trips>=totalTrips,表明时间还可以优化,部分车可能多跑了,向左查找right=mid
        2.若trips<totalTrips,表明时间不足,全部车出动了旅途还没跑完,向右查找left=mid+1
        坑点:注意返回类型为long
        时间复杂度:O(MlogN),空间复杂度:O(1)
class Solution {
    public long minimumTime(int[] time, int totalTrips) {
        /*
        怎么想到二分法的!!!!!
        对花费的时间进行二分查找
        初始最小时间为0,最大时间为只用一辆速度最快的车跑完所有旅途花费的时间
        取中间时间mid,求mid内能完成得旅途数目trips
        1.若trips>=totalTrips,表明时间还可以优化,部分车可能多跑了,向左查找right=mid
        2.若trips<totalTrips,表明时间不足,全部车出动了旅途还没跑完,向右查找left=mid+1
        坑点:注意返回类型为long
        时间复杂度:O(MlogN),空间复杂度:O(1)
        */
        // 先将时间排序
        Arrays.sort(time);
        // 计算最长时间:全部旅途都用速度最快的一辆车跑完
        long right = 1L * time[0] * totalTrips;
        long left = 0;
        // 进行二分查找
        while(left < right) {
            long mid = (left + right) >>> 1;
            // 计算mid时间能走的旅途次数
            long trips = 0;
            for(int t : time) {
                // 当mid时间不足以完成一趟旅途,接下来的车更不可能,退出
                if(mid < t) {
                    break;
                }
                // 累加每辆车在mid时间内能完成的旅行次数
                trips += mid / t;
            }
            // 判断trips与totalTrips的大小关系进行转移
            if(trips >= totalTrips)  {
                // 旅途数超标,时间还可以再优化,向左查找
                right = mid;
            }else {
                // 旅途数不足,时间不足,向右查找
                left = mid + 1;
            }
        }
        // 最后left=right,任意返回一个即可
        return left;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值