leetcode刷题笔记 2021-01-25

题目155.最小栈

  • class MinStack {
        Deque<Integer> xstack;
        Deque<Integer> minStack;
        /** initialize your data structure here. */
        public MinStack() {
            xstack=new LinkedList<Integer>();
            minStack=new LinkedList<Integer>();
            minStack.push(Integer.MAX_VALUE);//缺少这行代码会报空指针错。
            //原因是:pop()、top()、getMin()操作总是在非空栈上调用,栈不能空,所以在初始化的时候提前加了一个最大值。
        }
        
        public void push(int x) {
            xstack.push(x);
            minStack.push(Math.min(minStack.peek(),x));
        }
        
        public void pop() {
            xstack.pop();
            minStack.pop();
        }
        
        public int top() {
            return xstack.peek();
        }
        
        public int getMin() {
            return minStack.peek();
        }
    }
    
    /**
     * 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();
     */
    

题目225.用队列实现栈

  • class MyStack {
        //两个队列实现
        /*Queue<Integer> queue1;
        Queue<Integer> queue2;
        /** Initialize your data structure here. */
        /*public MyStack() {
            queue1=new LinkedList<Integer>();
            queue2=new LinkedList<Integer>();
        }
        
        /** Push element x onto stack. */
        /*public void push(int x) {
            queue2.offer(x);
            //if(queue1.isEmpty()){//queue1里面元素不止一个,应用循环。
            while(!queue1.isEmpty()){
                queue2.offer(queue1.poll());
            }
    
            Queue<Integer> temp=queue2;
            queue2=queue1;
            queue1=temp;
        }
        
        /** Removes the element on top of the stack and returns that element. */
        /*public int pop() {
            int b=queue1.peek();
            queue1.poll();
            return b;
        }
        
        /** Get the top element. */
       /* public int top() {
            
            return queue1.peek();
        }
        
        /** Returns whether the stack is empty. */
       /* public boolean empty() {
            return queue1.isEmpty();
        }*/
    
        //一个队列实现
            /** Initialize your data structure here. */
        Queue<Integer> queue;
        public MyStack() {
            queue=new LinkedList<Integer>();
           
        }
        
        /** Push element x onto stack. */
        public void push(int x) {
            int n=queue.size();
            queue.offer(x);
            for(int i=0;i<n;i++){
                queue.offer(queue.poll());
            }
        }
        
        /** Removes the element on top of the stack and returns that element. */
        public int pop() {
    
            return queue.poll();
        }
        
        /** Get the top element. */
        public int top() {
            return queue.peek();
        }
        
        /** Returns whether the stack is empty. */
        public boolean empty() {
            return queue.isEmpty();
        }
    
    }
    
    /**
     * Your MyStack object will be instantiated and called as such:
     * MyStack obj = new MyStack();
     * obj.push(x);
     * int param_2 = obj.pop();
     * int param_3 = obj.top();
     * boolean param_4 = obj.empty();
     */
    

题目232.用栈实现队列

  • class MyQueue {
        Deque<Integer> stack1;
        Deque<Integer> stack2;
        int front;
        /** Initialize your data structure here. */
        public MyQueue() {
            stack1=new LinkedList<Integer>();
            stack2=new LinkedList<Integer>();
    
        }
    
    
        
        /* Push element x to the back of queue. */
        public void push(int x) {
            //解法一
           /* while(!stack1.isEmpty()){
                stack2.push(stack1.pop());
            }
            stack1.push(x);
            while(!stack2.isEmpty()){
                stack1.push(stack2.pop());
            }*/
    
            //解法二
            if(stack1.isEmpty()){
                front=x;
            }
            stack1.push(x);
    
    
        }
        
        /** Removes the element from in front of queue and returns that element. */
        public int pop() {
            //解法一
            //return stack1.pop();
    
            //解法二
            if(stack2.isEmpty()){
                while(!stack1.isEmpty()){
                    stack2.push(stack1.pop());
                }
            }
            return stack2.pop();
        } 
        
        /** Get the front element. */
        public int peek() {
            //解法一:return stack1.peek();
            //解法二:
            if(stack2.isEmpty()){
                return front;
            }else{
                return stack2.peek();
            }
        }
        
        /** Returns whether the queue is empty. */
        public boolean empty() {
            //解法一:return stack1.isEmpty();
            //解法二:
            return stack2.isEmpty()&&stack1.isEmpty();
        }
    }
    
    /**
     * 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();
     * boolean param_4 = obj.empty();
     */
    

题目493.下一个更大元素

  • 单调栈+哈希map

  • //本人解法
    class Solution {
        public int[] nextGreaterElement(int[] nums1, int[] nums2) {
            Deque<Integer> stack=new LinkedList<Integer>();
            Map<Integer,Integer> map=new HashMap<Integer,Integer>();
            int ans[]=new int[nums1.length];
            for(int i=0;i<nums2.length;i++){
            while((!stack.isEmpty())&&nums2[i]>stack.peek()){
                
                map.put(stack.pop(),nums2[i]);
            }
            stack.push(nums2[i]);
            }
            for(int i=0;i<nums1.length;i++){
                if(map.containsKey(nums1[i])){
                     ans[i]=map.get(nums1[i]);
                }else{
                    ans[i]= -1;
                }
            }
            return ans;
        }
    }
    
  • 
    class Solution {
        public int[] nextGreaterElement(int[] nums1, int[] nums2) {
            Deque<Integer> stack=new LinkedList<Integer>();
            Map<Integer,Integer> map=new HashMap<Integer,Integer>();
            int ans[]=new int[nums1.length];
            for(int i=0;i<nums2.length;i++){
            while((!stack.isEmpty())&&nums2[i]>stack.peek()){
                
                map.put(stack.pop(),nums2[i]);
            }
            stack.push(nums2[i]);
            }
            //本人用for()循环实现
            /*for(int i=0;i<nums1.length;i++){
                if(map.containsKey(nums1[i])){
                     ans[i]=map.get(nums1[i]);
                }else{
                    ans[i]= -1;
                }
            }*/
            //官方题解:
            while(!stack.isEmpty()){
                map.put(stack.pop(),-1);//栈中最后剩下的元素跟-1对应起来。
            }
            for(int i=0;i<nums1.length;i++){
                ans[i]=map.get(nums1[i]);
            }
            return ans;
        }
    }
    

题目682.棒球比赛

  • 首先想到用哈希map记录x,+,D,C分别对应得操作,但是不知如何实现对前面得分的操作。

  • 既然是栈这一节,考虑能不能用栈实现?

  • 突然想到能不能用递归?因为有些操作是对前次得分的操作,函数最后返回的是得分。但是递归结束条件不是很明显。

  • 将字符串入栈,x入栈,+把栈的元素弹出并且入栈(能够将前两次的值弹出加起来再分别入栈吗)(可以实现),c就把栈顶元素删除,D就取栈顶值2入栈。

  • class Solution {
        public int calPoints(String[] ops) {
            int ans=0;
            Deque<Integer> stack=new LinkedList<Integer>();
            for(int i=0;i<ops.length;i++){
               if(ops[i].equals("+")){
                   int a=stack.pop();
                   int b=stack.peek();
                   //int b=stack.pop();
                  // stack.push(b)
                   stack.push(a);
                   stack.push(a+b);
               }else if(ops[i].equals("D")){
                   stack.push(stack.peek()*2);
               }else if(ops[i].equals("C")){
                   stack.pop();
               }else{
                   stack.push(Integer.parseInt(ops[i]));
               }
            }
            while(!stack.isEmpty()){
                ans=stack.pop()+ans;
            }
    
            return ans;
        }
    }
    
  • 两个方法内存消耗差0.lMB,全国排名差了60%。

题目844.比较含退格的字符串

  • 本题需要先对字符串进行处理,之后再比较

  • 退格字符串左侧字母删掉

  • 需对字符串操作

  • 遍历字符串找到所有退格字符,将其左侧字符删掉。

  • 可考虑将字符串入栈,当遇到退格字符时,栈顶值pop。当栈为空遇到退格字符不操作。

  • 对两个栈中元素进行比较,循环出栈。

    class Solution {
        public boolean backspaceCompare(String S, String T) {
            //自己解法:
            /*Deque<Character> stack1=new LinkedList<Character>();
            Deque<Character> stack2=new LinkedList<Character>();
            for(int i=0;i<S.length();i++){
                if(S.charAt(i) == '#'&&(!stack1.isEmpty())){
                    stack1.pop();
                }else if(S.charAt(i) == '#'){
                    stack1.push(S.charAt(i));
                }else{
                    stack1.push(S.charAt(i));
                }
            }
            for(int i=0;i<T.length();i++){
                if(T.charAt(i) == '#'&&(!stack2.isEmpty())){
                    stack2.pop();
                }else if(T.charAt(i) == '#'){
                    stack2.push(T.charAt(i));
                }else{
                    stack2.push(T.charAt(i));
                }
            }
            while(!stack1.isEmpty()&&!stack2.isEmpty()){
                if(stack1.pop()!=stack2.pop()){
                    return false;
                }
            }
         return (stack1.isEmpty()||stack1.peek()=='#')&&(stack2.isEmpty()||stack2.peek()=='#');*/
         //官方解法:重构字符串
            return build(S).equals(build(T));
        }
                public String build(String str){
                StringBuffer ret=new StringBuffer();
                int length=str.length();
                for(int i=0;i<length;i++){
                    char ch=str.charAt(i);
                    if(ch!='#'){
                        ret.append(ch);
                    }else{
                        if(ret.length()>0){
                            ret.deleteCharAt(ret.length()-1);
                        }
                    }
                }
                return ret.toString();
            }
    }
    
  • /

    //双指针
    class Solution {
        public boolean backspaceCompare(String S, String T) {
            //自己解法:
            /*Deque<Character> stack1=new LinkedList<Character>();
            Deque<Character> stack2=new LinkedList<Character>();
            for(int i=0;i<S.length();i++){
                if(S.charAt(i) == '#'&&(!stack1.isEmpty())){
                    stack1.pop();
                }else if(S.charAt(i) == '#'){
                    stack1.push(S.charAt(i));
                }else{
                    stack1.push(S.charAt(i));
                }
            }
            for(int i=0;i<T.length();i++){
                if(T.charAt(i) == '#'&&(!stack2.isEmpty())){
                    stack2.pop();
                }else if(T.charAt(i) == '#'){
                    stack2.push(T.charAt(i));
                }else{
                    stack2.push(T.charAt(i));
                }
            }
            while(!stack1.isEmpty()&&!stack2.isEmpty()){
                if(stack1.pop()!=stack2.pop()){
                    return false;
                }
            }
         return (stack1.isEmpty()||stack1.peek()=='#')&&(stack2.isEmpty()||stack2.peek()=='#');*/
         //官方解法:
          /*  return build(S).equals(build(T));
        }
                public String build(String str){
                StringBuffer ret=new StringBuffer();
                int length=str.length();
                for(int i=0;i<length;i++){
                    char ch=str.charAt(i);
                    if(ch!='#'){
                        ret.append(ch);
                    }else{
                        if(ret.length()>0){
                            ret.deleteCharAt(ret.length()-1);
                        }
                    }
                }
                return ret.toString();*/
    
                //双指针:
                int i=S.length()-1,j=T.length()-1;
                int skipS=0,skipT=0;
                while(i>=0 || j>=0){//当两个字符串的指针都小于0退出循环
                    while(i>=0){//对字符串s处理,若是#则skipS加一,说明前面多一个被抵消的字符。
                        //若不是#且skipS>0说明是个需要删掉的字符。两者都不是则是需要保留的字符,跳出循环去跟另一个字串比较。
                        if(S.charAt(i)=='#'){
                            skipS++;
                            i--;
                        }else if(skipS>0){
                            skipS--;
                            i--;
                        }else{
                            break;
                        }
                    }
                    while(j>=0){
                        if(T.charAt(j)=='#'){
                            skipT++;
                            j--;
                        }else if(skipT>0){
                            skipT--;
                            j--;
                        }else{
                            break;
                        }
                    }
                    //判断条件:
                    //如果这个字符不相等,直接返回false
                    //如果这个字符只是一个字串有,另一个字串指针已经<0,则数目不匹配。
                    //这里之所以要排除return false而不是直接限定相等的情况,是因为这只是判断一个字符,即使判断出相等也无法返回true,相反判断出不相等可以直接返回false。
                    if(i>=0&&j>=0){
                        if(S.charAt(i)!=T.charAt(j)){
                            return false;
                        }
                    }else{
                        if(i>=0||j>=0){
                            return false;
                        }
                    }
                    i--;
                    j--;
                }
                return true;//当两个字符都遍历完之后,若还是不不相等,则返回true。
    
            }
    }
    
    • 双指针解法时间复杂度O(N+M),空间复杂度O(1)。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值