栈和队列

239. 滑动窗口最大值

题意:给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。返回 滑动窗口中的最大值 。

示例:

算法练习-day11_unordered_map

       思路:我们的思路是,使用一个特殊队列,该队列可以实现,添加元素,删除元素和返回队列中最大元素的功能,由于STL中并没有完全符合我们条件的队列,因此,我们需要自己定义一个队列类:

  1. push(val):在加入队列前,需要判断val前,是否有小于它的元素,如果有则需要移除,我们的队列并不需要维护不需要的元素
  2. pop(val):该删除元素,主要是为了删除特定的元素,即不在滑动窗口范围内的最大元素。有些元素会非常大,导致无法自动移除,此时就需要该元素手动移除那些不在滑动窗口范围内的元素
  3. 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;
    }

347. 前 K 个高频元素

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

示例:

算法练习-day11_栈和队列_02

       思路:本题的思路比较简单,先创建一个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;
    }