题目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)。