From 282edf97eca0979eaceb1b8d544f8ab4b4cd132b Mon Sep 17 00:00:00 2001 From: zhangsan <646228430@qq.com> Date: Sun, 30 Mar 2025 15:37:13 +0800 Subject: [PATCH] =?UTF-8?q?3.29=20=E4=BA=8C=E5=88=86=E6=9F=A5=E6=89=BE+?= =?UTF-8?q?=E6=A0=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/binary_search/FindMin.java | 53 +++++++++++++++++++++ src/main/java/binary_search/Search.java | 2 +- src/main/java/stack/DecodeString.java | 19 ++++++++ src/main/java/stack/IsValid.java | 51 +++++++++++++++++++++ src/main/java/stack/MinStack.java | 56 +++++++++++++++++++++++ src/test/java/stack/DecodeStringTest.java | 16 +++++++ 6 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 src/main/java/binary_search/FindMin.java create mode 100644 src/main/java/stack/DecodeString.java create mode 100644 src/main/java/stack/IsValid.java create mode 100644 src/main/java/stack/MinStack.java create mode 100644 src/test/java/stack/DecodeStringTest.java diff --git a/src/main/java/binary_search/FindMin.java b/src/main/java/binary_search/FindMin.java new file mode 100644 index 0000000..c6af274 --- /dev/null +++ b/src/main/java/binary_search/FindMin.java @@ -0,0 +1,53 @@ +package binary_search; + +/** + * 题目: 153. 寻找旋转排序数组中的最小值 (findMin) + * 描述:已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,2,4,5,6,7] 在变化后可能得到: + * 若旋转 4 次,则可以得到 [4,5,6,7,0,1,2] + * 若旋转 7 次,则可以得到 [0,1,2,4,5,6,7] + * 注意,数组 [a[0], a[1], a[2], ..., a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], ..., a[n-2]] 。 + * 给你一个元素值 互不相同 的数组 nums ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。 + * 你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。 + *

+ * 示例 1: + * 输入:nums = [3,4,5,1,2] + * 输出:1 + * 解释:原数组为 [1,2,3,4,5] ,旋转 3 次得到输入数组。 + *

+ * 链接:https://leetcode.cn/problems/find-minimum-in-rotated-sorted-array/ + */ +public class FindMin { + /** + * 判断区间是否已经有序 + * + * 如果当前区间(由 left 到 right)是有序的(即 nums[left] < nums[right]),说明这个区间没有发生旋转,最小值一定是区间的第一个元素 nums[left],所以直接返回它。 + * 计算中间索引 + * + * 使用 int mid = left + (right - left) / 2; 计算中间索引,避免直接相加可能造成的溢出问题。 + * 判断最小值在哪个区间 + * + * 左侧有序情况:如果 nums[mid] >= nums[left],说明从 left 到 mid 是有序的,此时最小值不可能出现在有序部分,所以最小值一定在右半部分,因此更新 left = mid + 1。 + * 旋转点在左侧情况:如果 nums[mid] < nums[left],说明中间部分处于旋转状态,即最小值可能出现在左半部分或就是 nums[mid],因此将 right 更新为 mid。 + * 退出条件 + * + * 循环在 left == right 时退出,此时 nums[left] 就是整个数组的最小值。 + * @param nums + * @return + */ + public int findMin(int[] nums) { + int left = 0, right = nums.length - 1; + while (left < right) { + if (nums[left] < nums[right]) { + return nums[left]; + } + int mid = left + (right - left) / 2; + if (nums[mid] >= nums[left]) { + left = mid + 1; + } else { + right = mid; + } + } + return nums[left]; + } + +} diff --git a/src/main/java/binary_search/Search.java b/src/main/java/binary_search/Search.java index cbe4253..0eca099 100644 --- a/src/main/java/binary_search/Search.java +++ b/src/main/java/binary_search/Search.java @@ -1,6 +1,6 @@ package binary_search; /** - * 题目: 33. 搜索旋转排序数组 (searchRange) + * 题目: 33. 搜索旋转排序数组 (search) * 描述:整数数组 nums 按升序排列,数组中的值 互不相同 。 * 在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。 * 给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。 diff --git a/src/main/java/stack/DecodeString.java b/src/main/java/stack/DecodeString.java new file mode 100644 index 0000000..e439871 --- /dev/null +++ b/src/main/java/stack/DecodeString.java @@ -0,0 +1,19 @@ +package stack; +/** + * 题目: 394. 字符串解码 (decodeString) + * 描述:给定一个经过编码的字符串,返回它解码后的字符串。 + * 编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。 + * 你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。 + * 此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。 + + * 示例 1: + 输入:s = "3[a]2[bc]" + 输出:"aaabcbc" + + * 链接:https://leetcode.cn/problems/search-in-rotated-sorted-array/ + */ +public class DecodeString { + public String decodeString(String s) { + return ""; + } +} \ No newline at end of file diff --git a/src/main/java/stack/IsValid.java b/src/main/java/stack/IsValid.java new file mode 100644 index 0000000..8fcb1da --- /dev/null +++ b/src/main/java/stack/IsValid.java @@ -0,0 +1,51 @@ +package stack; + +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.HashMap; + +/** + * 题目: 20. 有效的括号 (isValid) + * 描述:给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。 + * + * 有效字符串需满足: + * + * 左括号必须用相同类型的右括号闭合。 + * 左括号必须以正确的顺序闭合。 + * 每个右括号都有一个对应的相同类型的左括号。 + * + * 链接:https://leetcode.cn/problems/valid-parentheses/ + */ +public class IsValid { + public boolean isValid(String s) { + // 如果长度为奇数,直接返回 false + int sz = s.length(); + if (sz % 2 == 1) return false; + + // 映射括号 + HashMap map = new HashMap<>(); + map.put('(', ')'); + map.put('[', ']'); + map.put('{', '}'); + + Deque stack = new ArrayDeque<>(); + + for (int i = 0; i < sz; i++) { + char cur = s.charAt(i); + + // 如果是左括号,压入栈 + if (map.containsKey(cur)) { + stack.push(cur); + } + // 如果是右括号,检查栈顶是否是匹配的左括号 + else { + if (stack.isEmpty() || map.get(stack.pop()) != cur) { + return false; + } + } + } + + // 最后栈应为空 + return stack.isEmpty(); + } +} diff --git a/src/main/java/stack/MinStack.java b/src/main/java/stack/MinStack.java new file mode 100644 index 0000000..734f3e4 --- /dev/null +++ b/src/main/java/stack/MinStack.java @@ -0,0 +1,56 @@ +package stack; + +import java.util.Stack; + +/** + * 题目: 155. 最小栈 (MinStack) + * 描述:设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。 + * + * 实现 MinStack 类: + * MinStack() 初始化堆栈对象。 + * void push(int val) 将元素val推入堆栈。 + * void pop() 删除堆栈顶部的元素。 + * int top() 获取堆栈顶部的元素。 + * int getMin() 获取堆栈中的最小元素。 + * + * 链接:https://leetcode.cn/problems/min-stack/description/ + */ +public class MinStack { + + private Stack stack; // 主栈 + private Stack minStack; // 辅助栈,存储每个阶段的最小值 + + public MinStack() { + stack = new Stack<>(); + minStack = new Stack<>(); + } + + // 向栈中压入一个值 + public void push(int val) { + stack.push(val); + // 如果辅助栈为空,或者当前值比辅助栈的栈顶元素还小,压入辅助栈 + if (minStack.isEmpty() || val <= minStack.peek()) { + minStack.push(val); + } + } + + // 弹出栈顶元素 + public void pop() { + // 弹出主栈的栈顶元素 + int poppedValue = stack.pop(); + // 如果弹出的元素是当前最小值,则同时弹出辅助栈的栈顶元素 + if (poppedValue == minStack.peek()) { + minStack.pop(); + } + } + + // 获取栈顶元素 + public int top() { + return stack.peek(); + } + + // 获取当前栈中的最小值 + public int getMin() { + return minStack.peek(); + } +} diff --git a/src/test/java/stack/DecodeStringTest.java b/src/test/java/stack/DecodeStringTest.java new file mode 100644 index 0000000..60dde59 --- /dev/null +++ b/src/test/java/stack/DecodeStringTest.java @@ -0,0 +1,16 @@ +package stack; + +import org.junit.Test; + +import static org.junit.Assert.*; + +public class DecodeStringTest { + + @Test + public void decodeString() { + String s = "3[a]2[bc]"; + DecodeString solution = new DecodeString(); + String res=solution.decodeString(s); + System.out.println(res); + } +} \ No newline at end of file