LeetCode 347 Top K Frequent Elements, 22 Generate Parentheses

本文深入解析LeetCode上的两道经典题目:Top K 高频元素和生成括号。通过详细阐述解题思路和提供C++代码实现,帮助读者理解如何运用哈希表、优先队列及递归等数据结构与算法解决实际问题。

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

LeetCode 347 Top K Frequent Elements AND 22 Generate Parentheses

347 Top K Frequent Elements

题意

给一个非空整数数组,求出现次数最多的K个不同的数,题目保证k有效。要求时间复杂度优于O(nlogn)。

思路

本以为会有O(n)的方法,但思考不出来,看了讨论版之后发现点赞最多的使用的是unordered_map + 优先队列。unordered_map 实际上是采用哈希方法实现的map,区别于使用红黑树实现的map,复杂度基本上为O(n)左右,而后在使用优先队列时候有一个小技巧:假设有n个不同的数,需要拿出K个值最大的,如果我们每次随机拿一个出来,那当我们拿出来n-k+1个数时,这n-k+1个数中最大的那个一定是要拿出的K个数中的一个。因此整体的复杂度为优先队列的O(n log(n - k)),因为优先队列(也就是大顶堆)最多包含n-k个元素。

代码

class Solution {
  public:
    vector<int> topKFrequent(vector<int> &nums, int k) {
        unordered_map<int, int> m;
        for (auto &&tmp : nums) {
            m[tmp]++;
        }
        vector<int> res;
        priority_queue<pair<int, int>> q;
        for (auto it = m.begin(); it != m.end(); it++) {
            q.push(make_pair(it->second, it->first));
            if (q.size() > m.size() - k) {
                res.push_back(q.top().second);
                q.pop();
            }
        }
        return res;
    }
};

22 Generate Parentheses

题意

给一个数n,表示n对小括号,写一个函数生成这n对括号的所有合法组合。

思路

如果回溯递归写的多的话这个难度其实不大,记录一下左括号和右括号分别有多少个,大概过程无非就是:

递归:
	左右括号都用完了?
		得到一个结果
		返回
	左括号还有?
		加一个左括号
		更新可用左括号,继续递归
	当前的字符串里右括号比左括号少?
		加一个右括号
		更新可用右括号,继续递归

然后递归即可。需要注意的是括号的组合中,右括号是不能比左括号多的,也就是 已用的右括号 <= 已用的左括号

代码

class Solution {
  public:
    vector<string> generateParenthesis(int n) {
        vector<string> res;
        string s;
        dfs(0, 0, n, "", res);
        return res; 
    }
    void dfs(int lbn, int rbn, int n, string s, vector<string> &res) {
        if (lbn == n && lbn == rbn)
            res.push_back(s);
        if (lbn < n)
            dfs(lbn + 1, rbn, n, s + "(", res);
        if (rbn < lbn)
            dfs(lbn, rbn + 1, n, s + ")", res);
    }
};

总结

两个题目难度不是很大,关键看对递归,回溯以及map和优先队列这些数据结构的熟练程度了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值