diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/dynamic/LC_309_MaxProfit.java b/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/dynamic/LC_309_MaxProfit.java new file mode 100644 index 0000000..ba21beb --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/dynamic/LC_309_MaxProfit.java @@ -0,0 +1,16 @@ +package com.markilue.leecode.hot100.interviewHot.dynamic; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.hot100.interviewHot.dynamic + *@Author: markilue + *@CreateTime: 2023-05-31 13:23 + *@Description: TODO 力扣309 最佳买卖股票时机含冷冻期 + *@Version: 1.0 + */ +public class LC_309_MaxProfit { + + public int maxProfit(int[] prices) { + return 0; + } +} diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/union_find/second/LC_685_FindRedundantConnection.java b/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/union_find/second/LC_685_FindRedundantConnection.java new file mode 100644 index 0000000..20e0c32 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/union_find/second/LC_685_FindRedundantConnection.java @@ -0,0 +1,102 @@ +package com.markilue.leecode.hot100.interviewHot.union_find.second; + +import java.util.ArrayList; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.hot100.interviewHot.union_find.second + *@Author: markilue + *@CreateTime: 2023-05-31 10:47 + *@Description: TODO 力扣685 冗余连接II + *@Version: 1.0 + */ +public class LC_685_FindRedundantConnection { + + int[] father;//父节点 + int n;//父节点个数 + + private void init(int[] father) { + for (int i = 0; i < father.length; i++) { + father[i] = i; + } + } + + private int find(int u) { + if (u == father[u]) { + return u; + } + father[u] = find(father[u]); + return father[u]; + } + + private void join(int u, int v) { + u = find(u); + v = find(v); + if (u == v) return; + father[v] = u; + } + + private boolean same(int u, int v) { + u = find(u); + v = find(v); + return u == v; + } + + + private boolean isSameAfterRemove(int[][] edges, int delete) { + init(father); + + for (int i = 0; i < edges.length; i++) { + if (i == delete) { + continue; + } + if (same(edges[i][0], edges[i][1])) { + return false; + } + join(edges[i][0], edges[i][1]); + } + return true; + } + + private int[] removeOne(int[][] edges) { + init(father); + + for (int i = 0; i < edges.length; i++) { + + if (same(edges[i][0], edges[i][1])) { + return edges[i]; + } + join(edges[i][0], edges[i][1]); + } + return null; + } + + + public int[] findRedundantDirectedConnection(int[][] edges) { + n = 1010; + father = new int[n]; + + //计算每个节点的入度 + int[] inDegree = new int[n]; + for (int[] edge : edges) { + inDegree[edge[1]]++; + } + + ArrayList twoDegree = new ArrayList<>(); + //判断入度为2的节点,该节点一定有子节点需要删除;反向遍历,因为后面的删除优先级更高 + for (int i = edges.length-1; i >=0; i--) { + if (inDegree[edges[i][1]] == 2) { + twoDegree.add(i);//这个节点需要删除 + } + } + + if (!twoDegree.isEmpty()) { + if (isSameAfterRemove(edges, twoDegree.get(0))) { + return edges[twoDegree.get(0)]; + } + return edges[twoDegree.get(1)]; + } + + return removeOne(edges); + } +} diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/second/T77_297_Codec.java b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T77_297_Codec.java index 3795046..1e14ac1 100644 --- a/Leecode/src/main/java/com/markilue/leecode/hot100/second/T77_297_Codec.java +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T77_297_Codec.java @@ -60,6 +60,7 @@ public class T77_297_Codec { // Decodes your encoded data to tree. public TreeNode deserialize(String data) { + if (in >= data.length() || data.charAt(in) == ')') { return null; } @@ -70,7 +71,7 @@ public class T77_297_Codec { in++; } - while (in < data.length() && data.charAt(in) >= '0' && data.charAt(in) <= '9') { + while (in < data.length() && Character.isDigit(data.charAt(in))) { root.val = root.val * 10 + data.charAt(in)-'0'; in++; } diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/second/T78_300_LengthOfLIS.java b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T78_300_LengthOfLIS.java new file mode 100644 index 0000000..5139c2b --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T78_300_LengthOfLIS.java @@ -0,0 +1,50 @@ +package com.markilue.leecode.hot100.second; + +import org.junit.Test; + +import java.util.ArrayDeque; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.hot100.second + *@Author: markilue + *@CreateTime: 2023-05-31 11:18 + *@Description: TODO 力扣300 最长递增子序列 + *@Version: 1.0 + */ +public class T78_300_LengthOfLIS { + + @Test + public void test() { +// int[] nums ={10,9,2,5,3,7,101,18}; + int[] nums = {0, 1, 0, 3, 2, 3}; + System.out.println(lengthOfLIS(nums)); + } + + + //构造一个单调栈:存放位置,核心问题在于子序列,所以动态规划不合适 + //单调栈不合适,因为pop出的数字可能还有用 + public int lengthOfLIS(int[] nums) { + + int[] stack = new int[nums.length]; + int index = 0; + stack[index] = nums[0]; + + + for (int i = 1; i < nums.length; i++) { + if (stack[index] < nums[i]) { + stack[++index] = nums[i]; + } else { + //找出第一个比他小的位置,并替代 + for (int j = 0; j <= index; j++) { + if (stack[j] >= nums[i]) { + stack[j] = nums[i]; + break; + } + } + } + } + + return index+1; + } +} diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/second/T79_301_RemoveInvalidParentheses.java b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T79_301_RemoveInvalidParentheses.java new file mode 100644 index 0000000..3909df0 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T79_301_RemoveInvalidParentheses.java @@ -0,0 +1,87 @@ +package com.markilue.leecode.hot100.second; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.hot100.second + *@Author: markilue + *@CreateTime: 2023-05-31 11:50 + *@Description: TODO 力扣301 删除无效的括号 + *@Version: 1.0 + */ +public class T79_301_RemoveInvalidParentheses { + + @Test + public void test() { + String s = "(a)())()"; + System.out.println(removeInvalidParentheses(s)); + } + + + //朴素的想法:判断左右括号哪个多,确定删除谁;然后挨个删,最后通过判断合不合适来加入结果 + public List removeInvalidParentheses(String s) { + + int left = 0; + int right = 0; + + for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) == '(') { + left++; + } else if (s.charAt(i) == ')') { + if (left > 0) { + left--; + } else { + right++; + } + } + } + List result = new ArrayList<>(); + removeHelper(s, left, right, result,0); + return result; + + } + + //需要注意这个start;一定要从这个字母后面开始删除 + public void removeHelper(String s, int left, int right, List res,int start) { + if (left == 0 && right == 0) { + if (isValid(s)) { + res.add(new String(s)); + } + return; + } + + for (int i = start; i < s.length(); i++) { + if (i > 0 && s.charAt(i) == s.charAt(i - 1)) continue;//去重 + if (left + right > s.length() - i) { + //怎么删都不够了 + return; + } + if (left > 0 && s.charAt(i) == '(') { + removeHelper(s.substring(0, i) + s.substring(i + 1), left - 1, right, res,i); + } + if (right > 0 && s.charAt(i) == ')') { + removeHelper(s.substring(0, i) + s.substring(i + 1), left, right - 1, res,i); + } + } + + } + + private boolean isValid(String s) { + int left = 0; + for (int i = 0; i < s.length(); i++) { + if (s.charAt(i) == '(') { + left++; + } else if (s.charAt(i) == ')') { + left--; + if (left < 0) return false; + } + } + return true; + } + + +} diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/second/T80_309_MaxProfit.java b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T80_309_MaxProfit.java new file mode 100644 index 0000000..1db8ff8 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T80_309_MaxProfit.java @@ -0,0 +1,39 @@ +package com.markilue.leecode.hot100.second; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.hot100.second + *@Author: markilue + *@CreateTime: 2023-05-31 13:22 + *@Description: TODO 力扣309 最佳买卖股票时机含冷冻期 + *@Version: 1.0 + */ +public class T80_309_MaxProfit { + + /** + * 动态规划: + * 状态分为: + * 1.今天没有股票(不在冷冻期) + * 2.今天没有股票(在冷冻期) ->刚刚卖出 + * 3.今天买了股票 + * @param prices + * @return + */ + public int maxProfit(int[] prices) { + + //对应状态1 2 3 + int dp0 = 0; + int dp1 = 0; + int dp2 = -prices[0]; + int temp; + for (int i = 0; i < prices.length; i++) { + temp = dp0; + dp0 = Math.max(dp0, dp1);//昨天就没买股票;昨天在冷冻期 + dp1 = dp2 + prices[i];//昨天有股票,今天卖了 + dp2 = Math.max(dp2, temp - prices[i]);//昨天有股票;昨天没股票且不再冷冻期,今天买了 + } + + return Math.max(dp0, dp1); + + } +}