zoukankan      html  css  js  c++  java
  • 183.Wood Cut【hard】

    183.Wood Cut【hard】

    Given n pieces of wood with length L[i] (integer array). Cut them into small pieces to guarantee you could have equal or more than k pieces with the same length. What is the longest length you can get from the n pieces of wood? Given L & k, return the maximum length of the small pieces.

     Notice

    You couldn't cut wood into float length.

    If you couldn't get >= k pieces, return 0.

    Example

    For L=[232, 124, 456]k=7, return 114.

    Challenge 

    O(n log Len), where Len is the longest length of the wood.

    这个题一上来一点思路没有,参考:https://algorithm.yuanbin.me/zh-hans/binary_search/wood_cut.html里面的思路

    这道题要直接想到二分搜素其实不容易,但是看到题中 Challenge 的提示后你大概就能想到往二分搜索上靠了。首先来分析下题意,题目意思是说给出 n 段木材L[i], 将这 n 段木材切分为至少 k 段,这 k 段等长,求能从 n 段原材料中获得的最长单段木材长度。以 k=7 为例,要将 L 中的原材料分为7段,能得到的最大单段长度为114, 232/114 = 2, 124/114 = 1, 456/114 = 4, 2 + 1 + 4 = 7。

    理清题意后我们就来想想如何用算法的形式表示出来,显然在计算如214等分片数时我们进行了取整运算,在计算机中则可以使用下式表示:

    其中 l 为单段最大长度,显然有 ≤ ≤ max(L[i]). 单段长度最小为1,最大不可能超过给定原材料中的最大木材长度。

    Warning 注意求和与取整的顺序,是先求 L[i]/l的单个值,而不是先对L[i]求和。

    分析到这里就和题 sqrt(x) 差不多一样了,要求的是 l 的最大可能取值,同时 l 可以看做是从有序序列[1, max(L[i])]的一个元素,典型的二分搜素!

    代码参考了:http://www.jiuzhang.com/solution/wood-cut/

    解法一:

     1 public class Solution {
     2     /** 
     3      *@param L: Given n pieces of wood with length L[i]
     4      *@param k: An integer
     5      *return: The maximum length of the small pieces.
     6      */
     7     public int woodCut(int[] L, int k) {
     8         int max = 0;
     9         for (int i = 0; i < L.length; i++) {
    10             max = Math.max(max, L[i]);
    11         }
    12         
    13         // find the largest length that can cut more than k pieces of wood.
    14         int start = 1, end = max;
    15         while (start + 1 < end) {
    16             int mid = start + (end - start) / 2;
    17             if (count(L, mid) >= k) {
    18                 start = mid;
    19             } else {
    20                 end = mid;
    21             }
    22         }
    23         
    24         if (count(L, end) >= k) {
    25             return end;
    26         }
    27         if (count(L, start) >= k) {
    28             return start;
    29         }
    30         return 0;
    31     }
    32     
    33     private int count(int[] L, int length) {
    34         int sum = 0;
    35         for (int i = 0; i < L.length; i++) {
    36             sum += L[i] / length;
    37         }
    38         return sum;
    39     }
    40 }

    对于上面发现还有可以优化的地方,那就是我们二分找长度的时候只需要找所有木块里面最短的即可,就是所谓的木桶原理,那么end上界又可以进一步减少。

    解法二:

     1 class Solution {
     2 public:
     3     /*
     4      * @param L: Given n pieces of wood with length L[i]
     5      * @param k: An integer
     6      * @return: The maximum length of the small pieces
     7      */
     8     int woodCut(vector<int> &L, int k) {
     9         if (L.empty() || k <= 0) {
    10             return 0;
    11         }
    12         //get min
    13         int min = INT_MIN;
    14         for (int i = 0; i < L.size(); ++i) {
    15             min = (min < L[i] ? L[i] : min);
    16         }
    17         
    18         int start = 1;
    19         int end = min;
    20         
    21         while (start + 1 < end) {
    22             int mid = start + (end - start) / 2;
    23             
    24             if (cal(L, mid) >= k) {
    25                 start = mid;
    26             }
    27             else {
    28                 end = mid;
    29             }
    30         }
    31         
    32         if (cal(L, end) >= k) {
    33             return end;
    34         }
    35         else if (cal(L, start) >= k) {
    36             return start;
    37         }
    38         else {
    39             return 0;
    40         }
    41     }
    42     
    43     int cal(vector<int> & L, int len) {
    44         int sum = 0;
    45         for (int i = 0; i < L.size(); ++i) {
    46             sum += L[i] / len;
    47         }
    48         
    49         return sum;
    50     }
    51 };
  • 相关阅读:
    cvpr热词云
    第八周总结
    从小工到专家阅读笔记01
    【Spring实战4】10--搭建SpringMVC环境
    【Spring实战4】09---构建Spring web
    【Spring实战4】08---面向切面AOP
    读书
    【Spring实战4】07---Bean的作用域
    【Spring实战4】06---装配Bean(xml)
    【Spring实战4】05---装配Bean(Java)
  • 原文地址:https://www.cnblogs.com/abc-begin/p/7552890.html
Copyright © 2011-2022 走看看