Open In App

Sort an array according to the order defined by another array

Last Updated : 08 Aug, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given two arrays a1[] and a2[], sort a1[] such that elements appear in the order of a2[]. Elements not in a2[] should be placed at the end in ascending order.

Example: 

Input: a1 = [2, 1, 2, 3, 4], a2 = [2, 1, 2]
Output: [2, 2, 1, 3, 4]
Explanation: Elements 2 and 1 follow the order in a2. Remaining 3 and 4 are sorted at the end.

Input: a1 = [4, 1, 3, 3, 2], a2 = [3, 1]
Output: [3, 3, 1, 2, 4]
Explanation: Elements 3 and 1 come first as per a2. Others (2, 4) are sorted and placed after.

[Approach 1] Using Hashing - O(m × log m + n) Time and O(m) Space

The main idea is to use a hash map to count frequencies of elements in a1, so we can efficiently place elements in the desired order. Then, iterate through a2 to append matching elements in order, followed by the sorted remaining elements from a1. This ensures correct relative order from a2, and sorted placement of extras.

Step-By-Step Approach:

  • Count frequency of each element in a1 using a hash map.
  • Add elements from a2 to the result based on their frequency.
  • Remove those elements from the map after processing.
  • Sort and add the remaining elements to the result using their frequency.
C++
#include<iostream>
#include<vector>
#include<unordered_map>
#include<algorithm>
using namespace std;

void relativeSort(vector<int>& a1, vector<int>& a2){
    
    int m = a1.size(), n = a2.size();
    unordered_map<int, int> freq;

    // Count frequency of each element in a1
    for (int i = 0; i < m; i++) {
        freq[a1[i]]++;
    }

    int index = 0;

    // Place elements of a2 in a1 based on frequency
    for (int i = 0; i < n; i++) {
        while (freq[a2[i]]) {
            a1[index++] = a2[i];
            freq[a2[i]]--;
        }
        freq.erase(a2[i]);
    }

    // Collect remaining elements and sort them
    vector<int> remaining;
    for (auto& pair : freq) {
        while (pair.second--) {
            remaining.push_back(pair.first);
        }
    }
    sort(remaining.begin(), remaining.end());

    // Append remaining elements to a1
    for (int i : remaining) {
        a1[index++] = i;
    }
}

int main(){
    
    vector<int> a1 = { 2, 1, 2, 3, 4};
    vector<int> a2 = { 2, 1, 2 };

    relativeSort(a1, a2);
    
    for (int i = 0; i < a1.size(); i++) {
        cout << a1[i] << " ";
    }
    
    cout << endl;
    return 0;
}
Java
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;

class GfG {

    static void relativeSort(int[] a1, int[] a2) {

        int m = a1.length, n = a2.length;
        Map<Integer, Integer> freq = new HashMap<>();

        // Count frequency of each element in a1
        for (int i = 0; i < m; i++) {
            freq.put(a1[i], freq.getOrDefault(a1[i], 0) + 1);
        }

        int index = 0;

        // Place elements of a2 in a1 based on frequency
        for (int i = 0; i < n; i++) {
            while (freq.getOrDefault(a2[i], 0) > 0) {
                a1[index++] = a2[i];
                freq.put(a2[i], freq.get(a2[i]) - 1);
            }
            freq.remove(a2[i]);
        }

        // Collect remaining elements and sort them
        List<Integer> remaining = new ArrayList<>();
        for (Map.Entry<Integer, Integer> entry : freq.entrySet()) {
            for (int i = 0; i < entry.getValue(); i++) {
                remaining.add(entry.getKey());
            }
        }
        Collections.sort(remaining);

        // Append remaining elements to a1
        for (int num : remaining) {
            a1[index++] = num;
        }
    }

    public static void main(String[] args) {

        int[] a1 = {2, 1, 2, 3, 4};
        int[] a2 = {2, 1, 2};

        relativeSort(a1, a2);

        for (int num : a1) {
            System.out.print(num + " ");
        }

        System.out.println();
    }
}
Python
def relativeSort(a1, a2):

    m, n = len(a1), len(a2)
    freq = {}

    # Count frequency of each element in a1
    for num in a1:
        freq[num] = freq.get(num, 0) + 1

    index = 0

    # Place elements of a2 in a1 based on frequency
    for num in a2:
        while freq.get(num, 0) > 0:
            a1[index] = num
            index += 1
            freq[num] -= 1
        freq.pop(num, None)

    # Collect remaining elements and sort them
    remaining = []
    for key in freq:
        remaining.extend([key] * freq[key])
    remaining.sort()

    # Append remaining elements to a1
    for num in remaining:
        a1[index] = num
        index += 1

if __name__ == "__main__":
    a1 = [2, 1, 2, 3, 4]
    a2 = [2, 1, 2]

    relativeSort(a1, a2)

    for num in a1:
        print(num, end=" ")
    print()
C#
using System;
using System.Collections.Generic;

class GfG {

    static void relativeSort(int[] a1, int[] a2) {

        int m = a1.Length, n = a2.Length;
        Dictionary<int, int> freq = new Dictionary<int, int>();

        // Count frequency of each element in a1
        for (int i = 0; i < m; i++) {
            if (!freq.ContainsKey(a1[i]))
                freq[a1[i]] = 0;
            freq[a1[i]]++;
        }

        int index = 0;

        // Place elements of a2 in a1 based on frequency
        for (int i = 0; i < n; i++) {
            while (freq.ContainsKey(a2[i]) && freq[a2[i]] > 0) {
                a1[index++] = a2[i];
                freq[a2[i]]--;
            }
            freq.Remove(a2[i]);
        }

        // Collect remaining elements and sort them
        List<int> remaining = new List<int>();
        foreach (var pair in freq) {
            for (int i = 0; i < pair.Value; i++) {
                remaining.Add(pair.Key);
            }
        }
        remaining.Sort();

        // Append remaining elements to a1
        foreach (int num in remaining) {
            a1[index++] = num;
        }
    }

    static void Main() {

        int[] a1 = {2, 1, 2, 3, 4};
        int[] a2 = {2, 1, 2};

        relativeSort(a1, a2);

        foreach (int num in a1) {
            Console.Write(num + " ");
        }

        Console.WriteLine();
    }
}
JavaScript
function relativeSort(a1, a2) {

    let m = a1.length, n = a2.length;
    let freq = new Map();

    // Count frequency of each element in a1
    for (let i = 0; i < m; i++) {
        freq.set(a1[i], (freq.get(a1[i]) || 0) + 1);
    }

    let index = 0;

    // Place elements of a2 in a1 based on frequency
    for (let i = 0; i < n; i++) {
        while (freq.get(a2[i]) > 0) {
            a1[index++] = a2[i];
            freq.set(a2[i], freq.get(a2[i]) - 1);
        }
        freq.delete(a2[i]);
    }

    // Collect remaining elements and sort them
    let remaining = [];
    for (let [key, val] of freq.entries()) {
        while (val--) remaining.push(key);
    }
    remaining.sort((a, b) => a - b);

    // Append remaining elements to a1
    for (let i = 0; i < remaining.length; i++) {
        a1[index++] = remaining[i];
    }
}

// Driver Code
let a1 = [2, 1, 2, 3, 4];
let a2 = [2, 1, 2];

relativeSort(a1, a2);

console.log(a1.join(" "));

Output
2 2 1 3 4 

[Approach 2] Using a Custom Comparator

The idea is to sort the first array a1[] based on the relative order of elements defined in the second array a2[]. A hash map stores the index of each element in a2[] to define their priority. While sorting a1[], a custom comparator uses this map to ensure that elements present in a2[] come first in the correct order, and the rest are sorted naturally in increasing order.

Step-By-Step Approach:

  • Traverse a2[] and store the index of each element in a hash map to define custom order.
  • Sort a1[] using a lambda comparator with the help of the map.
  • If both elements are in the map, compare their positions from the map.
  • If only one is in the map, prioritize it over the one that is not.
  • If neither is in the map, sort them in increasing numerical order.
  • The final a1[] follows the order of a2[] for common elements and sorts the rest normally.
C++
#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>
using namespace std;

void relativeSort(vector<int>& a1, vector<int>& a2) {
    
    // create a map to store the index of
    // each element in a2
    unordered_map<int, int> mp;
    for (int i = 0; i < a2.size(); i++) {
        if (mp.count(a2[i]) == 0)
            mp[a2[i]] = i;
    }

    // custom comparator using lambda
    sort(a1.begin(), a1.end(), [&](int a, int b) {
        bool aIn = mp.count(a), bIn = mp.count(b);
        if (!aIn && !bIn) return a < b;
        if (!aIn) return false;
        if (!bIn) return true;
        return mp[a] < mp[b];
    });
}

int main() {
    vector<int> a1 = {2, 1, 2, 3, 4};
    vector<int> a2 = {2, 1, 2};

    relativeSort(a1, a2);

    for (int x : a1)
        cout << x << " ";
    cout << endl;

    return 0;
}
Java
import java.util.Map;
import java.util.HashMap;
import java.util.Arrays;

class GfG {

    static void relativeSort(int[] a1, int[] a2) {

        // Create a map to store the index of each
        // element in a2
        Map<Integer, Integer> mp = new HashMap<>();
        for (int i = 0; i < a2.length; i++) {
            if (!mp.containsKey(a2[i]))
                mp.put(a2[i], i);
        }

        // Convert int[] to Integer[] for custom sorting
        Integer[] temp = Arrays.stream(a1).boxed().toArray(Integer[]::new);

        // Custom comparator using lambda
        Arrays.sort(temp, (a, b) -> {
            boolean aIn = mp.containsKey(a), bIn = mp.containsKey(b);
            if (!aIn && !bIn) return Integer.compare(a, b);
            if (!aIn) return 1;
            if (!bIn) return -1;
            return Integer.compare(mp.get(a), mp.get(b));
        });

        // Copy sorted values back to original array
        for (int i = 0; i < a1.length; i++) {
            a1[i] = temp[i];
        }
    }

    public static void main(String[] args) {

        int[] a1 = {2, 1, 2, 3, 4};
        int[] a2 = {2, 1, 2};

        relativeSort(a1, a2);

        for (int num : a1)
            System.out.print(num + " ");
        System.out.println();
    }
}
Python
def relativeSort(a1, a2):

    # create a map to store the index of each element in a2
    mp = {}
    for i in range(len(a2)):
        if a2[i] not in mp:
            mp[a2[i]] = i

    # custom comparator using lambda inside sort's key
    a1.sort(key=lambda x: (mp.get(x, float('inf')), x))

if __name__ == "__main__":
    a1 = [2, 1, 2, 3, 4]
    a2 = [2, 1, 2]

    relativeSort(a1, a2)

    for x in a1:
        print(x, end=" ")
    print()
C#
using System;
using System.Collections.Generic;

class GfG {

    static void relativeSort(int[] a1, int[] a2) {

        // Create a map to store the index of each element in a2
        Dictionary<int, int> mp = new Dictionary<int, int>();
        for (int i = 0; i < a2.Length; i++) {
            if (!mp.ContainsKey(a2[i]))
                mp[a2[i]] = i;
        }

        // Custom comparator using lambda
        Array.Sort(a1, (a, b) => {
            bool aIn = mp.ContainsKey(a), bIn = mp.ContainsKey(b);
            if (!aIn && !bIn) return a.CompareTo(b);
            if (!aIn) return 1;
            if (!bIn) return -1;
            return mp[a].CompareTo(mp[b]);
        });
    }

    static void Main() {

        int[] a1 = {2, 1, 2, 3, 4};
        int[] a2 = {2, 1, 2};

        relativeSort(a1, a2);

        foreach (int x in a1)
            Console.Write(x + " ");
        Console.WriteLine();
    }
}
JavaScript
function relativeSort(a1, a2) {

    // Create a map to store the index of 
    // each element in a2
    let mp = new Map();
    for (let i = 0; i < a2.length; i++) {
        if (!mp.has(a2[i])) {
            mp.set(a2[i], i);
        }
    }

    // Custom comparator using lambda
    a1.sort((a, b) => {
        let aIn = mp.has(a), bIn = mp.has(b);
        if (!aIn && !bIn) return a - b;
        if (!aIn) return 1;
        if (!bIn) return -1;
        return mp.get(a) - mp.get(b);
    });
}

// Driver Code
let a1 = [2, 1, 2, 3, 4];
let a2 = [2, 1, 2];

relativeSort(a1, a2);

console.log(a1.join(" "));

Output
2 2 1 3 4 

Time Complexity: O(m log m + n), sorting a1 takes O(m log m) time, and building the map from a2 takes O(n) time, where m is the size of a1 and n is the size of a2.
Auxiliary Space: O(n), an unordered map is used to store positions of m elements from a2, contributing to the extra space.


Sort an array according to the other | DSA Problem

Similar Reads