leetcode打卡-栈和队列

文章展示了如何使用栈和队列实现彼此的功能,如用队列实现栈,用栈实现队列,并提供了LeetCode上的相关问题解决方案,包括括号的有效性检查、逆波兰表达式求值等典型算法问题。
摘要由CSDN通过智能技术生成

目录

225. 用队列实现栈

232. 用栈实现队列

20. 有效的括号

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

150. 逆波兰表达式求值

239. 滑动窗口最大值

451. 根据字符出现频率排序

215. 数组中的第K个最大元素

347. 前 K 个高频元素


225. 用队列实现栈

        leetcode题目链接: https://leetcode.cn/problems/implement-stack-using-queues
        leetcode AC记录:

        思路:使用两个队列q1和q2,入栈操作:先把q1的元素都放到q2,然后把新入队的元素放到q1,再把q2的所有元素放到q1。 出栈操作:q1的元素出队。

        代码如下:

class MyStack {

    public Queue<Integer> queue1 = new LinkedList<>();

    public Queue<Integer> queue2 = new LinkedList<>();

    public MyStack() {

    }
    
    public void push(int x) {
        while(!queue1.isEmpty()) {
            queue2.offer(queue1.poll());
        }

        queue1.offer(x);
        while(!queue2.isEmpty()) {
            queue1.offer(queue2.poll());
        }
    }
    
    public int pop() {
        return queue1.poll();
    }
    
    public int top() {
        return queue1.peek();
    }
    
    public boolean empty() {
        return queue1.isEmpty();
    }
}

232. 用栈实现队列

        leetcode题目链接: https://leetcode.cn/problems/implement-queue-using-stacks
        leetcode AC记录:

        思路:使用两个栈s1和s2,入队操作:先把s1的元素都放到s2,然后把新入栈的元素放到s1,再把s2的所有元素放到s1。 出队操作:s1的元素出栈。

        代码如下:
class MyQueue {

    public Stack<Integer> stack1 = new Stack<>();

    public Stack<Integer> stack2 = new Stack<>();

    public MyQueue() {

    }
    
    public void push(int x) {
        while(!stack1.empty()) {
            stack2.push(stack1.pop());
        }

        stack1.push(x);
        while(!stack2.empty()) {
            stack1.push(stack2.pop());
        }

    }
    
    public int pop() {
        return stack1.pop();
    }
    
    public int peek() {
        return stack1.peek();
    }
    
    public boolean empty() {
        return stack1.empty();
    }
}

20. 有效的括号

        leetcode题目链接:https://leetcode.cn/problems/valid-parentheses

        leetcode AC记录:

        思路:使用栈解决。遇到左括号"("、"{"、"["进栈, 遇到右括号")"、"}"、"]"取栈顶元素进行匹配,如果不匹配,比如"}",栈顶元素为"{"是匹配的,否则不匹配。最后判断栈是否为空。

        代码如下:

public boolean isValid(String s) {
        Stack<Character> stack = new Stack<>();
        for(int i = 0;i < s.length();i++) {
            if(s.charAt(i) == '(' || s.charAt(i) == '[' || s.charAt(i) == '{') {
                stack.push(s.charAt(i));
            } else {
                if(stack.empty()) {
                    return false;
                }
                char c = stack.pop();
                if(c == '[' && s.charAt(i) != ']') {
                    return false;
                } else if(c == '(' && s.charAt(i) != ')') {
                    return false;
                } else if(c == '{' && s.charAt(i) != '}') {
                    return false;
                } 
            }
        }

        return stack.empty();
    }

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

        leetcode题目链接:https://leetcode.cn/problems/remove-all-adjacent-duplicates-in-string

        leetcode AC记录:

         思路:使用双向队列解决。遍历字符串,如果队列不为空并且队列尾部元素和当前字符相等,从队尾出队。如果不相等,队尾入队。遍历结束将双向队列元素输出即可。

        代码如下:

class Solution {
    public String removeDuplicates(String s) {
        Deque<Character> queue = new LinkedList<>();

        for(int i = 0;i < s.length();i++) {
            if(!queue.isEmpty() && queue.getLast() == s.charAt(i)) {
                queue.pollLast();
            } else {
                queue.offer(s.charAt(i));
            }
        }

        StringBuilder sb = new StringBuilder();
        while(!queue.isEmpty()) {
            sb.append(queue.poll());
        }

        return sb.toString();
    }
}

150. 逆波兰表达式求值

        leetcode题目链接:https://leetcode.cn/problems/evaluate-reverse-polish-notation

        leetcode AC记录:

        思路:使用栈解决。遇到符号+-*/,取两次栈顶元素a1和a2,进行运算后将结果a3入栈,直到结束,栈顶元素即为所求结果。

        代码如下:        

public int evalRPN(String[] tokens) {
        Stack<String> stack = new Stack<>();

        for(int i = 0;i < tokens.length;i++) {
            if(tokens[i].equals("+") || tokens[i].equals("-") || tokens[i].equals("*") || tokens[i].equals("/")) {
                int num1 = Integer.parseInt(stack.pop());
                int num2 = Integer.parseInt(stack.pop());
                if(tokens[i].equals("+")) {
                    stack.push(String.valueOf(num2 + num1));
                } else if(tokens[i].equals("-")) {
                    stack.push(String.valueOf(num2 - num1));
                } else if(tokens[i].equals("*")) {
                    stack.push(String.valueOf(num2 * num1));
                } else if(tokens[i].equals("/")) {
                    stack.push(String.valueOf(num2 / num1));
                }
            } else {
                stack.push(tokens[i]);
            }
        }

        return Integer.parseInt(stack.pop());
    }

239. 滑动窗口最大值

        leetcode题目链接:https://leetcode.cn/problems/sliding-window-maximum

        leetcode AC记录:

        思路:使用单调队列,保证队列中都是有可能成为最大值的元素。 遍历数组,如果单调队列是空的,nums[i]入队;如果不为空,将单调队列中从尾部开始小于当前元素nums[i]的值出队,把nums[i]入队。如果下标i+1大于等于窗口值k,取队首元素放入结果集中,如果窗口移动,nums[i-k+1]和队首元素相同,队首元素出队。

        代码如下:

 public int[] maxSlidingWindow(int[] nums, int k) {
        int[] res = new int[nums.length - k + 1];
        int index = 0;
        Deque<Integer> queue = new LinkedList<>();
        for(int i = 0;i < nums.length;i++) {
            
            this.push(queue, nums[i]);

            if(i >= k && nums[i-k] == queue.peek()) {
                queue.poll();
            }
            
            if(i + 1 >= k) {
                res[index++] = queue.peek();
            }
        }
        return res;
    }


    /**
     * 单调队列
     */
    public void push(Deque<Integer> queue, int k) {
        while(!queue.isEmpty() && queue.getLast() < k) {
            queue.pollLast();
        }

        if(queue.isEmpty() || queue.getLast() >= k) {
            queue.offer(k);
        }
    }

451. 根据字符出现频率排序

        leetcode题目链接:https://leetcode.cn/problems/sort-characters-by-frequency

        leetcode AC记录:

        思路:使用字典记录字符出现的频次。遍历字典,使用大顶堆进行排序。最后对大顶堆进行出栈并连接字符得到最后结果。

        代码如下:

 public String frequencySort(String s) {
        Map<Character, Integer> map = new HashMap<>();
        for(int i = 0;i < s.length();i++) {
            map.put(s.charAt(i), map.getOrDefault(s.charAt(i), 0) + 1);
        }

        PriorityQueue<Character> queue = new PriorityQueue<>(new Comparator<Character>() {
            @Override
            public int compare(Character o1, Character o2) {
                return map.get(o2) - map.get(o1);
            }
        });

        for (Character c : map.keySet()) {
            queue.offer(c);
        }



        StringBuilder sb = new StringBuilder();
        while(!queue.isEmpty()) {
            char c = queue.poll();
            int count = map.get(c);
            while(count-- > 0) {
                sb.append(c);
            }
        }
        return sb.toString();
    }

215. 数组中的第K个最大元素

        leetcode题目链接:https://leetcode.cn/problems/kth-largest-element-in-an-array

        leetcode AC记录:

        思路:使用大小为k的小顶堆优先队列。遍历数组,如果优先队列长度超过k,出队。否则入队,最后队顶元素即为结果。

        代码如下:

public int findKthLargest(int[] nums, int k) {
        PriorityQueue<Integer> queue = new PriorityQueue<>();
        for(int i = 0; i < nums.length;i++) {
            if(queue.size() <= k) {
                queue.offer(nums[i]);
            } 
            
            if(queue.size() > k) {
                queue.poll();
            }
        }

        return queue.poll();
    }

347. 前 K 个高频元素

        leetcode题目链接:https://leetcode.cn/problems/top-k-frequent-elements

        leetcode AC记录:

        思路:使用map记录字符出现的次数。遍历map,将元素放入优先队列, 排序按照map的value,超过k个出队,最后输出优先队列中的元素即可。

        代码如下:

public int[] topKFrequent(int[] nums, int k) {
        Map<Integer, Integer> countNumMap = new HashMap<>(nums.length);

        PriorityQueue<Integer> queue = new PriorityQueue<>(k, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return countNumMap.get(o1) - countNumMap.get(o2);
            }
        });

        for(int i =0;i < nums.length;i++) {
            countNumMap.put(nums[i], countNumMap.getOrDefault(nums[i], 0)  + 1);
        }

        for (Map.Entry<Integer, Integer> entry : countNumMap.entrySet()) {
            int num = entry.getKey();
            queue.offer(num);

            if(queue.size() > k) {
                queue.poll();
            }
        }

        int[] res = new int[k];
        int index = 0;
        while(!queue.isEmpty()) {
            int num = queue.poll();
            res[index++] = num;
        }
        return res;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值