给定N个元素的Array []和数K。(1 <= K <= N)。将给定的数组拆分为K个子数组(它们必须覆盖所有元素)。在形成的K个子阵列中,可达到的最大子阵列和必须最小。找到可能的子数组总和。
例子:
Input : Array[] = {1, 2, 3, 4}, K = 3
Output : 4
Optimal Split is {1, 2}, {3}, {4} . Maximum sum of all subarrays is 4, which is minimum possible for 3 splits.
Input : Array[] = {1, 1, 2} K = 2
Output : 2
方法 :
- 想法是使用二进制搜索来找到最佳解决方案。
- 对于二进制搜索,最小总和可以为1,最大总和可以为所有元素的总和。
- 要检查mid是否是最大子数组和。维护子数组的数量,包括子数组中所有可能的元素,直到它们的总和小于中值为止。评估之后,如果计数小于或等于K,则可以达到mid,否则无法实现。 (由于如果计数小于K,我们可以进一步将任何子数组相除,其总和将永远不会增加mid)。
- 找到满足条件的中值的最小可能值。
下面是上述方法的实现:
C++
// C++ implemenattion of the above approach
#include
using namespace std;
// Function to check if mid can
// be maximum sub - arrays sum
bool check(int mid, int array[], int n, int K)
{
int count = 0;
int sum = 0;
for (int i = 0; i < n; i++) {
// If individual element is greater
// maximum possible sum
if (array[i] > mid)
return false;
// Increase sum of current sub - array
sum += array[i];
// If the sum is greater than
// mid increase count
if (sum > mid) {
count++;
sum = array[i];
}
}
count++;
// Check condition
if (count <= K)
return true;
return false;
}
// Function to find maximum subarray sum
// which is minimum
int solve(int array[], int n, int K)
{
int* max = max_element(array, array + n);
int start = *max;
int end = 0;
for (int i = 0; i < n; i++) {
end += array[i];
}
// Answer stores possible
// maximum sub array sum
int answer = 0;
while (start <= end) {
int mid = (start + end) / 2;
// If mid is possible solution
// Put answer = mid;
if (check(mid, array, n, K)) {
answer = mid;
end = mid - 1;
}
else {
start = mid + 1;
}
}
return answer;
}
// Driver Code
int main()
{
int array[] = { 1, 2, 3, 4 };
int n = sizeof(array) / sizeof(array[0]);
int K = 3;
cout << solve(array, n, K);
}
Java
// Java implemenattion of the above approach
class GFG {
// Function to check if mid can
// be maximum sub - arrays sum
static boolean check(int mid, int array[], int n, int K)
{
int count = 0;
int sum = 0;
for (int i = 0; i < n; i++) {
// If individual element is greater
// maximum possible sum
if (array[i] > mid)
return false;
// Increase sum of current sub - array
sum += array[i];
// If the sum is greater than
// mid increase count
if (sum > mid) {
count++;
sum = array[i];
}
}
count++;
// Check condition
if (count <= K)
return true;
return false;
}
// Function to find maximum subarray sum
// which is minimum
static int solve(int array[], int n, int K)
{
int start = 1;
for (int i = 0; i < n; ++i) {
if (array[i] > start)
start = array[i];
}
int end = 0;
for (int i = 0; i < n; i++) {
end += array[i];
}
// Answer stores possible
// maximum sub array sum
int answer = 0;
while (start <= end) {
int mid = (start + end) / 2;
// If mid is possible solution
// Put answer = mid;
if (check(mid, array, n, K)) {
answer = mid;
end = mid - 1;
}
else {
start = mid + 1;
}
}
return answer;
}
// Driver Code
public static void main(String[] args)
{
int array[] = { 1, 2, 3, 4 };
int n = array.length;
int K = 3;
System.out.println(solve(array, n, K));
}
}
// This code is contributed by AnkitRai01
Python3
# Python 3 implemenattion of the above approach
# Function to check if mid can
# be maximum sub - arrays sum
def check(mid, array, n, K):
count = 0
sum = 0
for i in range(n):
# If individual element is greater
# maximum possible sum
if (array[i] > mid):
return False
# Increase sum of current sub - array
sum += array[i]
# If the sum is greater than
# mid increase count
if (sum > mid):
count += 1
sum = array[i]
count += 1
# Check condition
if (count <= K):
return True
return False
# Function to find maximum subarray sum
# which is minimum
def solve(array, n, K):
start = max(array)
end = 0
for i in range(n):
end += array[i]
# Answer stores possible
# maximum sub array sum
answer = 0
while (start <= end):
mid = (start + end) // 2
# If mid is possible solution
# Put answer = mid;
if (check(mid, array, n, K)):
answer = mid
end = mid - 1
else:
start = mid + 1
return answer
# Driver Code
if __name__ == '__main__':
array = [1, 2, 3, 4]
n = len(array)
K = 3
print(solve(array, n, K))
# This code is contributed by
# Surendra_Gangwar
C#
// C# implementation of the above approach
using System;
class GFG
{
// Function to check if mid can
// be maximum sub - arrays sum
static Boolean check(int mid, int []array,
int n, int K)
{
int count = 0;
int sum = 0;
for (int i = 0; i < n; i++)
{
// If individual element is greater
// maximum possible sum
if (array[i] > mid)
return false;
// Increase sum of current sub - array
sum += array[i];
// If the sum is greater than
// mid increase count
if (sum > mid)
{
count++;
sum = array[i];
}
}
count++;
// Check condition
if (count <= K)
return true;
return false;
}
// Function to find maximum subarray sum
// which is minimum
static int solve(int []array, int n, int K)
{
int start = 1;
for (int i = 0; i < n; ++i) {
if (array[i] > start)
start = array[i];
}
int end = 0;
for (int i = 0; i < n; i++)
{
end += array[i];
}
// Answer stores possible
// maximum sub array sum
int answer = 0;
while (start <= end)
{
int mid = (start + end) / 2;
// If mid is possible solution
// Put answer = mid;
if (check(mid, array, n, K))
{
answer = mid;
end = mid - 1;
}
else
{
start = mid + 1;
}
}
return answer;
}
// Driver Code
public static void Main (String[] args)
{
int []array = { 1, 2, 3, 4 };
int n = array.Length ;
int K = 3;
Console.WriteLine(solve(array, n, K));
}
}
// This code is contributed by Princi Singh
输出:
4
时间复杂度: O(N * log(Sum))
其中N是数组元素的数量,Sum是数组所有元素的总和。