难度
题目内容 给你两个数组,arr1 和 arr2,arr2 中的元素各不相同,arr2 中的每个元素都出现在 arr1 中。
对 arr1 中的元素进行排序,使 arr1 中项的相对顺序和 arr2 中的相对顺序相同。未在 arr2 中出现过的元素需要按照升序放在 arr1 的末尾。
题解
- 我们定义一个长度比arr2多1的数组resArr,它的前arr.length个位置用于储存arr1中等于arr2中的数字,存储的索引与arr2保持一致;resArr[arr2.length]用于存储arr1中不存在于arr2中的元素。
let len2 = arr2.length
// 这里如果直接传入引用类型数据会导致它们的地址全部相同,push,splice等操作会全部同时执行导致重复
// 因此需要通过map逐一往里添加地址不同的空数组
let resArr = new Array(len2+1).fill().map(()=>[])
- 然后就可以遍历arr1了:
// 为数组定义一个原型方法方便操作(升序插入数组)
Array.prototype.insert = function insert(num) {
if(this.length===0) this.push(num)
else {
for(let i=0;i<this.length;i++) {
if(num<=this[i]) {
this.splice(i, 0, num)
return;
}
}
this.push(num)
}
}
arr1.forEach(num => {
// 逐一查询arr1每个元素在arr2的索引,并把它放入对应位置
let index = arr2.indexOf(num);
// 如果它不在arr2中,那么升序放入resArr的最后一位所在数组
if(index===-1) resArr[len2].insert(num)
else {
resArr[index].push(num)
}
})
- 最后得到一个如下结构的数组:
resArr = [[arr2[0]*n], [arr2[1]*n], ..., sorted([arr2.length]*n, 'asc')]
- 于是reduce合并一下resArr并return出去
return resArr.reduce((a, b) => a.concat(b))
- 完整代码
Array.prototype.insert = function insert(num) {
if(this.length===0) this.push(num)
else {
for(let i=0;i<this.length;i++) {
if(num<=this[i]) {
this.splice(i, 0, num)
return;
}
}
this.push(num)
}
}
/**
* @param {number[]} arr1
* @param {number[]} arr2
* @return {number[]}
*/
var relativeSortArray = function(arr1, arr2) {
let len2 = arr2.length
let resArr = new Array(len2+1).fill().map(()=>[])
arr1.forEach(num => {
let index = arr2.indexOf(num);
if(index===-1) resArr[len2].insert(num)
else {
resArr[index].push(num)
}
})
return resArr.reduce((a, b) => a.concat(b))
};