
Problem Statement
Given two integer arrays, arr1
and arr2
, where arr2
consists of distinct elements, all of which are guaranteed to be in arr1
, the objective is to rearrange arr1
such that the ordering of elements follows the specific pattern established by arr2
. Elements from arr1
that do not appear in arr2
should then be subsequently appended to the end, sorted in ascending order. It involves a custom sorting mechanism based on the reference layout provided by arr2
.
Examples
Example 1
Input:
arr1 = [2,3,1,3,2,4,6,7,9,2,19], arr2 = [2,1,4,3,9,6]
Output:
[2,2,2,1,4,3,3,9,6,7,19]
Example 2
Input:
arr1 = [28,6,22,8,44,17], arr2 = [22,28,8,6]
Output:
[22,28,8,6,17,44]
Constraints
1 <= arr1.length, arr2.length <= 1000
0 <= arr1[i], arr2[i] <= 1000
- All the elements of
arr2
are distinct. - Each
arr2[i]
is inarr1
.
Approach and Intuition
The problem essentially combines custom ordering followed by standard sorting for elements not included in the custom reference. Here’s a step-by-step breakdown to tackle this problem:
Parse through
arr2
to create a relative order map. This map will hold each element ofarr2
as a key, and its index as the value. This is important as it sets the precedence of elements in the resulting array.Slice off any member of
arr1
that isn’t inarr2
. Here, you need these 'outside' elements to be managed later, specifically sorted and appended after the custom ordered elements.Order
arr1
with respect toarr2
using the map:- Each element that appears in
arr2
is placed in a new list according to the index given in the map. If the element occurs multiple times, it is repeated inline based on its occurrence inarr1
.
- Each element that appears in
Sort the isolated elements:
- The separated elements not found in
arr2
should be sorted, which is straightforward ascending order sorting.
- The separated elements not found in
Merge the two lists:
- The final list comprises the custom ordered elements followed by the sorted elements that didn’t fit the custom order.
Key Points
- Custom order is determined strictly by
arr2
's sequence. - Elements not present in
arr2
but inarr1
are sorted in ascending order naturally. - Time complexity involves sorting and ordered inserts but is efficiently managed due to constraints like the distinct nature of
arr2
and its presence inarr1
.
This approach makes sure that all special ordering and universal sorting requirements are satisfied efficiently while respecting the unique structure dictated by the elements of arr2
.
Solutions
- C++
- Java
- Python
class Solution {
public:
vector<int> sortRelativeToAnother(vector<int>& firstList, vector<int>& secondList) {
int largestVal = *max_element(firstList.begin(), firstList.end());
vector<int> frequency(largestVal + 1);
// Populate frequency array
for (int num : firstList) {
frequency[num]++;
}
vector<int> sortedArray;
// Place elements according to the order in secondList
for (int value : secondList) {
while (frequency[value] > 0) {
sortedArray.push_back(value);
frequency[value]--;
}
}
// Append the rest in sorted manner
for (int i = 0; i <= largestVal; i++) {
while (frequency[i] > 0) {
sortedArray.push_back(i);
frequency[i]--;
}
}
return sortedArray;
}
};
This C++ solution implements a method to sort an array (firstList
) in the order defined by another array (secondList
). The approach utilizes a counting sort mechanism, leveraging a frequency array to efficiently sort the elements according to the specified order. Here’s the process breakdown:
- Determine the largest value in
firstList
to define the size of the frequency array. - Populate the frequency array where the index represents numbers from
firstList
and the value at each index represents the count of occurrences of that number. - Construct the
sortedArray
based on the sequence provided insecondList
. Each number fromsecondList
is added tosortedArray
according to its frequency. - After placing all elements that appear in
secondList
, append the remaining elements fromfirstList
that were not insecondList
, in ascending order, using the frequency array to guide the placement.
This method proves efficient especially when secondList
represents a subset or a different order of the elements in firstList
, and it is particularly well-suited for when the range of potential values in firstList
is not excessively large compared to the size of the list.
class Solution {
public int[] sortArrayByOtherArray(int[] primaryArray, int[] referenceArray) {
int maximumValue = Arrays.stream(primaryArray).max().orElse(0);
int[] frequency = new int[maximumValue + 1];
// Calculate frequency of each element in primaryArray
for (int num : primaryArray) {
frequency[num]++;
}
List<Integer> sortedList = new ArrayList<>();
// Sort elements by referenceArray order
for (int elem : referenceArray) {
while (frequency[elem] > 0) {
sortedList.add(elem);
frequency[elem]--;
}
}
// Append remaining elements sorted in numeric order
for (int i = 0; i <= maximumValue; i++) {
while (frequency[i] > 0) {
sortedList.add(i);
frequency[i]--;
}
}
// Convert List to primitive int array
return sortedList.stream().mapToInt(i -> i).toArray();
}
}
This Java program effectively addresses the problem of sorting an array (primaryArray
) based on the order defined by another array (referenceArray
). The solution involves several clear steps:
- Determine the maximum value in
primaryArray
to set up a frequency array with appropriate size. - Populate the frequency array with the count of each element in
primaryArray
. - Initialize an empty list
sortedList
to hold the final sorted elements. - Iterate through
referenceArray
, and for each element, add it tosortedList
as many times as it appears inprimaryArray
by decrementing its count in the frequency array. - After processing all elements in
referenceArray
, any elements not included but present inprimaryArray
are appended tosortedList
. This is done by iterating through the frequency array and adding each element the number of times it appears. - Finally, convert
sortedList
from a list of Integer to a primitive int array.
This approach ensures that elements are sorted first by the order in referenceArray
, and then by their natural numerical order for any remaining elements not covered by referenceArray
. The use of a frequency array provides an efficient means of tracking and manipulating the count of elements during the sorting process.
class Solution:
def sortRelative(self, array1: List[int], array2: List[int]) -> List[int]:
highest_value = max(array1)
frequency = [0] * (highest_value + 1)
for num in array1:
frequency[num] += 1
ordered_result = []
for key in array2:
while frequency[key] > 0:
ordered_result.append(key)
frequency[key] -= 1
for i in range(highest_value + 1):
while frequency[i] > 0:
ordered_result.append(i)
frequency[i] -= 1
return ordered_result
To solve the "Relative Sort Array" problem in Python, follow these steps to create a custom ordered array based on a reference array:
- Calculate the maximum value in
array1
to determine the size of a frequency array. - Initialize a frequency list of zeroes with a length of the maximum value plus one. This serves to count occurrences of each integer in
array1
. - Iterate over
array1
, and for each number, increment its corresponding index in the frequency list to record the number of occurrences. - Create an empty list
ordered_result
to store the sorted numbers. - Iterate over
array2
(the reference array). For each element, append it toordered_result
as many times as it appears inarray1
while decrementing its count in the frequency list. - After processing all elements of
array2
, append any remaining numbers fromarray1
that are not inarray2
toordered_result
. These numbers are added in ascending order based on their index in the frequency list.
This strategy ensures that elements are sorted primarily by their order in array2
, and secondarily, by their usual ascending order if not found in array2
. This solution effectively handles cases where elements are repeated and maintains overall order coherency based on the provided reference array.
No comments yet.