Sort an array which contain 1 to n values (original) (raw)

Given an array **arr[] of size **n consisting of distinct integers from 1 to n. Your task is to **sort the array without using extra space.

**Examples :

**Input: arr[] = [2, 1, 5, 4, 3]
**Output: [1, 2, 3, 4, 5]
**Explanation: Sorting the array in ascending order rearranges the elements to [1, 2, 3, 4, 5].

**Input: arr[] = [1, 2, 3, 4, 5, 6]
**Output: [1, 2, 3, 4, 5, 6]
**Explanation: The array is already sorted, so it remains unchanged.

Table of Content

[Native approach] Using Sort Function - O(n log n) Time O(1) Space

We use a O(n Log n) sorting algorithm and it is possible to achieve with O(1) space. In the below implementation, we have simply used a library function.

C++ `

#include #include using namespace std;

vector sortArray(vector &arr) { sort(arr.begin(), arr.end());

return arr;

}

// Driver Code int main() { vector arr = {2, 1, 5, 4, 3};

vector<int> res = sortArray(arr);

cout << "[";
for (int i = 0; i < res.size(); i++)
{
    cout << res[i];
    if (i != res.size() - 1)
    {
        cout << ", ";
    }
}
cout << "]";

return 0;

}

Java

import java.util.Arrays;

public class GfG {

public static int[] sortArray(int[] arr)
{
    Arrays.sort(arr);
    return arr;
}

public static void main(String[] args)
{
    int[] arr = { 2, 1, 5, 4, 3 };

    int[] res = sortArray(arr);

    System.out.print("[");
    for (int i = 0; i < res.length; i++) {
        System.out.print(res[i]);
        if (i != res.length - 1) {
            System.out.print(", ");
        }
    }
    System.out.print("]");
}

}

Python

def sortArray(arr): # Function to sort array arr.sort() return arr

Driver Code

if name == "main": arr = [2, 1, 5, 4, 3]

res = sortArray(arr)

print('[', end='')
for i in range(len(res)):
    print(res[i], end='')
    if i != len(res) - 1:
        print(', ', end='')
print(']')

C#

using System; using System.Collections.Generic; using System.Linq;

public class GfG { // Function to sort array public static List sortArray(List arr) { arr.Sort(); return arr; }

// Driver Code
public static void Main()
{
    List<int> arr = new List<int>{ 2, 1, 5, 4, 3 };

    List<int> res = sortArray(arr);

    Console.Write("[");
    for (int i = 0; i < res.Count; i++) {
        Console.Write(res[i]);
        if (i != res.Count - 1) {
            Console.Write(", ");
        }
    }
    Console.Write("]");
}

}

JavaScript

function sortArray(arr) { arr.sort((a, b) => a - b); return arr; }

// Driver Code let arr = [ 2, 1, 5, 4, 3 ];

let res = sortArray(arr);

let ans = "["; for (let i = 0; i < res.length; i++) { ans += res[i]; if (i !== res.length - 1) { ans += ", "; } } ans += "]";

console.log(ans);

`

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

[Better Approach] Counting Sort - O(n) Time O(n) Space

We can use counting sort to achieve this in linear time. Note that the counting sort keeps array values only and does not copy values from 1 to n.

[Efficient Approach] Using Cyclic Sort - O(n) Time O(1) Space

Follow the steps mentioned below to solve the problem. The idea is based on Cycle Sort algorithm

#include <bits/stdc++.h> using namespace std;

// Function to sort the array

vector sortArray(vector &arr) { int i = 0;

while (i < arr.size())
{

    // If element is not at its correct position, swap it
    if (arr[arr[i] - 1] != arr[i])
    {
        swap(arr[i], arr[arr[i] - 1]);
    }
    else
    {
        i++;
    }
}

return arr;

}

// Driver Code int main() { vector arr = {2, 1, 5, 4, 3};

vector<int> res = sortArray(arr);

cout << "[";
for (int i = 0; i < res.size(); i++)
{
    cout << res[i];
    if (i != res.size() - 1)
    {
        cout << ", ";
    }
}
cout << "]";

return 0;

}

Java

import java.util.Arrays;

public class GfG {

// Function to sort the array
public static int[] sortArray(int[] arr)
{
    int i = 0;

    while (i < arr.length) {

        // If element is not at its correct position,
        // swap it
        if (arr[arr[i] - 1] != arr[i]) {
            int temp = arr[i];
            arr[i] = arr[arr[i] - 1];
            arr[temp - 1] = temp;
        }
        else {
            i++;
        }
    }

    return arr;
}

// Driver Code
public static void main(String[] args)
{
    int[] arr = { 2, 1, 5, 4, 3 };

    int[] res = sortArray(arr);

    System.out.print("[");
    for (int i = 0; i < res.length; i++) {
        System.out.print(res[i]);
        if (i != res.length - 1) {
            System.out.print(", ");
        }
    }
    System.out.print("]");
}

}

Python

Function to sort the array

def sortArray(arr): i = 0

while i < len(arr):

    # If element is not at its correct position, swap it
    if arr[arr[i] - 1] != arr[i]:
        temp = arr[i]
        arr[i] = arr[temp - 1]
        arr[temp - 1] = temp
    else:
        i += 1

return arr

Driver Code

if name == "main": arr = [2, 1, 5, 4, 3]

res = sortArray(arr)

print('[', end='')
for i in range(len(res)):
    print(res[i], end='')
    if i != len(res) - 1:
        print(', ', end='')
print(']')

C#

using System; using System.Collections.Generic;

class GfG { // Function to sort the array static List sortArray(List arr) { int i = 0;

    while (i < arr.Count) {

        // If element is not at its correct position,
        // swap it
        if (arr[arr[i] - 1] != arr[i]) {
            int temp = arr[i];
            arr[i] = arr[arr[i] - 1];
            arr[temp - 1] = temp;
        }
        else {
            i++;
        }
    }

    return arr;
}

// Driver Code
static void Main()
{
    List<int> arr = new List<int>{ 2, 1, 5, 4, 3 };

    List<int> res = sortArray(arr);

    Console.Write("[");
    for (int i = 0; i < res.Count; i++) {
        Console.Write(res[i]);
        if (i != res.Count - 1) {
            Console.Write(", ");
        }
    }
    Console.Write("]");
}

}

JavaScript

// Function to sort the array function sortArray(arr) { let i = 0;

while (i < arr.length) {

    // If element is not at its correct position, swap
    // it
    if (arr[arr[i] - 1] !== arr[i]) {
        let temp = arr[i];
        arr[i] = arr[temp - 1];
        arr[temp - 1] = temp;
    }
    else {
        i++;
    }
}

return arr;

}

// Driver Code let arr = [ 2, 1, 5, 4, 3 ];

let res = sortArray(arr);

let ans = "["; for (let i = 0; i < res.length; i++) { ans += res[i]; if (i !== res.length - 1) { ans += ", "; } } ans += "]";

console.log(ans);

`

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

**Illustration

arr[] = {3, 1, 2}

i = 0 : arr[0] = 3, Swap arr[0] and arr[2], arr[] = {2, 1, 3}

i = 0 : arr[0] = 2. Swap arr[0] and arr[1]. arr[] = {1, 2, 3}

i = 0 : arr[0] is already in its correct position, i = 1
i = 1 : arr[1] is already in its correct position, i = 2
i = 2 : arr[0] is already in its correct position, i = 3

**Why is this linear or O(n) Time? For every element in the array, the algorithm swaps it to its correct position only once. So we do at most n swaps And if we do not do a swap, we increment i. So the total work done is around 2n

[Alternate Approach**]** Using Mathematical Formula - O(n) Time O(1) Space

The idea is to traverse the input array and for each element **arr[i], place it at its correct index, that is ****(arr[i] - 1)**. To avoid overwriting, we ind the maximum value in the array, that is ****(n + 1)** and use it to store the original as well as the updated value at each index.

Let's say for any index i, we have the current element as arr[i]. We know that the correct index for arr[i], say **correctIdx is ****(arr[i] - 1)**. Now, instead of overwriting **arr[correctIdx], we add (**arr[i] * (n + 1)) to **arr[correctIdx]. This is because we can get the **original value by **arr[i] % ****(n + 1)** and **updated value by **arr[i] / (n + 1).

After traversing the array and modifying each index, traverse again and update **arr[i] to **arr[i] / (n + 1) to get the original values back.

The key idea is **encoding two values in one array cell:

#include #include #include using namespace std;

vector sortArray(vector &arr) { int n = arr.size();

for (int i = 0; i < n; i++)
{
    int originalVal = arr[i] % (n + 1);
    int correctIdx = originalVal - 1;

    arr[correctIdx] += originalVal * (n + 1);
}

for (int i = 0; i < n; i++)
{
    arr[i] /= (n + 1);
}

return arr;

}

// Driver Code int main() { vector arr = {2, 1, 5, 4, 3};

vector<int> res = sortArray(arr);

cout << "[";
for (int i = 0; i < res.size(); i++)
{
    cout << res[i];
    if (i != res.size() - 1)
    {
        cout << ", ";
    }
}
cout << "]";

return 0;

}

Java

import java.util.ArrayList; import java.util.Arrays;

public class GfG { public static ArrayList sortArray(ArrayList arr) { int n = arr.size();

    for (int i = 0; i < n; i++) {
        int originalVal = arr.get(i) % (n + 1);
        int correctIdx = originalVal - 1;

        arr.set(correctIdx,
                arr.get(correctIdx)
                    + originalVal * (n + 1));
    }

    for (int i = 0; i < n; i++) {
        arr.set(i, arr.get(i) / (n + 1));
    }

    return arr;
}

public static void main(String[] args)
{
    ArrayList<Integer> arr
        = new ArrayList<>(Arrays.asList(2, 1, 5, 4, 3));

    ArrayList<Integer> res = sortArray(arr);

    System.out.print("[");
    for (int i = 0; i < res.size(); i++) {
        System.out.print(res.get(i));
        if (i != res.size() - 1) {
            System.out.print(", ");
        }
    }
    System.out.print("]");
}

}

Python

def sortArray(arr): n = len(arr)

for i in range(n):
    originalVal = arr[i] % (n + 1)
    correctIdx = originalVal - 1

    arr[correctIdx] += originalVal * (n + 1)

for i in range(n):
    arr[i] //= (n + 1)

return arr

Driver Code

if name == "main": arr = [2, 1, 5, 4, 3]

res = sortArray(arr)

print('[', end='')
for i in range(len(res)):
    print(res[i], end='')
    if i!= len(res) - 1:
        print(', ', end='')
print(']')

C#

using System; using System.Collections.Generic;

public class GfG { public static List sortArray(List arr) { int n = arr.Count;

    for (int i = 0; i < n; i++) {
        int originalVal = arr[i] % (n + 1);
        int correctIdx = originalVal - 1;

        arr[correctIdx] += originalVal * (n + 1);
    }

    for (int i = 0; i < n; i++) {
        arr[i] /= (n + 1);
    }

    return arr;
}

public static void Main()
{
    List<int> arr = new List<int>{ 2, 1, 5, 4, 3 };

    List<int> res = sortArray(arr);

    Console.Write('[');
    for (int i = 0; i < res.Count; i++) {
        Console.Write(res[i]);
        if (i != res.Count - 1) {
            Console.Write(", ");
        }
    }
    Console.Write(']');
}

}

JavaScript

function sortArray(arr) { let n = arr.length;

for (let i = 0; i < n; i++) {
    let originalVal = arr[i] % (n + 1);
    let correctIdx = originalVal - 1;

    arr[correctIdx] += originalVal * (n + 1);
}

for (let i = 0; i < n; i++) {
    arr[i] = Math.floor(arr[i] / (n + 1));
}

return arr;

}

// Driver Code let arr = [ 2, 1, 5, 4, 3 ];

let res = sortArray(arr);

console.log("[" + res.join(", ") + "]");

`

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