栈实现队列很简单,在一个栈中压入,另一个栈负责弹出
push():只需要将元素压入栈1,时间复杂度是O(n)
pop():当栈2为空的时候将栈1中的元素全部弹出压入栈2.否则直接从栈2弹出即可
empty():两栈全部为空
class MyQueue {
private Stack<Integer> stack1;
private Stack<Integer> stack2;
/** Initialize your data structure here. */
public MyQueue() {
stack1 = new Stack<>();
stack2 = new Stack<>();
}
/** Push element x to the back of queue. */
public void push(int x) {
stack1.add(x);
}
/** Removes the element from in front of queue and returns that element. */
public int pop() {
if(stack2.isEmpty()){
while(!stack1.isEmpty()){
stack2.add(stack1.pop());
}
}
return stack2.pop();
}
/** Get the front element. */
public int peek() {
if(stack2.isEmpty()){
while(!stack1.isEmpty()){
stack2.add(stack1.pop());
}
}
return stack2.peek();
}
/** Returns whether the queue is empty. */
public boolean empty() {
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();
*/
1. 使用两个队列来实现,当要弹出元素的时候,将一个队列的除最后一个元素外的全部元素弹出压入另一个队列。
push()时间复杂度是O(1)
pop()时间复杂度是O(n)
2. 可以使用一个队列实现,当压入元素的时候将它压入,然后将除他以外的所有元素弹出重新压入到队列中
push()时间复杂度是O(n)
pop()时间复杂度是O(1)
class MyStack {
Queue<Integer> queue1;
/** Initialize your data structure here. */
public MyStack() {
queue1 = new LinkedList<>();
}
/** Removes the element on top of the stack and returns that element. */
public int pop() {
return queue1.poll();
}
public void push(int x){
queue1.add(x);
int c = queue1.size();
while(c > 1){
queue1.add(queue1.poll());
c--;
}
}
/** Get the top element. */
public int top() {
return queue1.peek();
}
/** Returns whether the stack is empty. */
public boolean empty() {
return queue1.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();
*/
思路:需要两个栈,一个栈存储源数据,另一个栈存储最小值,需要弹出的时候,二者同时pop()
class MinStack {
Stack<Integer> stack1;
Stack<Integer> min;
/** initialize your data structure here. */
public MinStack() {
stack1 = new Stack<Integer>();
min = new Stack<Integer>();
}
public void push(int x) {
stack1.add(x);
if(min.isEmpty() || x < min.peek()){
min.add(x);
}else{
min.add(min.peek());
}
}
public void pop() {
stack1.pop();
min.pop();
}
public int top() {
return stack1.peek();
}
public int getMin() {
return min.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();
*/
思考:
这道题我没想起来怎么写,太菜了
总结思路:
遍历一次,遇到开括号的时候,把它压到栈中,遇到闭括号的时候,从栈中弹出开括号,看二者是否匹配。
class Solution {
public boolean isValid(String s) {
//扫描的时候遇到开括号将开括号压入栈中,遇到闭括号,查看栈顶的值是否是与之对应的闭括号
if(s.length()%2 != 0){
return false;
}
Stack<Character> stack = new Stack<>();
for(int i = 0;i < s.length();i++){
char c = s.charAt(i);
if(c == '(' || c == '[' || c == '{'){
stack.add(c);
continue;
}
if(stack.isEmpty()){
return false;
}
switch(c){
case ']':
if(stack.peek() == '['){
stack.pop();
}else{
return false;
}
break;
case '}':
if(stack.peek() == '{'){
stack.pop();
}else{
return false;
}
break;
case ')':
if(stack.peek() == '('){
stack.pop();
}else{
return false;
}
break;
}
}
return stack.isEmpty();
}
}
数组中元素与下一个比它大的元素之间的距离
LeetCode739.每日温度
思路:O(N)的做法,逆序遍历数组列表,将他们放入栈中,如果当前元素比栈顶元素大,就把栈顶元素弹出,保证栈是单调的
class Solution {
public int[] dailyTemperatures(int[] T) {
Stack<Integer> stack = new Stack<>();
int[] ans = new int[T.length];
for(int i = T.length - 1;i >= 0;i--){
while(!stack.isEmpty() && T[i] >= T[stack.peek()]){
stack.pop();
}
if(!stack.isEmpty()){
ans[i] = stack.peek()-i;
}
stack.add(i);
}
return ans;
}
}
循环数组中比当前元素大的下一个元素
LeetCode503
这个很简单,就是将上题的操作执行两次,遍历两遍数组元素,入栈
class Solution {
public int[] nextGreaterElements(int[] nums) {
Stack<Integer> stack = new Stack<>();
int[] ans = new int[nums.length];
Arrays.fill(ans,-1);
for(int i = nums.length-1;i >= 0;i--){
while(!stack.isEmpty() && nums[i] >= stack.peek()){
stack.pop();
}
if(!stack.isEmpty()){
ans[i] = stack.peek();
// System.out.println("ans:"+ans[i]);
}
stack.add(nums[i]);
}
for(int i = nums.length-1;i >= 0;i--){
while(!stack.isEmpty() && nums[i] >= stack.peek()){
stack.pop();
}
if(!stack.isEmpty()){
ans[i] = stack.peek();
}
stack.add(nums[i]);
}
return ans;
}
}