Leetcode1122. 数组的相对排序

文章介绍了两种方法解决LeetCode问题1122,一种是使用哈希表统计arr2中元素出现次数,另一种是利用计数排序对arr1进行优化处理。两种方法都涉及时间复杂度和空间复杂度分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Every day a Leetcode

题目来源:1122. 数组的相对排序

解法1:哈希

用集合 set 存储 arr2 中的元素。

遍历数组 arr1 ,设当前元素为 num:

  • 如果 num 在 set 中出现,用哈希表 hash 记录 num 和它出现的次数。
  • 否则,用将 num 插入数组 remain。

遍历数组 arr2,设当前元素为 num。向 ans 中插入 hash[num] 个 num。

将 remain 增序排序,将 remain 插入 ans 的后面。

代码:

/*
 * @lc app=leetcode.cn id=1122 lang=cpp
 *
 * [1122] 数组的相对排序
 */

// @lc code=start
class Solution
{
public:
    vector<int> relativeSortArray(vector<int> &arr1, vector<int> &arr2)
    {
        unordered_map<int, int> hash;
        set<int> set(arr2.begin(), arr2.end());
        vector<int> remain;
        for (const int &num : arr1)
        {
            if (set.count(num))
                hash[num]++;
            else
                remain.push_back(num);
        }
        vector<int> ans;
        for (const int &num : arr2)
        {
            if (hash.count(num))
                for (int i = 0; i < hash[num]; i++)
                    ans.push_back(num);
        }
        // 未在 arr2 中出现过的元素需要按照升序放在 arr1 的末尾
        sort(remain.begin(), remain.end());
        for (int i = 0; i < remain.size(); i++)
            ans.push_back(remain[i]);
        return ans;
    }
};
// @lc code=end

结果:

在这里插入图片描述

复杂度分析:

时间复杂度:O(mlogm+n),其中 m 和 n 分别是数组 arr1 和 arr2 的长度。构建哈希表的时间复杂度为 O(n),排序的时间复杂度为 O(mlogm)。

空间复杂度:O(logm+n),其中 m 和 n 分别是数组 arr1 和 arr2 的长度。哈希表的空间复杂度为 O(n),排序使用的栈的空间复杂度为 O(mlogm)。

解法2:计数排序

注意到本题中元素的范围为 [0, 1000],这个范围不是很大,我们也可以考虑不基于比较的排序,例如「计数排序」。

优化:实际上,我们不需要使用长度为 1001 的数组,而是可以找出数组 arr1 中的最大值 upper,使用长度为 upper+1 的数组即可。

代码:

/*
 * @lc app=leetcode.cn id=1122 lang=cpp
 *
 * [1122] 数组的相对排序
 */

// @lc code=start
// class Solution
// {
// public:
//     vector<int> relativeSortArray(vector<int> &arr1, vector<int> &arr2)
//     {
//         unordered_map<int, int> hash;
//         set<int> set(arr2.begin(), arr2.end());
//         vector<int> remain;
//         for (const int &num : arr1)
//         {
//             if (set.count(num))
//                 hash[num]++;
//             else
//                 remain.push_back(num);
//         }
//         vector<int> ans;
//         for (const int &num : arr2)
//         {
//             if (hash.count(num))
//                 for (int i = 0; i < hash[num]; i++)
//                     ans.push_back(num);
//         }
//         // 未在 arr2 中出现过的元素需要按照升序放在 arr1 的末尾
//         sort(remain.begin(), remain.end());
//         for (int i = 0; i < remain.size(); i++)
//             ans.push_back(remain[i]);
//         return ans;
//     }
// };

class Solution
{
public:
    vector<int> relativeSortArray(vector<int> &arr1, vector<int> &arr2)
    {
        int upper = *max_element(arr1.begin(), arr1.end());
        vector<int> freq(upper + 1, 0);
        for (const int &num : arr1)
            freq[num]++;
        vector<int> ans;
        for (const int &num : arr2)
        {
            for (int i = 0; i < freq[num]; i++)
                ans.push_back(num);
            freq[num] = 0;
        }
        for (int num = 0; num <= upper; num++)
            for (int i = 0; i < freq[num]; i++)
                ans.push_back(num);
        return ans;
    }
};
// @lc code=end

结果:

在这里插入图片描述

复杂度分析:

时间复杂度:O(m+n+upper),其中 m 和 n 分别是数组 arr1 和 arr2 的长度。upper 是数组 arr1 的最大值。

空间复杂度:O(upper),其中 upper 是数组 arr1 的最大值。即为数组 freq 需要使用的空间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UestcXiye

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值