Minimize moves to sort Array in non decreasing order by breaking elements in two parts
Last Updated :
25 Apr, 2022
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++
#include <bits/stdc++.h>
#include <vector>
using namespace std;
int minimumSplits(vector< int > arr)
{
int totalSplits = 0;
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;
}
int main()
{
vector< int > arr{ 3, 2, 4 };
int minSplit = minimumSplits(arr);
cout << minSplit << endl;
return 0;
}
|
Java
import java.lang.*;
import java.util.*;
class GFG {
public static int minimumSplits( int arr[],
int n)
{
int totalSplits = 0 ;
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;
}
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
def minimumSplits(arr):
totalSplits = 0
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
arr = [ 3 , 2 , 4 ]
minSplit = minimumSplits(arr)
print (minSplit)
|
C#
using System;
using System.Collections.Generic;
public class GFG
{
public static int minimumSplits( int [] arr, int n)
{
int totalSplits = 0;
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;
}
public static void Main( string [] args)
{
int [] arr = { 3, 2, 4 };
int N = arr.Length;
int minSplit = minimumSplits(arr, N);
Console.Write(minSplit);
}
}
|
Javascript
<script>
const minimumSplits = (arr) => {
let totalSplits = 0;
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;
}
let arr = [3, 2, 4];
let minSplit = minimumSplits(arr);
document.write(minSplit);
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(1)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...