Open In App

Minimum Breaks to make the Array sorted

Last Updated : 07 Nov, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] of size N, the task is to return the minimum number of operations to make the array sorted (in non-decreasing order) by performing the following operation any number of times:

  • Break any element of the array into two elements whose sum is equal to the element.
  • The two new elements should have the same position as the previous element.

Examples:

Input: arr[] = {4, 3, 2, 1}, N = 4
Output: 6
Explanation: We need to reduce all the elements to 1,
4 => 3 operations are needed to break 4 to all 1s
3 => 2 operations are needed to break 3 to all 1s
2 => 1 operation is needed to break 2 to all 1s
Total operations = 3 + 2 + 1 = 6

Input: arr[] = {10, 20, 9}
Output: 3
Explanation: We need to reduce 20 and 10
20 => 2 operations are needed to reduce 20 to 6 + 7 + 7
10 => 1 operation is needed to reduce 10 to 5 + 5
Total operations = 2 + 1 = 3

Approach: To solve the problem follow the below idea:

Traverse the array in reverse order and for each element, check if it is greater than element to its right (the previous element). If the current element is greater, calculate the number of divisions to make it less than or equal to the previous element. Update the previous element to the value that the current element needs to be divided by. Add the number of divisions to the count of operations. After traversing the whole array, return the count.

Below are the steps to implement the above approach:

  • Traverse the array in reverse order. For every array element,
    • Check if the current element is smaller than or equal to the previous element.
      • If current element <= previous element, then the elements after the current element are already sorted
      • If current element > previous element, then break the current element such that every new element is as large as possible but smaller than or equal to the current element. This is because we need to have larger elements on the right so that the number of operations is minimized. Add the number of breaks to count.
  • Return count as the answer.

Below is the implementation for the above approach:

C++




// C++ code for the above approach:
#include <bits/stdc++.h>
using namespace std;
 
int minimumBreaks(vector<int>& arr)
{
    int n = arr.size();
    int previous = arr[n - 1];
    int count = 0;
 
    // Traverse the array in reverse order
    for (int i = n - 2; i >= 0; --i) {
 
        // We don't need to break the element
        if (arr[i] <= previous) {
            previous = arr[i];
        }
        // If we need to break the element
        else {
 
            // If the number can be perfectly
            // broken, so the previous
            // remains unchanged
            if (arr[i] % previous == 0) {
                int parts = arr[i] / previous;
                count = count + parts - 1;
            }
            // If the number cannot be broken
            // perfecly, we need to calculate
            // the previous
            else {
                int parts = ceil(arr[i] / (previous * 1.0));
                count = count + parts - 1;
                previous = arr[i] / parts;
            }
        }
    }
    return count;
}
 
// Drivers code
int main()
{
    vector<int> arr = { 10, 20, 9 };
 
    // Function Call
    cout << minimumBreaks(arr) << endl;
    return 0;
}


Java




/*package whatever //do not write package name here */
import java.util.*;
 
public class Main {
    public static int minimumBreaks(ArrayList<Integer> arr) {
        int n = arr.size();
        int previous = arr.get(n - 1);
        int count = 0;
        // Traverse the array in reverse order
        for (int i = n - 2; i >= 0; --i) {
            // We don't need to break the element
            if (arr.get(i) <= previous) {
                previous = arr.get(i);
            }
 
            else {
                // If the number can be perfectly
                // broken, so the previous
                // remains unchanged
                if (arr.get(i) % previous == 0) {
                    int parts = arr.get(i) / previous;
                    count = count + parts - 1;
                }
                // If the number cannot be broken
                // perfecly, we need to calculate
                // the previous
                    else {
                    int parts = (int) Math.ceil(arr.get(i) / (previous * 1.0));
                    count = count + parts - 1;
                    previous = arr.get(i) / parts;
                }
            }
        }
        return count;
    }
//Drivers code
    public static void main(String[] args) {
        ArrayList<Integer> arr = new ArrayList<>(Arrays.asList(10, 20, 9));
        // Function Call
        System.out.println(minimumBreaks(arr));
    }
}
//Code added by Flutterfly


Python




# code added by flutterfly
def minimumBreaks(arr):
    n = len(arr)
    previous = arr[n - 1]
    count = 0
    # Traverse the array in reverse order
    for i in range(n - 2, -1, -1):
        # We don't need to break the element
        if arr[i] <= previous:
            previous = arr[i]
        # If we need to break the element
        else:
            # If the number can be perfectly
            # broken, so the previous
            # remains unchanged
            if arr[i] % previous == 0:
                parts = arr[i] // previous
                count = count + parts - 1
                 
            # If the number cannot be broken
            # perfecly, we need to calculate
            # the previous
            else:
                parts = -(-arr[i] // (previous * 1.0))
                count = count + parts - 1
                previous = arr[i] // parts
     
    return count
# Drivers code
arr = [10, 20, 9]
#Function call
print(minimumBreaks(arr))


C#




using System;
using System.Collections.Generic;
 
class Program
{
    static int MinimumBreaks(List<int> arr)
    {
        int n = arr.Count;
        int previous = arr[n - 1];
        int count = 0;
        // Traverse the array in reverse order
        for (int i = n - 2; i >= 0; --i)
        {
          // We don't need to break the element
            if (arr[i] <= previous)
            {
                previous = arr[i];
            }
          // If we need to break the element
            else
            {
                  // If the number can be perfectly
                // broken, so the previous
                // remains unchanged
                if (arr[i] % previous == 0)
                {
                    int parts = arr[i] / previous;
                    count = count + parts - 1;
                }
                // If the number cannot be broken
                // perfecly, we need to calculate
                // the previous
                else
                {
                    int parts = (int)Math.Ceiling(arr[i] / (previous * 1.0));
                    count = count + parts - 1;
                    previous = arr[i] / parts;
                }
            }
        }
        return count;
    }
// Drivers code
    static void Main(string[] args)
    {
        List<int> arr = new List<int> { 10, 20, 9 };
//Function's Call
        Console.WriteLine(MinimumBreaks(arr));
    }
}


Javascript




function minimumBreaks(arr) {
    let n = arr.length;
    let previous = arr[n - 1];
    let count = 0;
     
    // Traverse the array in reverse order
    for (let i = n - 2; i >= 0; --i) {
     
        // We don't need to break the element
        if (arr[i] <= previous) {
            previous = arr[i];
        }
         
        // If we need to break the element
        else {
            // If the number can be perfectly
            // broken, so the previous
            // remains unchanged
 
            if (arr[i] % previous === 0) {
                let parts = arr[i] / previous;
                count = count + parts - 1;
            }
            // If the number cannot be broken
            // perfecly, we need to calculate
            // the previous
 
            else {
                let parts = Math.ceil(arr[i] / (previous * 1.0));
                count = count + parts - 1;
                previous = Math.floor(arr[i] / parts);
            }
        }
    }
    return count;
}
// Drivers code
let arr = [10, 20, 9];
// Functions call
console.log(minimumBreaks(arr));


Output

3






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



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

Similar Reads