LeetCode347:前 K 个高频元素

题目:给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。

示例 1:

输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
示例 2:

输入: nums = [1], k = 1
输出: [1]
 

提示:

1 <= nums.length <= 10^5
k 的取值范围是 [1, 数组中不相同的元素的个数]
题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的

思路一:使用哈希表HashMap,将nums数组中的元素遍历一遍,key值就是元素数值,value值就是每个元素的个数,因为无法直接将hashmap排序,需要再通过二阶vector的pair用法,将hashmap以value值的大小进行排序。找到前K个数值,将其key值输出。

思路二:在C++中,map是属于STL中的,但如果没有学过map该怎样解答呢?                                先定义多个vector容器,用两个容器来表示map。一个v1来存放元素数值,另一个v2存放每个元素的个数。再将v2进行排序,找到v1前K的数值,将其存放在path中,最后直接返回。

思路二比较繁琐,本道题就用思路二解决

前期准备工作

        sort(nums.begin(), nums.end());
        vector<int> vet;
        vet.assign(nums.begin(), nums.end());
        vet.erase(unique(vet.begin(), vet.end()), vet.end());
        vector<int> v1;
        vector<int> v2;
        vector<int> v3;
        v1.resize(vet.size());
        v2.resize(vet.size());
        vector<int> path;
        int pos = 0;

通过vet的排序后删除重复元素,统计共多少不重复的元素

resize()是将各个数组进行扩大容量,因为是直接通过数组形式v1[ ]输出的,以防容量不够,如果是通过push_back()添加元素,就不需要resize()了。

path数组是存放前K个元素的数组,是返回的vector。

下面就该统计每个元素的数量了,用排序后的nums进行for()遍历

        v1[pos] = 1;
        v2[pos] = nums[0];
        for (int i = 1; i < nums.size(); i++)
        {
            if (nums[i] == nums[i - 1])
            {
                v1[pos] = v1[pos] + 1;
            }
            else
            {
                pos = pos + 1;
                v1[pos] = 1;
            }
            v2[pos] = nums[i];
        }

因为v1中存放各个元素的个数,正好与v2的元素值对应,想要找到前K个元素,只能通过再添加一个容器来复制v1,找到目标值。

        v3.assign(v1.begin(), v1.end());
        sort(v3.begin(), v3.end());
        int target = v3[v3.size() - k];

找到目标值后,再对v1数组进行遍历,如果满足条件,将v2中与v1对应的下标值存放在数组path中

完整代码:

class Solution
{
public:
    vector<int> topKFrequent(vector<int> &nums, int k)
    {
        sort(nums.begin(), nums.end());
        vector<int> vet;
        vet.assign(nums.begin(), nums.end());
        vet.erase(unique(vet.begin(), vet.end()), vet.end());
        vector<int> v1;
        vector<int> v2;
        vector<int> v3;
        v1.resize(vet.size());
        v2.resize(vet.size());
        vector<int> path;
        int pos = 0;
        v1[pos] = 1;
        v2[pos] = nums[0];
        for (int i = 1; i < nums.size(); i++)
        {
            if (nums[i] == nums[i - 1])
            {
                v1[pos] = v1[pos] + 1;
            }
            else
            {
                pos = pos + 1;
                v1[pos] = 1;
            }
            v2[pos] = nums[i];
        }
        v3.assign(v1.begin(), v1.end());
        sort(v3.begin(), v3.end());
        int target = v3[v3.size() - k];
        for (int i = 0; i <= pos; i++)
        {
            if (v1[i] >= target)
            {
                path.push_back(v2[i]);
            }
        }
        return path;
    }
};

本道题的思路就是这样了!

欢迎各位读者的纠正!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

北方以南ccc

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

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

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

打赏作者

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

抵扣说明:

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

余额充值