Given an array of arr[] of N integers, the task is to find the minimum number of moves to sort the array in non-decreasing order by splitting any array element into two parts such that the sum of the parts is the same as that element.
Examples:
Input: arr[] = {3, 4, 2}
Output: 2
Explanation: The moves are:
Split 4 into two parts {2, 2}. Array becomes arr[] = {3, 2, 2, 2}
Split 3 into two parts {1, 2}. Array becomes arr[] = {1, 2, 2, 2, 2}Input: arr[] = {3, 2, 4}
Output: 1
Explanation: Split 3 into two parts {1, 2}. [3, 2, 4] -> [1, 2, 2, 4]Â
Approach: The solution of the problem is based on the following observation:
As there is need to minimize the operations so keep the rightmost elements as large as possible, i.e., don’t split it.
To minimize operations, split a number into numbers as large as possible and as close to the element just right to it.
Follow the steps mentioned below to solve this problem:
- Traverse from the rightmost element of the array i = N-2 to 0.
- Split the array element into two parts as large as possible and not exceeding the element just at the right and increment the count of split.
- Continue this till the values obtained from splitting arr[i] is not less than the minimum value obtained just at its right.
- Update the minimum value obtained in this process.
- Return the total count of split as the answer.
Below is the implementation of the above approach:
C++
// C++ code to implement the approach Â
#include <bits/stdc++.h> #include <vector> using namespace std; Â
// Function to find the minimum // number of split int minimumSplits(vector< int > arr) { Â Â Â Â int totalSplits = 0; Â
    // Get the value at the last index     int prevVal = arr.back(); Â
    for ( int idx = arr.size() - 2;          idx >= 0; idx--) { Â
        totalSplits             += (arr[idx] - 1) / prevVal;         int numGroups             = ((arr[idx] - 1) / prevVal + 1);         prevVal = arr[idx] / numGroups;     } Â
    return totalSplits; } Â
// Driver Code int main() { Â Â Â Â vector< int > arr{ 3, 2, 4 }; Â
    // Function call     int minSplit = minimumSplits(arr);     cout << minSplit << endl;     return 0; } |
Java
// Java code to implement the approach Â
import java.lang.*; import java.util.*; Â
class GFG { Â
    // Function to count the minimum     // number of splits     public static int minimumSplits( int arr[],                                     int n)     {         int totalSplits = 0 ; Â
        // Get the value at the last index         int prevVal = arr[n - 1 ]; Â
        for ( int idx = n - 2 ; idx >= 0 ;              idx--) {             totalSplits                 += (arr[idx] - 1 ) / prevVal;             int numGroups                 = ((arr[idx] - 1 )                        / prevVal                    + 1 );             prevVal = arr[idx] / numGroups;         } Â
        return totalSplits;     } Â
    // Driver code     public static void main(String[] args)     {         int arr[] = { 3 , 2 , 4 };         int N = arr.length; Â
        int minSplit = minimumSplits(arr, N);         System.out.print(minSplit);     } } |
Python3
# Python code to implement the approach Â
# Function to find the minimum # number of split def minimumSplits(arr): Â
    totalSplits = 0 Â
    # Get the value at the last index     prevVal = arr[ len (arr) - 1 ] Â
    for idx in range ( len (arr) - 2 , - 1 , - 1 ): Â
        totalSplits + = (arr[idx] - 1 ) / / prevVal         numGroups = ((arr[idx] - 1 ) / / prevVal + 1 )         prevVal = arr[idx] / / numGroups Â
    return totalSplits Â
# Driver Code arr = [ 3 , 2 , 4 ] Â
# Function call minSplit = minimumSplits(arr) print (minSplit) Â
# This code is contributed by shinjanpatra |
C#
// C# code to implement the approach using System; using System.Collections.Generic; Â
public class GFG { Â
  // Function to count the minimum   // number of splits   public static int minimumSplits( int [] arr, int n)   {     int totalSplits = 0; Â
    // Get the value at the last index     int prevVal = arr[n - 1]; Â
    for ( int idx = n - 2; idx >= 0; idx--) {       totalSplits += (arr[idx] - 1) / prevVal;       int numGroups = ((arr[idx] - 1) / prevVal + 1);       prevVal = arr[idx] / numGroups;     } Â
    return totalSplits;   } Â
  // Driver Code   public static void Main( string [] args)   {     int [] arr = { 3, 2, 4 };     int N = arr.Length; Â
    // function call     int minSplit = minimumSplits(arr, N);     Console.Write(minSplit);   } } Â
// This code is contributed by phasing17 |
Javascript
<script> Â Â Â Â // JavaScript code to implement the approach Â
    // Function to find the minimum     // number of split     const minimumSplits = (arr) => {         let totalSplits = 0; Â
        // Get the value at the last index         let prevVal = arr[arr.length - 1]; Â
        for (let idx = arr.length - 2;             idx >= 0; idx--) { Â
            totalSplits                 += parseInt((arr[idx] - 1) / prevVal);             let numGroups                 = parseInt((arr[idx] - 1) / prevVal + 1);             prevVal = parseInt(arr[idx] / numGroups);         } Â
        return totalSplits;     } Â
    // Driver Code     let arr = [3, 2, 4]; Â
    // Function call     let minSplit = minimumSplits(arr);     document.write(minSplit); Â
// This code is contributed by rakeshsahni Â
</script> |
1
Time Complexity: O(N)
Auxiliary Space: O(1)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!