classSolution: defrelativeSortArray(self, arr1: List[int], arr2: List[int]) -> List[int]: defmycmp(x: int) -> (int, int): return (0, rank[x]) if x in rank else (1, x) rank = {x: i for i, x inenumerate(arr2)} arr1.sort(key=mycmp) return arr1
此外,由于题目中给定的元素都是正数,因此我们可以用 rank}[x]-n 和 x 分别代替 (0, \textit{rank}[x]) 和 (1, x),其中 n 是数组 arr}_2 的长度(同时也是哈希表 rank 的大小)。这样做的正确性在于,rank}[x]-n 一定是负数,而 x 一定是正数。
[sol3-C++]
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classSolution { public: vector<int> relativeSortArray(vector<int>& arr1, vector<int>& arr2){ unordered_map<int, int> rank; int n = arr2.size(); for (int i = 0; i < n; ++i) { rank[arr2[i]] = i - n; } sort(arr1.begin(), arr1.end(), [&](int x, int y) { return (rank.count(x) ? rank[x] : x) < (rank.count(y) ? rank[y] : y); }); return arr1; } };
[sol3-Python3]
1 2 3 4 5 6 7 8 9
classSolution: defrelativeSortArray(self, arr1: List[int], arr2: List[int]) -> List[int]: defmycmp(x: int) -> (int, int): return rank[x] if x in rank else x n = len(arr2) rank = {x: i - n for i, x inenumerate(arr2)} arr1.sort(key=mycmp) return arr1
[sol3-Golang]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
funcrelativeSortArray(arr1 []int, arr2 []int) []int { rank := map[int]int{} for i, v := range arr2 { rank[v] = i - len(arr2) } sort.Slice(arr1, func(i, j int)bool { x, y := arr1[i], arr1[j] if r, has := rank[x]; has { x = r } if r, has := rank[y]; has { y = r } return x < y }) return arr1 }
classSolution { publicint[] relativeSortArray(int[] arr1, int[] arr2) { intupper=0; for (int x : arr1) { upper = Math.max(upper, x); } int[] frequency = newint[upper + 1]; for (int x : arr1) { ++frequency[x]; } int[] ans = newint[arr1.length]; intindex=0; for (int x : arr2) { for (inti=0; i < frequency[x]; ++i) { ans[index++] = x; } frequency[x] = 0; } for (intx=0; x <= upper; ++x) { for (inti=0; i < frequency[x]; ++i) { ans[index++] = x; } } return ans; } }
[sol4-Python3]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
classSolution: defrelativeSortArray(self, arr1: List[int], arr2: List[int]) -> List[int]: upper = max(arr1) frequency = [0] * (upper + 1) for x in arr1: frequency[x] += 1 ans = list() for x in arr2: ans.extend([x] * frequency[x]) frequency[x] = 0 for x inrange(upper + 1): if frequency[x] > 0: ans.extend([x] * frequency[x]) return ans
funcrelativeSortArray(arr1 []int, arr2 []int) []int { upper := 0 for _, v := range arr1 { if v > upper { upper = v } } frequency := make([]int, upper+1) for _, v := range arr1 { frequency[v]++ }
ans := make([]int, 0, len(arr1)) for _, v := range arr2 { for ; frequency[v] > 0; frequency[v]-- { ans = append(ans, v) } } for v, freq := range frequency { for ; freq > 0; freq-- { ans = append(ans, v) } } return ans }
int* relativeSortArray(int* arr1, int arr1Size, int* arr2, int arr2Size, int* returnSize) { int upper = 0; for (int i = 0; i < arr1Size; i++) { upper = fmax(upper, arr1[i]); } int frequency[upper + 1]; memset(frequency, 0, sizeof(frequency)); for (int i = 0; i < arr1Size; i++) { frequency[arr1[i]]++; } int* ans = malloc(sizeof(int) * arr1Size); *returnSize = 0; for (int i = 0; i < arr2Size; i++) { int x = arr2[i]; for (int j = 0; j < frequency[x]; j++) { ans[(*returnSize)++] = x; } frequency[x] = 0; } for (int x = 0; x <= upper; x++) { for (int i = 0; i < frequency[x]; i++) { ans[(*returnSize)++] = x; } } return ans; }
复杂度分析
时间复杂度:O(m + n + \textit{upper}),其中 m 和 n 分别是数组 arr}_1 和 arr}_2 的长度,upper 是数组 arr}_1 中的最大值,在本题中 upper 不会超过 1000。遍历数组 arr}_2 的时间复杂度为 O(n),遍历数组 frequency 的时间复杂度为 O(\textit{upper}),而在遍历的过程中,我们一共需要 O(m) 的时间得到答案数组。
空间复杂度:O(\textit{upper}),即为数组 frequency 需要使用的空间。注意到与方法一不同的是,方法二的代码使用了额外的空间(而不是直接覆盖数组 arr}_1)存放答案,但我们一般不将存储返回答案的数组计入空间复杂度,并且在我们得到数组 frequency 之后,实际上也是可以将返回答案覆盖在数组 arr}_1 上的。如果在面试中遇到了本题,这些细节都可以和面试官进行确认。