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一秒鐘。留個言點個讚唄,謝謝你#

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章