代码随想录第13天

150. 逆波兰表达式求值

题目

链接: link

题解

注意

1.报错:
terminate called after throwing an instance of ‘std::invalid_argument’ what(): stoi
原因:stoi()无输入

239. 滑动窗口最大值

题目

链接: link

题解

class Solution {
private:
    class MyQueue { //单调队列(从大到小)
    public:
        deque<int> que; // 使用deque来实现单调队列
        // 每次弹出的时候,比较当前要弹出的数值是否等于队列出口元素的数值,如果相等则弹出。
        // 同时pop之前判断队列当前是否为空。
        void pop(int value) {
            if (!que.empty() && value == que.front()) {
                que.pop_front();
            }
        }
        // 如果push的数值大于入口元素的数值,那么就将队列后端的数值弹出,直到push的数值小于等于队列入口元素的数值为止。
        // 这样就保持了队列里的数值是单调从大到小的了。
        void push(int value) {
            while (!que.empty() && value > que.back()) {
                que.pop_back();
            }
            que.push_back(value);

        }
        // 查询当前队列里的最大值 直接返回队列前端也就是front就可以了。
        int front() {
            return que.front();
        }
    };
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        MyQueue que;
        vector<int> result;
        for (int i = 0; i < k; i++) { // 先将前k的元素放进队列
            que.push(nums[i]);
        }
        result.push_back(que.front()); // result 记录前k的元素的最大值
        for (int i = k; i < nums.size(); i++) {
            que.pop(nums[i - k]); // 滑动窗口移除最前面元素
            que.push(nums[i]); // 滑动窗口前加入最后面的元素
            result.push_back(que.front()); // 记录对应的最大值
        }
        return result;
    }
};

注意

1.stack、queue、deque
stack
a)定义:

stack<typename T, typename Container=deque>

第二个参数默认为deque
b)初始化:
不能在 stack 构造函数中使用初始化列表,必须使用圆括号。

std::list values {1.414, 3.14159265, 2.71828};
std::stack<double,std::list> my_stack (values);

圆括号中的数据类型与定义时的第二个参数类型相同。
c)拷贝构造函数:

std::stack<double,std::list>copy_stack {my_stack}

在使用拷贝构造函数时,既可以用初始化列表,也可以用圆括号。
d)堆栈操作:
top(): 返回一个栈顶元素的引用,类型为 T&。如果栈为空,返回值未定义。
push(const T& obj): 可以将对象副本压入栈顶。这是通过调用底层容器的 push_back() 函数完成的。
push(T&& obj): 以移动对象的方式将对象压入栈顶。这是通过调用底层容器的有右值引用参数的 push_back() 函数完成的。
pop(): 弹出栈顶元素。
size(): 返回栈中元素的个数。
empty(): 在栈中没有元素的情况下返回 true。
emplace(): 用传入的参数调用构造函数,在栈顶生成对象。
swap(stack & other_stack): 将当前栈中的元素和参数中的元素交换。参数所包含元素的类型必须和当前栈的相同。对于 stack 对象有一个特例化的全局函数 swap() 可以使用。
queue
a)定义:与stack相同
b)初始化:与stack相同
c)拷贝构造函数:与stack相同
d)堆栈操作:
front(): 返回 queue 中第一个元素的引用。如果 queue 是常量,就返回一个常引用;如果 queue 为空,返回值是未定义的。
back(): 返回 queue 中最后一个元素的引用。如果 queue 是常量,就返回一个常引用;如果 queue 为空,返回值是未定义的。
push(const T& obj): 在 queue 的尾部添加一个元素的副本。这是通过调用底层容器的成员函数 push_back() 来完成的。
push(T&& obj): 以移动的方式在 queue 的尾部添加元素。这是通过调用底层容器的具有右值引用参数的成员函数 push_back() 来完成的。
pop(): 删除 queue 中的第一个元素。
size(): 返回 queue 中元素的个数。
empty(): 如果 queue 中没有元素的话,返回 true。
emplace(): 用传给 emplace() 的参数调用 T 的构造函数,在 queue 的尾部生成对象。
swap(queue &other_q): 将当前 queue 中的元素和参数 queue 中的元素交换。它们需要包含相同类型的元素。也可以调用全局函数模板 swap() 来完成同样的操作。
deque
a)定义:

std::deque d;

b)初始化:

std::deque d(10, 5)

创建了一个包含 10 个元素(值都为 5)的 deque 容器。

std::deque d(10);

创建一个具有 10 个元素(默认都为 0)的 deque 容器。

c)拷贝构造函数:

std::deque d1(5);
std::deque d2(d1);

//拷贝普通数组,创建deque容器 int a[] = { 1,2,3,4,5 }; std::dequed(a, a +
5); //适用于所有类型的容器 std::array<int, 5>arr{ 11,12,13,14,15 };
std::dequed(arr.begin()+2, arr.end());//拷贝arr容器中的{13,14,15}

d)堆栈操作:
front(): 返回第一个元素的引用。
back(): 返回最后一个元素的引用。
empty(): 判断容器中是否有元素,若无元素,则返回 true;反之,返回 false。
push_back(): 在序列的尾部添加一个元素。
push_front(): 在序列的头部添加一个元素。
pop_back(): 移除容器尾部的元素。
pop_front(): 移除容器头部的元素。
insert(): 在指定的位置插入一个或多个元素。
erase() : 移除一个元素或一段元素。
clear(): 移出所有的元素,容器大小变为 0。
swap(): 交换两个容器的所有元素。
emplace(): 在指定的位置直接生成一个元素。
emplace_front(): 在容器头部生成一个元素。和 push_front() 的区别是,该函数直接在容器头部构造元素,省去了复制移动元素的过程。
emplace_back(): 在容器尾部生成一个元素。和 push_back() 的区别是,该函数直接在容器尾部构造元素,省去了复制移动元素的过程。
2.思路
定义一个数据结构,满足该数据结构的顶部就是所需的值(本文为窗口内最大值),需处理:①新传入的数据如何放置;②滑动出去的数据如何处理;③如何保证顶部为所需值。
①新传入的数据a如何放置
比较a与结构中原有数据,pop所有比a小的值
②滑动出去的数据b如何处理
若b恰好为所需值(原窗口数据中的最大值),则pop;
若不是,则在传入时已经pop,此时不需要处理
③如何保证顶部为所需值
在传入时就已经进行比较
由于此数据结构需要保持栈顶不变,又需要对栈底做处理,所以使用deque作为底部实现。
3.在主函数中定义自定义的数据结构:

 MyQueue que;
 vector<int> result;
 for (int i = 0; i < k; i++) { // 先将前k的元素放进队列
     que.push(nums[i]);
 }

347. 前 K 个高频元素

题目

https://leetcode.cn/problems/top-k-frequent-elements/

题解

class Solution {
public:
    class MyComparison
    {
        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> mp;
        vector<int> res(k);
        for(int i = 0;i < nums.size();i++)
        {
            mp[nums[i]]++;
        }
      
        priority_queue<pair<int,int>, vector<pair<int,int>>,MyComparison> pque;
        for (unordered_map<int, int>::iterator it = mp.begin(); it != mp.end(); it++) {
            pque.push(*it);
            if (pque.size() > k) { // 如果堆的大小大于了K,则队列弹出,保证堆的大小一直为k
                pque.pop();
            }
        }
        for(int i = k - 1;i >= 0;i--)
        {
            res[i] = pque.top().first;
            pque.pop();
        }
        return res;
    }
};

注意

1.priority_queue
①定义

template <typename T, typename Container=std::vector, typename Compare=std::less> class priority_queue

第一个参数是存储对象的类型,第二个参数是存储元素的底层容器,第三个参数是函数对象,它定义了一个用来决定元素顺序的函数。
priority_queue 实例默认有一个 vector 容器。函数对象类型 less 是一个默认的排序函数,定义在头文件 function 中,决定了容器中最大的元素会排在队列前面。
②初始化

std::string wrds[] { “one”, “two”, “three”, “four”};
std::priority_queuestd::string words { std::begin(wrds),std:: end(wrds)}; // “two” “three” “one” “four”

③拷贝构造函数

std::priority_queuestd::string copy_words {words}; // copy of words

④堆栈操作
push(const T& obj): 将obj的副本放到容器的适当位置,这通常会包含一个排序操作。
push(T&& obj): 将obj放到容器的适当位置,这通常会包含一个排序操作。
emplace(T constructor a rgs…): 通过调用传入参数的构造函数,在序列的适当位置构造一个T对象。为了维持优先顺序,通常需要一个排序操作。
top(): 返回优先级队列中第一个元素的引用。
pop(): 移除第一个元素。
size(): 返回队列中元素的个数。
empty(): 如果队列为空的话,返回true。
swap(priority_queue& other): 和参数的元素进行交换,所包含对象的类型必须相同。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值