Open In App

Minimize moves to sort Array in non decreasing order by breaking elements in two parts

Last Updated : 25 Apr, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

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>


Output

1

Time Complexity: O(N)
Auxiliary Space: O(1)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads