栈总结

首先记住这句话,笔试都遇到好几次了:

从数据结构角度看,栈也是线性表!

目录

20. 有效的括号

Leetcode150.逆波兰表达式求值

LeetCode1021.删除最外层的括号

LeetCode921.使括号有效的最少添加

LeetCode1047.删除字符串中的所有相邻重复项

LeetCode面试题03.04.化栈为队

LeetCode682.棒球比赛

LeetCode496.下一个更大的元素I

Leetcode150.逆波兰表达式求值
————————————————

最经典的一道栈的题目,想当年为了弄懂这题可是花了不少劲,现在看来实属easy!

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


LeetCode1021.


 


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

————————————————

LeetCode921.使括号有效的最少添加

这题是上面那题的姊妹版,同样用栈stack解决,但是注意先判断栈是否为空!

class Solution {
public:
    int minAddToMakeValid(string S) {
        stack<char> s;
        for(int i=0;i<S.size();i++){
            if(S[i]=='('||s.empty())//先判断栈是否为空
                s.push(S[i]);
            else if(S[i]==')'&&s.top()=='(')
                s.pop();
            else
                s.push(S[i]);
        }
        return s.size();
    }
};
————————————————

LeetCode1047.删除字符串中的所有相邻重复项

想一下没有再比这个更明显的栈结构模拟的了……

进阶一点的逆波兰算法:栈解逆波兰算法

class Solution {
public:
    string removeDuplicates(string S) {
        stack<char> s;
        s.push(-1);//开头放进一个不可能的元素放置后面地址错误
        for(int i=0;i<S.size();i++){
            if(S[i]!=s.top())
                s.push(S[i]);
            else
                s.pop();
        }
        string ss;
        int size = s.size();
        for(int i=0;i<size-1;i++){
            ss.push_back(s.top());
            s.pop();
        }
        reverse(ss.begin(),ss.end());//结果需要反转
        return ss;
    }


LeetCode面试题03.04.化栈为队

用两个栈来模拟队列,是一个十分经典的栈与队列问题!


class MyQueue {
public:
    /** Initialize your data structure here. */
    stack<int> s1,s2;//s1记录队列的压入顺序,s2作转换使用
    MyQueue() {
 
    }
    
    /** Push element x to the back of queue. */
    void push(int x) {
    //因为每次pop或者peek的时候都改变了s1,所以push的时候要将s2中的倒回s1
        while(!s2.empty()){
            s1.push(s2.top());
            s2.pop();
        }
        s1.push(x);
    }
    
    /** Removes the element from in front of queue and returns that element. */
    int pop() {
        while(!s1.empty()){
            s2.push(s1.top());
            s1.pop();
        }
        int ans = s2.top();
        s2.pop();
        return ans;
    }
    
    /** Get the front element. */
    int peek() {
        while(!s1.empty()){
            s2.push(s1.top());
            s1.pop();
        }
        return s2.top();
    }
    
    /** Returns whether the queue is empty. */
    bool empty() {
        return s1.empty()&&s2.empty();
    }
};
 
/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue* obj = new MyQueue();
 * obj->push(x);
 * int param_2 = obj->pop();
 * int param_3 = obj->peek();
 * bool param_4 = obj->empty();

LeetCode682.棒球比赛

典型的栈,会逆波兰算法,这个很快就会有思路

class Solution {
public:
    int calPoints(vector<string>& ops) {
        stack<int> s;
        for(int i=0;i<ops.size();i++){
            if(ops[i]=="+"){
                int a = s.top();
                s.pop();
                int b = s.top();
                s.push(a);
                s.push(a+b);
            }else if(ops[i]=="C"){
                s.pop();
            }else if(ops[i]=="D"){
                int c = s.top();
                s.push(2*c);
            }else{
                //牢记将string转换成int的方法!
                s.push(stoi(ops[i]));
            }
        }
        int ans = 0;
        while(!s.empty()){
            ans+=s.top();
            s.pop();
        }
        return ans;
    }

 

LeetCode496.下一个更大的元素I

感觉不用用栈就可以做啊

官方题解用单调栈+hashmap,有点小题大做了

class Solution {
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
        vector<int> v;
        for(int i=0;i<nums1.size();i++){
            bool flag = true;
            for(int j = 0;j<nums2.size();j++)
                if(nums2[j]==nums1[i])
                    for(int k = j+1;k<nums2.size();k++)
                        if(nums2[k]>nums1[i]){
                            v.push_back(nums2[k]);
                            flag = false;
                            break;
                        }
            if(flag)
                v.push_back(-1);
        }
        return v;
    }
};
 
————————————————

 

 

 

 

维护一个单调递减的栈。

Leetcode 42:接雨水(超详细的解法!!!)

function countSubArray(nums) {
  let ans = 0;
  let pre = 0;
  for (_ in nums) {
    pre += 1;
    ans += pre;
  }
  return ans;
}
复制代码

Leetcode 496:下一个更大元素 I(超详细的解法!!!)

function countSubArray(nums) {
  let ans = 0;
  let pre = 0;
  for (_ in nums) {
    pre += 1;
    ans += pre;
  }
  return ans;
}
复制代码

Leetcode 503:下一个更大元素 II(超详细的解法!!!)

function countSubArray(nums) {
  let ans = 0;
  let pre = 0;
  for (_ in nums) {
    pre += 1;
    ans += pre;
  }
  return ans;
}
复制代码

Leetcode 739:每日温度(超详细的解法!!!)

function countSubArray(nums) {
  let ans = 0;
  let pre = 0;
  for (_ in nums) {
    pre += 1;
    ans += pre;
  }
  return ans;
}
复制代码

1006. 笨阶乘

function countSubArray(nums) {
  let ans = 0;
  let pre = 0;
  for (_ in nums) {
    pre += 1;
    ans += pre;
  }
  return ans;
}
复制代码

32. 最长有效括号

function countSubArray(nums) {
  let ans = 0;
  let pre = 0;
  for (_ in nums) {
    pre += 1;
    ans += pre;
  }
  return ans;
}
复制代码

224. 基本计算器」、

 

227. 基本计算器 II

 

 

 

leetcode42 接雨水

 

 

 

 

class Solution {
    public int trap(int[] height) {
        if(height==null||height.length==0){
            return 0;
        }
        int result=0;
        Deque<Integer> stack=new LinkedList<Integer>();
        for(int i=0;i<height.length;i++){
            int curHeight=height[i];
            if(stack.isEmpty()){
                stack.push(i);
            }else{

                while(!stack.isEmpty()&&curHeight>height[stack.peek()]){
                    //当出现升高的柱子之后,低位柱子最右边的索引
                    int rightIndex=stack.pop();
                    if(stack.isEmpty()){
                        break;
                    }
                    //最右边柱子的左边柱子可能之前已经被计算掉了一些,需要用左边未计算的第一个柱子计算
                    //例如[4,2,0,3,2,5]  3时已经把之前2 0 就算,5时先把2计算,之后应该从4开始计算高度3的量
                    int leftIndex=stack.peek();
                    result+=(Math.min(curHeight,height[leftIndex])-height[rightIndex])*(i-leftIndex-1);
                }
                stack.push(i);
            }

        }
        return result;

    }
}

19. 删除链表的倒数第 N 个结点

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    // public ListNode removeNthFromEnd(ListNode head, int n) {
    //     Deque<ListNode> stack=new LinkedList<ListNode>();
    //     ListNode tempNode=new ListNode(0,head);
    //     ListNode curNode=tempNode;
    //    while(curNode!=null){
    //        stack.push(curNode);
    //        curNode=curNode.next;
    //    }
    //    while(n>0){
    //        stack.pop();
    //        n--;
    //    }
    //     if(stack.isEmpty()){
    //         return null;
    //     }else{
    //         stack.peek().next=stack.peek().next.next;
    //     }
    //     return tempNode.next;

    // }


        public ListNode removeNthFromEnd(ListNode head, int n) {
        if(head==null||head.next==null){
            return null;
        }
        ListNode fast=head,slow=head;
        while(n>0&&fast!=null){
            fast=fast.next;
            n--;
        }
        if(fast==null&&n==0){
            return head.next;
        }
        if(fast==null&&n>0){
            return null;
        }
        while(fast!=null&&fast.next!=null){
            fast=fast.next;
            slow=slow.next;
        }
        if(slow.next!=null){
            slow.next=slow.next.next;
        }
        return head;


    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值