C++ algorithm learning (stack)

What is a stack?

It is a linear table with restricted operations, which can only be inserted and deleted at the end of the table, that is, first-in-last-out, last-in-first-out. (Novices suggest to search for an algorithm diagram, the explanation is very clear)

Question type

Principle learning: 155, 71, 682, 341
monotonous stack: 42,496, 1081
auxiliary stack (just a tool for counting): 1021, 331
personally feel that there is no new type, basically do not repeat the recording of questions.

Sequential stack

If you understand it, Baidu Baike is fine. I also take notes for fear of misleading you. The application of the link
sequence stack (too many algorithms to summarize):
There is an obvious sorting phenomenon, or the first largest (smallest) situation on the left or the right is found.

Practice topic

155. Minimal stack

struct Node{
    
    
        int val;
        int min;
        Node *next;
};
//建立结构体,写入题目要求的功能
class MinStack {
    
    
private:
Node* head;
public:
    MinStack() {
    
     
    head = nullptr;
    }
    //构造函数
    void push(int x) {
    
    
    if(head != NULL){
    
    
    int temp = (head -> min > x)? x : head -> min;
    Node *node = new Node();
    node -> min = temp;
    node -> val = x;
    node -> next = head;
    head = node;
    }//这里使用头插
    else{
    
    
        head = new Node();
        head -> val = x;
        head -> min = x;
        head -> next = nullptr;
    }
    }
    void pop() {
    
    
        head = head ->next;
    }
    
    int top() {
    
    
    return head -> val;
    }
    int getMin() {
    
    
    return head -> min;
    }
};

42. catch rain

This uses a monotonically decreasing stack:
a little talk about the monotonically decreasing stack and the monotonically increasing stack:
(Take the monotonically decreasing stack as an example)
1. If the data is less than the top element of the stack, it is pushed into the stack.
2. If the data is larger than the top element of the stack, then the top element of the stack is popped from the stack until the data is smaller than the top element of the stack.

For example: 4312
4,3,1 is normally pushed
to the stack to 2, and 1 is compared, 1 is popped, and 3 is compared, and the result is less than 3.

For this question, we only need to ask for the area of ​​the place where there is a water drop, so the data stored in our stack is the subscript of the array (of course there are other solutions, but I use the stack here)

class Solution {
    
    
public:
    int trap(vector<int>& height) {
    
    
    stack<int> num;
    int sum = 0;
    for(int i = 0;i < height.size();i++){
    
    
        while(!num.empty() && height[num.top()] < height[i]){
    
    
            int val = height[num.top()];
            num.pop();
            if(num.empty()) break;
            int l = i - num.top() - 1;
            int h = min(height[i],height[num.top()]) - val;
            sum += l * h;
        }
        num.push(i);
    }
    return sum;
    }
};

71. Simplify the path

After reading the questions and examples, the information I got:
1. If the top of the stack is/the next data to be pushed is also/then the top of the stack is popped out, and the next data is normally pushed into the stack.
2. If the top of the stack is / (do not rule out the case of inputting a randomly in the example) the next data to be pushed is... then all the data is popped out of the stack, and the next data is pushed into the stack.
3. If the top of the stack is /, the next data to be pushed is. Then the top of the stack is popped, and continue to pop to the top of the next stack is /
4. At the end of the program run, judge whether the top of the stack is /, if it is Pop out of the stack.
How to say it, we just need to judge what is between the two/between things, and then do the corresponding operations.

class Solution {
    
    
public:
    string simplifyPath(string path) {
    
    
    path += '/';
    stack<string> stk;
    string str;
    for(char m : path){
    
    
        if(m == '/'){
    
    
            //如果str为.那么直接清除str即可
            //如果str为..那么stk把上一个数据给出栈(这里有特殊情况/../需要判断是否为空栈)
            //其他情况就把数据读进去,注意我这么写'/'这个字符是不会读进去的
            if(str == ".." && !stk.empty()){
    
    
                stk.pop();
            }
            else if(str != "." && !str.empty() && str != ".."){
    
    
                stk.push(str);
            }
            str.clear();
        }
        else{
    
    
            str.push_back(m);
        }
    }
    string result;
    if(stk.empty()) return "/";
    while(!stk.empty()){
    
    
        result = "/" + stk.top() + result;
        stk.pop();
    }
    return result;
    }
};

496. The Next Greater Element I

This question uses a descending sequence of numbers, save the small data in to find the first big data on the right, and then save the relationship (remember to pop the top of the stack), I use hashmap to establish the relationship, and finally check the results, if you can’t find it. Returns -1.

class Solution {
    
    
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
    
    
    stack<int> num;
    vector<int> answer;
    map<int, int> s1;
    for(auto a:nums2){
    
    
        while(!num.empty() && num.top() < a){
    
    
            s1[num.top()] = a;
            num.pop();
        }
        num.push(a);
    }
    for(auto a:nums1){
    
    
        if(s1.count(a) == 0) answer.push_back(-1);
        else answer.push_back(s1[a]);
    }
    return answer;
    }
};

682. Baseball Game

This question is also a hand-practice question. I thought I would use the asl code, but I don’t know how 60 points can be scored in a baseball game?

class Solution {
    
    
public:
    int calPoints(vector<string>& ops) {
    
    
    stack<int> num;
    int sum = 0;
    for(auto a:ops){
    
    
        if(a[0] == '+'){
    
    
            int t = num.top();
            num.pop();
            int t1 = t + num.top();
            num.push(t);
            num.push(t1);
        }
        else if(a[0] == 'D'){
    
    
            int t = num.top() + num.top();
            num.push(t);
        }
        else if(a[0] == 'C'){
    
    
            num.pop();
        }
        else num.push(stoi(a));//大家可以记一下这个函数
    }
    while(!num.empty()){
    
    
        sum += num.top();
        num.pop();
    }
    return sum;
    }
};

1021. Delete the outermost parenthesis

I started by looking for the distance between the two stacks and adding up the things between the two, but I looked at what the big guy wrote == I am ashamed, the reference user: ping-ze-ping -ze-ping-ping-ze code.

class Solution {
    
    
public:
    string removeOuterParentheses(string S) {
    
    
        stack<char> a;
        string b("");
        for(int i = 0;i < S.length();i++){
    
    
            if(S[i] == ')') a.pop();
            if(!a.empty() ) b += S[i];
          if(S[i] == '(')  a.push(S[i]);
        }
        return b;
    }
}

341. Flattening nested list iterators

The middle-difficulty questions are suitable for hand training (I didn't understand the meaning of the questions at first, and it was annoying to write).

class NestedIterator {
    
    
private:
stack<int> a;
stack<int> b;
void add(vector<NestedInteger> nested){
    
    
    for(auto nestedi : nested)
        if(nestedi.isInteger()) a.push(nestedi.getInteger());
        else add(nestedi.getList());
}
public:
    NestedIterator(vector<NestedInteger> &nestedList) {
    
    
        add(nestedList);
        while(!a.empty()){
    
    
            b.push(a.top());
            a.pop();
        }
    }
    int next() {
    
    
        int ai = b.top();
        b.pop();
        return ai;
    }
    bool hasNext() {
    
    
        return !b.empty();
    }
};

331. Verify the preorder serialization of the binary tree

This is a binary tree == Anyway, my impression is: the number of empty nodes = the number of non-empty nodes + 1. I suggest you remember a few theorems about trees.
Then # is empty, the number is non-empty, # is 1 more than the number, then if it is a number, it will be pushed into the stack, if it is #, it will be popped out of the stack, then when the character is # and # is the last digit of the string to see if the stack is If it is empty, the verification is successful, and if it is not empty, the verification has failed.
Then when I wrote it out, I met the two-digit number 19, and this is a string, it’s difficult to do == I borrowed from other people’s practices, every time he finds a number, he goes down to find the next one", "there are many", "There is only one, I have to say that this idea is really powerful.

class Solution {
    
    
private:
stack<char> a;
public:
    bool isValidSerialization(string preorder) {
    
    
    if (preorder.empty()) return false;
    for(int i = 0;i < preorder.length();i++){
    
    
        if(preorder[i] == '#'){
    
    
            if(a.empty()) return i == preorder.size() - 1;
            else {
    
    
                a.pop();
                i++;
            }
        }
        else{
    
    
            while (i < preorder.size() && preorder[i] != ',') i++;
            a.push(preorder[i]);
        }
    }
    return false;
    }
};

1081. The smallest subsequence of different characters

The principle of this problem is very simple. It is a monotonic stack (monotonically increasing). If data already exists in the stack, pass this data. If the data is smaller than the top of the stack, then delete the data on the top of the stack until the data on the top of the stack is less than the data. Because C++ has few library functions, we use vector instead. In fact, you can use go and python to adjust the library directly.

class Solution {
    
    
public:
    bool get_num(int i,string s,char si){
    
    
        for(int j = i + 1;j<s.length();j++) if(s[j] == si) return true;
        return false;
    }
    string smallestSubsequence(string s) {
    
    
     string str("");
     vector<char> already;
     int i = -1;
     for(auto si :s){
    
    
         i++;
         if(count(already.begin(),already.end(),si) > 0) continue;
         while(!already.empty() && already.back() > si && get_num(i,s,already.back()) == true) already.pop_back();
         already.push_back(si);
     }
     while(!already.empty()){
    
    
         str = already.back() + str;
         already.pop_back();
     }
     return str;
    }
};

Guess you like

Origin blog.csdn.net/weixin_45743162/article/details/113619752