leetcode上的一些栈、队列问题

20-有效的括号

思路:主要考察栈的一些基本操作,像push()(将数据压入栈顶)、top()(取栈顶的数据但不删除)、pop()(直接删除栈顶的元素)、empty()(判断栈是否为空)。这题就是先把三种括号类型的左边先入栈,然后再判断后面紧接着进入的是否是同类型匹配。

class Solution {
public:
    bool isValid(string s) {
        stack<char> p;
        for(int i=0;i<s.size();i++){
            if(s[i]=='('||s[i]=='{'||s[i]=='[')
                p.push(s[i]);
            else{
                if(p.empty()) return false;
                if(s[i]==')'&&p.top() != '(') return false;
                if(s[i]=='}'&&p.top() != '{') return false;
                if(s[i]==']'&&p.top() != '[') return false;
                p.pop();    
            }
        }
        return p.empty();
     }
};

150-逆波兰表达式

思路:逆波兰,把运算符放在两个数后面进行运算的表达式。可以想到使用栈解决时能够把遇到的数字都压入栈中,遇到符号则拿出来计算,然后再把结果压入栈中。

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        if(tokens.size()==1) 
            return stoi(tokens[0]);
        stack<int> st;
        
        for(int i=0;i<tokens.size();i++){
            if(tokens[i]!="+"&&tokens[i]!="-"&&tokens[i]!="*"&&tokens[i]!="/"){
                st.push(stoi(tokens[i]));
            }else{
                int num1=st.top();st.pop();
                int num2=st.top();st.pop();
                if(tokens[i]=="+") st.push(num2+num1);
                if(tokens[i]=="-") st.push(num2-num1);
                if(tokens[i]=="*") st.push(num2*num1);
                if(tokens[i]=="/") st.push(num2/num1);
            }
        }
        return st.top();
    }
};

71-简化路径

 思路:

  1. 是“..”时删掉它上面紧挨着的一个路径;
  2. 中间是"."时直接去掉;
  3. 如果是空,则直接返回“/”;
  4. 如果是多个“/”,只保留一个;
  5. 路径可以看做是一个或多个"/"分隔开众多子字符串
class Solution {
public:
    string simplifyPath(string path) {
        vector<string> v;
        int i=0;
        while(i<path.size()){
            while(path[i]=='/'&&i<path.size()) i++;
            if(i==path.size()) break;
            int start=i;
            while(path[i]!='/'&&i<path.size()) i++;
            int end=i-1;
            string s=path.substr(start,end-start+1);
            if(s==".."){
                if(!v.empty()) v.pop_back();
            }else if(s!="."){
                v.push_back(s);
            }
        }
        if(v.empty()) return "/";
        string res;
        for(int i=0;i<v.size();i++){
            res +='/'+v[i];
        }
        return res;
    }
};

126-单词接龙

 思路:有点难理解。。

347-前K个高频词汇

思路:统计出现数字的频次考虑用HashMap,建立数字和其出现次数的映射,然后按照次数排序,然后按照最大堆来从大到小排序。

class Solution {
public:
    vector<int> topKFrequent(vector<int>& nums, int k) {
        unordered_map<int, int> m;
        priority_queue<pair<int, int>> q;
        vector<int> res;
        for(auto a:nums) 
            m[a]++;
        for(auto it:m) 
            q.push({it.second,it.first});
        for(int i=0;i<k;i++){
            res.push_back(q.top().second);
            q.pop();
        }
        return res;
    }
};

23-合并K个排序链表

思路:K个链表先划分为合并K/2个链表,再不停地往下划分,直到划分成只有一个或者两个链表的任务。k通过(n+1)/2的目的是可以确保取值为奇数时能从后半段开始,当然为偶数的时候不会存在影响。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        if(lists.empty()) 
            return NULL;
        int n=lists.size();
        while(n>1){
            int k=(n+1)/2;
            for(int i=0;i<n/2;i++){
                lists[i]=mergeTwolists(lists[i],lists[i+k]);
            }
            n=k;
        }
        return lists[0];
    }
    
    ListNode* mergeTwolists(ListNode* l1,ListNode* l2){
        ListNode* p=new ListNode(-1),*cur=p;
        while(l1&&l2){
            if(l1->val<l2->val){
                cur->next=l1;
                l1=l1->next;
            }else{
                cur->next=l2;
                l2=l2->next;
            }
            cur=cur->next;
        }
        if(l1) cur->next=l1;
        if(l2) cur->next=l2;
        return p->next;
    }
};

  

posted @ 2019-09-29 14:00  codeg  阅读(250)  评论(0编辑  收藏  举报