[路飞]_数组的相对排序

192 阅读3分钟

「这是我参与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