comments | difficulty | edit_url | rating | source | tags | ||||
---|---|---|---|---|---|---|---|---|---|
true |
Easy |
1188 |
Weekly Contest 145 Q1 |
|
Given two arrays arr1
and arr2
, the elements of arr2
are distinct, and all elements in arr2
are also in arr1
.
Sort the elements of arr1
such that the relative ordering of items in arr1
are the same as in arr2
. Elements that do not appear in arr2
should be placed at the end of arr1
in ascending order.
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
.
First, we use a hash table
The time complexity is
class Solution:
def relativeSortArray(self, arr1: List[int], arr2: List[int]) -> List[int]:
pos = {x: i for i, x in enumerate(arr2)}
return sorted(arr1, key=lambda x: pos.get(x, 1000 + x))
class Solution {
public int[] relativeSortArray(int[] arr1, int[] arr2) {
Map<Integer, Integer> pos = new HashMap<>(arr2.length);
for (int i = 0; i < arr2.length; ++i) {
pos.put(arr2[i], i);
}
int[][] arr = new int[arr1.length][0];
for (int i = 0; i < arr.length; ++i) {
arr[i] = new int[] {arr1[i], pos.getOrDefault(arr1[i], arr2.length + arr1[i])};
}
Arrays.sort(arr, (a, b) -> a[1] - b[1]);
for (int i = 0; i < arr.length; ++i) {
arr1[i] = arr[i][0];
}
return arr1;
}
}
class Solution {
public:
vector<int> relativeSortArray(vector<int>& arr1, vector<int>& arr2) {
unordered_map<int, int> pos;
for (int i = 0; i < arr2.size(); ++i) {
pos[arr2[i]] = i;
}
vector<pair<int, int>> arr;
for (int i = 0; i < arr1.size(); ++i) {
int j = pos.count(arr1[i]) ? pos[arr1[i]] : arr2.size();
arr.emplace_back(j, arr1[i]);
}
sort(arr.begin(), arr.end());
for (int i = 0; i < arr1.size(); ++i) {
arr1[i] = arr[i].second;
}
return arr1;
}
};
func relativeSortArray(arr1 []int, arr2 []int) []int {
pos := map[int]int{}
for i, x := range arr2 {
pos[x] = i
}
arr := make([][2]int, len(arr1))
for i, x := range arr1 {
if p, ok := pos[x]; ok {
arr[i] = [2]int{p, x}
} else {
arr[i] = [2]int{len(arr2), x}
}
}
sort.Slice(arr, func(i, j int) bool {
return arr[i][0] < arr[j][0] || arr[i][0] == arr[j][0] && arr[i][1] < arr[j][1]
})
for i, x := range arr {
arr1[i] = x[1]
}
return arr1
}
function relativeSortArray(arr1: number[], arr2: number[]): number[] {
const pos: Map<number, number> = new Map();
for (let i = 0; i < arr2.length; ++i) {
pos.set(arr2[i], i);
}
const arr: number[][] = [];
for (const x of arr1) {
const j = pos.get(x) ?? arr2.length;
arr.push([j, x]);
}
arr.sort((a, b) => a[0] - b[0] || a[1] - b[1]);
return arr.map(a => a[1]);
}
We can use the idea of counting sort. First, count the occurrence of each element in array
The time complexity is
class Solution:
def relativeSortArray(self, arr1: List[int], arr2: List[int]) -> List[int]:
cnt = Counter(arr1)
ans = []
for x in arr2:
ans.extend([x] * cnt[x])
cnt.pop(x)
mi, mx = min(arr1), max(arr1)
for x in range(mi, mx + 1):
ans.extend([x] * cnt[x])
return ans
class Solution {
public int[] relativeSortArray(int[] arr1, int[] arr2) {
int[] cnt = new int[1001];
int mi = 1001, mx = 0;
for (int x : arr1) {
++cnt[x];
mi = Math.min(mi, x);
mx = Math.max(mx, x);
}
int m = arr1.length;
int[] ans = new int[m];
int i = 0;
for (int x : arr2) {
while (cnt[x] > 0) {
--cnt[x];
ans[i++] = x;
}
}
for (int x = mi; x <= mx; ++x) {
while (cnt[x] > 0) {
--cnt[x];
ans[i++] = x;
}
}
return ans;
}
}
class Solution {
public:
vector<int> relativeSortArray(vector<int>& arr1, vector<int>& arr2) {
vector<int> cnt(1001);
for (int x : arr1) {
++cnt[x];
}
auto [mi, mx] = minmax_element(arr1.begin(), arr1.end());
vector<int> ans;
for (int x : arr2) {
while (cnt[x]) {
ans.push_back(x);
--cnt[x];
}
}
for (int x = *mi; x <= *mx; ++x) {
while (cnt[x]) {
ans.push_back(x);
--cnt[x];
}
}
return ans;
}
};
func relativeSortArray(arr1 []int, arr2 []int) []int {
cnt := make([]int, 1001)
mi, mx := 1001, 0
for _, x := range arr1 {
cnt[x]++
mi = min(mi, x)
mx = max(mx, x)
}
ans := make([]int, 0, len(arr1))
for _, x := range arr2 {
for cnt[x] > 0 {
ans = append(ans, x)
cnt[x]--
}
}
for x := mi; x <= mx; x++ {
for cnt[x] > 0 {
ans = append(ans, x)
cnt[x]--
}
}
return ans
}
function relativeSortArray(arr1: number[], arr2: number[]): number[] {
const cnt = Array(1001).fill(0);
let mi = Number.POSITIVE_INFINITY;
let mx = Number.NEGATIVE_INFINITY;
for (const x of arr1) {
cnt[x]++;
mi = Math.min(mi, x);
mx = Math.max(mx, x);
}
const ans: number[] = [];
for (const x of arr2) {
while (cnt[x]) {
cnt[x]--;
ans.push(x);
}
}
for (let i = mi; i <= mx; i++) {
while (cnt[i]) {
cnt[i]--;
ans.push(i);
}
}
return ans;
}