代码随想录算法训练营第十三天|239. 滑动窗口最大值,347.前 K 个高频元素,总结

239. 滑动窗口最大值

239. 滑动窗口最大值 

自己构建一个队列应实现pop、push、和max功能;弹入弹出元素很好实现,问题是如何获取滑动窗口的最大值。如果暴力循环的话时间复杂度将是o(n*k)。

因为我们的目的是获取到滑动窗口的最大值,而不是保存当前的窗口,所以我们没必要维护当前窗口的所有值,只需要保证最大值在窗口的出口处,这样我们直接调用函数deque.front()就可以获取了。那么就有思路了,只需要在放入元素的时候,把队列内小于该元素的值全部移除就可以了。在移除元素时判断一下队列出口处的元素是否与我们要移除的元素相同,如果不同那说明我们在执行push时已经把该元素移除了,就不用移除了;如果相同则移除该元素。

  代码随想录

class Solution {
private:
class Myque {
public:
    deque<int> que;
    void pop(int val) {
        if (!que.empty() && que.front() == val) que.pop_front();    //如果队头元素(最大值)等于要移除的元素就移除
    }
    void push(int val) {                
        while (!que.empty() && que.back() < val) {      //把队内所有比新入队小的元素弹出,保证单调性
            que.pop_back();
        }
        que.push_back(val);                 //然后在入队新元素
    }
    int _front() {
        return que.front();         //返回队头元素(即是当前滑动窗口最大值)
    }

};
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
    Myque que;
    vector<int> res;            
    for (int i = 0; i < k; ++i) {       //把前三个元素入队
        que.push(nums[i]);
    }
    res.push_back(que._front());       //记录当前窗口最大值
    for (int i = k; i < nums.size(); ++i) { 
        
        que.push(nums[i]);          //移除窗口开头元素
        que.pop(nums[i - k]);       //加入下一个元素
        res.push_back(que._front());        //记录当前窗口最大值
    }
    return res;
    }
};

347.前 K 个高频元素

347. 前 K 个高频元素 

先把元素都存放在map里得到每个元素的频率,再创建一个小顶堆,里面只放k个元素,最后大顶堆里的k个元素就是 前k个高频元素。

代码随想录

 

class Solution {
public:
class myComprisom {         //重新定义排序,从小到大
public:
	bool operator()(const pair<int, int>& lhs, const pair<int, int>& rhs) {
		return lhs.second > rhs.second;
	}
};
vector<int> topKFrequent(vector<int>& nums, int k) {
	unordered_map<int, int> map;        //把数据存到map里,重复出现的value+1;
	for (int i = 0; i < nums.size(); i++)
	{
		map[nums[i]]++;
	}
	priority_queue<pair<int, int>, vector<pair<int, int>>, myComprisom> pri_que;    //定义大小为k优先队列,只存放value前三大的数
	for (unordered_map<int,int>::iterator it=map.begin(); it != map.end(); it++)
	{
		pri_que.push(*it);
		if (pri_que.size()>k)
		{
			pri_que.pop();
		}
	}
	vector<int> res(k);
	// for (int i = 0; i < k; i++)  因为结果不用顺序所以倒序输出也可以
    for (int i = k-1; i >=0; i--)       //把队列里的key存到res里
	{
		res[i] = pri_que.top().first;
		pri_que.pop();
	}
	return res;
}
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值