• 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]);
            }
        }
    }
  • 相关阅读:
    高价格快消品终端制胜的七大“法宝”
    欧美零售商的全渠道实践
    如何做好IT项目启动阶段的管理
    项目进度管理的三大软技巧
    如何建立生鲜商品的组织结构和采购渠道
    生鲜关注点和注意点
    超市基本业务介绍
    chrome开发配置(四)生成项目及配置库引用
    chrome开发配置(三)安装开发工具
    chrome开发配置(二)获取源代码
  • 原文地址:https://www.cnblogs.com/errornull/p/9862709.html
Copyright © 2020-2023  润新知