Sort an array according to the order defined by another array

Last Updated : 18 Oct, 2026

Given two integer arrays a1[] and a2[]. Sort the first array a1[] such that all the relative positions of the elements in the first array are the same as the elements in the second array a2[].

Note: If elements are repeated in the second array, consider their first occurance only. Elements not in a2[] should appear in a1[] 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: Array elements of a1[] are sorted according to a2[]. So 2 comes first then 1 comes, now we append remaining elements of a1[] in sorted order.

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.

Try It Yourself
redirect icon

Hashing - O(m*log m + n) Time and O(m) Space

First, count how many times each number appears in a1[] using a map. Then, follow the order of a2[] and place all occurrences of each number into a1[]. Finally, sort the numbers that are left and place them at the end.

Consider a1[] = [2, 1, 2, 3, 4] and a2[] = [2, 1, 2].

Step 1: Count the frequency of each element in a1[].

The map becomes {2: 2, 1: 1, 3: 1, 4: 1} because 2 appears twice, while 1, 3, and 4 appear once.

Step 2: Traverse a2[] and place its elements first.

  • The first element is 2. Its frequency is 2, so place both occurrences of 2 in a1[]. Result: [2, 2].
  • The next element is 1. Its frequency is 1, so place it next. Result: [2, 2, 1].
  • The last element is 2 again, but it has already been processed, so skip it.

Step 3: Place the remaining elements.

  • The remaining elements are 3 and 4.
  • Sort them in ascending order and append them to the result.

Final array: [2, 2, 1, 3, 4]

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++) {
            // Safely check if a2[i] exists and its frequency is greater than 0
            while (freq.ContainsKey(a2[i]) && freq[a2[i]] > 0) {
                a1[index++] = a2[i];
                freq[a2[i]]--;
            }
            // Remove the key just like Java's freq.remove(a2[i])
            if (freq.ContainsKey(a2[i])) {
                freq.Remove(a2[i]);
            }
        }

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

        // Append remaining elements to a1
        foreach (int num in 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);

        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 

Custom Comparator - O(m*log m + n) Time and O(n) Space

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.

  • 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]);
        });
    }

    public 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 
Comment