class Solution:
def relativeSortArray(self, arr1, arr2):
from collections import Counter
count = Counter(arr1)
result = []
# Add elements in arr2 order
for num in arr2:
result.extend([num] * count[num])
count[num] = 0
# Add remaining elements sorted
leftovers = []
for num in count:
if count[num] > 0:
leftovers.extend([num] * count[num])
result.extend(sorted(leftovers))
return result
class Solution {
public:
vector<int> relativeSortArray(vector<int>& arr1, vector<int>& arr2) {
unordered_map<int, int> count;
for (int n : arr1) count[n]++;
vector<int> result;
// Add elements in arr2 order
for (int n : arr2) {
for (int i = 0; i < count[n]; ++i) result.push_back(n);
count[n] = 0;
}
// Add remaining elements sorted
vector<int> leftovers;
for (auto& it : count) {
for (int i = 0; i < it.second; ++i) leftovers.push_back(it.first);
}
sort(leftovers.begin(), leftovers.end());
result.insert(result.end(), leftovers.begin(), leftovers.end());
return result;
}
};
class Solution {
public int[] relativeSortArray(int[] arr1, int[] arr2) {
Map<Integer, Integer> count = new HashMap<>();
for (int n : arr1) count.put(n, count.getOrDefault(n, 0) + 1);
List<Integer> result = new ArrayList<>();
// Add elements in arr2 order
for (int n : arr2) {
for (int i = 0; i < count.getOrDefault(n, 0); ++i) result.add(n);
count.put(n, 0);
}
// Add remaining elements sorted
List<Integer> leftovers = new ArrayList<>();
for (int n : count.keySet()) {
int c = count.get(n);
for (int i = 0; i < c; ++i) leftovers.add(n);
}
Collections.sort(leftovers);
result.addAll(leftovers);
// Convert to array
int[] resArr = new int[result.size()];
for (int i = 0; i < result.size(); ++i) resArr[i] = result.get(i);
return resArr;
}
}
var relativeSortArray = function(arr1, arr2) {
let count = {};
for (let n of arr1) count[n] = (count[n] || 0) + 1;
let result = [];
// Add elements in arr2 order
for (let n of arr2) {
for (let i = 0; i < (count[n] || 0); ++i) result.push(n);
count[n] = 0;
}
// Add remaining elements sorted
let leftovers = [];
for (let n in count) {
for (let i = 0; i < count[n]; ++i) leftovers.push(Number(n));
}
leftovers.sort((a, b) => a - b);
result = result.concat(leftovers);
return result;
};
You are given two arrays: arr1
and arr2
. The task is to sort arr1
such that the relative ordering of items in arr1
matches the order given in arr2
. Elements of arr1
that are not present in arr2
should be placed at the end of arr1
in ascending order.
arr2
is unique and appears in arr1
.arr2
can appear anywhere in arr1
and should be sorted at the end.arr1
must be used exactly once in the output.
The core challenge is to reorder arr1
so that elements present in arr2
maintain the same order as in arr2
, while the rest are sorted. A brute-force approach could repeatedly scan arr1
for each value in arr2
, but this is inefficient. Optimally, we want a way to quickly count and retrieve values in the desired order.
The key insight is to use a counting structure (like a hash map) to record how many times each number appears in arr1
. Then, for each value in arr2
, we can append that number the correct number of times, and finally sort and append the leftovers.
arr1
using a hash map or counter.arr2
, append that element to the result as many times as it appears in arr1
. After adding, set its count to zero to mark it as used.arr2
), collect them from the counter, sort them in ascending order, and append them to the result.We use a hash map (dictionary) for counting because it allows O(1) lookups and updates, making the process efficient even for large arrays.
Input: arr1 = [2,3,1,3,2,4,6,7,9,2,19]
, arr2 = [2,1,4,3,9,6]
arr1
: 2 appears 3 times, 3 appears 2 times, 1 appears 1 time, 4 appears 1 time, 6 appears 1 time, 7 appears 1 time, 9 appears 1 time, 19 appears 1 time.arr2
:
arr2
), sort them: [7, 19]arr2
, scan arr1
to collect matches (O(mn), where m = len(arr2), n = len(arr1)). Sorting leftovers adds O(k log k).arr2
: O(m)arr2
The optimized approach is much faster and uses reasonable extra space.
This problem is elegantly solved by counting occurrences and then reconstructing the array in the desired order. Using a hash map for counting ensures efficient lookups and insertions. The two-phase process—first placing elements by arr2
's order, then sorting and appending the rest—makes the solution both intuitive and efficient, even for large inputs.