📌  相关文章
📜  将给定数组拆分为K个子数组,以使所有子数组的最大和为最小

📅  最后修改于: 2021-05-06 22:53:07             🧑  作者: Mango

给定N个元素的Array []和数K。(1 <= K <= N)。将给定的数组拆分为K个子数组(它们必须覆盖所有元素)。在形成的K个子阵列中,可达到的最大子阵列和必须最小。找到可能的子数组总和。
例子:

方法 :

  • 想法是使用二进制搜索来找到最佳解决方案。
  • 对于二进制搜索,最小总和可以为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是数组所有元素的总和。