从何时你也忌讳空山无人,从何时开始|

Drunker•L

园龄:4个月粉丝:0关注:0

1122. 数组的相对排序

数组的相对排序
给你两个数组,arr1arr2arr2 中的元素各不相同,arr2 中的每个元素都出现在 arr1 中。

arr1 中的元素进行排序,使 arr1 中项的相对顺序和 arr2 中的相对顺序相同。未在 arr2 中出现过的元素需要按照升序放在 arr1 的末尾。

示例 1:

输入: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]

示例 2:

输入:arr1 = [28,6,22,8,44,17], arr2 = [22,28,8,6]
输出:[22,28,8,6,17,44]

思路

  1. arr1 中的元素进行排序,使其满足两个要求:
    • 首先按 arr2 中的顺序排列arr2 中的每个元素都出现在 arr1 中,我们需要确保 arr1 中的元素按照 arr2 的相对顺序排列。
    • 然后将不在 arr2 中的元素按照升序排列arr1 中除了 arr2 中的元素,其他元素需要按升序放到 arr1 的末尾。

详细步骤

  1. 统计 arr1 中每个元素出现的次数
    • 我们需要知道 arr1 中每个元素的出现次数,这样可以方便地根据 arr2 中的顺序来填充 arr1
  2. 根据 arr2 中的顺序填充 arr1
    • 遍历 arr2,把 arr2 中的元素按照它们在 arr2 中的顺序依次放入 arr1,并将它们从 arr1 中去除(通过调整它们的频率)。
  3. 处理 arr2 中未出现的元素
    • 将剩下的元素(即未在 arr2 中出现的元素)按升序排序,并追加到 arr1 的末尾。
class Solution {
    public int[] relativeSortArray(int[] arr1, int[] arr2) {
        int upper = 0;
        for(int x : arr1){
            upper = Math.max(upper, x);
        }
        int[] frequency = new int[upper + 1];
        for(int x : arr1){
            frequency[x]++;
        }
        int[] res = new int[arr1.length];
        int index = 0;
        for(int x : arr2){
            for(int i = 0; i < frequency[x]; i++){
                res[index++] = x;
            }
            frequency[x] = 0;
        }
        for(int x = 0; x <= upper; x++){
            for(int i = 0; i < frequency[x]; i++){
                res[index++] = x;
            }
        }
        return res;
    }
}

节省一点内存的写法:

class Solution {
    public int[] relativeSortArray(int[] arr1, int[] arr2) {
        // 1. 找到 arr1 的最小值和最大值
        int min = Integer.MAX_VALUE;
        int max = Integer.MIN_VALUE;
        for (int num : arr1) {
            min = Math.min(min, num);
            max = Math.max(max, num);
        }
        
        // 2. 创建一个频率数组,大小为 max - min + 1
        int[] frequency = new int[max - min + 1];
        
        // 3. 统计 arr1 中每个元素的出现次数
        for (int num : arr1) {
            frequency[num - min]++;  // 使用 num - min 作为索引
        }
        
        // 4. 创建一个结果数组 ans
        int[] ans = new int[arr1.length];
        int index = 0;
        
        // 5. 按照 arr2 中的顺序填充 ans 数组
        for (int num : arr2) {
            for (int i = 0; i < frequency[num - min]; i++) {
                ans[index++] = num;
            }
            frequency[num - min] = 0;  // 已处理过的元素,频率归零
        }
        
        // 6. 将剩余的元素(不在 arr2 中的元素)按升序填充到 ans 数组
        for (int i = 0; i <= max - min; i++) {
            while (frequency[i] > 0) {
                ans[index++] = i + min;  // 转换回原始值
                frequency[i]--;
            }
        }
        
        // 7. 返回排序后的结果
        return ans;
    }
}

本文作者:Drunker•L

本文链接:https://www.cnblogs.com/drunkerl/p/18628634

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Drunker•L  阅读(17)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起