数组的相对排序

316 阅读2分钟

这是我参与8月更文挑战的第31天,活动详情查看:8月更文挑战

题目描述

给你两个数组,arr1 和 arr2,

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

图片.png

解题思路详解

  • 解题需要在本体范围内。题目中也已经提示了两个数组的长度在1000之内。所以我们可以用一个1001的数组来进行分解两个数组。

利用桶式排序的思路,使用一个数组count[]大小为1001,表示1001个桶,每个桶存储的数为和下标相等的数的个数。遍历arr2,将在arr2中的桶中的数输出在arr1中,然后在遍历所有桶,将不在arr2中的桶中的数继续往后输出在arr1中。 时间复杂度:O(M+N+R)。M为arr1的长度,N为arr2的长度,R为桶的个数。相当于O(N),线性级别。 空间复杂度:O(R)。R为桶的个数,若R为常数,则相当于O(1)。

AC Code


class Solution {
    public int[] relativeSortArray(int[] arr1, int[] arr2) {
        int[] count=new int[1001];
        for(int i : arr1)
            count[i]++;
        int i=0;
        for(int j : arr2) 
        {
            while(count[j]>0)
            {
                arr1[i++]=j;
                count[j]--;
            }
        }
        for(int j=0;j<=1000;j++)
        {
            while(count[j]>0)
            {
                arr1[i++]=j;
                count[j]--;
            }
        }
        return arr1;
    }
}


总结

  • 本文需要注意发生的场景。在特定的场景下解决就会是一巧妙的解法。因为需要按照arr2的顺序进行填充arr1,不重合的数据需要按照默认升序的方法。
  • 如果离开了本体的场景我们有应该怎么做呢?这里我的想法是通过链表+计数器的方式去实现。将arr1中的数据按照arr2的参考生成一个链表。最终将链表在转换成新的数组作为arr1输出。这种方法和上面的解法两个是时间和空间的问题。
  • 上面的解法是需要提前开辟内存。而通过链表的方式就解决了提前开辟空间的问题了。这里链表就是有多少开辟多少内存。在内存效率上应该会好一点。

关注我。不迷路