Rearrange an array so that arr[i] becomes arr[arr[i]] with O(1) extra space

Given an array arr[] of size n where every element is in range from 0 to n-1. Rearrange the given array so that arr[i] becomes arr[arr[i]]. This should be done with O(1) extra space.

Examples:

Input: arr[]  = {3, 2, 0, 1}
Output: arr[] = {1, 0, 3, 2}

Input: arr[] = {4, 0, 2, 1, 3}
Output: arr[] = {3, 4, 2, 0, 1}

Input: arr[] = {0, 1, 2, 3}
Output: arr[] = {0, 1, 2, 3}

If the extra space condition is removed, the question becomes very easy. The main part of the question is to do it without extra space.

We strongly recommend that you click here and practice it, before moving on to the solution.


The credit for following solution goes to Ganesh Ram Sundaram . Following are the steps.

1) Increase every array element arr[i] by (arr[arr[i]] % n)*n.
2) Divide every element by n.



Let us understand the above steps by an example array {3, 2, 0, 1}
In first step, every value is incremented by (arr[arr[i]] % n)*n
After first step array becomes {7, 2, 12, 9}. 
The important thing is, after the increment operation
of first step, every element holds both old values and new values. 
Old value can be obtained by arr[i]%n and new value can be obtained
by arr[i]/n.

In second step, all elements are updated to new or output values 
by doing arr[i] = arr[i]/n.
After second step, array becomes {1, 0, 3, 2}

Following is the implementation of the above approach.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

#include <iostream>
using namespace std;
  
// The function to rearrange an array in-place so that arr[i]
// becomes arr[arr[i]].
void rearrange(int arr[], int n)
{
    // First step: Increase all values by (arr[arr[i]]%n)*n
    for (int i=0; i < n; i++)
        arr[i] += (arr[arr[i]]%n)*n;
  
    // Second Step: Divide all values by n
    for (int i=0; i<n; i++)
        arr[i] /= n;
}
  
// A utility function to print an array of size n
void printArr(int arr[], int n)
{
    for (int i = 0; i < n; i++)
        cout << arr[i] << " ";
    cout << endl;
}
  
  
/* Driver program to test above functions*/
int main()
{
    int arr[] = {3, 2, 0, 1};
    int n = sizeof(arr)/sizeof(arr[0]);
  
    cout << "Given array is \n";
    printArr(arr, n);
  
    rearrange(arr, n);
  
    cout << "Modified array is \n";
    printArr(arr, n);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

class Rearrange 
{
    // The function to rearrange an array in-place so that arr[i]
    // becomes arr[arr[i]].
    void rearrange(int arr[], int n) 
    {
        // First step: Increase all values by (arr[arr[i]]%n)*n
        for (int i = 0; i < n; i++)
            arr[i] += (arr[arr[i]] % n) * n;
  
        // Second Step: Divide all values by n
        for (int i = 0; i < n; i++)
            arr[i] /= n;
    }
  
    // A utility function to print an array of size n
    void printArr(int arr[], int n) 
    {
        for (int i = 0; i < n; i++)
            System.out.print(arr[i] + " ");
        System.out.println("");
    }
  
    /* Driver program to test above functions */
    public static void main(String[] args) 
    {
        Rearrange rearrange = new Rearrange();
        int arr[] = {3, 2, 0, 1};
        int n = arr.length;
  
        System.out.println("Given Array is :");
        rearrange.printArr(arr, n);
  
        rearrange.rearrange(arr, n);
  
        System.out.println("Modified Array is :");
        rearrange.printArr(arr, n);
    }
}
  
// This code has been contributed by Mayank Jaiswal

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to Rearrange 
# an array so that arr[i] becomes 
# arr[arr[i]]
  
# The function to rearrange an
# array in-place so that arr[i]
# becomes arr[arr[i]].
def rearrange(arr, n):
  
    # First step: Increase all values
    # by (arr[arr[i]] % n) * n
    for i in range(0, n):
        arr[i] += (arr[arr[i]] % n) * n
  
    # Second Step: Divide all values
    # by n
    for i in range(0, n):
        arr[i] = int(arr[i] / n)
  
# A utility function to print 
# an array of size n
def printArr(arr, n):
  
    for i in range(0, n):
        print (arr[i], end =" ")
    print ("")
  
# Driver program
arr = [3, 2, 0, 1]
n = len(arr)
  
print ("Given array is")
printArr(arr, n)
  
rearrange(arr, n);
print ("Modified array is")
printArr(arr, n)
  
# This code is contributed by shreyanshi_arun

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# Program to rearrange an array
// so that arr[i] becomes arr[arr[i]] 
// with O(1) extra space
using System;
  
class Rearrange
{
      
    // Function to rearrange an 
    // array in-place so that arr[i]
    // becomes arr[arr[i]].
    void rearrange(int []arr, int n) 
    {
          
        // First step: Increase all values 
        // by (arr[arr[i]] % n) * n
        for (int i = 0; i < n; i++)
            arr[i] += (arr[arr[i]] % n) * n;
  
        // Second Step: Divide all values by n
        for (int i = 0; i < n; i++)
            arr[i] /= n;
    }
  
    // A utility function to 
    // print an array of size n
    void printArr(int []arr, int n) 
    {
        for (int i = 0; i < n; i++)
            Console.Write(arr[i] + " ");
        Console.WriteLine("");
    }
  
    //  Driver Code
    public static void Main() 
    {
        Rearrange rearrange = new Rearrange();
        int []arr = {3, 2, 0, 1};
        int n = arr.Length;
  
        Console.Write("Given Array is :");
        rearrange.printArr(arr, n);
  
        rearrange.rearrange(arr, n);
  
        Console.Write("Modified Array is :");
        rearrange.printArr(arr, n);
    }
}
  
// This code has been contributed by Nitin Mittal.

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php 
// The function to rearrange an array 
// in-place so that arr[i] becomes arr[arr[i]].
function rearrange(&$arr, $n)
{
    // First step: Increase all values
    // by (arr[arr[i]]%n)*n
    for ($i = 0; $i < $n; $i++)
        $arr[$i] += ($arr[$arr[$i]] % $n) * $n;
  
    // Second Step: Divide all values by n
    for ($i = 0; $i < $n; $i++)
        $arr[$i] = intval($arr[$i] / $n);
}
  
// A utility function to print 
// an array of size n
function printArr(&$arr, $n)
{
    for ($i = 0; $i < $n; $i++)
        echo $arr[$i] ." ";
    echo "\n";
}
  
  
// Driver Code
$arr = array(3, 2, 0, 1);
$n = sizeof($arr);
  
echo "Given array is \n";
printArr($arr, $n);
  
rearrange($arr, $n);
  
echo "Modified array is \n";
printArr($arr, $n);
  
// This code is contributed 
// by ChitraNayal
?>

chevron_right



Output:

Given array is
3 2 0 1
Modified array is
1 0 3 2

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

The problem with above solution is, it may cause overflow.

Please see below post for a better solution:
Rearrange an array such that ‘arr[j]’ becomes ‘i’ if ‘arr[i]’ is ‘j’

This article is contributed by Himanshu Gupta. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above



My Personal Notes arrow_drop_up

Improved By : nitin mittal, Ita_c



Article Tags :
Practice Tags :


8


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.