@@ -17,51 +17,35 @@ Write an algorithm to minimize the largest sum among these m subarrays.
17
17
18
18
class Hard410 : ArraysTopic , BinarySearchTopic , DynamicProgrammingTopic , GreedyTopic {
19
19
20
- var memo = Array < Array < Int ?>>( 1001 ) { arrayOfNulls( 51 ) }
20
+ lateinit var nums : IntArray
21
21
22
- private fun getMinimumLargestSplitSum (prefixSum : IntArray , currIndex : Int , subarrayCount : Int ): Int {
23
- val n = prefixSum.size - 1
24
-
25
- // We have already calculated the answer so no need to go into recursion
26
- if (memo[currIndex][subarrayCount] != null ) {
27
- return memo[currIndex][subarrayCount]!!
28
- }
29
-
30
- // Base Case: If there is only one subarray left, then all of the remaining numbers
31
- // must go in the current subarray. So return the sum of the remaining numbers.
32
- if (subarrayCount == 1 ) {
33
- return prefixSum[n] - prefixSum[currIndex].also { memo[currIndex][subarrayCount] = it }
22
+ fun splitArray (nums : IntArray , m : Int ): Int {
23
+ this .nums = nums
24
+ var low = 0
25
+ var high = 0
26
+ var min = Int .MAX_VALUE
27
+ for (i in nums.indices) {
28
+ low = Math .max(low, nums[i])
29
+ high + = nums[i]
34
30
}
35
-
36
- // Otherwise, use the recurrence relation to determine the minimum largest subarray
37
- // sum between currIndex and the end of the array with subarrayCount subarrays remaining.
38
- var minimumLargestSplitSum = Int .MAX_VALUE
39
- for (i in currIndex.. n - subarrayCount) {
40
- // Store the sum of the first subarray.
41
- val firstSplitSum = prefixSum[i + 1 ] - prefixSum[currIndex]
42
-
43
- // Find the maximum subarray sum for the current first split.
44
- val largestSplitSum = Math .max(
45
- firstSplitSum,
46
- getMinimumLargestSplitSum(prefixSum, i + 1 , subarrayCount - 1 )
47
- )
48
-
49
- // Find the minimum among all possible combinations.
50
- minimumLargestSplitSum = Math .min(minimumLargestSplitSum, largestSplitSum)
51
- if (firstSplitSum >= minimumLargestSplitSum) {
52
- break
53
- }
31
+ while (low <= high) {
32
+ val mid = (low + high) / 2
33
+ if (required_no_of_chunks(mid, m)) {
34
+ min = Math .min(min, mid)
35
+ high = mid - 1
36
+ } else low = mid + 1
54
37
}
55
- return minimumLargestSplitSum. also { memo[currIndex][subarrayCount] = it }
38
+ return min
56
39
}
57
40
58
- fun splitArray (nums : IntArray , m : Int ): Int {
59
- // Store the prefix sum of nums array.
60
- val n = nums.size
61
- val prefixSum = IntArray (n + 1 )
62
- for (i in 0 until n) {
63
- prefixSum[i + 1 ] = prefixSum[i] + nums[i]
41
+ private fun required_no_of_chunks (mid : Int , m : Int ): Boolean {
42
+ var chunks = 0
43
+ var i = 0
44
+ while (i < nums.size) {
45
+ var `val ` = 0
46
+ while (i < nums.size && nums[i] + `val ` <= mid) `val ` + = nums[i++ ]
47
+ chunks++
64
48
}
65
- return getMinimumLargestSplitSum(prefixSum, 0 , m)
49
+ return chunks <= m
66
50
}
67
51
}
0 commit comments