Relative Sort Array - Solution
Solutions and explanations
Video Explanation
class Solution:
def relativeSortArray(self, arr1: List[int], arr2: List[int]) -> List[int]:
order = {ele: idx for idx, ele in enumerate(arr2)}
def relative_key(num):
if num in order:
return (0, order[num])
return (1, num)
return sorted(arr1, key=relative_key)
Complexity Analysis
Here, n is size of the first array arr1 (array to be sorted).
m is size of the second array arr2 (defines relative order), m <= n.
- Time Complexity:
O(n log n)- Sorting:
O(n log n)(dominant factor) - Construction of Ordering HashMap:
O(m) - Overall:
O(n log n + m)=O(n log n)
- Sorting:
- Space Complexity:
O(n)- Ordering HashMap:
O(m)space, as it stores index mapping formelements. - Output Sorted List:
O(n)space, as we are returning a new list withnelements. - Overall:
O(n + m)=O(n)
- Ordering HashMap:
class Solution:
def relativeSortArray(self, arr1: List[int], arr2: List[int]) -> List[int]:
order = {ele: idx for idx, ele in enumerate(arr2)}
return sorted(arr1, key=lambda x: (order.get(x, float("inf")), x))
Complexity Analysis
Here, n is size of the first array arr1 (array to be sorted).
m is size of the second array arr2 (defines relative order), m <= n.
- Time Complexity:
O(n log n)- Sorting:
O(n log n)(dominant factor) - Construction of Ordering HashMap:
O(m) - Overall:
O(n log n + m)=O(n log n)
- Sorting:
- Space Complexity:
O(n)- Ordering HashMap:
O(m)space, as it stores index mapping formelements. - Output Sorted List:
O(n)space, as we are returning a new list withnelements. - Overall:
O(n + m)=O(n)
- Ordering HashMap:
class Solution:
def relativeSortArray(self, arr1: List[int], arr2: List[int]) -> List[int]:
freq_map = collections.Counter(arr1)
res = []
# Add elements in the order defined by arr2, and remove from the frequency map
for num in arr2:
num_cnt = freq_map.pop(num, 0)
res.extend([num] * num_cnt)
# Add remaining elements in ascending order
for key in sorted(freq_map):
cnt = freq_map[key]
res.extend([key] * cnt)
return res
Complexity Analysis
Here, n is size of the first array arr1 (array to be sorted).
m is size of the second array arr2 (defines relative order), m <= n.
k is the number of distinct remaining elements in arr1 which are not in arr2, so (k <= n - m).
- Time Complexity:
O(n + k log k)- Construction of Frequency Map:
O(n) - Traversing
arr2and adding elements to the result:O(m + sum of counts)i.e. at mostO(m + n) - Sorting and adding remaining elements:
O(k log k + sum of remaining counts)i.e. at mostO(k log k + n) - So, overall Time Complexity is
O(n + m + k log k)=O(n + k log k) asm <= n.
- Construction of Frequency Map:
- Space Complexity:
O(n + k)=O(n)- Frequency Map Space:
O(n)in worst case. - Output Space:
O(n), as we are returning a new array withnelements. - Auxiliary Space for sorting remaining elements:
O(1)if done in-place, orO(k)if the sorting algorithm uses additional space.
- Frequency Map Space:
class Solution:
def relativeSortArray(self, arr1: List[int], arr2: List[int]) -> List[int]:
max_num = max(arr1)
count = [0] * (max_num + 1)
for num in arr1:
count[num] += 1
res = []
for num in arr2:
res.extend([num] * count[num])
count[num] = 0
for num in range(max_num + 1):
res.extend([num] * count[num])
return res
Complexity Analysis
Here, n is the size of the first array arr1 (array to be sorted).
m is size of the second array arr2 (defines relative order), m <= n.
max_num is the maximum element in arr1.
-
Time Complexity:
O(n + max_num)- Counting occurrences in
arr1:O(n) - Traversing
arr2and adding elements to the result:O(m + n) - Traversing count array and adding remaining elements:
O(max_num + n) - Overall:
O(m + n + max_num)=O(n + max_num)=O(n), sincemax_num ≤ 1000
- Counting occurrences in
-
Space Complexity:
O(n + max_num)- Count array:
O(max_num + 1) - Output array:
O(n) - Overall:
O(n + max_num)=O(n), sincemax_num ≤ 1000
- Count array: