diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/union_find/LC_685_FindRedundantConnection.java b/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/union_find/LC_685_FindRedundantConnection.java index c73a060..50d391e 100644 --- a/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/union_find/LC_685_FindRedundantConnection.java +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/interviewHot/union_find/LC_685_FindRedundantConnection.java @@ -2,6 +2,7 @@ package com.markilue.leecode.hot100.interviewHot.union_find; import org.junit.Test; +import java.util.ArrayList; import java.util.Arrays; /** @@ -14,9 +15,105 @@ import java.util.Arrays; */ public class LC_685_FindRedundantConnection { - public int[] findRedundantDirectedConnection(int[][] edges) { + 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 (father[u] == 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; + } + + /** + * 在有向图里找到需要删除的那条边,删除之后会变为树结构 + * @param edges + * @return + */ + private int[] getRemoveEdge(int[][] edges) { + init(father); + for (int[] edge : edges) { + if (same(edge[0], edge[1])) { + return edge;//有连接的 + } + join(edge[0], edge[1]); + } + return null; } + /** + * 删除一条边之后判断是不是树 + * @param edges + * @param deleteEdge 要删除的边 + * @return + */ + private boolean isTreeAfterRemoveEdge(int[][] edges, int deleteEdge) { + init(father); + for (int i = 0; i < edges.length; i++) { + //跳过删除的边,判断是否为树 + if (deleteEdge == i) continue; + if (same(edges[i][0], edges[i][1])) { + return false; + } + join(edges[i][0], edges[i][1]); + } + return true; + } + + + public int[] findRedundantDirectedConnection(int[][] edges) { + n = 1010; + father = new int[n]; + init(father); + //判断图的入度 + int[] oneDegree = new int[n]; + for (int[] edge : edges) { + oneDegree[edge[1]]++; + } + + // 找入度为2的节点所对应的边,注意要倒序,因为优先返回最后出现在二维数组中的答案 + ArrayList twoDegree = new ArrayList<>(); + + for (int i = edges.length - 1; i >= 0; i--) { + if (oneDegree[edges[i][1]] == 2) { + twoDegree.add(i); + } + } + + + // 处理图中情况1 和 情况2 + // 如果有入度为2的节点,那么一定是两条边里删一个,看删哪个可以构成树 + if (!twoDegree.isEmpty()) { + if (isTreeAfterRemoveEdge(edges, twoDegree.get(0))) { + return edges[twoDegree.get(0)]; + } + return edges[twoDegree.get(1)]; + } + + + return getRemoveEdge(edges); + } + } diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/second/T75_283_MoveZeroes.java b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T75_283_MoveZeroes.java new file mode 100644 index 0000000..4786711 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T75_283_MoveZeroes.java @@ -0,0 +1,60 @@ +package com.markilue.leecode.hot100.second; + +import org.junit.Test; + +import java.util.Arrays; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.hot100.second + *@Author: markilue + *@CreateTime: 2023-05-30 17:15 + *@Description: TODO 力扣283 移动零: + *@Version: 1.0 + */ +public class T75_283_MoveZeroes { + + @Test + public void test() { + int[] nums = {0, 1, 0, 3, 12}; + moveZeroes(nums); + System.out.println(Arrays.toString(nums)); + } + + //插入排序 + public void moveZeroes(int[] nums) { + + for (int i = nums.length - 1; i >= 0; i--) { + if (nums[i] == 0) { + //需要更换位置 + int j = i; + while (j < nums.length - 1 && nums[j + 1] != 0) { + nums[j] = nums[j + 1]; + j++; + } + nums[j] = 0; + } + } + + } + + //双指针 + public void moveZeroes1(int[] nums) { + int left = 0; + int right = 0;//寻找不是0的 注意是从0开始不是从length开始 + while (right < nums.length) { + if (nums[right] != 0) { + swap(nums, left, right); + left++; + } + right++; + } + } + + private void swap(int[] nums, int left, int right) { + int temp = nums[left]; + nums[left] = nums[right]; + nums[right] = temp; + } + +} diff --git a/Leecode/src/main/java/com/markilue/leecode/hot100/second/T76_287_FindDuplicate.java b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T76_287_FindDuplicate.java new file mode 100644 index 0000000..8fc0aa1 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T76_287_FindDuplicate.java @@ -0,0 +1,34 @@ +package com.markilue.leecode.hot100.second; + +import org.junit.Test; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.hot100.second + *@Author: markilue + *@CreateTime: 2023-05-30 17:46 + *@Description: TODO 力扣287 寻找重复数 + *@Version: 1.0 + */ +public class T76_287_FindDuplicate { + + @Test + public void test() { + int[] nums = {1, 3, 4, 2, 2}; + System.out.println(findDuplicate(nums)); + } + + //改变数组 + public int findDuplicate(int[] nums) { + for (int i = 0; i < nums.length; i++) { + nums[nums[i] % nums.length] += nums.length; + } + + for (int i = 0; i < nums.length; i++) { + if (nums[i] / nums.length > 1) { + return i; + } + } + return -1; + } +} 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 new file mode 100644 index 0000000..3795046 --- /dev/null +++ b/Leecode/src/main/java/com/markilue/leecode/hot100/second/T77_297_Codec.java @@ -0,0 +1,92 @@ +package com.markilue.leecode.hot100.second; + +import com.markilue.leecode.tree.TreeNode; +import com.markilue.leecode.tree.TreeUtils; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + *@BelongsProject: Leecode + *@BelongsPackage: com.markilue.leecode.hot100.second + *@Author: markilue + *@CreateTime: 2023-05-30 17:58 + *@Description: TODO 力扣297 二叉树的序列化与反序列化 + *@Version: 1.0 + */ +public class T77_297_Codec { + + @Test + public void test() { + List nodeList = new ArrayList<>(Arrays.asList(1, 2, 3, null, null, 4, 5)); + TreeNode root = TreeUtils.structureTree(nodeList, 0); + System.out.println(serialize(root)); + TreeNode next = deserialize(serialize(root)); + TreeUtils.printTreeByLevel(next); +// System.out.println(next); + } + + + // Encodes a tree to a single string. + public String serialize(TreeNode root) { + StringBuilder sb = new StringBuilder(); + serialize(root, sb); + return sb.toString(); + } + + public void serialize(TreeNode node, StringBuilder sb) { + if (node == null) { + return; + } + sb.append(node.val); + if (node.left != null) { + sb.append("("); + serialize(node.left, sb); + sb.append(")"); + } + if (node.right != null) { + if (node.left == null) { + sb.append("()"); + } + sb.append("("); + serialize(node.right, sb); + sb.append(")"); + } + } + + int in = 0; + + // Decodes your encoded data to tree. + public TreeNode deserialize(String data) { + if (in >= data.length() || data.charAt(in) == ')') { + return null; + } + TreeNode root = new TreeNode(); + int multi = 1; + if (data.charAt(in) == '-') { + multi = -1; + in++; + } + + while (in < data.length() && data.charAt(in) >= '0' && data.charAt(in) <= '9') { + root.val = root.val * 10 + data.charAt(in)-'0'; + in++; + } + root.val *= multi; + if(in