这道题,要求cut ribbons,怎么cut都行,只要能cut出k条丝带就行,不是每条丝带都需要被cut,cut完没用的可以丢弃,求能cut出k条丝带的情况下,丝带的最大长度。你可以想象这样的场景,客户给你一堆丝带,让你帮忙cut出几条丝带,希望丝带越长越好,剩下的丝带就不要了。

暴力求解方法很简单,就是从数组里的最大数开始,每次减1,挨个试,作为被除数去除每个数,如果得到的商的总数等于k了,把数值返回即可, 如果都试到1了,还达不到k,就返回0.

我的暴力算法,时间复杂度O(n*m), n是数组里的最大数的数值,m是数组长度,会TLE:

   public int maxLength(int[] ribbons, int k) {
  
      Arrays.sort(ribbons);
       int max = ribbons[ribbons.length-1];
        for(int i=max;i>=1;i--){
            if(cutRibben(ribbons, i, k))
                return i;
        }
       return 0;
    }
    public boolean cutRibben(int[] ribbons, int length, int k) {
        int count = 0;
        for (int ribbon: ribbons) {
            count += (ribbon / length);
            if(count>=k)
                return true;
        } 
        return false;
    }

既然时间超时了,咱就得想想有没有时间复杂度好一点的算法,那么自然就想到了binary search, 时间复杂度是O(logn*m), n是数组里的最大数的数值, m是数组长度:

 

   public int maxLength(int[] ribbons, int k) {
      Arrays.sort(ribbons);
       int max = ribbons[ribbons.length-1];
       int low = 1, high = max, mid = low, res = 0;
       while(low <= high){
           mid = (low+high)/2;
           if(cutRibben(ribbons, mid, k)){
               low = mid+1;
               res = mid;
           }
           else
               high = mid-1;
       }
       return res;
    }
    public boolean cutRibben(int[] ribbons, int length, int k) {
        int count = 0;
        for (int ribbon: ribbons) {
            count += (ribbon / length);
            if(count>=k)
                return true;
        } 
        return false;
    }

 

利用万能模版:

class Solution {
    public int maxLength(int[] ribbons, int k) {
        int r=0;
        for(int i=0;i<ribbons.length;i++){
            r = Math.max(r, ribbons[i]);
        }
        int l=1;
        while(l+1<r){
            int mid = (l+r)/2;
            int count = getRibbons(ribbons, mid);
            if(count>=k){
                l=mid;
            }else{
                r=mid;
            }
        }
        int right = getRibbons(ribbons, r);
        if(right>=k)
            return r;
          int left = getRibbons(ribbons,l);
        if(left>=k)
            return l;
        else return 0;
    }
    
    private int getRibbons(int[] ribbons, int n){
        int res = 0;
        for(int i=0;i<ribbons.length;i++){
            res+=ribbons[i]/n;
        }
        return res;
    }
}

 

posted on 2022-01-16 15:56  阳光明媚的菲越  阅读(225)  评论(0编辑  收藏  举报