栈的进阶篇

参考资料来源灵神在力扣所发的题单,仅供分享学习笔记和记录,无商业用途。

核心思路: 查看栈的基础篇-CSDN博客

**应用场景:**处理具有完全包含关系(括号关系)的问题,递归实现和栈实现本质上没有区别

力扣刷题

3170. 删除星号以后字典序最小的字符串

题意:

给定一个带:'*'的字符串,遇到*时需要删除它并且在它之前找到字典序最小的字符进行删除,存在多个任意删除一个,返回重构的字符串

思路:

用动态数组记录26个字符出现的位置,遇到*直接按顺序遍历26个数组,遇到存在的数组删除一个元素即可。

遍历完字符串后将26个字母动态数组存放的元素进行升序排序,变成重构字符串后的元素位置

cpp 复制代码
class Solution {
public:
    string clearStars(string s) {
        //题意:给定一个带:'*'的字符串,遇到*时需要删除它并且在它之前找到字典序最小的字符进行删除,存在多个任意删除一个,返回重构的字符串
        //思路:用动态数组记录26个字符出现的位置,遇到*直接按顺序遍历26个数组,遇到存在的数组删除一个元素即可。
        //遍历完字符串后将26个字母动态数组存放的元素进行升序排序,变成重构字符串后的元素位置
        vector<int> ans[26];
        for(int i=0;i<s.size();i++){
            if(s[i]!='*'){
                ans[s[i]-'a'].push_back(i);
                continue;
            }
            for(auto&x:ans){
                if(x.size()){
                    x.pop_back();
                    break;
                }
            }
        }
        vector<int> buff;
        for(auto&x:ans) buff.insert(buff.end(),x.begin(),x.end());
        sort(buff.begin(),buff.end());
        string ret="";
        for(auto x:buff) ret+=s[x];
        return ret;
    }
};

155. 最小栈

**题意:**获取当前栈中最小元素

**思路:**当元素小于等于栈顶元素或者最小栈为空时才能放入。保证了栈顶为当前栈中最小元素

cpp 复制代码
class MinStack {
public:
    vector<int> ans,ans_min;
    MinStack() {}
    //当元素小于等于栈顶元素或者最小栈为空时才能放入。保证了栈顶为当前栈中最小元素
    void push(int val) {
        ans.push_back(val);
        if(ans_min.empty() || ans_min.back()>=val) ans_min.push_back(val);
        return ;
    }
    
    void pop() {
        if(ans.empty()) return ;
        if(ans_min.back()==ans.back()) ans_min.pop_back();
        ans.pop_back(); 
    }
    
    int top() {
        return ans.back();
    }
    
    int getMin() {
        return ans_min.back();
    }
};

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack* obj = new MinStack();
 * obj->push(val);
 * obj->pop();
 * int param_3 = obj->top();
 * int param_4 = obj->getMin();
 */

636. 函数的独占时间

**题意:**给定一组[函数编号:状态:时间]的数据,一定符合时间先后调用关系,求各个编号函数执行完需要花费多少时间

思路:

先划分好数据,用栈存储上一个开始函数并用一个变量记录上一个时间。如果栈中有函数启动并且又递归调用一个函数则先计算好前一个函数的部分时间在入栈递归函数,在统计好递归函数时间出栈递归函数后,最后统计好前函数时间。

递归的本质就是栈思想,着重理解递归与栈的关系

cpp 复制代码
class Solution {
public:
    vector<int> exclusiveTime(int n, vector<string>& logs) {
        //题意:给定一组[函数编号:状态:时间]的数据,一定符合时间先后调用关系,求各个编号函数执行完需要花费多少时间
        //思路:先划分好数据,用栈存储上一个开始函数并用一个变量记录上一个时间。如果栈中有函数启动并且又递归调用一个函数则先计算好前一个函数的部分时间在入栈递归函数,在统计好递归函数时间出栈递归函数后,最后统计好前函数时间。
        //递归的本质就是栈思想,着重理解递归与栈的关系
        vector<int> ans(n);
        stack<int> vID;
        for(int i=0,pre=0;i<logs.size();i++){
            int pos1=logs[i].find_first_of(":");
            int pos2=logs[i].find_last_of(":");
            string id_str=logs[i].substr(0,pos1);
            string status=logs[i].substr(pos1+1,pos2-pos1-1);
            string time_str=logs[i].substr(pos2+1,logs[i].size()-pos2-1);
            int id=atoi(id_str.c_str());
            int time_stamp=atoi(time_str.c_str());
            if(!vID.empty()) ans[vID.top()]+=time_stamp-pre+(status=="end");
            pre=time_stamp+(status=="end");
            if(status=="start"){
                vID.push(id);
            }else vID.pop();
        }
        return ans;
    }
};

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

**题意:**给定一个字符串按顺序全部入栈。自行选择入栈和出栈的时机,要求在入栈和出栈的过程中找到组成最小字典序的方法

思路:

在入栈后判断栈顶是否能小于后缀最小字符,能则说明是当下最优解直到栈顶大于后缀最小字符停止。

给后缀最小字符数组最后一位标记成最大字符保证在遍历字符串的最后一次能清空栈内元素归并到结果中

cpp 复制代码
class Solution {
public:
    string robotWithString(string s) {
        //题意:给定一个字符串按顺序全部入栈。自行选择入栈和出栈的时机,要求在入栈和出栈的过程中找到组成最小字典序的方法
        //思路:在入栈后判断栈顶是否能小于后缀最小字符,能则说明是当下最优解直到栈顶大于后缀最小字符停止。
        //给后缀最小字符数组最后一位标记成最大字符保证在遍历字符串的最后一次能清空栈内元素归并到结果中
        vector<char> ans(s.size()+1);
        stack<char> buff;
        ans[s.size()]='z';  //清空栈元素
        for(int i=s.size()-1;i>=0;i--) ans[i]=min(ans[i+1],s[i]);  //后缀最小字符
        string ret="";
        for(int i=0;i<s.size();i++){
            buff.push(s[i]);
            while(!buff.empty() && buff.top()<=ans[i+1]){
                ret+=buff.top();
                buff.pop();
            }
        }
        return ret;
    }
};
相关推荐
长安er3 分钟前
LeetCode 124/543 树形DP
算法·leetcode·二叉树·动态规划·回溯
Sheep Shaun6 分钟前
STL:list,stack和queue
数据结构·c++·算法·链表·list
杜子不疼.7 分钟前
【LeetCode 153 & 173_二分查找】寻找旋转排序数组中的最小值 & 缺失的数字
算法·leetcode·职场和发展
CSDN_RTKLIB8 分钟前
【LeetCode 热题 HOT 100】两数之和
算法·leetcode·职场和发展
Tisfy9 分钟前
LeetCode 2054.两个最好的不重叠活动:二分查找
算法·leetcode·二分查找·题解
_OP_CHEN11 分钟前
【C++数据结构进阶】吃透 LRU Cache缓存算法:O (1) 效率缓存设计全解析
数据结构·数据库·c++·缓存·线程安全·内存优化·lru
Looooking12 分钟前
Python 之通过一个天平找出9个小球中唯一重量较轻的小球
python·算法
white-persist12 分钟前
【攻防世界】reverse | tt3441810 详细题解 WP
java·c语言·开发语言·数据结构·c++·算法·安全
YGGP15 分钟前
【Golang】LeetCode 70. 爬楼梯
算法·leetcode