代码随想录打卡-栈与队列

栈与队列

232.用栈实现队列

方法:使用两个栈,一个输入栈,一个输出栈

其中需要注意的点是,在进行pop()和peek()操作时,要先判断stackOut空了,再把stackIn的数倒进去

代码实现为:

class MyQueue {
    //负责进栈
    Stack<Integer> stackIn;
    //负责出栈
    Stack<Integer> stackOut;
    public MyQueue() {
        stackIn = new Stack<>();
        stackOut = new Stack<>();
    }
    
    public void push(int x) {
        stackIn.push(x);
    }
    
    public int pop() {
        dumpStackIn();
        return stackOut.pop();
    }
    
    public int peek() {
        dumpStackIn();
       return stackOut.peek();
    }
    
    public boolean empty() {
        return stackOut.isEmpty() && stackIn.isEmpty();
    }

    private void dumpStackIn(){
        if(!stackOut.isEmpty()){
            return;
        }
        while(!stackIn.isEmpty()){
            stackOut.push(stackIn.pop());
        }
    }
}

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

225.用队列实现栈

添加元素:栈 - push()        队列 - push()插到队列开头   offer()插到队列末尾

查看元素:栈 - peek()        队列 - top()/peek()

移除元素: 栈 - pop()        队列 - poll()     确定队列不为空也可使用pop()

方法:使用两个Deque实现,其中一个作为辅助队列,另一个维护和栈中元素一样的队列

代码实现为:

class MyStack {
    //和栈中保持一样元素的队列
    Queue<Integer> queue1;
    //辅助队列
    Queue<Integer> queue2;
    public MyStack() {
        queue1 = new LinkedList<>();
        queue2 = new LinkedList<>();
    }
    
    public void push(int x) {
        queue2.offer(x);
        while(!queue1.isEmpty()){
            queue2.offer(queue1.poll());
        }
        //交换,元素都放到queue1中
        Queue tmpQueue = queue1;
        queue1 = queue2;
        queue2 = tmpQueue;
    }
    
    public int pop() {
        return queue1.poll();
    }
    
    public int top() {
        return queue1.peek();
    }
    
    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();
 */

20.有效的括号

注意,此处向栈中存入左括号,使用的是push(),因为要将其放在队列的开头

代码实现为:

class Solution {
    public boolean isValid(String s) {
        Map<Character,Character> hashmap = new HashMap<>();
        hashmap.put('[',']');
        hashmap.put('{','}');
        hashmap.put('(',')');
        Deque<Character> stack = new LinkedList<>();
    // Stack<Character> stack = new Stack<>();
    //一般来说,在Java中推荐使用Deque接口及其实现类来代替Stack类
    //因为Deque接口提供了更加灵活和现代化的栈操作方式,同时也避免了Stack类可能存在的一些问题。

        for(char c:s.toCharArray()){
            //遇到左括号,进栈
            if(hashmap.containsKey(c)){
                stack.push(c);
            }else{
                if(stack.isEmpty()){
                    return false;
                }else if(c!=hashmap.get(stack.peek())){
                    return false;
                }
                stack.pop();
            }
        }
        return stack.isEmpty();
    }
}

1047.删除字符串中所有相邻重复项

注意最后要把字符串反转

代码实现为:

class Solution {
    public String removeDuplicates(String s) {
        Deque<Character> stack = new LinkedList<>();
        for(char c:s.toCharArray()){
            if(stack.isEmpty() || c!=stack.peek()){
                stack.push(c);
            }else{
                stack.pop();
            }
        }
        StringBuilder sb = new StringBuilder();
        while(!stack.isEmpty()){
            sb.append(stack.pop());
        }
        return sb.reverse().toString();
    }
}

150.逆波兰表达式求值

注意:1、比较值是否相等使用equals()方法

          2、减法和除法注意特殊处理

代码实现为:

class Solution {
    public int evalRPN(String[] tokens) {
        Deque<Integer> stack = new LinkedList<>();
        for(String s:tokens){
            //注意减法和除法需要特殊处理!
            if(s.equals("+")){
            stack.push(stack.pop()+stack.pop());
            }else if(s.equals("-")){
                stack.push(-stack.pop()+stack.pop());
            }else if(s.equals("*")){
                stack.push(stack.pop()*stack.pop());
            }else if(s.equals("/")){
                int tmp1 = stack.pop();
                int tmp2 = stack.pop();
                stack.push(tmp2/tmp1);
            }else{
                stack.push(Integer.valueOf(s));
            }
        }
        return stack.pop();
    }
}

239.滑动窗口最大值

难点:自定义队列

代码实现为:

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        MyQueue myQueue = new MyQueue();
        int len = nums.length-k+1;
        int[] res = new int[len];
        int num = 0;
        for(int i = 0;i<k;i++){
            myQueue.add(nums[i]);
        }
        res[num++] = myQueue.peek();
        for(int i = k;i<nums.length;i++){
            //滑动窗口移除最前面的元素
            myQueue.poll(nums[i-k]);
            //滑动窗口加入最后面的元素
            myQueue.add(nums[i]);
            //记录对应的最大值
            res[num++] = myQueue.peek();
        }
        return res;
    }
}

//自定义数组
class MyQueue{
    Deque<Integer> deque = new LinkedList<>();

    //移除元素
    void poll(int val){
        //注意为if而不是while,因为只移除队列最左的一个数(滑动窗口移动)
        if(!deque.isEmpty() && val==deque.peek()){
            deque.poll();
        }
        }
    //添加元素
    //注意循环为while循环,因为要一直执行循环体,直到前面的数都比新加的数大为止
    void add(int val){
        while(!deque.isEmpty() && val>deque.getLast()){
            deque.removeLast();
        }
        deque.add(val);
    }
    //维护队列队顶元素为最大值
    int peek(){
        return deque.peek();
    }
    }

347.前K个高频元素

重点:使用优先级队列中的大顶堆

代码实现为:

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        Map<Integer,Integer> hashmap = new HashMap<>();
        for(int num:nums){
           hashmap.put(num,hashmap.getOrDefault(num,0)+1);
        }

        //使用大顶堆:1、默认为小顶堆,故要颠倒次序 2、利用第二个元素即出现次数进行排序
        //int[0]表示键,int[1]表示值
        PriorityQueue<int[]>pq = new PriorityQueue<>((pair1,pair2)->pair2[1]-pair1[1]);
        //遍历哈希表存储的键值对
        for(Map.Entry<Integer,Integer>entry:hashmap.entrySet()){
            pq.add(new int[]{entry.getKey(),entry.getValue()});
        }
        int[] res = new int[k];
        for(int i = 0;i<k;i++){
            res[i] = pq.poll()[0];
        }
        return res;
    }
}

  • 12
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值