「这是我参与2022首次更文挑战的第2天,活动详情查看:2022首次更文挑战」
1122. 数组的相对排序
题目
给你两个数组,arr1 和 arr2,
- arr2 中的元素各不相同
- arr2 中的每个元素都出现在 arr1 中 对 arr1 中的元素进行排序,使 arr1 中项的相对顺序和 arr2 中的相对顺序相同。未在 arr2 中出现过的元素需要按照升序放在 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]
题解
计数排序
- 按照题目要求, arr1 中项的相对顺序和 arr2 中的相对顺序相同;可以理解为在arr2上新增arr1中的的元素; 比如:arr1 = [2,3,1,3,2,4,6,7,9,2,19], arr2 = [2,1,4,3,9,6]
- 第一步,将array数据统计到哈希表map中
- arr1 = > map ;得到map = { '1': 1, '2': 3, '3': 2, '4': 1, '6': 1, '7': 1, '9': 1, '19': 1 }
- 枚举arr2,从右到左;
- 第len-1位元素6,在map中存在且数量是1,将1个6放入arr1的len-1位置
- 第len-2位元素9,在map中存在且数量是1,将1个9放入arr1的len-2位置
- 第len-3位元素3,在map中存在且数量是2,将2个3放入arr1的len-3位置
- 第len-4位元素4,在map中存在且数量是1,将1个4放入arr1的len-4位置
- 第len-5位元素1,在map中存在且数量是1,将1个1放入arr1的len-5位置
- 第len-6位元素2,在map中存在且数量是3,将3个1放入arr1的len-6位置
- arr2枚举结束,将map中没有使用到的值排序并合并到arr2即可
代码
var relativeSortArray = function(arr1, arr2) {
if(arr2.length === 0) return arr1;
if(arr1.length === 0) return arr2;
let map = {};
arr1.forEach(v=>{
map[v] = ( map[v]||0)+1;
})
// 对arr2扩充
for(let i = arr2.length - 1 ; i >= 0 ; i--){
const k = arr2[i];
const v = map[k];
arr2.splice(i,1,...Array(v).fill(k))
map[k] = false
}
const list =[];
arr1.forEach(v=>{
if(map[v]) list.push(v);
})
list.sort((a,b)=>a-b);
return arr2.concat(list)
};
自定义排序
重新认识sort
在JavaScript中sort是可以对数组排序的方法,并且sort可以使用一个函数作为参数,处理sort的排序规则;
常规从小到大排序一般sort((a,b)=>a-b);
如果a-b>1 ,a,b会调换位置,否则a,b不回调换位置。
根据sort上述排序规则,将arr2中元素与元素下标放入对象map中;arr1使用sort排序;
在sort中判断,如果a在map情况,b在map中,使用a,b在arr2中下标作为排序;如果b不在map中,不需要调换位置
根据上述思路编辑代码
代码
var relativeSortArray = function(arr1, arr2) {
const map = {};
for(let i = 0 ; i < arr2.length ; i++){
map[arr2[i]] = i+1
}
arr1.sort((a,b)=>{
if(map[a]){
return map[b]? map[a] - map[b]:-1
}else{
return map[b]?1:a-b
}
})
return arr1
};
结语
从新认识了sort