🧠
Better Approach Using Hash Map and Sorting
💡 This approach improves efficiency by counting frequencies and sorting leftovers only once, avoiding repeated scans.
Intuition
Count how many times each element appears in arr1. Output elements in arr2 order using counts, then output leftover elements sorted ascending.
Algorithm
- Count frequency of each element in arr1 using a hash map.
- Initialize an empty result list.
- For each element in arr2, append it frequency times to result and remove from map.
- Sort remaining keys in map and append their elements frequency times to result.
- Return the result list.
💡 Counting frequencies avoids repeated scanning; sorting leftovers once is efficient.
def relative_sort_array(arr1, arr2):
from collections import Counter
freq = Counter(arr1)
result = []
for val in arr2:
result.extend([val] * freq[val])
del freq[val]
leftover = sorted(freq.elements())
result.extend(leftover)
return result
# Driver code
if __name__ == '__main__':
arr1 = [2,3,1,3,2,4,6,7,9,2,19]
arr2 = [2,1,4,3,9,6]
print(relative_sort_array(arr1, arr2))
Line Notes
from collections import CounterImport Counter to count frequencies efficiently
freq = Counter(arr1)Count frequency of each element in arr1
for val in arr2:Output elements in arr2 order using frequency
result.extend([val] * freq[val])Append val frequency times to result
del freq[val]Remove processed element from frequency map
leftover = sorted(freq.elements())Sort leftover elements ascending
result.extend(leftover)Append leftover elements at the end
import java.util.*;
public class Solution {
public static int[] relativeSortArray(int[] arr1, int[] arr2) {
Map<Integer, Integer> freq = new HashMap<>();
for (int num : arr1) freq.put(num, freq.getOrDefault(num, 0) + 1);
List<Integer> result = new ArrayList<>();
for (int val : arr2) {
int count = freq.get(val);
for (int i = 0; i < count; i++) result.add(val);
freq.remove(val);
}
List<Integer> leftover = new ArrayList<>(freq.keySet());
Collections.sort(leftover);
for (int val : leftover) {
int count = freq.get(val);
for (int i = 0; i < count; i++) result.add(val);
}
int[] resArr = new int[result.size()];
for (int i = 0; i < result.size(); i++) resArr[i] = result.get(i);
return resArr;
}
public static void main(String[] args) {
int[] arr1 = {2,3,1,3,2,4,6,7,9,2,19};
int[] arr2 = {2,1,4,3,9,6};
System.out.println(Arrays.toString(relativeSortArray(arr1, arr2)));
}
}
Line Notes
Map<Integer, Integer> freq = new HashMap<>();Map to store frequency counts
for (int num : arr1)Count frequency of each element in arr1
for (int val : arr2)Output elements in arr2 order
freq.remove(val);Remove processed elements from map
Collections.sort(leftover);Sort leftover keys ascending
for (int val : leftover)Output leftover elements frequency times
#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>
using namespace std;
vector<int> relativeSortArray(vector<int>& arr1, vector<int>& arr2) {
unordered_map<int,int> freq;
for (int num : arr1) freq[num]++;
vector<int> result;
for (int val : arr2) {
int count = freq[val];
for (int i = 0; i < count; i++) result.push_back(val);
freq.erase(val);
}
vector<int> leftover;
for (auto& p : freq) leftover.push_back(p.first);
sort(leftover.begin(), leftover.end());
for (int val : leftover) {
int count = freq[val];
for (int i = 0; i < count; i++) result.push_back(val);
}
return result;
}
int main() {
vector<int> arr1 = {2,3,1,3,2,4,6,7,9,2,19};
vector<int> arr2 = {2,1,4,3,9,6};
vector<int> res = relativeSortArray(arr1, arr2);
for (int x : res) cout << x << ' ';
cout << '\n';
return 0;
}
Line Notes
unordered_map<int,int> freq;Hash map to count frequencies
for (int num : arr1) freq[num]++;Count frequency of each element
for (int val : arr2)Output elements in arr2 order
freq.erase(val);Remove processed elements
sort(leftover.begin(), leftover.end());Sort leftover keys ascending
for (int val : leftover)Output leftover elements frequency times
function relativeSortArray(arr1, arr2) {
const freq = new Map();
for (const num of arr1) freq.set(num, (freq.get(num) || 0) + 1);
const result = [];
for (const val of arr2) {
const count = freq.get(val);
for (let i = 0; i < count; i++) result.push(val);
freq.delete(val);
}
const leftover = Array.from(freq.keys()).sort((a,b) => a - b);
for (const val of leftover) {
const count = freq.get(val);
for (let i = 0; i < count; i++) result.push(val);
}
return result;
}
// Test
const arr1 = [2,3,1,3,2,4,6,7,9,2,19];
const arr2 = [2,1,4,3,9,6];
console.log(relativeSortArray(arr1, arr2));
Line Notes
const freq = new Map();Map to store frequency counts
for (const num of arr1)Count frequency of each element
for (const val of arr2)Output elements in arr2 order
freq.delete(val);Remove processed elements
const leftover = Array.from(freq.keys()).sort((a,b) => a - b);Sort leftover keys ascending
for (const val of leftover)Output leftover elements frequency times
TimeO(n + m + k log k) where n = arr1.length, m = arr2.length, k = leftover elements
SpaceO(n) for frequency map and result list
Counting frequencies is O(n), outputting arr2 elements O(m), sorting leftover keys O(k log k).
💡 For n=100000, this approach is efficient enough to run within time limits.
Interview Verdict: Accepted; efficient and practical for interviews.
This approach balances clarity and efficiency, suitable for coding in interviews.