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