LeetCode(410):分割数组的最大值 Split Array Largest Sum(Java)

2019.11.15 #程序员笔试必备# LeetCode 从零单刷个人笔记整理(持续更新)

github:https://github.com/ChopinXBP/LeetCode-Babel

经典的最大和最小问题,也是2019年携程校招后台开发执行任务题的母题。

根本思路是桶思想+二分查找+贪心,将分割的子数组看成很多个buckets,子数组的最大和为桶容量。题目要求给定桶数量下使桶容量最大值最小的桶容量。

我们可以对分隔数组最大和(最大桶容量)进行二分查找,范围为[数组最大元素值,数组元素和]。

每次查找时判断在当前桶数量m和最大桶容量mid限定下,数组能否完成分割。判断方式可以用贪心策略从前往后将每个桶装满最大容量求桶数。

最终只要找出能够完成分割的最小桶容量即可。


传送门:分割数组的最大值

Given an array which consists of non-negative integers and an integer m, you can split the array into m non-empty continuous subarrays. Write an algorithm to minimize the largest sum among these m subarrays.

给定一个非负整数数组和一个整数 m,你需要将这个数组分成 m 个非空的连续子数组。设计一个算法使得这 m 个子数组各自和的最大值最小。

示例:
输入:
nums = [7,2,5,10,8]
m = 2
输出:
18

解释:
一共有四种方法将nums分割为2个子数组。
其中最好的方式是将其分为[7,2,5] 和 [10,8],
因为此时这两个子数组各自的和的最大值为18,在所有情况中最小。

注意:
数组长度 n 满足以下条件:
1 ≤ n ≤ 1000
1 ≤ m ≤ min(50, n)



/**
 *
 *  Given an array which consists of non-negative integers and an integer m, you can split the array into m non-empty continuous subarrays.
 *  Write an algorithm to minimize the largest sum among these m subarrays.
 *  给定一个非负整数数组和一个整数 m,你需要将这个数组分成 m 个非空的连续子数组。设计一个算法使得这 m 个子数组各自和的最大值最小。
 *
 */

public class SplitArrayLargestSum {
    //最大和最小问题
    public int splitArray(int[] nums, int m) {
        long max = Integer.MIN_VALUE;
        long sum = 0;
        for(int num : nums){
            max = num > max ? num : max;
            sum += num;
        }
        //对分隔数组最大和(最大桶容量)进行二分查找,范围为[数组最大元素值,数组元素和]
        long begin = max;
        long end = sum;
        while(begin < end){
            long mid = (begin + end) >> 1;
            //判断在当前桶数量m和最大桶容量mid限定下,数组能否完成分割
            if(canBeSplit(nums, m, mid)){
                end = mid;
            }else{
                begin = mid + 1;
            }
        }
        return (int)begin;
    }

    private boolean canBeSplit(int[] nums, int m, long maxSum){
        long curSum = 0;
        long curNum = 0;
        for(int i = 0; i < nums.length; i++){
            curSum += nums[i];
            if(curSum > maxSum){
                curSum = nums[i];
                curNum++;
            }else if(curSum == maxSum){
                curSum = 0;
                curNum++;
            }
            if(curNum > m){
                return false;
            }
        }
        if(curSum > 0){
            curNum++;
        }
        return curNum <= m;
    }
}




#Coding一小时,Copying一秒钟。留个言点个赞呗,谢谢你#

发布了246 篇原创文章 · 获赞 316 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_20304723/article/details/103081644
今日推荐