From 53958087afdef25a50b57c6b1e4758cdf6368a37 Mon Sep 17 00:00:00 2001 From: whai Date: Tue, 9 Jan 2024 17:49:57 +0800 Subject: [PATCH] =?UTF-8?q?-=20239=20=E9=98=9F=E5=88=97=E7=9A=84=E5=BA=94?= =?UTF-8?q?=E7=94=A8=EF=BC=8C=E6=B2=A1=E5=81=9A=E5=87=BA=E6=9D=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../whaifree/leetCode/Stack/LeetCode1047.java | 64 +++++++++++++ .../whaifree/leetCode/Stack/LeetCode150.java | 90 ++++++++++++++++++ .../whaifree/leetCode/Stack/LeetCode239.java | 94 +++++++++++++++++++ 3 files changed, 248 insertions(+) create mode 100644 src/main/java/cn/whaifree/leetCode/Stack/LeetCode1047.java create mode 100644 src/main/java/cn/whaifree/leetCode/Stack/LeetCode150.java create mode 100644 src/main/java/cn/whaifree/leetCode/Stack/LeetCode239.java diff --git a/src/main/java/cn/whaifree/leetCode/Stack/LeetCode1047.java b/src/main/java/cn/whaifree/leetCode/Stack/LeetCode1047.java new file mode 100644 index 0000000..63a180b --- /dev/null +++ b/src/main/java/cn/whaifree/leetCode/Stack/LeetCode1047.java @@ -0,0 +1,64 @@ +package cn.whaifree.leetCode.Stack; + +import org.junit.Test; + +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.LinkedList; +import java.util.function.Consumer; + +public class LeetCode1047 { + + @Test + public void test() { + System.out.println(new Solution1().removeDuplicates("adff")); + } + + class Solution { + public String removeDuplicates(String s) { + Deque stack = new ArrayDeque<>(); + char[] chars = s.toCharArray(); + for (char aChar : chars) { + // 入栈前判断第一个是不是相同的 + if (!stack.isEmpty() && stack.peek() == aChar) { + stack.pop(); + }else { + stack.push(aChar); + } + + } + + char[] ans = new char[stack.size()]; + for (int i = stack.size() - 1; i >=0; i--) { + ans[i] = stack.pop(); + } + + return new String(ans); + } + } + + class Solution1 { + /** + * stringBuilder也能作为栈使用 + */ + public String removeDuplicates(String s) { + // 将StringBuilder作为栈 abbacd + StringBuilder res = new StringBuilder(); + + int top = -1; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (res.length() != 0 && c == res.charAt(top)) { + res.deleteCharAt(top); + top--; + } else { + res.append(c); + top++; + } + } + + return res.toString(); + } + } + +} diff --git a/src/main/java/cn/whaifree/leetCode/Stack/LeetCode150.java b/src/main/java/cn/whaifree/leetCode/Stack/LeetCode150.java new file mode 100644 index 0000000..2f05a53 --- /dev/null +++ b/src/main/java/cn/whaifree/leetCode/Stack/LeetCode150.java @@ -0,0 +1,90 @@ +package cn.whaifree.leetCode.Stack; + +import org.junit.Test; + +import java.util.Deque; +import java.util.LinkedList; + +/** + * 逆转波兰表达式 + */ +public class LeetCode150 { + + @Test + public void test() { + System.out.println(new Solution1().evalRPN(new String[]{"2", "1", "+", "3", "*"})); + System.out.println(new Solution1().evalRPN(new String[]{"4", "13", "5", "/", "+"})); + } + + + class Solution { + public int evalRPN(String[] tokens) { + + Deque stack = new LinkedList<>(); + + int index = 0; + while (index < tokens.length) { + String token = tokens[index]; + if (token.equals("+")) { + Integer pop1 = Integer.parseInt(stack.pop()); + Integer pop2 = Integer.parseInt(stack.pop()); + stack.push(String.valueOf(pop1 + pop2)); + } else if (token.equals("-")) { //避免多次判断 + Integer pop1 = Integer.parseInt(stack.pop()); + Integer pop2 = Integer.parseInt(stack.pop()); + stack.push(String.valueOf(pop2 - pop1)); + } else if (token.equals("*")) { + Integer pop1 = Integer.parseInt(stack.pop()); + Integer pop2 = Integer.parseInt(stack.pop()); + stack.push(String.valueOf(pop2 * pop1)); + } else if (token.equals("/")) { + Integer pop1 = Integer.parseInt(stack.pop()); + Integer pop2 = Integer.parseInt(stack.pop()); + stack.push(String.valueOf(pop2 / pop1)); + } else { + stack.push(token); + } + index++; + } + return Integer.parseInt(stack.pop()); + + } + } + + class Solution1 { + public int evalRPN(String[] tokens) { + + Deque stack = new LinkedList<>(); + + for (String token : tokens) { + switch (token) { + case "+": + int i = Integer.parseInt(stack.pop()); + int j = Integer.parseInt(stack.pop()); + stack.push(String.valueOf(i + j)); + break; + case "-": + int k = Integer.parseInt(stack.pop()); + int l = Integer.parseInt(stack.pop()); + stack.push(String.valueOf(l - k)); + break; + case "*": + int m = Integer.parseInt(stack.pop()); + int n = Integer.parseInt(stack.pop()); + stack.push(String.valueOf(n * m)); + break; + case "/": + int o = Integer.parseInt(stack.pop()); + int p = Integer.parseInt(stack.pop()); + stack.push(String.valueOf(p / o)); + break; + default: + stack.push(token); + break; + } + } + return Integer.parseInt(stack.pop()); + } + } + +} diff --git a/src/main/java/cn/whaifree/leetCode/Stack/LeetCode239.java b/src/main/java/cn/whaifree/leetCode/Stack/LeetCode239.java new file mode 100644 index 0000000..5e4efc9 --- /dev/null +++ b/src/main/java/cn/whaifree/leetCode/Stack/LeetCode239.java @@ -0,0 +1,94 @@ +package cn.whaifree.leetCode.Stack; + +import org.junit.Test; + +import java.util.Deque; +import java.util.LinkedList; + +/** + * @Author whai文海 + * @Date 2024/1/9 14:49 + * @注释 + * + * 239. 滑动窗口最大值 + + * 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 + * + * 返回 滑动窗口中的最大值 。 + * + * + * + * 示例 1: + * + * 输入:nums = [1,3,-1,-3,5,3,6,7], k = 3 + * 输出:[3,3,5,5,6,7] + * 解释: + * 滑动窗口的位置 最大值 + * --------------- ----- + * [1 3 -1] -3 5 3 6 7 3 + * 1 [3 -1 -3] 5 3 6 7 3 + * 1 3 [-1 -3 5] 3 6 7 5 + * 1 3 -1 [-3 5 3] 6 7 5 + * 1 3 -1 -3 [5 3 6] 7 6 + * 1 3 -1 -3 5 [3 6 7] 7 + * 示例 2: + * + * 输入:nums = [1], k = 1 + * 输出:[1] + */ +public class LeetCode239 { + + @Test + public void test() { + int[] nums = new int[]{1, 3, -1, -3, 5, 3, 6, 7}; + int[] res = new Solution().maxSlidingWindow(nums, 3); + for (int re : res) { + System.out.println(re); + } + } + + class Solution { + /** + * 维持一个单调队列,队列里存放的是对应值得下标。 + * 如果 此次队列头部指针为i,即num[i]为目前窗口的最大值。 + * - 如果这个最大值的下标不在下一个窗口的范围内,那么需要将这个值删除 + * @param nums + * @param k + * @return + */ + public int[] maxSlidingWindow(int[] nums, int k) { + // 单调队列,维持一个单调递减的队列 + Deque queue = new LinkedList<>(); + + // n个元素,k个窗口,一共为n-k个输出 + int[] res = new int[nums.length - k + 1]; + + + for (int i = 0; i < nums.length; i++) { + + // 判断当前队首的值是否在本次的窗口内,i-k为窗口左边 + if (!queue.isEmpty()&&queue.peek() <= i - k) { + queue.pop(); + } + + // 保证单调递减 + while (!queue.isEmpty() && nums[i] >= nums[queue.peekLast()]) { + queue.removeLast(); + } + queue.addLast(i); + + + // 从第k个开始才有结果 + if(i+1 >= k){ + res[i+1-k] = nums[queue.peek()]; + } + + // 从第k个开始,先把值存进去,在下次循环判断是否这个值存在于这个新的区间中 + } + + + return res; + + } + } +}