【面试算法题总结04】栈与队列数据结构

栈与队列数据结构:

 

例题1:用队列实现栈

解法1:双队列的题解思路

主要是一个push就调换一下队列。

class MyStack {
    Queue<Integer> queue1;
    Queue<Integer> queue2;
    /** Initialize your data structure here. */
    public MyStack() {
        queue1=new LinkedList<>();
        queue2=new LinkedList<>();
    }
    
    /** Push element x onto stack. */
    public void push(int x) {
        queue2.offer(x);
        while(!queue1.isEmpty()){
            queue2.offer(queue1.poll());
        }
        Queue<Integer> temporary=new LinkedList<>();
        temporary=queue1;
        queue1=queue2;
        queue2=temporary;
    }
    
    /** Removes the element on top of the stack and returns that element. */
    public int pop() {
        return queue1.poll();
    }
    
    /** 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();
 */
解法2:单队列的题解思路:
class MyStack {
    Queue<Integer> queue;
    /** Initialize your data structure here. */
    public MyStack() {
        queue = new LinkedList<Integer>();
    }
    
    /** Push element x onto stack. */
    public void push(int x) {
        int size=queue.size();
        queue.offer(x);
        for(int i=0;i<size;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();
 */

例题2:用栈实现队列

解法1:

class MyQueue {
    Stack<Integer> s1;
    Stack<Integer> s2;
    /** Initialize your data structure here. */
    public MyQueue() {
        s1=new Stack<>();
        s2=new Stack<>();
    }
    
    /** Push element x to the back of queue. */
    public void push(int x) {
        while (!s1.isEmpty())
            s2.push(s1.pop());
        s2.push(x);
        while (!s2.isEmpty())
            s1.push(s2.pop());
    }
    
    /** Removes the element from in front of queue and returns that element. */
    public int pop() {
        return s1.pop();
    }
    
    /** Get the front element. */
    public int peek() {
        return s1.peek();
    }
    
    /** Returns whether the queue is empty. */
    public boolean empty() {
        return s1.empty();
    }
}

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

解法2:

class CQueue {
    Stack<Integer> stack1;
    Stack<Integer> stack2;
    public CQueue() {
        stack1=new Stack<>();
        stack2=new Stack<>();
    }
    
    public void appendTail(int value) {
        stack1.push(value);
    }
    
    public int deleteHead() {
        if(stack2.empty()){
            while(!stack1.empty()){
                int temp=stack1.pop();
                stack2.push(temp);
            }
        }
        if(stack2.size()==0){
            return -1;
        }else{
            return stack2.pop();
        }
    }
}

/**
 * Your CQueue object will be instantiated and called as such:
 * CQueue obj = new CQueue();
 * obj.appendTail(value);
 * int param_2 = obj.deleteHead();
 */

 

例题3:每日温度

解法1:遍历+跳跃

class Solution {
    public int[] dailyTemperatures(int[] temperatures) {
        int n=temperatures.length;
        int[] result=new int[n];
        for(int i=n-2;i>=0;--i){
            for(int j=i+1;j<n;j+=result[j]){
                if(temperatures[i]<temperatures[j]){
                    result[i]=j-i;
                    break;
                }
                if(result[j]==0){
                    result[i]=0;
                    break;
                }
            }
        }
        return result;
    }
}

解法2:栈

class Solution {
    public int[] dailyTemperatures(int[] temperatures) {
        int n=temperatures.length;
        int[] result=new int[n];
        Stack<Integer> stack=new Stack<>();
        for(int i=0;i<n;++i){
            while(!stack.isEmpty()&&temperatures[stack.peek()]<temperatures[i]){
                int prevIndex=stack.pop();
                result[prevIndex]=i-prevIndex;
            }
            stack.push(i);
        }
        return result;
    }
}

 

例题4:包含min函数的栈

class MinStack {
    Stack<Integer> stack;
    Stack<Integer> minStack;
    /** initialize your data structure here. */
    public MinStack() {
        stack=new Stack<>();
        minStack=new Stack<>();
    }
    
    public void push(int x) {
        stack.push(x);
        if(minStack.isEmpty()||minStack.peek()>x){
            minStack.push(x);
        }else{
            minStack.push(minStack.peek());
        }
        
    }
    
    public void pop() {
        stack.pop();
        minStack.pop();
    }
    
    public int top() {
        return stack.peek();
    }
    
    public int min() {
        return minStack.peek();
    }
}

 

例题5:栈的压入、弹出序列

class Solution {
    public boolean validateStackSequences(int[] pushed, int[] popped) {
        Stack<Integer> stack=new Stack<>();
        int pushedIndex=0,poppedIndex=0;
        while(poppedIndex<popped.length){
            while(stack.isEmpty()||stack.peek()!=popped[poppedIndex]){
                if(pushedIndex==pushed.length){
                    break;
                }
                stack.push(pushed[pushedIndex++]);    
            }
            if(stack.peek()!=popped[poppedIndex]){
                break;
            }
            stack.pop();
            ++poppedIndex;
        }
        if(stack.isEmpty()&&poppedIndex==popped.length){
            return true;
        }
        return false;
    }
}

 

例题6:有效的括号

class Solution {
    public boolean isValid(String s) {
        //初始化map
        Map<Character,Character> map=new HashMap<>();
        map.put(')','(');
        map.put('}','{');
        map.put(']','[');
        //逻辑开始
        Stack<Character> stack=new Stack<>();
        for(int i=0;i<s.length();++i){
            char ch=s.charAt(i);
            if(map.containsKey(ch)){    //ch为),},]的情况
                if(stack.isEmpty()||stack.peek()!=map.get(ch)){
                    return false;
                }
                stack.pop();
            }else{      //ch为(,{,[ 这两种情况
                stack.push(ch);
            }
        }
        return stack.isEmpty();
    }
}

 

例题7:简化路径

class Solution {
    public String simplifyPath(String path) {
        //根据/进行切分
        String[] strArr=path.split("/");
        //使用栈进行保存
        Stack<String> stack=new Stack<>();
        for(int i=0;i<strArr.length;++i){
            if(strArr[i].equals("..")&&!stack.isEmpty()){
                stack.pop();
            }else if(strArr[i].equals("..")||strArr[i].equals(".")||strArr[i].equals("")){
                continue;
            }else{
                stack.push(strArr[i]);
            }
        }
        //输出
        List<String> myList=new ArrayList<>();
        while(!stack.isEmpty()){
            myList.add(stack.pop());
        }
        StringBuilder strB=new StringBuilder();
        for(int i=myList.size()-1;i>=0;--i){
            strB.append("/");
            strB.append(myList.get(i));
        }
        return strB.length()==0?"/":strB.toString();
    }
}

 

例题8:柱状图中最大的矩形

class Solution {
    public int largestRectangleArea(int[] heights) {
        int n=heights.length;
        int[] left=new int[n];
        int[] right=new int[n];

        Stack<Integer> stack=new Stack<>();
        for(int i=0;i<n;++i){
            while(!stack.isEmpty()&&heights[stack.peek()]>=heights[i]){
                stack.pop();
            }
            left[i]=stack.isEmpty()?-1:stack.peek();        //注意这里填充的是-1
            stack.push(i);
        }
        stack.clear();
        for(int i=n-1;i>=0;--i){
            while(!stack.isEmpty()&&heights[stack.peek()]>=heights[i]){
                stack.pop();
            }
            right[i]=stack.isEmpty()?n:stack.peek();        //注意这里填充的是n
            stack.push(i);
        }

        int ans=0;
        for(int i=0;i<n;++i){
            ans=Math.max(ans,heights[i]*(right[i]-left[i]-1));
        }
        return ans;
    }
}


 

例题9:最大矩形

class Solution {
    public int maximalRectangle(char[][] matrix) {
        int n=matrix.length;
        if(n==0){
            return 0;
        }
        int m=matrix[0].length;

        //获得每个元素左侧连续1的个数
        int[][] left=new int[n][m];
        for(int i=0;i<n;++i){
            for(int j=0;j<m;++j){
                if(matrix[i][j]=='1'){
                    left[i][j]=(j==0?1:left[i][j-1]+1);
                }
            }
        }

        int result=0;
        for(int j=0;j<m;++j){

            //对于每一列使用“柱状图中最大的矩形”的单调栈方法
            int[] up=new int[n];
            int[] down=new int[n];
            Stack<Integer> stack=new Stack<>();
            for(int i=0;i<n;++i){
                while(!stack.isEmpty()&&left[stack.peek()][j]>=left[i][j]){
                    stack.pop();
                }
                up[i]=stack.isEmpty()?-1:stack.peek();
                stack.push(i);
            }
            stack.clear();
            for(int i=n-1;i>=0;--i){
                while(!stack.isEmpty()&&left[stack.peek()][j]>=left[i][j]){
                    stack.pop();
                }
                down[i]=stack.isEmpty()?n:stack.peek();
                stack.push(i);
            }
            for(int i=0;i<n;++i){
                int height=down[i]-up[i]-1;
                int areas=height*left[i][j];
                result=Math.max(result,areas);
            }

        }
        return result;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值