183.木材加工(难题)

描述

有一些原木,现在想把这些木头切割成一些长度相同的小段木头,需要得到的小段的数目至少为 k。当然,我们希望得到的小段越长越好,你需要计算能够得到的小段木头的最大长度。

注意事项

木头长度的单位是厘米。原木的长度都是正整数,我们要求切割得到的小段木头的长度也要求是整数。 无法切出要求至少 k 段的,则返回 0 即可。

样例

有3根木头[232, 124, 456], k=7, 最大长度为114.

挑战

O(n log Len), Len为 n 段原木中最大的长度

代码

// 对长度进行二分
public class Solution {
     /**
     *@param L: Given n pieces of wood with length L[i]
     *@param k: An integer
     *return: The maximum length of the small pieces.
     */
    public int woodCut(int[] L, int k) {
        int max = 0;
        // 切割最大长度,即所给数组中最大值
        for (int i = 0; i < L.length; i++) {
            max = Math.max(max, L[i]);
        }

        // 题目要求长度为正整数,最小切割长度为1
        int start = 1;
        int end = max;
        // 对长度进行二分,判断是否满足k,找出满足k的最大长度
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (count(L, mid) == k) {
                start = mid;
            }
            if (count(L, mid) < k) {
                end = mid;
            }
            if (count(L, mid) > k) {
                start = mid;
            }
        }

        // 求最大长度所以先检查end
        if (count(L, end) >= k) {
            return end;
        }

        if (count(L, start) >= k) {
            return start;
        }
        return 0;
    }
    
    // 计算当前切割长度标准下,数组能切多少个
    private int count(int[] L, int length) {
        int sum = 0;
        for (int i = 0; i < L.length; i++) {
            sum += L[i] / length;
        }
        return sum;
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容