239. 滑动窗口最大值
给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回滑动窗口中的最大值。
进阶:
你能在线性时间复杂度内解决此题吗?
滑动窗口不难,难的是找最大值,这里我们使用双向队列实现滑动窗口,并使用它来完成最大值的寻找,思路如下:
我们让出口始终有一个滑动窗口内的最大值,当新加进来的数比前一个数大时,就弹出前一个数,代码如下,注意pop的条件是!dq.empty()&&dq.front()==val,这个很重要,有了这个条件,我们就可以及时将多余的值弹出滑动窗口。
class Solution {
public:
deque<int> dq;
void pop(int val){
if(!dq.empty()&&dq.front()==val)
dq.pop_front();
}
void push(int val)
{
while(!dq.empty()&&val>dq.back())
dq.pop_back();
dq.push_back(val);
}
int Getmaxvalue()
{
return dq.front();
}
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
vector<int> res;
for(int i=0;i<k;i++)
{ push(nums[i]);
}
res.push_back(Getmaxvalue());
for(int i=0,j=k;j<nums.size();i++,j++)
{
pop(nums[i]);
push(nums[j]);
res.push_back(Getmaxvalue());
}
return res;
}
};
暴力解法在这里,时间复杂度O(n*k),会超时:
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
queue<int> qu1;
vector<int> res;
int a=INT32_MIN;
for(int i=0;i<k;i++) //先推k个进队列
{
qu1.push(nums[i]);
a=max(a,nums[i]);
}
res.push_back(a);
for(int i=1,j=k;j<nums.size();i++,j++)
{
qu1.pop();
qu1.push(nums[j]);
a=INT32_MIN;
while(!qu1.empty())
{
a=max(a,qu1.front());
qu1.pop();
}
res.push_back(a);
for(int l=i;l<=j;l++)
{
qu1.push(nums[l]);
}
}
return res;
}
};
347.前 K 个高频元素
给定一个非空的整数数组,返回其中出现频率前 k 高的元素。
示例 1:
- 输入: nums = [1,1,1,2,2,3], k = 2
- 输出: [1,2]
示例 2:
- 输入: nums = [1], k = 1
- 输出: [1]
提示:
- 你可以假设给定的 k 总是合理的,且 1 ≤ k ≤ 数组中不相同的元素的个数。
- 你的算法的时间复杂度必须优于 O(n \log n) , n 是数组的大小。
- 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的。
- 你可以按任意顺序返回答案。
这个说实话,主要是这种键值对的排序太麻烦了,我的思路是用unodered_map+unordered_set,最后遍历n次,将不重复的放到set里面,条件是
if(sign<itt->second&&st.find(itt->first)==st.end())
这里每次都会放入一个最大的值,之前放入的最大的值就不算了。
代码如下,时间复杂度比较高:
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
sort(nums.begin(),nums.end());
unordered_map<int,int> mymap;
unordered_set<int> st;
//vector<int> res;
int sign=INT32_MIN;
int a=INT32_MIN;
int b=0;
for(int i=0;i<nums.size();i++)
{
if(mymap.find(nums[i])==mymap.end())
mymap.insert({nums[i],1});
else
{
auto it=mymap.find(nums[i]);
it->second++;
}
}
for(int j=0;j<k;j++)
{
if(j==0)
{for(auto itt=mymap.begin();itt!=mymap.end();itt++)
{
if(sign<itt->second)
{b=itt->first;
sign=itt->second;}
}
a=sign;
st.insert(b);
}
else
{ sign=INT32_MIN;
for(auto itt=mymap.begin();itt!=mymap.end();itt++)
{
if(sign<itt->second&&st.find(itt->first)==st.end())
{
b=itt->first;
sign=itt->second;
}
}
st.insert(b);
}
}
return vector<int>(st.begin(),st.end());
}
};
这里可以用priority_queue来做,取前k个最大的值就行
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int,int> mymap;
priority_queue<pair<int,int>> result;
for(int i=0;i<nums.size();i++)
{
mymap[nums[i]]++;
}
for(auto it=mymap.begin();it!=mymap.end();it++)
{ result.push({it->second,it->first});
}
vector<int> res;
while(k)
{ res.push_back(result.top().second);
result.pop();
k--;
}
return res;
}
};
发现一件事,前面的我好像没用总结过,之后把前面的总结补上。