题目描述
给你两个数组,
arr1
和arr2
,
arr2
中的元素各不相同
arr2
中的每个元素都出现在arr1
中
对arr1
中的元素进行排序,使arr1
中项的相对顺序和arr2
中的相对顺序相同。未在arr2
中出现过的元素需要按照升序放在arr1
的末尾。提示:
arr1.length, arr2.length <= 1000
0 <= arr1[i], arr2[i] <= 1000
arr2
中的元素 arr2[i] 各不相同
arr2
中的每个元素arr2[i]
都出现在arr1
中
样例
输入:
arr1 = [2,3,1,3,2,4,6,7,9,2,19], arr2 = [2,1,4,3,9,6]
输出:
[2,2,2,1,4,3,3,9,6,7,19]
算法
(模拟 + 哈希表) $O(n)$
思路
- 统计出
arr1
中每个元素出现的次数 - 对
arr1
中和arr2
相同的元素进行相对顺序排序 - 对
arr2
中剩余的元素进行升序排序- 在第二步中将
arr1
和arr2
共同出现的元素在map
中删除 - 剩下的元素自然是有序的
- 在第二步中将
时间复杂度
arr1最多遍历2次,时间复杂度为线性 : $0(n)$
C++ 代码
blablablaclass Solution {
public:
vector<int> relativeSortArray(vector<int>& arr1, vector<int>& arr2) {
vector<int> res;
map<int, int> hash;
for(auto a : arr1) hash[a] ++;
// 首先按照arr2的顺序处理出现在arr2种的元素
for(auto a : arr2)
{
int n = hash[a];
hash.erase(a);
while(n--)
res.push_back(a);
}
// 之后在处理没有出现在arr2种的元素 升序 map已经有序
if(hash.size())
{
for(auto &h : hash)
{
int n = h.second;
while(n--)
res.push_back(h.first);
}
}
return res;
}
};
其他
- map的访问方式
- map的自定义排序