LeetCode-C#实现-栈(#20/155/224/232/496/682/844)

20. Valid Parentheses

有效的括号

解题思路

将括号比较后者后,不同的入栈,相同的出栈,最后字符串遍历结束后栈为空则匹配成功。

public bool IsValid(string s) {
        //声明字典,括号匹配键值对
        Dictionary<char, char> dict = new Dictionary<char, char>();
        dict.Add(')', '(');
        dict.Add(']', '[');
        dict.Add('}', '{');
        Stack<char> stack = new Stack<char>();
        //遍历字符s,直到遍历s所有字符结束循环
        for (int i = 0; i < s.Length; i++)
        {
                //栈空则直接将下个字符入栈,结束本次循环
                if (stack.Count == 0)
                {
                        stack.Push(s[i]);
                        continue;
                }
                //获取字典中对应的括号,若和循环中s[i]相等则出栈,否则压入栈中
                char temp;
                dict.TryGetValue(s[i], out temp);
                if (stack.Peek() == temp)
                        stack.Pop();
                else
                        stack.Push(s[i]);
        }
        //遍历结束后若栈空,说明括号匹配
        if (stack.Count == 0)
                return true;
        else
                return false;
}

 

155. Min Stack

最小栈

解题思路

使用链栈,实现基本的入栈出栈,遍历栈中元素,同时比较其值,取其中最小,最后返回最小值。

public class MinStack {
    //结点类
    public class Node{
        public int val;
        public Node next;
        public Node(int item){
            val=item;
            next=null;
        }
        public Node(){
            val=0;
            next=null;
        }
    }
    //头结点指针和初始化
    Node head;
    /** initialize your data structure here. */
    public MinStack() {
        head=null;
    }
    //入栈方法,新入栈的结点成为head
    public void Push(int x) {
        if(head==null)
            head=new Node(x);
        Node p=new Node(x);
        p.next=head;
        head=p;
    }
    //出栈方法,head指向其后继结点
    public void Pop() {
        if(head==null)
            return;
        head=head.next;
    }
    //返回head的值
    public int Top() {
        return head.val;
    }
    //遍历链表,同时比较结点的值
    public int GetMin() {
        Node p=head;
        int minNum=int.MaxValue;
        while(p.next!=null){
            if(p.val<minNum){
                minNum=p.val;
            }
            p=p.next;
        }
        return minNum;
    }
}

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack obj = new MinStack();
 * obj.Push(x);
 * obj.Pop();
 * int param_3 = obj.Top();
 * int param_4 = obj.GetMin();
 */

224. Basic Calculator

基本计算器

解题思路

准备两个栈,一个存放数字,一个存放"+"、"-"和"(",遇到")"不用入栈,直接进行操作。

取出一个操作符计算一个数字,直到遇到"(",加上"()"里最后一个数字后将总数入栈,循环往复后最后的表达式时没有括号的。

然后再进行循环遍历操作符栈,将数字进行计算,返回总数。

其中需要注意入栈是一个个字符,而数字不会只是个位数,所以要标记操作符的数量。

只要数字数量超过操作符,再遇到新数字就将数字栈是栈顶元素取出,乘以10加上新数字后入栈。

public class Solution {
    public int Calculate(string s)
    {
        int sum = 0 ;
        //操作符栈和数字栈
        Stack<int> stackNum = new Stack<int>();
        Stack<string> stackOpe = new Stack<string>();
        //操作符的数量
        int opeNum=0;
        //遍历s
        for (int i = 0; i < s.Length; i++)
        {
            //空字符直接跳过
            if(s[i]==' ') continue;
            //遇到反括号开始计算括号里的数
            else if(s[i]==')'){
                //括号里的数的大小
                int num=0;
                while(true){
                    //遇到+、-计算符号执行对应操作
                    if(stackOpe.Peek()=="+"){
                        num+=stackNum.Pop();
                        stackOpe.Pop();
                        opeNum--;
                    }
                    else if(stackOpe.Peek()=="-"){
                        num-=stackNum.Pop();
                        stackOpe.Pop();
                        opeNum--;
                    }
                    //遇到开括号结束计算
                    else if(stackOpe.Peek()=="("){
                        num+=stackNum.Pop();
                        stackOpe.Pop();
                        stackNum.Push(num);
                        break;
                    }
                }
            }
            //如果是+、-、)就将其入栈
            else if(s[i]=='+'||s[i]=='-'||s[i]=='('){
                stackOpe.Push(s[i].ToString());
                //但只有+、-算作操作符数量
                if(s[i]=='+'||s[i]=='-')
                    opeNum++;
            }
            //如果不符合以上情形就是数字,入数字栈
            else{
                //如果数字栈中数字的数量大于操作符数量,说明这个字符和上一个字符是一个数字
                //取出栈顶元素*10后加上该数字后再入栈
                if(stackNum.Count-1>=opeNum)
                    stackNum.Push(stackNum.Pop()*10+Convert.ToInt32(s[i].ToString()));
                else
                    stackNum.Push(Convert.ToInt32(s[i].ToString()));
            }       
        }
        //以操作符的数量为长度遍历
        int length=stackOpe.Count;
        for(int i=0;i<length;i++){
            //遇到+、-执行对应操作,这时整个表达式没有括号了
            if(stackOpe.Peek()=="+"){
                sum+=stackNum.Pop();
                stackOpe.Pop();
            }
            else if(stackOpe.Peek()=="-"){
                sum-=stackNum.Pop();
                stackOpe.Pop();
            }
        }
        //加上栈中最后一个数字得到结果
        sum+=stackNum.Peek();
        return sum;
    }
}

232. Implement Queue using Stacks

用栈实现队列

解题思路

用栈2接收栈1push出的数据,将栈2的栈顶元素记录后,再把栈2push回栈1

public class MyQueue {
    Stack<int> stack = new Stack<int>();
    /** Initialize your data structure here. */
    public MyQueue(){}
    /** Push element x to the back of queue. */
    public void Push(int x){
        stack.Push(x);
    }
    /** Removes the element from in front of queue and returns that element. */
    public int Pop() {
        //声明一个新的栈2,记录栈1的长度
        Stack<int> stack2 = new Stack<int>();
        int length = stack.Count;
        //将栈1push到栈2中
        for (int i = 0; i < length; i++)
            stack2.Push(stack.Pop());
        //栈2执行pop操作就相当于栈1出队。
        int temp = stack2.Pop();
        //再将栈2push到栈1中
        for (int i = 0; i < length-1; i++)
            stack.Push(stack2.Pop());
        return temp;
    }
    /** Get the front element. */
    public int Peek() {
        //peek的操作和pop的区别在于不移除栈顶元素,length不需要减一
        Stack<int> stack2 = new Stack<int>();
        int length = stack.Count;
        for(int i = 0; i < length; i++)
            stack2.Push(stack.Pop());
        int temp = stack2.Peek();
        for (int i = 0; i < length; i++)
            stack.Push(stack2.Pop());
        return temp;
    }

    /** Returns whether the queue is empty. */
    public bool Empty() {
        return stack.Count == 0;
    }
}

/**
 * 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();
 */

496. Next Greater Element I

下一个最大元素Ⅰ

解题思路

每次比较子数组元素在nums中时,都要新声明一个栈进行操作,这个栈否则只能操作一次

public class Solution {
    public int[] NextGreaterElement(int[] findNums, int[] nums) {
        int[] put = new int[findNums.Length];
        Stack<int> stack = new Stack<int>();
        //将nums2倒序入栈
        for (int i = nums.Length - 1; i >= 0; i--)
            stack.Push(nums[i]);
        //遍历nums1的元素
        for (int i = 0; i < findNums.Length; i++)
            put[i] = CheckItem(findNums[i], nums);
        return put;
    }
    public int CheckItem(int item, int[] nums) {
        //新建一份临时的nums的栈
        Stack<int> temp = new Stack<int>();
        for (int i = nums.Length - 1; i >= 0; i--) {
            temp.Push(nums[i]);
        }
        //循环直到栈中为空或找到符合条件的元素
        while (true) {
            //找到元素在nums的位置
            if (temp.Peek() == item) {
                //循环直到栈空或找到符合条件的元素
                while (true) {
                    if (temp.Peek() > item) return temp.Peek();
                    else temp.Pop();
                    if (temp.Count == 0) break;
                }
            }
            else temp.Pop();
            if (temp.Count == 0) break;
        }
        return -1;
    }
}

 

682. Baseball Game

棒球比赛

解题思路

对字符分别处理,每轮分数入栈,最后再把栈中元素相加,f若把or循环中if语句改写成switch后性能下降。

public class Solution {
    public int CalPoints(string[] ops) {
        Stack<int> stack = new Stack<int>();
        int sum = 0;
        //遍历字符串
        for (int i = 0; i < ops.Length; i++) {
            //针对C、D、+等情况进行操作
            if (ops[i] == "C") stack.Pop();
            else if (ops[i] == "D") stack.Push(stack.Peek() * 2);
            else if (ops[i] == "+") {
                //记录移除并记录栈顶元素
                int pre = stack.Pop();
                //记录此时的栈顶元素
                int prepre = stack.Peek();
                //将移除的元素入栈
                stack.Push(pre);
                //将和入栈
                stack.Push(pre + prepre);
            }
            //将分数入栈
            else stack.Push(Convert.ToInt32(ops[i]));
        }
        //记录栈的数据数量,遍历取出计算总和
        int length = stack.Count;
        for (int i = 0; i < length; i++)
            sum += stack.Pop();
        return sum;
    }
}

844. Backspace String Compare

比较含退格符的字符串

解题思路

注意遇到#时,栈执行移除栈顶操作,但若栈中无元素,不能执行移除操作,也不能把#入栈,其他情况都依次入栈。

然后比较两字符串的栈,其中一个空就跳出循环,若另一个也空就说明相等,否则不相等。

如果两栈移除的元素比较不相等,直接返回false。

public class Solution {
    public bool BackspaceCompare(string S, string T)
    {
        Stack<int> stack1 = new Stack<int>();
        Stack<int> stack2 = new Stack<int>();
        //将S、T两个字符串用栈处理退格符
        PopBackspace(stack1, S);
        PopBackspace(stack2, T);
        while (true)
        {
            //两栈有一个空的就跳出循环,如果有一个没空说明字符串不相等
            if (stack1.Count == 0 || stack2.Count == 0) break;
            //两栈移除栈顶元素并做比较,如果有一次不等就说明字符串不相等
            if (stack1.Pop() != stack2.Pop()) return false;
        }
        return stack1.Count==0&&stack2.Count==0;
    }
    public void PopBackspace(Stack<int> stack, string N)
    {
        for (int i = 0; i < N.Length; i++)
        {
            //遇到#时移除栈顶元素,但栈不能为空否则报错栈空
            if (N[i] == '#' && stack.Count != 0) stack.Pop();
            //栈空时遇到了#结束不做任何操作,否则将#入栈了,错误
            else if (N[i] == '#') continue;
            //除以上情况都入栈
            else stack.Push(N[i]);
        }
    }
}
原文地址:https://www.cnblogs.com/errornull/p/9862709.html