栈和队列
题意:给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。返回 滑动窗口中的最大值 。
示例:
思路:我们的思路是,使用一个特殊队列,该队列可以实现,添加元素,删除元素和返回队列中最大元素的功能,由于STL中并没有完全符合我们条件的队列,因此,我们需要自己定义一个队列类:
- push(val):在加入队列前,需要判断val前,是否有小于它的元素,如果有则需要移除,我们的队列并不需要维护不需要的元素
- pop(val):该删除元素,主要是为了删除特定的元素,即不在滑动窗口范围内的最大元素。有些元素会非常大,导致无法自动移除,此时就需要该元素手动移除那些不在滑动窗口范围内的元素
- front:该元素可以直接返回队列的首元素,首元素一直存储着滑动窗口中的最大元素
C++代码:
class MyQueue
{
public:
MyQueue()
{}
void push(int val)
{
while(!arr.empty()&&val>arr.back())//循环判断加入的val是否大于队列末尾元素,大于则删除
{
arr.pop_back();
}
arr.push_back(val);
}
void pop(int val)//这里的删除是特指删除不在滑动窗口范围的元素
{
if(!arr.empty()&&val==arr.front())
{
arr.pop_front();
}
}
int front()//队列最前面的一定是滑动窗口中最大值的元素
{
return arr.front();
}
private:
deque<int> arr;
};
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
MyQueue q;
for(int i=0;i<k;i++)//先放入k个元素进行比较
{
q.push(nums[i]);
}
vector<int> arr;
arr.push_back(q.front());//保存前k个元素的最大值
for(int i=k;i<nums.size();i++)
{
q.pop(nums[i-k]);//这里需要先删除不在滑动窗口范围的元素
q.push(nums[i]);//加入新元素
arr.push_back(q.front());
}
return arr;
}
题意:给你一个整数数组nums和一个整数k,请你返回其中出现频率前k高的元素。你可以按任意顺序返回答案
示例:
思路:本题的思路比较简单,先创建一个unordered_map用于存储数组中的元素及其对应出现次数,然后再将这些数据以键值对的方式传给vector,然后在使用自定义sort对map中的value进行排序,此时vector的前k个key就是我们需要的元素了
C++代码:
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int, int> map;
for (auto e : nums)
{
map[e]++;
}
vector<pair<int, int>> arr(map.begin(), map.end());//需要将map转换为vector才能进行自定义排序
vector<int> tmp;
sort(arr.begin(), arr.end(),[](const pair<int,int>& a,const pair<int,int>& b)->bool{return a.second>b.second;});//lambda表达式进行排序
for (int i = 0; i<k; i++)//保存前k个元素
{
tmp.push_back(arr[i].first);
}
return tmp;
}