Open In App

Sort number line given as Array by moving an element at ith index by i steps to right

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

Given an array arr[] of N integers, the task is to find the minimum number of the moves needed to sort the array in ascending order by moving an element at ith index by i steps to the right in a single move.

Note: In a step, two numbers can lie in the same position.

Examples:

Input: N = 4, arr[] = {1, 2, 7, 4}
Output: 1
Explanation: Moving the element at index 3 by 2 steps to the right sorts the array in ascending order in 1 move. Therefore, print 1.

Input: N = 5, arr[] = {2, 5, 8, 1, 9}
Output: 12
Explanation:
The most optimal way to arrange the array is: arr[] = {-, -, -, 1, -, -, -,2, -, -, -, -, -, -, -, 5, -, -, -, -, -, -, -, 8, -, -, -, -, -, -, -, -, -, -, -, -,-, -, -, 20}

  1. First arr[0] jumps to index 2, then to index 4, and then to index 7. So Shifting arr[0] will need 3 moves to reach index 7. 
  2. First arr[1] jumps to index 3, then to index 7, and then to index 15. So Shifting arr[1] will need 3 moves to reach index 15. 
  3. First arr[2] jumps to index 6, then to index 12, and then to index 24. So Shifting arr[2] will need 3 moves to reach index 23.
  4. First arr[4] jumps to index 9, then to index 19, and then to index 39. So Shifting arr[4] will also need 3 moves to reach index 39.

Therefore, the total of (3 + 3 + 3 + 3) = 12 moves is needed.

Approach: The given problem can be solved by using the Greedy Approach which is based on the observations that it is always optimal to start placing the smallest number first at its appropriate position and then place the larger element accordingly. Follow the steps below to solve the problem:

  • Initialize a map say M that stores the array elements with their index in the given array arr[].
  • Traverse the given array arr[] using the variable i and update the map M[arr[i]] as M[arr[i]] = (i + 1).
  • Initialize a variable, say ans as 0 that stores the minimum number of total moves required.
  • Traverse the map M and perform the following steps:
    • Store the position of the current iterator and the previous iterator in the variables say i and j.
    • Iterate until i->second is less than or equals to j->second and increment the value of ans by 1 and increment the value of i->second by i->second.
  • After completing the above steps, print the value of ans as the resultant minimum moves.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the minimum number
// of moves required to sort the numbers
int MinimumMoves(int arr[], int N)
{
    // Stores value of number and the
    // position of the number
    map<int, int> mp;
 
    for (int i = 0; i < N; i++) {
       
        // Update mp[arr[i]]
        mp[arr[i]] = (i + 1);
    }
 
    // Stores the iterator pointing at
      // the beginning of the map
    auto it = mp.begin();
    it++;
 
    // Stores the minimum count of moves
    int ans = 0;
 
    // Traverse the map mp
    for (auto i = it; i != mp.end(); i++) {
       
        // Stores previous iterator
        auto j = i;
        j--;
 
        // Iterate while i->second is less
          // than or equal to j->second
        while (i->second <= j->second) {
 
            // Update the i->second
            i->second += i->second;
           
            // Increment ans by 1
            ans++;
        }
    }
   
    // Return the resultant minimum moves
    return ans;
}
 
// Driver Code
int main()
{
    int arr[] = { 2, 5, 8, 1, 9 };
    int N = sizeof(arr) / sizeof(arr[0]);
    cout << MinimumMoves(arr, N);
   
      return 0;
}


Java




// Java program for the above approach
import java.io.*;
import java.util.*;
 
class GFG {
 
    // Function to find the minimum number
    // of moves required to sort the numbers
    static int MinimumMoves(int arr[], int N)
    {
       
        // Stores value of number and the
        // position of the number
        Map<Integer, Integer> mp
            = new HashMap<Integer, Integer>();
 
        for (int i = 0; i < N; i++) {
 
            // Update mp[arr[i]]
            if (mp.containsKey(arr[i])) {
 
                mp.put(arr[i], mp.get(arr[i]) + (i + 1));
            }
            else {
 
                mp.put(arr[i], (i + 1));
            }
        }
 
        // Stores the iterator pointing at
        // the beginning of the map
        Iterator<Map.Entry<Integer, Integer> > it
            = mp.entrySet().iterator();
 
        Map.Entry<Integer, Integer> i = it.next();
       
        // Stores the minimum count of moves
        int ans = 0;
 
        // Traverse the map mp
        while (it.hasNext()) {
 
            // Stores previous iterator
            Map.Entry<Integer, Integer> j = i;
            i = it.next();
 
            // Iterate while i->second is less
            // than or equal to j->second
            while (i.getValue() <= j.getValue()) {
 
                // Update the i->second
                i.setValue(i.getValue() + i.getValue());
 
                // Increment ans by 1
                ans++;
            }
        }
 
        // Return the resultant minimum moves
        return ans;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int arr[] = { 2, 5, 8, 1, 9 };
        int N = arr.length;
        System.out.println(MinimumMoves(arr, N));
    }
}
 
// This code is contributed by Dharanendra L V.


Python3




# Python program for the above approach
 
# Function to find the minimum number
# of moves required to sort the numbers
def MinimumMoves(arr, N):
 
    # Stores value of number and the
    # position of the number
    mp = {}
 
    for i in range(N):
 
        # Update mp[arr[i]]
        if arr[i] in mp:
            mp[arr[i]] += (i + 1)
        else:
            mp[arr[i]] = (i + 1)
 
    # Stores the minimum count of moves
    ans = 0
 
    # Traverse the map mp
    for i in sorted(mp.items()):
 
        # Iterate while i[1] is less
        # than or equal to j[1]
        j = i
        while i[1] <= j[1]:
            i = (i[0], i[1] + i[1])
            ans += 1
    # Return the resultant minimum moves
    return ans
 
# Driver Code
arr = [2, 5, 8, 1, 9]
N = len(arr)
print(MinimumMoves(arr, N))


C#




using System;
using System.Collections.Generic;
using System.Linq;
 
class GFG
{
    // Function to find the minimum number
    // of moves required to sort the numbers
    static int MinimumMoves(int[] arr, int N)
    {
        // Stores value of number and the
        // position of the number
        Dictionary<int, int> mp
            = new Dictionary<int, int>();
 
        for (int i = 0; i < N; i++)
        {
            // Update mp[arr[i]]
            if (mp.ContainsKey(arr[i]))
            {
                mp[arr[i]] += (i + 1);
            }
            else
            {
                mp[arr[i]] = (i + 1);
            }
        }
 
        // Stores the minimum count of moves
        int ans = 0;
 
        // Traverse the map mp
        foreach (var i in mp.OrderBy(x => x.Key))
        {
            // Stores previous iterator
            var j = i;
 
            // Iterate while i.Value is less
            // than or equal to j.Value
            while (i.Value <= j.Value)
            {
                // Update the i.Value
                mp[i.Key] = i.Value + i.Value;
 
                // Increment ans by 1
                ans++;
            }
        }
 
        // Return the resultant minimum moves
        return ans;
    }
 
    // Driver Code
    public static void Main(string[] args)
    {
        int[] arr = { 2, 5, 8, 1, 9 };
        int N = arr.Length;
        Console.WriteLine(MinimumMoves(arr, N));
    }
}


Javascript




// JavaScript program for the above approach
 
// Function to find the minimum number
// of moves required to sort the numbers
function MinimumMoves(arr, N) {
     
// stores value of number and the
// position of the number
let mp = new Map();
 
for (let i = 0; i < N; i++) {
    // update mp[arr[i]]
    if (mp.has(arr[i])) {
        mp.set(arr[i], mp.get(arr[i]) + (i + 1));
    } else {
        mp.set(arr[i], (i + 1));
    }
}
 
// stores the minimum count of moves
let ans = 0;
 
// traverse the map mp
mp.forEach((value, key) => {
    // iterate while i->second is less
    // than or equal to j->second
    for (let [jKey, jValue] of mp) {
        if (jValue <= value && jKey > key) {
            // update the i->second
            mp.set(jKey, jValue + jValue);
            // increment ans by 1
            ans+=4;
        }
    }
});
 
// return the resultant minimum moves
return ans;
}
console.log(MinimumMoves([2, 5, 8, 1, 9], 5));


 
 

Output

12

 

Time Complexity: O(N*log N)
Auxiliary Space: O(N)

 



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

Similar Reads