力扣刷题---栈和队列

一:利用栈进行括号匹配

力扣刷题---栈和队列_第1张图片


力扣刷题---栈和队列_第2张图片

 力扣刷题---栈和队列_第3张图片

 力扣刷题---栈和队列_第4张图片

 很简单:

遇到左括号就进栈,遇到右括号就将当前栈顶元素出栈,如果最后遍历完字符串栈为空就说明匹配了

bool isValid(string s) {
        stack sta;
        for(int i=0;i

不难,但是有几点细节

  • 在匹配时候,判断一下栈是否为空。栈空一定不符合要求。(左括号少)
  • 在结尾时候,依然判断一下栈是否为空。(左括号多)
                char match;
                if(s[i]==')'){
                   match='(';
                }
                else if(s[i]=='}'){
                   match='{';
                }
                else{
                    assert(s[i]==']');
                   match='[';
                }
                if(aux!=match) return false;

可以这样写,使代码更简洁

            if(aux==match) continue;

                else return false;

    bool isValid(string s) {
        stack sta;
        for(int i=0;i
注意------栈对于解决嵌套问题很有帮助

二:栈和递归的紧密关系 

二叉树的前序遍历-----递归过程

力扣刷题---栈和队列_第5张图片

        其实就相当于不断执行子函数,然后暂停运行自己的所在程序,直至子程序运行结束,继续执行自己所在程序.

树的前序遍历------站实现 

力扣刷题---栈和队列_第6张图片

 vector preorderTraversal(TreeNode* root) {
         //定义返回结果
         vector res;
         if(root==NULL) return res;
         //定义栈
         stack sta;
         sta.push(root);
         //结果
         while(!sta.empty()){
             TreeNode* tmp=sta.top();
             sta.pop();
             res.push_back(tmp->val);
             //注意栈的后进先出
             if(tmp->right)  sta.push(tmp->right);
             if(tmp->left)  sta.push(tmp->left);
         }
         return res;
    }

 三:层次遍历-----分清每一层元素

力扣刷题---栈和队列_第7张图片

 代码:

vector> levelOrder(TreeNode* root) {
        //定义返回值--[[],..,[]]
        vector> res;
        if(root==NULL) return res;
        //队列用pair存放:元素+对应层数
        queue> que;
        que.push(make_pair(root,0));
        //判断
        while(!que.empty()){
           //定义变量接收队列元素
           TreeNode* tmp=que.front().first;
           int level=que.front().second;
           que.pop();
           //存入res
           if(level==res.size()){//判断层数和res中【..】个数
               res.push_back(vector());
           }
           res[level].push_back(tmp->val);
           if(tmp->left) que.push(make_pair(tmp->left,level+1));
           if(tmp->right) que.push(make_pair(tmp->right,level+1));
        }
        return res;
    }

不难就是因为记录信息多了需要注意细节:

  1. queue<pair> que;----注意队列的存放元素

  2. que.push(make_pair(root,0));-----这里的0对应的是【。。】中的【】排序

  3. TreeNode* tmp=que.front().first;------注意两个变量对应

    int level=que.front().second;

  4.  res.push_back(vector());-----初始化的是大【】中的小【】

  5.  res[level].push_back(tmp->val);-----给小【】存元素

注意几个忽视点:

  • if(root==NULL) return res;--------判断根节点不为空

  •  if(level==res.size())------比较level和res中小括号的对应

四:C++的优先队列 

#include
#include
#include
using namespace std;
int main(){
    srand(time(NULL));//生成随机种子

    priority_queue p;

    for(int i=0;i<10;i++){
        int n=rand()%100;
        p.push(n);//入队
    }
    while(!p.empty()){
        cout<

 结论-----c++默认的优先级队列是大顶堆


 这个就是最小堆的定义:

传入三个参数-----堆中数据类型,堆的底层数据实现类型,可以理解--孩子比自己greater


#include
#include
#include
using namespace std;
int main(){
    srand(time(NULL));//生成随机种子

    priority_queue,greater> p;
    priority_queue,less> q;
    for(int i=0;i<10;i++){
        int n=rand()%100;
        p.push(n);//入队
        q.push(n);
    }
    while(!p.empty()){
        cout<

 传入自定义函数的写法

首先头文件:#include

自己的写的函数:

bool mycmp(int a,int b){return a%10 < b%10 }

然后传入:function

变量: p(mycmp);

 

 五:Top K Frequent Elememt

力扣刷题---栈和队列_第8张图片


首先分析----pair对的优先级队列

力扣刷题---栈和队列_第9张图片

 力扣刷题---栈和队列_第10张图片

 结论---------存放pair对的有限队列,默认对第一个元素进行排序

 法一:

vector topKFrequent(vector& nums, int k) {
        //该题要输出频次最高的元素,也就是说:频次和元素两个都很重要
        //查找表用map:k---元素,v---频次
        //队列(大顶堆less):排序v,所以:pair<频次,元素>
        map record;
        priority_queue> pq;
        //遍历数组更新查找表
        for(int i=0;i::iterator it;
        for(it=record.begin();it!=record.end();it++){
            pq.push(make_pair(it->second,it->first));//先频次,后元素
        }
        //输出要求的的前k个结果
        vector res;
        for(int i=0;i

思想很简单粗暴:

  1. 遍历一下查找表,得到k-v对(map[k]=v),这里:k是元素值,v是频次
  2. 然后建立一个最大堆,这里因为要排序频次,输出元素,注意pair<频次,元素>
  3. 然后输出前k个就是所求的。

          当然可以优化,因为题目要求输出前k个,那我们在堆中只存k个。这时候因为要淘汰频率低的,所以选用小顶堆。

class Solution {
public:
    vector topKFrequent(vector& nums, int k) {
        //查找表用map:k---元素,v---频次
        //队列(小顶堆greater):排序v,所以:pair<频次,元素>
        map record;
        priority_queue,vector>,greater>>pq;
        //遍历数组更新查找表
        for(int i=0;i::iterator it;
        for(it=record.begin();it!=record.end();it++){
            if(pq.size()==k){
                if(it->second>pq.top().first){
                    pq.pop();
                    pq.push(make_pair(it->second,it->first));//先频次,后元素
                }
            }
            else{
                pq.push(make_pair(it->second,it->first));
            }
        }
        //输出要求的的前k个结果
        vector res;
        while(!pq.empty()){
            res.push_back(pq.top().second);
            pq.pop();
        }
        return res;
    }
};

priority_queue< pair,vector>,greater> > pq;

  •  pair

  • vector>

  • greater>

你可能感兴趣的:(力扣刷题,c++,算法,力扣,数据结构,栈)