From 8d4440e0dcef845d0e1711bc01764b798b23c3da Mon Sep 17 00:00:00 2001 From: zhangsan <646228430@qq.com> Date: Sat, 27 Sep 2025 12:25:49 +0800 Subject: [PATCH] 9.27 --- src/main/java/All/AsteroidCollision.java | 55 ++++++++++++++ src/main/java/All/ClosedIsland.java | 49 +++++++++++++ .../java/All/CountAlternatingSubarrays.java | 38 ++++++++++ src/main/java/All/MaxResult.java | 65 +++++++++++++++++ src/main/java/All/NthPersonGetsNthSeat.java | 21 ++++++ .../java/All/NumberOfAlternatingGroupsa.java | 39 ++++++++++ src/main/java/All/RankTeams.java | 72 +++++++++++++++++++ src/main/java/All/RotateString.java | 28 ++++++++ src/main/java/All/SolveEquation.java | 43 +++++++++++ src/main/java/All/ValidPalindrome.java | 40 +++++++++++ src/main/java/All/ValidPalindromeK.java | 47 ++++++++++++ .../dynamic_programming/CountSubstrings.java | 1 + .../java/dynamic_programming/FindLength.java | 1 + .../FindTargetSumWays.java | 1 + .../LongestPalindrome.java | 1 + .../LongestPalindromeSubseq.java | 1 + .../java/dynamic_programming/MaxProduct.java | 1 + .../java/dynamic_programming/MaxSubArray.java | 1 + .../dynamic_programming/MaximalSquare.java | 17 ++--- .../MinCostClimbingStairs.java | 4 +- src/main/java/graph/NumIslands.java | 1 - src/main/java/greedy/Jump.java | 16 +++++ src/main/java/stack/AsteroidCollision.java | 55 ++++++++++++++ src/main/java/实现类功能/MyHashMap.java | 1 + src/test/java/All/MaxResultTest.java | 13 ++++ 25 files changed, 599 insertions(+), 12 deletions(-) create mode 100644 src/main/java/All/AsteroidCollision.java create mode 100644 src/main/java/All/ClosedIsland.java create mode 100644 src/main/java/All/CountAlternatingSubarrays.java create mode 100644 src/main/java/All/MaxResult.java create mode 100644 src/main/java/All/NthPersonGetsNthSeat.java create mode 100644 src/main/java/All/NumberOfAlternatingGroupsa.java create mode 100644 src/main/java/All/RankTeams.java create mode 100644 src/main/java/All/RotateString.java create mode 100644 src/main/java/All/SolveEquation.java create mode 100644 src/main/java/All/ValidPalindrome.java create mode 100644 src/main/java/All/ValidPalindromeK.java create mode 100644 src/main/java/stack/AsteroidCollision.java create mode 100644 src/test/java/All/MaxResultTest.java diff --git a/src/main/java/All/AsteroidCollision.java b/src/main/java/All/AsteroidCollision.java new file mode 100644 index 0000000..6a8cd64 --- /dev/null +++ b/src/main/java/All/AsteroidCollision.java @@ -0,0 +1,55 @@ +package All; + +import java.util.*; + +/** + * 题目: 735. 小行星碰撞 + * 描述:给定一个整数数组 asteroids,表示在同一行的小行星。数组中小行星的索引表示它们在空间中的相对位置。 + * 对于数组中的每一个元素,其绝对值表示小行星的大小,正负表示小行星的移动方向(正表示向右移动,负表示向左移动)。每一颗小行星以相同的速度移动。 + * 找出碰撞后剩下的所有小行星。碰撞规则:两个小行星相互碰撞,较小的小行星会爆炸。如果两颗小行星大小相同,则两颗小行星都会爆炸。两颗移动方向相同的小行星,永远不会发生碰撞。 + + 示例 1: + 输入 + 输入:asteroids = [5,10,-5] + 输出:[5,10] + 解释:10 和 -5 碰撞后只剩下 10 。 5 和 10 永远不会发生碰撞。 + + * 链接:https://leetcode.cn/problems/asteroid-collision/ + */ +public class AsteroidCollision { + public int[] asteroidCollision(int[] asteroids) { + Deque stack=new ArrayDeque<>(); + Listres=new ArrayList<>(); + for (int i = 0; i < asteroids.length; i++) { + if(stack.isEmpty()){ + stack.push(asteroids[i]); + }else { + int cur=asteroids[i]; + if(cur>0)stack.push(cur); + else { + boolean flag=true; + while (!stack.isEmpty()&&stack.peek()>0){ + int curr=Math.abs(cur); + if(stack.peek()>curr){ + flag=false; + break; + } else if (stack.peek()==curr) { + flag=false; + stack.pop(); + break; + }else + stack.pop(); + } + if(flag)stack.push(cur); + } + } + } + while (!stack.isEmpty()) + res.add(0,stack.pop()); + int[] arr = new int[res.size()]; + for (int i = 0; i < res.size(); i++) { + arr[i] = res.get(i); + } + return arr; + } +} diff --git a/src/main/java/All/ClosedIsland.java b/src/main/java/All/ClosedIsland.java new file mode 100644 index 0000000..bc0bb67 --- /dev/null +++ b/src/main/java/All/ClosedIsland.java @@ -0,0 +1,49 @@ +package All; +/** + * 题目: 1254. 统计封闭岛屿的数目 + * 描述:二维矩阵 grid 由 0 (土地)和 1 (水)组成。岛是由最大的4个方向连通的 0 组成的群,封闭岛是一个 完全 由1包围(左、上、右、下)的岛。 + * 请返回 封闭岛屿 的数目。 + + 示例 1: + 输入:grid = [[1,1,1,1,1,1,1,0],[1,0,0,0,0,1,1,0],[1,0,1,0,1,1,1,0],[1,0,0,0,0,1,0,1],[1,1,1,1,1,1,1,0]] + 输出:2 + 解释: + 灰色区域的岛屿是封闭岛屿,因为这座岛屿完全被水域包围(即被 1 区域包围)。 + + * 链接:https://leetcode.cn/problems/number-of-closed-islands/ + */ +public class ClosedIsland { + int[][]dirs=new int[][]{{-1,0},{0,1},{1,0},{0,-1}}; + + boolean dfs(int[][] grid,int i,int j){ + int row=grid.length,col=grid[0].length; + if(i<0 || i>=row || j<0 || j>=col)return false; + int cur=grid[i][j]; + if(cur==0){ + grid[i][j]=2; + boolean isClosed = true; + for (int k = 0; k < 4; k++) { + if (!dfs(grid, i + dirs[k][0], j + dirs[k][1])) { + isClosed = false; + } + } + return isClosed; + } + return true; + } + public int closedIsland(int[][] grid) { + int cnt=0; + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + if(grid[i][j]==0) + if(dfs(grid,i,j)) + cnt++; + } + } + return cnt; + } + + public static void main(String[] args) { + + } +} diff --git a/src/main/java/All/CountAlternatingSubarrays.java b/src/main/java/All/CountAlternatingSubarrays.java new file mode 100644 index 0000000..df5b6e1 --- /dev/null +++ b/src/main/java/All/CountAlternatingSubarrays.java @@ -0,0 +1,38 @@ +package All; +/** + * 题目: 3101. 交替子数组计数 + * 描述:给你一个二进制数组nums 。 + * 如果一个子数组中 不存在 两个 相邻 元素的值 相同 的情况,我们称这样的子数组为 交替子数组 。 + * 返回数组 nums 中交替子数组的数量。 + + 示例 1: + 输入: nums = [0,1,1,1] + 输出: 5 + 解释: + 以下子数组是交替子数组:[0] 、[1] 、[1] 、[1] 以及 [0,1] 。 + + * 链接:https://leetcode.cn/problems/count-alternating-subarrays/ + */ +public class CountAlternatingSubarrays { + public long countAlternatingSubarrays(int[] nums) { + int prenum=nums[0],precnt=1; + long total=1; + for (int i = 1; i < nums.length; i++) { + if(prenum==nums[i]){ + precnt=1; + }else { + precnt++; + } + prenum=nums[i]; + total += precnt; + } + return total; + } + + public static void main(String[] args) { + CountAlternatingSubarrays countAlternatingSubarrays = new CountAlternatingSubarrays(); + int[] nums = new int[]{0,1,1,1}; + long total=countAlternatingSubarrays.countAlternatingSubarrays(nums); + System.out.println(total); + } +} diff --git a/src/main/java/All/MaxResult.java b/src/main/java/All/MaxResult.java new file mode 100644 index 0000000..7e49615 --- /dev/null +++ b/src/main/java/All/MaxResult.java @@ -0,0 +1,65 @@ +package All; + +import java.util.Deque; +import java.util.LinkedList; + +/** + * 题目: 1696. 跳跃游戏 VI + * 描述:给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。 + * 一开始你在下标 0 处。每一步,你最多可以往前跳 k 步,但你不能跳出数组的边界。也就是说,你可以从下标 i 跳到 [i + 1, min(n - 1, i + k)] 包含 两个端点的任意位置。 + * 你的目标是到达数组最后一个位置(下标为 n - 1 ),你的 得分 为经过的所有数字之和。 + * 请你返回你能得到的 最大得分 。 + + 示例 1: + 输入:nums = [1,-1,-2,4,-7,3], k = 2 + 输出:7 + 解释:你可以选择子序列 [1,-1,4,3] (上面加粗的数字),和为 7 。 + + * 链接:https://leetcode.cn/problems/jump-game-vi/ + */ +//不会做 +public class MaxResult { + //超时 + public int maxResult2(int[] nums, int k) { + int n = nums.length; + int[] f = new int[n]; + f[0] = nums[0]; + for (int i = 1; i < n; i++) { + int mx = Integer.MIN_VALUE; + for (int j = Math.max(i - k, 0); j < i; j++) { + mx = Math.max(mx, f[j]); + } + f[i] = mx + nums[i]; + } + return f[n - 1]; + } + /* + dp[i] = max(dp[j]) + nums[i],其中 j ∈ [i - k, i - 1]。 + 用一个双端队列存放“候选下标”,保持队列里的 dp 值是单调递减的,这样队首永远是最大值。 + */ + public int maxResult(int[] nums, int k) { + int n = nums.length; + int[] dp = new int[n]; + dp[0] = nums[0]; + + Deque deque = new LinkedList<>(); + deque.offer(0); // 队列存的是下标 + + for (int i = 1; i < n; i++) { + // 队首如果滑出窗口 [i-k, i-1] 就移除 + while (!deque.isEmpty() && deque.peek() < i - k) { + deque.poll(); + } + + // 队首就是窗口内 dp 最大值的下标 + dp[i] = dp[deque.peek()] + nums[i]; + + // 保持队列单调递减:把比当前 dp[i] 小的值都踢掉 + while (!deque.isEmpty() && dp[i] >= dp[deque.peekLast()]) { + deque.pollLast(); + } + deque.offer(i); + } + return dp[n - 1]; + } +} diff --git a/src/main/java/All/NthPersonGetsNthSeat.java b/src/main/java/All/NthPersonGetsNthSeat.java new file mode 100644 index 0000000..45327b1 --- /dev/null +++ b/src/main/java/All/NthPersonGetsNthSeat.java @@ -0,0 +1,21 @@ +package All; +/** + * 题目: 1227. 飞机座位分配概率 + * 描述:有 n 位乘客即将登机,飞机正好有 n 个座位。第一位乘客的票丢了,他随便选了一个座位坐下。 + * 剩下的乘客将会: + * 如果他们自己的座位还空着,就坐到自己的座位上, + * 当他们自己的座位被占用时,随机选择其他座位 + * 第 n 位乘客坐在自己的座位上的概率是多少? + + 示例 1: + 输入: n = 2 + 输出: 0.50000 + 解释:在第一个人选好座位坐下后,第二个人坐在自己的座位上的概率是 0.5。 + + * 链接:https://leetcode.cn/problems/airplane-seat-assignment-probability/ + */ +public class NthPersonGetsNthSeat { + public double nthPersonGetsNthSeat(int n) { + return n == 1? 1: 0.5; + } +} diff --git a/src/main/java/All/NumberOfAlternatingGroupsa.java b/src/main/java/All/NumberOfAlternatingGroupsa.java new file mode 100644 index 0000000..5d0c479 --- /dev/null +++ b/src/main/java/All/NumberOfAlternatingGroupsa.java @@ -0,0 +1,39 @@ +package All; +/** + * 题目: 3208. 交替组 II + * 描述:给你一个整数数组 colors 和一个整数 k ,colors表示一个由红色和蓝色瓷砖组成的环,第 i 块瓷砖的颜色为 colors[i] : + * colors[i] == 0 表示第 i 块瓷砖的颜色是 红色 。 + * colors[i] == 1 表示第 i 块瓷砖的颜色是 蓝色 。 + * 环中连续 k 块瓷砖的颜色如果是 交替 颜色(也就是说除了第一块和最后一块瓷砖以外,中间瓷砖的颜色与它 左边 和 右边 的颜色都不同),那么它被称为一个 交替 组。 + * 请你返回 交替 组的数目。 + * 注意 ,由于 colors 表示一个 环 ,第一块 瓷砖和 最后一块 瓷砖是相邻的。 + + 示例 1: + 输入:colors = [0,1,0,1,0], k = 3 + 输出:3 + + * 链接:https://leetcode.cn/problems/alternating-groups-ii/ + */ +//不会 +public class NumberOfAlternatingGroupsa { + public int numberOfAlternatingGroups(int[] colors, int k) { + int n = colors.length; + int ans = 0; + int cnt = 0; // 当前连续交替子段的长度 + + for (int i = 0; i < n + k - 1; i++) { + // 更新 cnt + if (colors[i % n] == colors[(i + 1) % n]) { + cnt = 0; + } + cnt++; + if (cnt >= k) ans++; + } + return ans; + } + + public static void main(String[] args) { + NumberOfAlternatingGroupsa solution = new NumberOfAlternatingGroupsa(); + System.out.println(solution.numberOfAlternatingGroups(new int[]{0,1,0,1,0}, 3)); // 3 + } +} diff --git a/src/main/java/All/RankTeams.java b/src/main/java/All/RankTeams.java new file mode 100644 index 0000000..554d138 --- /dev/null +++ b/src/main/java/All/RankTeams.java @@ -0,0 +1,72 @@ +package All; + +import java.util.*; + +/** + * 题目: 1366. 通过投票对团队排名 + * 描述:现在有一个特殊的排名系统,依据参赛团队在投票人心中的次序进行排名,每个投票者都需要按从高到低的顺序对参与排名的所有团队进行排位。 + * 排名规则如下: + * 参赛团队的排名次序依照其所获「排位第一」的票的多少决定。如果存在多个团队并列的情况,将继续考虑其「排位第二」的票的数量。以此类推,直到不再存在并列的情况。 + * 如果在考虑完所有投票情况后仍然出现并列现象,则根据团队字母的字母顺序进行排名。 + * 给你一个字符串数组 votes 代表全体投票者给出的排位情况,请你根据上述排名规则对所有参赛团队进行排名。 + * 请你返回能表示按排名系统 排序后 的所有团队排名的字符串。 + + 示例 1: + 输入:votes = ["ABC","ACB","ABC","ACB","ACB"] + 输出:"ACB" + 解释: + A 队获得五票「排位第一」,没有其他队获得「排位第一」,所以 A 队排名第一。 + B 队获得两票「排位第二」,三票「排位第三」。 + C 队获得三票「排位第二」,两票「排位第三」。 + 由于 C 队「排位第二」的票数较多,所以 C 队排第二,B 队排第三。 + + * 链接:https://leetcode.cn/problems/rank-teams-by-votes/ + */ +//不会 +public class RankTeams { + public String rankTeams(String[] votes) { + int n = votes[0].length(); // 队伍总数,每张票都包含全部队伍 + // 用 map 统计每个队伍在每个名次上的票数 + Map countMap = new HashMap<>(); + + for (String vote : votes) { + for (int i = 0; i < n; i++) { + char team = vote.charAt(i); + if (!countMap.containsKey(team)) { + countMap.put(team, new int[n]); + } + countMap.get(team)[i]++; // team 在第 i 个名次上多一票 + } + } + + // 所有参赛队伍 + List teams = new ArrayList<>(countMap.keySet()); + + // 自定义排序规则: + // 1. 优先比较每个名次的票数(从第一名到最后一名) + // 2. 如果所有名次票数相同,则按字母顺序排 + Collections.sort(teams, (a, b) -> { + int[] cntA = countMap.get(a); + int[] cntB = countMap.get(b); + for (int i = 0; i < n; i++) { + if (cntA[i] != cntB[i]) { + return cntB[i] - cntA[i]; // 谁在这一名上的票多,谁排前面 + } + } + return a - b; // 所有票数相同,按字母顺序 + }); + + // 拼接成最终结果 + StringBuilder sb = new StringBuilder(); + for (char team : teams) { + sb.append(team); + } + return sb.toString(); + } + + public static void main(String[] args) { + RankTeams solution = new RankTeams(); + String[] votes = {"ABC","ACB","ABC","ACB","ACB"}; + System.out.println(solution.rankTeams(votes)); // 输出 "ACB" + } +} diff --git a/src/main/java/All/RotateString.java b/src/main/java/All/RotateString.java new file mode 100644 index 0000000..384c1f7 --- /dev/null +++ b/src/main/java/All/RotateString.java @@ -0,0 +1,28 @@ +package All; +/** + * 题目: 796. 旋转字符串 + * 描述:给定两个字符串, s 和 goal。如果在若干次旋转操作之后,s 能变成 goal ,那么返回 true 。 + * s 的 旋转操作 就是将 s 最左边的字符移动到最右边。 + * 例如, 若 s = 'abcde',在旋转一次之后结果就是'bcdea' 。 + + 示例 1: + 输入: s = "abcde", goal = "cdeab" + 输出: true + + * 链接:https://leetcode.cn/problems/rotate-string/ + */ +public class RotateString { + public boolean rotateString(String s, String goal) { + int target=goal.length(); + int len=s.length(); + if(target!=len)return false; + for (int i = 0; i < len; i++) { + for (int j = 0; j < target; j++) { + if(s.charAt((i+j)%len)!=goal.charAt(j)) + break; + if(j==target-1)return true; + } + } + return false; + } +} diff --git a/src/main/java/All/SolveEquation.java b/src/main/java/All/SolveEquation.java new file mode 100644 index 0000000..26a4199 --- /dev/null +++ b/src/main/java/All/SolveEquation.java @@ -0,0 +1,43 @@ +package All; +/** + * 题目: 640. 求解方程 + * 描述:求解一个给定的方程,将x以字符串 "x=#value" 的形式返回。该方程仅包含 '+' , '-' 操作,变量 x 和其对应系数。 + * + * 如果方程没有解或存在的解不为整数,请返回 "No solution" 。如果方程有无限解,则返回 “Infinite solutions” 。 + * + * 题目保证,如果方程中只有一个解,则 'x' 的值是一个整数。 + + 示例 1: + 输入: equation = "x+5-3+x=6+x-2" + 输出: "x=2" + + * 链接:https://leetcode.cn/problems/solve-the-equation/ + */ +public class SolveEquation { + class Solution { + public String solveEquation(String s) { + int x = 0, num = 0, n = s.length(); + char[] cs = s.toCharArray(); + for (int i = 0, op = 1; i < n; ) { + if (cs[i] == '+') { + op = 1; i++; + } else if (cs[i] == '-') { + op = -1; i++; + } else if (cs[i] == '=') { + x *= -1; num *= -1; op = 1; i++; + } else { + int j = i; + //找当前数字/变量的边界 比如 "3x"、"x"、"5"。 + while (j < n && cs[j] != '+' && cs[j] != '-' && cs[j] != '=') j++; + //"3x" → "3" "x" → 前面没数字,这时就走 else 1,表示系数是 1 + if (cs[j - 1] == 'x') x += (i < j - 1 ? Integer.parseInt(s.substring(i, j - 1)) : 1) * op; + //如果不是 x 项,就说明是数字,比如 "5"、"10" + else num += Integer.parseInt(s.substring(i, j)) * op; + i = j; + } + } + if (x == 0) return num == 0 ? "Infinite solutions" : "No solution"; + else return "x=" + (num / -x); + } + } +} diff --git a/src/main/java/All/ValidPalindrome.java b/src/main/java/All/ValidPalindrome.java new file mode 100644 index 0000000..c887710 --- /dev/null +++ b/src/main/java/All/ValidPalindrome.java @@ -0,0 +1,40 @@ +package All; +/** + * 题目: 680. 验证回文串 II + * 描述:给你一个字符串 s,最多 可以从中删除一个字符。 + * 请你判断 s 是否能成为回文字符串:如果能,返回 true ;否则,返回 false 。 + + 示例 1: + 输入:s = "aba" + 输出:true + + * 链接:https://leetcode.cn/problems/valid-palindrome-ii/ + */ +public class ValidPalindrome { + public boolean validPalindrome(String s) { + int l = 0, r = s.length() - 1; + while (l < r) { + if (s.charAt(l) == s.charAt(r)) { + l++; r--; + } else { + // 尝试跳过左边或右边的字符 + return isPalindrome(s, l + 1, r) || isPalindrome(s, l, r - 1); + } + } + return true; + } + + private boolean isPalindrome(String s, int l, int r) { + while (l < r) { + if (s.charAt(l++) != s.charAt(r--)) return false; + } + return true; + } + + public static void main(String[] args) { + ValidPalindrome solution = new ValidPalindrome(); + String s="bddb"; + solution.validPalindrome(s); + + } +} diff --git a/src/main/java/All/ValidPalindromeK.java b/src/main/java/All/ValidPalindromeK.java new file mode 100644 index 0000000..8f48478 --- /dev/null +++ b/src/main/java/All/ValidPalindromeK.java @@ -0,0 +1,47 @@ +package All; + +import java.util.HashMap; +import java.util.Map; +/* + * 题目: 680. 验证回文串 II 改 + * 描述:给你一个字符串 s,最多 可以从中删除 k 个字符。 + * 请你判断 s 是否能成为回文字符串:如果能,返回 true ;否则,返回 false 。 + */ +public class ValidPalindromeK { + public boolean validPalindrome(String s, int k) { + // 从整个字符串 [0..n-1] 开始判断,初始可删 k 次 + return judge(s, 0, s.length() - 1, k, new HashMap<>()); + } + + private boolean judge(String s, int l, int r, int k, Map memo) { + // 用 "l,r,k" 作为 key 唯一标识当前子问题 + String key = l + "," + r + "," + k; + if (memo.containsKey(key)) return memo.get(key); + + while (l < r) { + if (s.charAt(l) == s.charAt(r)) { + l++; r--; + } else { + if (k == 0) { + memo.put(key, false); + return false; + } + // 尝试两种删除方式: + // 1. 删除左边字符(l+1, r, k-1) + // 2. 删除右边字符(l, r-1, k-1) + boolean res = judge(s, l + 1, r, k - 1, memo) || judge(s, l, r - 1, k - 1, memo); + memo.put(key, res); + return res; + } + } + memo.put(key, true); + return true; + } + + public static void main(String[] args) { + ValidPalindromeK solution = new ValidPalindromeK(); + System.out.println(solution.validPalindrome("bddb", 1)); // true + System.out.println(solution.validPalindrome("abc", 1)); // false + System.out.println(solution.validPalindrome("abc", 2)); // true (删掉 "a" 和 "c") + } +} diff --git a/src/main/java/dynamic_programming/CountSubstrings.java b/src/main/java/dynamic_programming/CountSubstrings.java index 4ceb42f..8df1738 100644 --- a/src/main/java/dynamic_programming/CountSubstrings.java +++ b/src/main/java/dynamic_programming/CountSubstrings.java @@ -13,6 +13,7 @@ package dynamic_programming; * 链接:https://leetcode.cn/problems/palindromic-substrings/ */ //不会 +//二刷不会 public class CountSubstrings { /** *布尔类型的dp[i][j]:表示区间范围[i,j] (注意是左闭右闭)的子串是否是回文子串 diff --git a/src/main/java/dynamic_programming/FindLength.java b/src/main/java/dynamic_programming/FindLength.java index cd34308..a6079b0 100644 --- a/src/main/java/dynamic_programming/FindLength.java +++ b/src/main/java/dynamic_programming/FindLength.java @@ -24,6 +24,7 @@ package dynamic_programming; * dp[i][j] = 0; */ //二刷不会 +//三刷会做 public class FindLength { public int findLength(int[] nums1, int[] nums2) { int n = nums1.length, m = nums2.length; diff --git a/src/main/java/dynamic_programming/FindTargetSumWays.java b/src/main/java/dynamic_programming/FindTargetSumWays.java index 8ca7426..dac4e56 100644 --- a/src/main/java/dynamic_programming/FindTargetSumWays.java +++ b/src/main/java/dynamic_programming/FindTargetSumWays.java @@ -19,6 +19,7 @@ package dynamic_programming; * 链接:https://leetcode.cn/problems/target-sum/ */ //二刷不会 +//三刷不会,数学转换很重要! public class FindTargetSumWays { /** diff --git a/src/main/java/dynamic_programming/LongestPalindrome.java b/src/main/java/dynamic_programming/LongestPalindrome.java index 71a78c0..bcd7b4e 100644 --- a/src/main/java/dynamic_programming/LongestPalindrome.java +++ b/src/main/java/dynamic_programming/LongestPalindrome.java @@ -12,6 +12,7 @@ package dynamic_programming; * 链接:https://leetcode.cn/problems/longest-palindromic-substring/ */ //二刷不会 +//三刷会做 public class LongestPalindrome { /* 遍历顺序为什么是 i 从大到小,j 从小到大? diff --git a/src/main/java/dynamic_programming/LongestPalindromeSubseq.java b/src/main/java/dynamic_programming/LongestPalindromeSubseq.java index 2b21a72..79b71ee 100644 --- a/src/main/java/dynamic_programming/LongestPalindromeSubseq.java +++ b/src/main/java/dynamic_programming/LongestPalindromeSubseq.java @@ -11,6 +11,7 @@ package dynamic_programming; * 链接:https://leetcode.cn/problems/longest-palindromic-subsequence/ */ +//二刷会做 public class LongestPalindromeSubseq { public int longestPalindromeSubseq(String s) { int n = s.length(); diff --git a/src/main/java/dynamic_programming/MaxProduct.java b/src/main/java/dynamic_programming/MaxProduct.java index 2fe5b77..9317280 100644 --- a/src/main/java/dynamic_programming/MaxProduct.java +++ b/src/main/java/dynamic_programming/MaxProduct.java @@ -13,6 +13,7 @@ package dynamic_programming; */ //不会 //二刷不会 +//三刷不会 public class MaxProduct { /** diff --git a/src/main/java/dynamic_programming/MaxSubArray.java b/src/main/java/dynamic_programming/MaxSubArray.java index fda733e..30c5fec 100644 --- a/src/main/java/dynamic_programming/MaxSubArray.java +++ b/src/main/java/dynamic_programming/MaxSubArray.java @@ -11,6 +11,7 @@ package dynamic_programming; * 链接:https://leetcode.cn/problems/maximum-subarray/ */ +//会做 public class MaxSubArray { //dp[i]:包括下标i(以nums[i]为结尾)的最大连续子序列和为dp[i]。 public static int maxSubArray(int[] nums) { diff --git a/src/main/java/dynamic_programming/MaximalSquare.java b/src/main/java/dynamic_programming/MaximalSquare.java index 841c810..7e3552c 100644 --- a/src/main/java/dynamic_programming/MaximalSquare.java +++ b/src/main/java/dynamic_programming/MaximalSquare.java @@ -10,22 +10,19 @@ package dynamic_programming; * 链接:https://leetcode.cn/problems/maximal-square/ */ //不会 +//二刷不会 public class MaximalSquare { /** + * dp[i][j] 表示 以 (i, j) 作为右下角的最大全 1 正方形的边长 + * * 那么如何计算 dp 中的每个元素值呢?对于每个位置 (i,j),检查在矩阵中该位置的值: - * + * 如果该位置的值是 0,则 dp(i,j)=0,因为当前位置不可能在由 1 组成的正方形中; - * + * 如果该位置的值是 1,则 dp(i,j) 的值由其上方、左方和左上方的三个相邻位置的 dp 值决定。具体而言,当前位置的元素值等于三个相邻位置的元素中的最小值加 1,状态转移方程如下: - * + * dp(i,j)=min(dp(i−1,j),dp(i−1,j−1),dp(i,j−1))+1 - * - * 作者:力扣官方题解 - * 链接:https://leetcode.cn/problems/maximal-square/solutions/234964/zui-da-zheng-fang-xing-by-leetcode-solution/ - * 来源:力扣(LeetCode) - * 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 - * @param matrix - * @return + */ public int maximalSquare(char[][] matrix) { int maxSide = 0; diff --git a/src/main/java/dynamic_programming/MinCostClimbingStairs.java b/src/main/java/dynamic_programming/MinCostClimbingStairs.java index a8ebb80..f784a61 100644 --- a/src/main/java/dynamic_programming/MinCostClimbingStairs.java +++ b/src/main/java/dynamic_programming/MinCostClimbingStairs.java @@ -14,11 +14,13 @@ package dynamic_programming; * 链接:https://leetcode.cn/problems/min-cost-climbing-stairs/ */ +//会做 public class MinCostClimbingStairs { + //dp[i] 表示到达第 i 个台阶所需要支付的最小花费。 public int minCostClimbingStairs(int[] cost) { int n = cost.length; int[] dp = new int[n + 1]; - // 默认第一步和第二步不花费体力 + // 默认第一步和第二步不花费 dp[0] = 0; dp[1] = 0; // 从第 2 阶开始,递推计算到顶楼 diff --git a/src/main/java/graph/NumIslands.java b/src/main/java/graph/NumIslands.java index 6d354af..3a1dbae 100644 --- a/src/main/java/graph/NumIslands.java +++ b/src/main/java/graph/NumIslands.java @@ -42,7 +42,6 @@ public class NumIslands { } } } - return num_islands; } } diff --git a/src/main/java/greedy/Jump.java b/src/main/java/greedy/Jump.java index d49e66a..06f3f15 100644 --- a/src/main/java/greedy/Jump.java +++ b/src/main/java/greedy/Jump.java @@ -48,4 +48,20 @@ public class Jump { } return count; } + + + public int jump2(int[] nums) { + if(nums.length==1)return 0; + int curmax=0,allmax=nums[0]; + int step=0; + for (int i = 0; i < nums.length; i++) { + allmax=Math.max(allmax,i+nums[i]); + if(allmax>=nums.length-1)return step+1; + if(i==curmax){ + step++; + curmax=allmax; + } + } + return -1; + } } diff --git a/src/main/java/stack/AsteroidCollision.java b/src/main/java/stack/AsteroidCollision.java new file mode 100644 index 0000000..70526f1 --- /dev/null +++ b/src/main/java/stack/AsteroidCollision.java @@ -0,0 +1,55 @@ +package stack; + +import java.util.*; + +/** + * 题目: 735. 小行星碰撞 + * 描述:给定一个整数数组 asteroids,表示在同一行的小行星。数组中小行星的索引表示它们在空间中的相对位置。 + * 对于数组中的每一个元素,其绝对值表示小行星的大小,正负表示小行星的移动方向(正表示向右移动,负表示向左移动)。每一颗小行星以相同的速度移动。 + * 找出碰撞后剩下的所有小行星。碰撞规则:两个小行星相互碰撞,较小的小行星会爆炸。如果两颗小行星大小相同,则两颗小行星都会爆炸。两颗移动方向相同的小行星,永远不会发生碰撞。 + + 示例 1: + 输入 + 输入:asteroids = [5,10,-5] + 输出:[5,10] + 解释:10 和 -5 碰撞后只剩下 10 。 5 和 10 永远不会发生碰撞。 + + * 链接:https://leetcode.cn/problems/asteroid-collision/ + */ +public class AsteroidCollision { + public int[] asteroidCollision(int[] asteroids) { + Deque stack=new ArrayDeque<>(); + Listres=new ArrayList<>(); + for (int i = 0; i < asteroids.length; i++) { + if(stack.isEmpty()){ + stack.push(asteroids[i]); + }else { + int cur=asteroids[i]; + if(cur>0)stack.push(cur); + else { + boolean flag=true; + while (!stack.isEmpty()&&stack.peek()>0){ + int curr=Math.abs(cur); + if(stack.peek()>curr){ + flag=false; + break; + } else if (stack.peek()==curr) { + flag=false; + stack.pop(); + break; + }else + stack.pop(); + } + if(flag)stack.push(cur); + } + } + } + while (!stack.isEmpty()) + res.add(0,stack.pop()); + int[] arr = new int[res.size()]; + for (int i = 0; i < res.size(); i++) { + arr[i] = res.get(i); + } + return arr; + } +} diff --git a/src/main/java/实现类功能/MyHashMap.java b/src/main/java/实现类功能/MyHashMap.java index 8e45c2c..59053cc 100644 --- a/src/main/java/实现类功能/MyHashMap.java +++ b/src/main/java/实现类功能/MyHashMap.java @@ -1,5 +1,6 @@ package 实现类功能; /* +实现一个HashMap 数组(table):核心结构,存储键值对(Entry)的桶(bucket)。 链表:当多个键的哈希值落在同一个桶中时,会形成一个链表。 */ diff --git a/src/test/java/All/MaxResultTest.java b/src/test/java/All/MaxResultTest.java new file mode 100644 index 0000000..d5ee4d2 --- /dev/null +++ b/src/test/java/All/MaxResultTest.java @@ -0,0 +1,13 @@ +package All; + +import junit.framework.TestCase; + +public class MaxResultTest extends TestCase { + + public void testMaxResult() { + MaxResult maxResult=new MaxResult(); + int[]nums = {10,-5,-2,4,0,3}; + int res=maxResult.maxResult(nums,3); + System.out.println(res); + } +} \ No newline at end of file