leetCode常用数据结构题单

1. 基础

栈可以用stack,或者vector来模拟操作,其实vector更方便,很多时候需要从头输出栈内元素。
没有什么写模板的必要,下面列出一些栈的基本操作

  stack<int> st;  vector<int> vec;
  
  st.push(1);     vec.push_back(1);
  st.pop();       vec.pop_back();

  int a = st.top();     
  int b = vec.back();

2. 进阶

什么时候入栈,什么时候出栈,是个大学问。

2434. 使用机器人打印字典序最小的字符串

本题栈操作的为t字符串,s内的字符依次入栈,而要求t中的字符出栈后拿到字典序最小的字符串。
对于当前栈顶元素top,若其字典序小于等于未入栈元素中字典序最小的,显然应当立即出栈,否则未入栈元素中字典序最小的应比当前的栈顶元素更早出栈。

string robotWithString(string s) {
    string ans;
    stack<int> st;
    vector<int> cnt(26);
    for(auto &temp : s) cnt[temp-'a']++;  //  记录剩余元素出现的次数
    for(auto &temp : s){
        st.push(temp-'a');
        cnt[temp-'a']--;
        int mins = 25;                    // 剩余元素中字典序最小的元素
        for(int i = 0; i < 25; i++) 
            if(cnt[i]) {mins = i; break;}  
        while(!st.empty() && st.top() <= mins) {
            ans += st.top()+'a';
            st.pop();
        }
    }
    
    return ans;
}

3. 邻项消除

735.小行星碰撞

这题逻辑很简单,小行星移动速度相同,相撞只与方向相关,两颗小行星面对面相撞时,较小行星会爆炸,一样大就都爆炸。比较细节的操作是用一个参数记录当前待入栈的小行星存活状态。

vector<int> asteroidCollision(vector<int>& asteroids) {
    vector<int> st;
    for(auto & temp : asteroids){
        bool alive = true;  //记录temp是否存在
        // 只有栈顶行星向右(>0) 且 temp向左(<0) 时会发生碰撞
        while(alive && temp < 0 && st.size() && st.back() > 0){
            alive = st.back() < -temp;
            if(st.back() <= -temp)  st.pop_back();
        }
        if(alive) st.push_back(temp);
    }
    return st;
}

4. 合法括号字符串(RBS)

856.括号的分数

用栈记录每层括号内部的分数。遇到'(',进入新的一层,新一层的初始分数为0;遇到')',结算当前的分数,将其×2累加到上一层。

int scoreOfParentheses(string s) {
    stack<int> sums;
    sums.push(0);
    for(auto &temp : s){
        if(temp == '(') {sums.push(0); continue;}
        int v = sums.top(); sums.pop();
        if(!v) sums.top() += 1;
        else sums.top() += 2*v;
    }
    return sums.top();
}

1111.有效括号的嵌套深度

需要想到如何分配括号是合理且正确的。本题可以将深度为奇数的一对括号分配给A,深度为偶数的一对括号分配给B,保证了括号是配对的,但我不理解为什么这是深度最小的分配方式。以后回来二刷再思考一下吧。

vector<int> maxDepthAfterSplit(string seq) {
    int cntl = 0;
    vector<int> ans(seq.size());
    for(int i = 0; i < seq.size(); i++){
        if(seq[i] == '('){
            cntl++; ans[i] = cntl%2;
        }
        else {
            ans[i] = cntl%2; cntl--;
        }
    }
    return ans;
}

5. 表达式解析

394.字符串解码

理清基本逻辑就不难。遇到数字num,把num放入数字栈nums;遇到'[',把现有的字符串res入字符串栈st;遇到']',把res复制nums.top()份,添加到st.top()后面,作为新的res,并把nums.top()和st.top()弹出;遇到字符,将其添加到res后面。最后的res即为答案。

string decodeString(string s) {
    vector<int> nums;
    vector<string> st;
    string res;
    int i = 0, n = s.size();
    while(i < n){
        if(s[i] >= '0' && s[i] <= '9'){
            int num = 0;
            while(i < n && s[i] >= '0' && s[i] <= '9'){
                num = num*10 -'0' + s[i];
                i++;
            }
            nums.push_back(num);
            continue;
        }
        if(s[i] == '['){
            st.push_back(res);
            res = "";
            i++; continue;
        }
        if(s[i] == ']'){
            string nres = res;
            for(int i = 1; i < nums.back(); i++) nres += res;
            res = st.back() + nres;
            nums.pop_back(); st.pop_back();
            i++; continue;
        }
        res += s[i++]; 
    }
    return res;
}

6. 对顶栈

对顶栈说白了就是两个栈,左栈的顶连着右栈的顶,左栈自底向上为实际顺序,右栈自顶向下为实际顺序。

posted @ 2025-07-10 21:38  zerolt  阅读(9)  评论(0)    收藏  举报