算法小知识-----7.28-----数组序号转换

124 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情

遇到难题了,工作上的,会议越拉越多,整理文档越来越多,开发的时间越发稀少。偶尔做道题才能重拾开发乐趣

数组序号转换

该题出自力扣的1331题 —— 数组序号转换【简单题】,虽然是简单题,但是确实没看懂一开始;序号和下标,傻傻分不清楚

审题

image.png

  • 既然能作为简单题,那么肯定证明了题意简单或者是可以暴力突围的
  • 给出一个整数数组,将数组内的每个元素替换成排序后的下标
    • 下标从1开始
    • 如果元素相等,下标对应的序号一致
  • 解法许多,但是围绕题意的话,可以总结出几个无法避免的步骤
    • 复制数组
    • 排序复制后的数组
    • 对数组进行查重
    • 遍历原数组,替换原数组的值为复制数组的下标
  • 复制数组这个就很好说了,但是可以加插一个小彩蛋
    • System.arraycopy和Arrays.copyOf之间的区别
      • 首先Arrays.copyOf方法的底层是调用了System.arraycopy方法的
      • System.arraycopy的本事是native方法,直接调用相对高效
      • 但是System.arraycopy面向的传参是Object,Arrays.copyOf的传参是class,所以在操作目标数组和拷贝数组的时候,可能会有校验开销(System.arraycopy)
  • 排序数组这个就不用多说了,直接上Arrays.sort
  • 对数组查重的话,这边是使用了HashMap,进行遍历插入,利用业务代码去查重,也可以使用其他的数据结构
  • 最后替换的话,如果使用了HashMap的手段,可以直接使用containKey方法,进行下标的对换
  • 最后一步也有许多方法,例如说冒泡、二分,本质就是两个数组间的遍历

编码

class Solution {
    public int[] arrayRankTransform(int[] arr) {
        HashMap<Integer,Integer> map = new HashMap<>();
        int len = arr.length;
        int[] copy = Arrays.copyOf(arr,len);
        Arrays.sort(copy);
        for (int i = 0; i < len; i++) {
            if (!map.containsKey(copy[i])){
                map.put(copy[i],map.size() + 1);
            }
        }
        for (int i = 0; i < len; i++) {
            arr[i] = map.get(arr[i]);
        }
        return arr;
    }

}

image.png