From 2cfd2ffab357c18aebd97c5d0baf008192f03ee9 Mon Sep 17 00:00:00 2001 From: "ethan.zj" Date: Fri, 5 Jun 2020 14:51:02 +0800 Subject: [PATCH 01/43] =?UTF-8?q?=E6=9C=80=E5=A4=A7K=E4=B8=AA=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/algorithm/array/Merge.java | 20 ++++++++ src/main/java/algorithm/graph/FindOrder.java | 14 ++++++ src/main/java/algorithm/heap/KthLargest.java | 45 +++++++++++++++++ src/main/java/algorithm/link/Reverse.java | 22 +++++---- .../java/algorithm/queue/StackImplQueue.java | 48 +++++++++++++++++++ .../algorithm/str/IsValidParanthesis.java | 44 +++++++++++++++++ src/main/java/algorithm/str/Similarity.java | 1 + 7 files changed, 186 insertions(+), 8 deletions(-) create mode 100644 src/main/java/algorithm/array/Merge.java create mode 100644 src/main/java/algorithm/heap/KthLargest.java create mode 100644 src/main/java/algorithm/queue/StackImplQueue.java create mode 100644 src/main/java/algorithm/str/IsValidParanthesis.java diff --git a/src/main/java/algorithm/array/Merge.java b/src/main/java/algorithm/array/Merge.java new file mode 100644 index 0000000..3eb298c --- /dev/null +++ b/src/main/java/algorithm/array/Merge.java @@ -0,0 +1,20 @@ +package algorithm.array; + +public class Merge { + + public void merge(int[] nums1, int m, int[] nums2, int n) { + int left = m - 1; + int right = n - 1; + int index = m + n - 1; + while (left >= 0 && right >= 0) { + if (nums1[left] > nums2[right]) { + nums1[index--] = nums1[left--]; + } else { + nums1[index--] = nums2[right--]; + } + } + + // 左边索引到-1之后,nums2还有数据,需要copy + System.arraycopy(nums2, 0, nums1, 0, right + 1); + } +} diff --git a/src/main/java/algorithm/graph/FindOrder.java b/src/main/java/algorithm/graph/FindOrder.java index 30d1884..b2f1c7d 100644 --- a/src/main/java/algorithm/graph/FindOrder.java +++ b/src/main/java/algorithm/graph/FindOrder.java @@ -9,8 +9,13 @@ */ class FindOrder { + // 存储有向图 private List> edges; + + // private int[] visited; + + // private boolean invalid = false; private int[] res; private int index; @@ -38,6 +43,7 @@ public int[] findOrder(int numCourses, int[][] prerequisites) { if (invalid) { return new int[0]; } + return res; } @@ -46,6 +52,7 @@ public void dfs(int u) { for (int v : edges.get(u)) { if (visited[v] == 0) { dfs(v); + if (invalid) { return; } @@ -57,4 +64,11 @@ public void dfs(int u) { visited[u] = 2; res[index--] = u; } + + public static void main(String[] args) { + int n = 4; + int[][] pres = new int[][]{new int[]{1, 0}, new int[]{2, 0}, new int[]{3, 1}, new int[]{3, 2}}; + + new FindOrder().findOrder(n, pres); + } } diff --git a/src/main/java/algorithm/heap/KthLargest.java b/src/main/java/algorithm/heap/KthLargest.java new file mode 100644 index 0000000..23806bf --- /dev/null +++ b/src/main/java/algorithm/heap/KthLargest.java @@ -0,0 +1,45 @@ +package algorithm.heap; + +import java.util.PriorityQueue; + +public class KthLargest { + + final PriorityQueue queue; + + final int k; + + public KthLargest(int[] a, int k) { + this.queue = new PriorityQueue<>(k); + this.k = k; + for (int temp : a) { + this.queue.add(temp); + } + } + + public int add(int x) { + if (this.queue.size() < k) { + this.queue.add(x); + } else if (x > this.queue.peek()) { + this.queue.poll(); + this.queue.add(x); + } + + return queue.peek(); + } + + public static void main(String[] args) { + PriorityQueue queue = new PriorityQueue<>(3); + + + queue.add(1); + queue.add(2); + queue.add(3); + queue.add(4); + queue.add(5); + + System.out.println(queue.poll()); + System.out.println(queue.poll()); + System.out.println(queue.poll()); + System.out.println(queue.poll()); + } +} diff --git a/src/main/java/algorithm/link/Reverse.java b/src/main/java/algorithm/link/Reverse.java index 71b0f7f..52fa8d7 100644 --- a/src/main/java/algorithm/link/Reverse.java +++ b/src/main/java/algorithm/link/Reverse.java @@ -8,13 +8,19 @@ */ public class Reverse { - public void reverse(Node header) { - if (header == null || header.next == null) { - return; - } + public void reverse(Node head) { + Node cur = null; + Node prev = head; + while (prev != null) { + Node next = head.next; + prev.next = cur; - Node current = header.next; - Node next = current.next; - //while () - } + cur = prev; + prev = next; + } + } + + public static void main(String[] args) { + System.out.println("()".substring(2, 2).length()); + } } diff --git a/src/main/java/algorithm/queue/StackImplQueue.java b/src/main/java/algorithm/queue/StackImplQueue.java new file mode 100644 index 0000000..b127fe3 --- /dev/null +++ b/src/main/java/algorithm/queue/StackImplQueue.java @@ -0,0 +1,48 @@ +package algorithm.queue; + +import java.util.Stack; + +public class StackImplQueue { + + private Stack s1; + + private Stack s2; + + private Integer front; + + /** Initialize your data structure here. */ + public StackImplQueue() { + s1 = new Stack<>(); + s2 = new Stack<>(); + } + + /** Push element x to the back of queue. */ + public void push(int x) { + if (s1.isEmpty()) { + front = x; + } + + s1.push(x); + } + + /** Removes the element from in front of queue and returns that element. */ + public int pop() { + if (s2.isEmpty()) { + while (!s1.isEmpty()) { + s2.push(s1.pop()); + } + } + + return s2.pop(); + } + + /** Get the front element. */ + public int peek() { + return !s2.isEmpty() ? s2.peek() : front; + } + + /** Returns whether the queue is empty. */ + public boolean empty() { + return s1.isEmpty() && s2.isEmpty(); + } +} diff --git a/src/main/java/algorithm/str/IsValidParanthesis.java b/src/main/java/algorithm/str/IsValidParanthesis.java new file mode 100644 index 0000000..c4ef202 --- /dev/null +++ b/src/main/java/algorithm/str/IsValidParanthesis.java @@ -0,0 +1,44 @@ +package algorithm.str; + +import java.util.HashMap; +import java.util.Map; +import java.util.Stack; + +public class IsValidParanthesis { + + private Map params = new HashMap<>(); + + { + this.params.put(')', '('); + this.params.put(']', '['); + this.params.put('}', '{'); + } + + public boolean isValid(String s) { + if (s == null) { + return false; + } + + if ("".equals(s)) { + return true; + } + + Stack stack = new Stack<>(); + for (Character c : s.toCharArray()) { + if (this.params.containsKey(c)) { + if (stack.pop() != this.params.get(c) || stack.isEmpty()) { + return false; + } + + } else { + stack.push(c); + } + } + + return stack.isEmpty(); + } + + public static void main(String[] args) { + System.out.println(new IsValidParanthesis().isValid("[")); + } +} diff --git a/src/main/java/algorithm/str/Similarity.java b/src/main/java/algorithm/str/Similarity.java index 9ae1384..958e09f 100644 --- a/src/main/java/algorithm/str/Similarity.java +++ b/src/main/java/algorithm/str/Similarity.java @@ -55,6 +55,7 @@ public static float cos(String a, String b) { for (int i : bVec) { p3 += (i * i); } + p3 = (float) Math.sqrt(p3); return ((float) p1) / (p2 * p3); From 7d40bdfa0a73c97ec5b7a355d2c894ece4bdc4db Mon Sep 17 00:00:00 2001 From: "ethan.zj" Date: Thu, 11 Jun 2020 14:54:04 +0800 Subject: [PATCH 02/43] =?UTF-8?q?=E5=B9=B6=E6=9F=A5=E9=9B=86&=E5=8D=95?= =?UTF-8?q?=E8=B0=83=E6=A0=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../algorithm/stack/DailyTemperatures.java | 25 ++++++++++++ .../java/algorithm/union/QuickUnionUF.java | 38 +++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 src/main/java/algorithm/stack/DailyTemperatures.java create mode 100644 src/main/java/algorithm/union/QuickUnionUF.java diff --git a/src/main/java/algorithm/stack/DailyTemperatures.java b/src/main/java/algorithm/stack/DailyTemperatures.java new file mode 100644 index 0000000..a9748cd --- /dev/null +++ b/src/main/java/algorithm/stack/DailyTemperatures.java @@ -0,0 +1,25 @@ +package algorithm.stack; + +import java.util.Deque; +import java.util.LinkedList; + +/** + * https://leetcode-cn.com/problems/daily-temperatures/submissions/ + */ +public class DailyTemperatures { + + public int[] dailyTemperatures(int[] T) { + int[] ans = new int[T.length]; + Deque deque = new LinkedList<>(); + for (int i = 0; i < T.length; i++) { + while (!deque.isEmpty() && T[i] > T[deque.peek()]) { + int prevIndex = deque.pop(); + ans[prevIndex] = i - prevIndex; + } + + deque.push(i); + } + + return ans; + } +} diff --git a/src/main/java/algorithm/union/QuickUnionUF.java b/src/main/java/algorithm/union/QuickUnionUF.java new file mode 100644 index 0000000..a17a019 --- /dev/null +++ b/src/main/java/algorithm/union/QuickUnionUF.java @@ -0,0 +1,38 @@ +package algorithm.union; + +public class QuickUnionUF { + + private int[] roots; + + public QuickUnionUF(int N) { + roots = new int[N]; + for (int i = 0; i < roots.length; i++) { + roots[i] = i; + } + } + + private int findRoot(int i) { + int root = i; + while (root != roots[root]) { + root = roots[root]; + } + + while (i != roots[i]) { + int tmp = roots[i]; + roots[i] = root; + i = tmp; + } + + return root; + } + + public boolean connected(int p, int q) { + return findRoot(p) == findRoot(q); + } + + public void union(int p, int q) { + int qroot = findRoot(q); + int proot = findRoot(p); + roots[proot] = roots[qroot]; + } +} From 223cc7397be7ff8f84d91f1f52e82dd348ab8fd9 Mon Sep 17 00:00:00 2001 From: "ethan.zj" Date: Sat, 13 Jun 2020 23:16:02 +0800 Subject: [PATCH 03/43] =?UTF-8?q?=E7=88=AC=E6=A5=BC=E6=A2=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/algorithm/array/ClimbStairs.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/main/java/algorithm/array/ClimbStairs.java diff --git a/src/main/java/algorithm/array/ClimbStairs.java b/src/main/java/algorithm/array/ClimbStairs.java new file mode 100644 index 0000000..4ed1817 --- /dev/null +++ b/src/main/java/algorithm/array/ClimbStairs.java @@ -0,0 +1,20 @@ +package algorithm.array; + +/** + * https://leetcode-cn.com/problems/climbing-stairs/submissions/ + */ +public class ClimbStairs { + + public int climbStairs(int n) { + int a = 0; + int b = 0; + int r = 1; + for (int i = 0; i < n; ++i) { + a = b; + b = r; + r = a + b; + } + + return r; + } +} From 5d9ddd3018e7251742ffbe898345e78c87640c44 Mon Sep 17 00:00:00 2001 From: Ethan Date: Fri, 11 Feb 2022 19:40:23 +0800 Subject: [PATCH 04/43] =?UTF-8?q?=E6=9C=80=E5=B0=8F=E8=A6=86=E7=9B=96?= =?UTF-8?q?=E5=AD=90=E4=B8=B2/=E5=89=8D=E7=BC=80=E5=92=8C/=E4=B8=80?= =?UTF-8?q?=E4=B8=AA=E5=AD=A4=E6=95=B0/=E4=B8=A4=E4=B8=AA=E5=AD=A4?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 29 ++++- src/main/java/algorithm/Solution.java | 69 ----------- .../java/algorithm/array/ClimbStairs.java | 20 ---- .../algorithm/array/ContainsDuplicate.java | 37 ------ src/main/java/algorithm/array/Merge.java | 20 ---- src/main/java/algorithm/array/MergeSort.java | 60 ---------- src/main/java/algorithm/array/NumArray.java | 38 ++++++ src/main/java/algorithm/array/QuickSort.java | 54 --------- src/main/java/algorithm/array/Rotate.java | 69 ----------- .../java/algorithm/array/SingleNumber.java | 46 -------- .../java/algorithm/array/StockComputeII.java | 91 --------------- src/main/java/algorithm/cache/LRUCache.java | 92 --------------- src/main/java/algorithm/graph/FindOrder.java | 74 ------------ src/main/java/algorithm/heap/KthLargest.java | 45 -------- src/main/java/algorithm/link/Reverse.java | 26 ----- src/main/java/algorithm/link/model/Node.java | 12 -- src/main/java/algorithm/link/model/Nodes.java | 40 ------- src/main/java/algorithm/pruning/NQueens.java | 32 ------ .../java/algorithm/queue/StackImplQueue.java | 48 -------- .../algorithm/stack/DailyTemperatures.java | 25 ---- src/main/java/algorithm/stack/MinStack.java | 82 ------------- .../algorithm/str/IsValidParanthesis.java | 44 ------- .../algorithm/str/ParanthesisGenerator.java | 44 ------- src/main/java/algorithm/str/Similarity.java | 63 ---------- .../java/algorithm/str/ValidPalindrome.java | 32 ------ src/main/java/algorithm/tree/Depth.java | 107 ----------------- src/main/java/algorithm/tree/LevelOrder.java | 53 --------- src/main/java/algorithm/tree/Traversal.java | 108 ------------------ .../java/algorithm/tree/model/TreeNode.java | 53 --------- .../java/algorithm/tree/model/TreeNodes.java | 68 ----------- .../java/algorithm/union/QuickUnionUF.java | 38 ------ src/main/java/bit/OneSolitaryNumber.java | 34 ++++++ src/main/java/bit/TwoSolitaryNumber.java | 73 ++++++++++++ ...\347\233\226\345\255\220\344\270\262.java" | 65 +++++++++++ 34 files changed, 238 insertions(+), 1553 deletions(-) delete mode 100644 src/main/java/algorithm/Solution.java delete mode 100644 src/main/java/algorithm/array/ClimbStairs.java delete mode 100644 src/main/java/algorithm/array/ContainsDuplicate.java delete mode 100644 src/main/java/algorithm/array/Merge.java delete mode 100644 src/main/java/algorithm/array/MergeSort.java create mode 100644 src/main/java/algorithm/array/NumArray.java delete mode 100644 src/main/java/algorithm/array/QuickSort.java delete mode 100644 src/main/java/algorithm/array/Rotate.java delete mode 100644 src/main/java/algorithm/array/SingleNumber.java delete mode 100644 src/main/java/algorithm/array/StockComputeII.java delete mode 100644 src/main/java/algorithm/cache/LRUCache.java delete mode 100644 src/main/java/algorithm/graph/FindOrder.java delete mode 100644 src/main/java/algorithm/heap/KthLargest.java delete mode 100644 src/main/java/algorithm/link/Reverse.java delete mode 100644 src/main/java/algorithm/link/model/Node.java delete mode 100644 src/main/java/algorithm/link/model/Nodes.java delete mode 100644 src/main/java/algorithm/pruning/NQueens.java delete mode 100644 src/main/java/algorithm/queue/StackImplQueue.java delete mode 100644 src/main/java/algorithm/stack/DailyTemperatures.java delete mode 100644 src/main/java/algorithm/stack/MinStack.java delete mode 100644 src/main/java/algorithm/str/IsValidParanthesis.java delete mode 100644 src/main/java/algorithm/str/ParanthesisGenerator.java delete mode 100644 src/main/java/algorithm/str/Similarity.java delete mode 100644 src/main/java/algorithm/str/ValidPalindrome.java delete mode 100644 src/main/java/algorithm/tree/Depth.java delete mode 100644 src/main/java/algorithm/tree/LevelOrder.java delete mode 100644 src/main/java/algorithm/tree/Traversal.java delete mode 100644 src/main/java/algorithm/tree/model/TreeNode.java delete mode 100644 src/main/java/algorithm/tree/model/TreeNodes.java delete mode 100644 src/main/java/algorithm/union/QuickUnionUF.java create mode 100644 src/main/java/bit/OneSolitaryNumber.java create mode 100644 src/main/java/bit/TwoSolitaryNumber.java create mode 100644 "src/main/java/window/\346\234\200\345\260\217\350\246\206\347\233\226\345\255\220\344\270\262.java" diff --git a/pom.xml b/pom.xml index 05f5019..b0cf76c 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,34 @@ io.netty netty-all - 4.1.49.Final + 4.1.32.Final + + + org.junit.jupiter + junit-jupiter-engine + 5.6.2 + test + + + org.cassandraunit + cassandra-unit-spring + 2.2.2.1 + test + + + org.springframework.security + spring-security-web + 5.3.4.RELEASE + + + joda-time + joda-time + 2.10.8 + + + org.apache.commons + commons-lang3 + 3.11 diff --git a/src/main/java/algorithm/Solution.java b/src/main/java/algorithm/Solution.java deleted file mode 100644 index 2f16e58..0000000 --- a/src/main/java/algorithm/Solution.java +++ /dev/null @@ -1,69 +0,0 @@ -package algorithm; - -import algorithm.tree.model.TreeNode; -import algorithm.tree.model.TreeNodes; - -import java.util.Deque; -import java.util.LinkedList; - -/** - * @author Ethan Zhang - * @email ethan.zj@antfin.com - */ -public class Solution { - - Deque Q = new LinkedList<>(); - - Deque P = new LinkedList<>(); - - TreeNode currentP = null; - - TreeNode currentQ = null; - - public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { - currentP = p; - currentQ = q; - recursive(root); - - if (P.contains(q)) { - return q; - } else if (Q.contains(p)) { - return p; - } - - TreeNode result = null; - while (!Q.isEmpty() && !P.isEmpty()) { - TreeNode temp = Q.pollFirst(); - if (temp == P.pollFirst()) { - result = temp; - } - } - - return result; - } - - private void recursive(TreeNode root) { - if (root == null) { - return; - } - - recursive(root.left); - recursive(root.right); - - if (root.left == currentP || root.right == currentP) { - P.add(root); - currentP = root; - } - - if (root.left == currentQ || root.right == currentQ) { - Q.add(root); - currentQ = root; - } - } - - public static void main(String[] args) { - TreeNode[] root = TreeNodes.generate1(); - - new Solution().lowestCommonAncestor(root[0], root[1], root[2]); - } -} diff --git a/src/main/java/algorithm/array/ClimbStairs.java b/src/main/java/algorithm/array/ClimbStairs.java deleted file mode 100644 index 4ed1817..0000000 --- a/src/main/java/algorithm/array/ClimbStairs.java +++ /dev/null @@ -1,20 +0,0 @@ -package algorithm.array; - -/** - * https://leetcode-cn.com/problems/climbing-stairs/submissions/ - */ -public class ClimbStairs { - - public int climbStairs(int n) { - int a = 0; - int b = 0; - int r = 1; - for (int i = 0; i < n; ++i) { - a = b; - b = r; - r = a + b; - } - - return r; - } -} diff --git a/src/main/java/algorithm/array/ContainsDuplicate.java b/src/main/java/algorithm/array/ContainsDuplicate.java deleted file mode 100644 index c3fb3b3..0000000 --- a/src/main/java/algorithm/array/ContainsDuplicate.java +++ /dev/null @@ -1,37 +0,0 @@ -package algorithm.array; - -import java.util.Arrays; -import java.util.HashSet; - -/** - * @author Ethan Zhang - * @email ethan.zj@antfin.com - */ -public class ContainsDuplicate { - - public boolean containsDuplicate(int[] nums) { - Arrays.sort(nums); - - for (int i = 0; i < nums.length - 1; i++) { - if (nums[i] == nums[i + 1]) { - return true; - } - } - - return false; - } - - public boolean containsDuplicateI(int[] nums) { - HashSet set = new HashSet<>(nums.length); - - for (int i = 0; i < nums.length; i++) { - if (set.contains(nums[i])) { - return true; - } - - set.add(nums[i]); - } - - return false; - } -} diff --git a/src/main/java/algorithm/array/Merge.java b/src/main/java/algorithm/array/Merge.java deleted file mode 100644 index 3eb298c..0000000 --- a/src/main/java/algorithm/array/Merge.java +++ /dev/null @@ -1,20 +0,0 @@ -package algorithm.array; - -public class Merge { - - public void merge(int[] nums1, int m, int[] nums2, int n) { - int left = m - 1; - int right = n - 1; - int index = m + n - 1; - while (left >= 0 && right >= 0) { - if (nums1[left] > nums2[right]) { - nums1[index--] = nums1[left--]; - } else { - nums1[index--] = nums2[right--]; - } - } - - // 左边索引到-1之后,nums2还有数据,需要copy - System.arraycopy(nums2, 0, nums1, 0, right + 1); - } -} diff --git a/src/main/java/algorithm/array/MergeSort.java b/src/main/java/algorithm/array/MergeSort.java deleted file mode 100644 index ee878e9..0000000 --- a/src/main/java/algorithm/array/MergeSort.java +++ /dev/null @@ -1,60 +0,0 @@ -package algorithm.array; - -import java.util.Arrays; - -/** - * @author Ethan Zhang - * @email ethan.zj@antfin.com - */ -public class MergeSort { - - public static void main(String[] args) { - int[] arr = {9, 8, 7, 6, 5, 4, 3, 2, 1}; - sort(arr); - - System.out.println(Arrays.toString(arr)); - } - - public static void sort(int[] arr) { - int[] temp = new int[arr.length];//在排序前,先建好一个长度等于原数组长度的临时数组,避免递归中频繁开辟空间 - sort(arr, 0, arr.length - 1, temp); - } - - private static void sort(int[] arr, int left, int right, int[] temp) { - if (left < right) { - return; - } - - int mid = (left + right) / 2; - sort(arr, left, mid, temp);//左边归并排序,使得左子序列有序 - sort(arr, mid + 1, right, temp);//右边归并排序,使得右子序列有序 - merge(arr, left, mid, right, temp);//将两个有序子数组合并操作 - } - - private static void merge(int[] arr, int left, int mid, int right, int[] temp) { - int i = left;//左序列指针 - int j = mid + 1;//右序列指针 - int t = 0;//临时数组指针 - while (i <= mid && j <= right) { - if (arr[i] <= arr[j]) { - temp[t++] = arr[i++]; - } else { - temp[t++] = arr[j++]; - } - } - - while (i <= mid) {//将左边剩余元素填充进temp中 - temp[t++] = arr[i++]; - } - - while (j <= right) {//将右序列剩余元素填充进temp中 - temp[t++] = arr[j++]; - } - - t = 0; - //将temp中的元素全部拷贝到原数组中 - while (left <= right) { - arr[left++] = temp[t++]; - } - } -} diff --git a/src/main/java/algorithm/array/NumArray.java b/src/main/java/algorithm/array/NumArray.java new file mode 100644 index 0000000..a860887 --- /dev/null +++ b/src/main/java/algorithm/array/NumArray.java @@ -0,0 +1,38 @@ +package algorithm.array; + +/** + * 1 1 1 1 1 1 + * 0 1 1 1 1 1 1 + * + * + * @author Ethan Zhang + * @date 2022/1/20 + */ +public class NumArray { + + private final int[] nums; + + public NumArray(int[] nums) { + this.nums = new int[nums.length + 1]; + + int sum = this.nums[0]; + for (int i = 0; i < nums.length; i++) { + sum += nums[i]; + + this.nums[i + 1] = sum; + } + } + + public int sumRange(int left, int right) { + if (left < 0 || right > nums.length - 1 || left > right) { + return 0; + } + + return this.nums[right + 1] - this.nums[left]; + } + + public static void main(String[] args) { + System.out.println(new NumArray(new int[]{1, 2, 3, 4, 5}).sumRange(0, 4)); + System.out.println(new NumArray(new int[]{1, 2, 3, 4, 5}).sumRange(0, 2)); + } +} diff --git a/src/main/java/algorithm/array/QuickSort.java b/src/main/java/algorithm/array/QuickSort.java deleted file mode 100644 index 1ef7c11..0000000 --- a/src/main/java/algorithm/array/QuickSort.java +++ /dev/null @@ -1,54 +0,0 @@ -package algorithm.array; - -import java.util.Arrays; - -/** - * @author Ethan Zhang - * @email ethan.zj@antfin.com - */ -public class QuickSort { - - public void sort(int[] nums) { - if (nums == null || nums.length == 0) { - return; - } - - quickSort(nums, 0, nums.length - 1); - } - - private void quickSort(int[] nums, int start, int end) { - if (start >= end) { - return; - } - - int basic = nums[start]; - int left = start; - int right = end; - while (left < right) { - while (nums[right] >= basic && left < right) { - right--; - } - - while (nums[left] <= basic && left < right) { - left++; - } - - int temp = nums[right]; - nums[right] = nums[left]; - nums[left] = temp; - } - - nums[start] = nums[left]; - nums[left] = basic; - - quickSort(nums, start, right - 1); - quickSort(nums, right + 1, end); - } - - public static void main(String[] args) { - int[] input = {3, 2, 1}; - new QuickSort().sort(input); - - System.out.println(Arrays.toString(input)); - } -} diff --git a/src/main/java/algorithm/array/Rotate.java b/src/main/java/algorithm/array/Rotate.java deleted file mode 100644 index f798429..0000000 --- a/src/main/java/algorithm/array/Rotate.java +++ /dev/null @@ -1,69 +0,0 @@ -package algorithm.array; - -/** - * https://leetcode-cn.com/problems/rotate-array/ - * - * @author Ethan Zhang - * @email ethan.zj@antfin.com - */ -public class Rotate { - - // 暴力解法 - public void rotate(int[] nums, int k) { - k %= nums.length; - - int previous, temp; - - for (int i = 0; i < k; i++) { - previous = nums[nums.length - 1]; - for (int j = 0; j < nums.length; j++) { - temp = nums[j]; - nums[j] = previous; - previous = temp; - } - } - } - - // 占位法 - public void rotateI(int[] nums, int k) { - k %= nums.length; - - int count = 0; - for (int i = 0; count < nums.length; i++) { - int prev = nums[i]; - int prevIndex = i; - - do { - int next = (prevIndex + k) % nums.length; - - int temp = nums[next]; - nums[next] = prev; - - prev = temp; - prevIndex = next; - - count++; - } while (prevIndex != i); - } - } - - // 三次反转 - public void rotateII(int[] nums, int k) { - k %= nums.length; - - reverse(nums, 0, nums.length - 1); - reverse(nums, 0, k - 1); - reverse(nums, k, nums.length - 1); - } - - private void reverse(int[] nums, int start, int end) { - while (start < end) { - int temp = nums[start]; - nums[start] = nums[end]; - nums[end] = temp; - - start++; - end--; - }; - } -} diff --git a/src/main/java/algorithm/array/SingleNumber.java b/src/main/java/algorithm/array/SingleNumber.java deleted file mode 100644 index 9af2978..0000000 --- a/src/main/java/algorithm/array/SingleNumber.java +++ /dev/null @@ -1,46 +0,0 @@ -package algorithm.array; - -import java.util.Arrays; - -/** - * @author Ethan Zhang - * @email ethan.zj@antfin.com - */ -public class SingleNumber { - - public int singleNumber(int[] nums) { - if (nums == null || nums.length == 0) { - return 0; - } - - if (nums.length == 1) { - return nums[1]; - } - - Arrays.sort(nums); - - Integer prev = nums[0]; - int count = 0; - int result = 0; - for (int i = 0; i < nums.length; i++) { - if (nums[i] == prev) { - count++; - } else { - if (count == 1) { - result = nums[i]; - break; - } - - count = 1; - } - - prev = nums[i]; - } - - return result; - } - - public static void main(String[] args) { - new SingleNumber().singleNumber(new int[]{2, 2, 1}); - } -} diff --git a/src/main/java/algorithm/array/StockComputeII.java b/src/main/java/algorithm/array/StockComputeII.java deleted file mode 100644 index 192fde0..0000000 --- a/src/main/java/algorithm/array/StockComputeII.java +++ /dev/null @@ -1,91 +0,0 @@ -package algorithm.array; - -/** - * @author Ethan Zhang - * @email ethan.zj@antfin.com - */ -public class StockComputeII { - - public int maxProfit(int[] prices) { - if (prices.length == 1) { - return 0; - } - - int sum = 0; - int prev = 0; - for (int i = 0; i < prices.length; i++) { - if (i == 0) { - prev = prices[i]; - continue; - } - - if (prices[i] - prev >= 0) { - sum += prices[i] - prev; - } - - prev = prices[i]; - } - - return sum; - } - - // 非贪心算法 - public int maxProfit1(int[] prices) { - if (prices.length == 1) { - return 0; - } - - int sum = 0; - int initial = 0; - int prev = 0; - int step = 0; - for (int i = 0; i < prices.length; i++) { - if (i == 0) { - prev = prices[i]; - continue; - } - - if (prices[i] - prev <= 0 || i == prices.length - 1) { - if (step > 0) { - if (i == prices.length - 1 && prices[i] - prev > 0) { - sum += prices[i] - initial; - } else { - sum += prev - initial; - } - } else if (i == prices.length - 1 && prices[i] - prev > 0) { - sum += prices[i] - prev; - } - - initial = 0; - step = 0; - } else { - if (step == 0) { - initial = prev; - } - - step++; - } - - prev = prices[i]; - } - - return sum; - } - - public static void main(String[] args) { - int[] array = new int[]{7,1,5,3,6,4}; - - new StockComputeII().maxProfit(array); - new StockComputeII().maxProfit1(array); - - array = new int[]{1,2,3,4,5}; - - new StockComputeII().maxProfit(array); - new StockComputeII().maxProfit1(array); - - array = new int[]{7,6,4,3,1}; - - new StockComputeII().maxProfit(array); - new StockComputeII().maxProfit1(array); - } -} diff --git a/src/main/java/algorithm/cache/LRUCache.java b/src/main/java/algorithm/cache/LRUCache.java deleted file mode 100644 index 6bd32b5..0000000 --- a/src/main/java/algorithm/cache/LRUCache.java +++ /dev/null @@ -1,92 +0,0 @@ -package algorithm.cache; - -import java.util.*; - -/** - * @author Ethan Zhang - * @email ethan.zj@antfin.com - */ -public class LRUCache { - - private Deque deque; - - private Map cache; - - private int capacity; - - static class Node { - int key; - - int value; - - public Node(int key, int value) { - this.key = key; - this.value = value; - } - } - - public LRUCache(int capacity) { - this.deque = new LinkedList<>(); - this.cache = new HashMap<>(); - this.capacity = capacity; - } - - public int get(int key) { - if (!cache.containsKey(key)) { - return -1; - } - - Node node = cache.get(key); - deque.remove(node); - deque.addFirst(node); - - return node.value; - } - - - public void put(int key, int value) { - if (cache.containsKey(key)) { - Node old = cache.get(key); - - Node newer = new Node(key, value); - cache.put(key, newer); - deque.remove(old); - deque.addFirst(newer); - - return; - } - - if (this.capacity == cache.size()) { - Node last = deque.getLast(); - deque.removeLast(); - cache.remove(last.key); - } - - Node cur = new Node(key, value); - deque.addFirst(cur); - cache.put(cur.key, cur); - } - - public static void main(String[] args) { - ArrayDeque deque = new ArrayDeque<>(); - - deque.addFirst("1"); - deque.addFirst("2"); - deque.addFirst("3"); - deque.addFirst("4"); - deque.addFirst("5"); - deque.addFirst("6"); - deque.addFirst("7"); - deque.addFirst("8"); - - deque.addLast("9"); - deque.addLast("10"); - deque.addLast("11"); - deque.addLast("12"); - deque.addLast("13"); - deque.addLast("14"); - deque.addLast("15"); - deque.addLast("16"); - deque.addLast("17"); - } -} diff --git a/src/main/java/algorithm/graph/FindOrder.java b/src/main/java/algorithm/graph/FindOrder.java deleted file mode 100644 index b2f1c7d..0000000 --- a/src/main/java/algorithm/graph/FindOrder.java +++ /dev/null @@ -1,74 +0,0 @@ -package algorithm.graph; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author Ethan Zhang - * @email ethan.zj@antfin.com - */ -class FindOrder { - - // 存储有向图 - private List> edges; - - // - private int[] visited; - - // - private boolean invalid = false; - private int[] res; - private int index; - - public int[] findOrder(int numCourses, int[][] prerequisites) { - edges = new ArrayList<>(numCourses); - for (int i = 0; i < numCourses; i++) { - edges.add(new ArrayList<>()); - } - - for (int[] pre : prerequisites) { - edges.get(pre[1]).add(pre[0]); - } - - res = new int[numCourses]; - index = numCourses - 1; - visited = new int[numCourses]; - - for (int i = 0; i < edges.size(); i++) { - if (visited[i] == 0) { - dfs(i); - } - } - - if (invalid) { - return new int[0]; - } - - return res; - } - - public void dfs(int u) { - visited[u] = 1; - for (int v : edges.get(u)) { - if (visited[v] == 0) { - dfs(v); - - if (invalid) { - return; - } - } else if (visited[v] == 1) { - invalid = true; - } - } - - visited[u] = 2; - res[index--] = u; - } - - public static void main(String[] args) { - int n = 4; - int[][] pres = new int[][]{new int[]{1, 0}, new int[]{2, 0}, new int[]{3, 1}, new int[]{3, 2}}; - - new FindOrder().findOrder(n, pres); - } -} diff --git a/src/main/java/algorithm/heap/KthLargest.java b/src/main/java/algorithm/heap/KthLargest.java deleted file mode 100644 index 23806bf..0000000 --- a/src/main/java/algorithm/heap/KthLargest.java +++ /dev/null @@ -1,45 +0,0 @@ -package algorithm.heap; - -import java.util.PriorityQueue; - -public class KthLargest { - - final PriorityQueue queue; - - final int k; - - public KthLargest(int[] a, int k) { - this.queue = new PriorityQueue<>(k); - this.k = k; - for (int temp : a) { - this.queue.add(temp); - } - } - - public int add(int x) { - if (this.queue.size() < k) { - this.queue.add(x); - } else if (x > this.queue.peek()) { - this.queue.poll(); - this.queue.add(x); - } - - return queue.peek(); - } - - public static void main(String[] args) { - PriorityQueue queue = new PriorityQueue<>(3); - - - queue.add(1); - queue.add(2); - queue.add(3); - queue.add(4); - queue.add(5); - - System.out.println(queue.poll()); - System.out.println(queue.poll()); - System.out.println(queue.poll()); - System.out.println(queue.poll()); - } -} diff --git a/src/main/java/algorithm/link/Reverse.java b/src/main/java/algorithm/link/Reverse.java deleted file mode 100644 index 52fa8d7..0000000 --- a/src/main/java/algorithm/link/Reverse.java +++ /dev/null @@ -1,26 +0,0 @@ -package algorithm.link; - -import algorithm.link.model.Node; - -/** - * @author Ethan Zhang - * @email ethan.zj@antfin.com - */ -public class Reverse { - - public void reverse(Node head) { - Node cur = null; - Node prev = head; - while (prev != null) { - Node next = head.next; - prev.next = cur; - - cur = prev; - prev = next; - } - } - - public static void main(String[] args) { - System.out.println("()".substring(2, 2).length()); - } -} diff --git a/src/main/java/algorithm/link/model/Node.java b/src/main/java/algorithm/link/model/Node.java deleted file mode 100644 index a8156bf..0000000 --- a/src/main/java/algorithm/link/model/Node.java +++ /dev/null @@ -1,12 +0,0 @@ -package algorithm.link.model; - -/** - * @author Ethan Zhang - * @email ethan.zj@antfin.com - */ -public class Node { - - public int val; - - public Node next; -} diff --git a/src/main/java/algorithm/link/model/Nodes.java b/src/main/java/algorithm/link/model/Nodes.java deleted file mode 100644 index 5d58c86..0000000 --- a/src/main/java/algorithm/link/model/Nodes.java +++ /dev/null @@ -1,40 +0,0 @@ -package algorithm.link.model; - -/** - * @author Ethan Zhang - * @email ethan.zj@antfin.com - */ -public class Nodes { - - public Node list() { - Node header = new Node(); - header.val = 1; - - Node n1 = new Node(); - n1.val = 2; - - header.next = n1; - - Node n2 = new Node(); - n2.val = 3; - - n1.next = n2; - - Node n3 = new Node(); - n3.val = 4; - - n2.next = n3; - - Node n4 = new Node(); - n4.val = 5; - - n3.next = n4; - - Node n5 = new Node(); - n5.val = 6; - - n4.next = n5; - - return header; - } -} diff --git a/src/main/java/algorithm/pruning/NQueens.java b/src/main/java/algorithm/pruning/NQueens.java deleted file mode 100644 index 97b9dcf..0000000 --- a/src/main/java/algorithm/pruning/NQueens.java +++ /dev/null @@ -1,32 +0,0 @@ -package algorithm.pruning; - -import java.util.HashMap; - -/** - * @author Ethan Zhang - * @email ethan.zj@antfin.com - */ -public class NQueens { - - public void traverse(int n) { - recursive(0, n); - } - - private void recursive(int row, int col) { - if (row >= col) { - return; - } - - for (int i = 0; i < col; i++) { - System.out.println(row + "---" + i); - } - - recursive(row + 1, col); - } - - public static void main(String[] args) { - new NQueens().traverse(4); - - HashMap[] map = new HashMap[9]; - } -} diff --git a/src/main/java/algorithm/queue/StackImplQueue.java b/src/main/java/algorithm/queue/StackImplQueue.java deleted file mode 100644 index b127fe3..0000000 --- a/src/main/java/algorithm/queue/StackImplQueue.java +++ /dev/null @@ -1,48 +0,0 @@ -package algorithm.queue; - -import java.util.Stack; - -public class StackImplQueue { - - private Stack s1; - - private Stack s2; - - private Integer front; - - /** Initialize your data structure here. */ - public StackImplQueue() { - s1 = new Stack<>(); - s2 = new Stack<>(); - } - - /** Push element x to the back of queue. */ - public void push(int x) { - if (s1.isEmpty()) { - front = x; - } - - s1.push(x); - } - - /** Removes the element from in front of queue and returns that element. */ - public int pop() { - if (s2.isEmpty()) { - while (!s1.isEmpty()) { - s2.push(s1.pop()); - } - } - - return s2.pop(); - } - - /** Get the front element. */ - public int peek() { - return !s2.isEmpty() ? s2.peek() : front; - } - - /** Returns whether the queue is empty. */ - public boolean empty() { - return s1.isEmpty() && s2.isEmpty(); - } -} diff --git a/src/main/java/algorithm/stack/DailyTemperatures.java b/src/main/java/algorithm/stack/DailyTemperatures.java deleted file mode 100644 index a9748cd..0000000 --- a/src/main/java/algorithm/stack/DailyTemperatures.java +++ /dev/null @@ -1,25 +0,0 @@ -package algorithm.stack; - -import java.util.Deque; -import java.util.LinkedList; - -/** - * https://leetcode-cn.com/problems/daily-temperatures/submissions/ - */ -public class DailyTemperatures { - - public int[] dailyTemperatures(int[] T) { - int[] ans = new int[T.length]; - Deque deque = new LinkedList<>(); - for (int i = 0; i < T.length; i++) { - while (!deque.isEmpty() && T[i] > T[deque.peek()]) { - int prevIndex = deque.pop(); - ans[prevIndex] = i - prevIndex; - } - - deque.push(i); - } - - return ans; - } -} diff --git a/src/main/java/algorithm/stack/MinStack.java b/src/main/java/algorithm/stack/MinStack.java deleted file mode 100644 index d5a8cab..0000000 --- a/src/main/java/algorithm/stack/MinStack.java +++ /dev/null @@ -1,82 +0,0 @@ -package algorithm.stack; - -import java.util.Arrays; - -/** - * @author Ethan Zhang - * @email ethan.zj@antfin.com - */ -public class MinStack { - - private Integer[] data; - - private Integer[] sortedData; - - private int currentIndex; - - /** initialize your data structure here. */ - public MinStack() { - data = new Integer[8]; - sortedData = new Integer[8]; - } - - public void push(int x) { - ensureCapacity(); - - if (currentIndex < 0) { - return; - } - - data[currentIndex] = x; - if (sortedData[currentIndex == 0 ? currentIndex : currentIndex - 1] == null) { - sortedData[currentIndex] = x; - } else { - sortedData[currentIndex] = Math.min(x, sortedData[currentIndex == 0 ?currentIndex : currentIndex - 1]); - } - - currentIndex++; - } - - private void ensureCapacity() { - if (currentIndex >= data.length) { - data = Arrays.copyOf(data, data.length + 8); - sortedData = Arrays.copyOf(sortedData, sortedData.length + 8); - } - } - - public void pop() { - data[currentIndex - 1] = null; - sortedData[currentIndex - 1] = null; - currentIndex--; - } - - public int top() { - return data[currentIndex - 1]; - } - - public int getMin() { - return sortedData[currentIndex - 1]; - } - - public static void main(String[] args) { - MinStack stack = new MinStack(); - stack.push(2); - stack.push(0); - stack.push(3); - stack.push(0); - - System.out.println(stack.getMin()); - - stack.pop(); - - System.out.println(stack.getMin()); - - stack.pop(); - - System.out.println(stack.getMin()); - - stack.pop(); - - System.out.println(stack.getMin()); - } -} diff --git a/src/main/java/algorithm/str/IsValidParanthesis.java b/src/main/java/algorithm/str/IsValidParanthesis.java deleted file mode 100644 index c4ef202..0000000 --- a/src/main/java/algorithm/str/IsValidParanthesis.java +++ /dev/null @@ -1,44 +0,0 @@ -package algorithm.str; - -import java.util.HashMap; -import java.util.Map; -import java.util.Stack; - -public class IsValidParanthesis { - - private Map params = new HashMap<>(); - - { - this.params.put(')', '('); - this.params.put(']', '['); - this.params.put('}', '{'); - } - - public boolean isValid(String s) { - if (s == null) { - return false; - } - - if ("".equals(s)) { - return true; - } - - Stack stack = new Stack<>(); - for (Character c : s.toCharArray()) { - if (this.params.containsKey(c)) { - if (stack.pop() != this.params.get(c) || stack.isEmpty()) { - return false; - } - - } else { - stack.push(c); - } - } - - return stack.isEmpty(); - } - - public static void main(String[] args) { - System.out.println(new IsValidParanthesis().isValid("[")); - } -} diff --git a/src/main/java/algorithm/str/ParanthesisGenerator.java b/src/main/java/algorithm/str/ParanthesisGenerator.java deleted file mode 100644 index 4ceb064..0000000 --- a/src/main/java/algorithm/str/ParanthesisGenerator.java +++ /dev/null @@ -1,44 +0,0 @@ -package algorithm.str; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author Ethan Zhang - * @email ethan.zj@antfin.com - */ -public class ParanthesisGenerator { - - public List dfs(int n) { - List result = new ArrayList(2 * n); - - dfsImpl("", result, n, n); - - return result; - } - - private void dfsImpl(String str, List result, int left, int right) { - if (left == 0 && right == 0) { - result.add(str); - - return; - } - - // 剪枝 - if (right < left) { - return; - } - - if (left > 0) { - dfsImpl(str + "(", result, left - 1, right); - } - - if (right > 0) { - dfsImpl(str + ")", result, left, right - 1); - } - } - - public static void main(String[] args) { - System.out.println(new ParanthesisGenerator().dfs(3)); - } -} diff --git a/src/main/java/algorithm/str/Similarity.java b/src/main/java/algorithm/str/Similarity.java deleted file mode 100644 index 958e09f..0000000 --- a/src/main/java/algorithm/str/Similarity.java +++ /dev/null @@ -1,63 +0,0 @@ -package algorithm.str; - -import com.google.common.collect.Sets; - -import java.util.*; -import java.util.stream.Collectors; - -/** - * @author Ethan Zhang - * @email ethan.zj@antfin.com - */ -public class Similarity { - - public static float cos(String a, String b) { - if (a == null || b == null) { - return 0F; - } - - Set aChar = a.chars().boxed().collect(Collectors.toSet()); - Set bChar = b.chars().boxed().collect(Collectors.toSet()); - - // 统计字频 - Map aMap = new HashMap<>(); - Map bMap = new HashMap<>(); - for (Integer a1 : aChar) { - aMap.put(a1, aMap.getOrDefault(a1, 0) + 1); - } - for (Integer b1 : bChar) { - bMap.put(b1, bMap.getOrDefault(b1, 0) + 1); - } - - // 向量化 - Set union = Sets.union(aChar, bChar); - int[] aVec = new int[union.size()]; - int[] bVec = new int[union.size()]; - List collect = new ArrayList<>(union); - for (int i = 0; i < collect.size(); i++) { - aVec[i] = aMap.getOrDefault(collect.get(i), 0); - bVec[i] = bMap.getOrDefault(collect.get(i), 0); - } - - // 分别计算三个参数 - int p1 = 0; - for (int i = 0; i < aVec.length; i++) { - p1 += (aVec[i] * bVec[i]); - } - - float p2 = 0f; - for (int i : aVec) { - p2 += (i * i); - } - p2 = (float) Math.sqrt(p2); - - float p3 = 0f; - for (int i : bVec) { - p3 += (i * i); - } - - p3 = (float) Math.sqrt(p3); - - return ((float) p1) / (p2 * p3); - } -} diff --git a/src/main/java/algorithm/str/ValidPalindrome.java b/src/main/java/algorithm/str/ValidPalindrome.java deleted file mode 100644 index 06dbdad..0000000 --- a/src/main/java/algorithm/str/ValidPalindrome.java +++ /dev/null @@ -1,32 +0,0 @@ -package algorithm.str; - -public class ValidPalindrome { - - boolean del = false; - - public boolean validPalindrome(String s) { - int left = 0; - int right = s.length() - 1; - while (left < right) { - if (s.charAt(left) == s.charAt(right)) { - left++; - right--; - } else { - if (!del) { - del = true; - - return validPalindrome(s.substring(left, right)) || validPalindrome(s.substring(left + 1, right + 1)); - } - - return false; - } - } - - return true; - } - - public static void main(String[] args) { - System.out.println(new ValidPalindrome().validPalindrome("abcba")); - System.out.println(new ValidPalindrome().validPalindrome("abcbba")); - } -} diff --git a/src/main/java/algorithm/tree/Depth.java b/src/main/java/algorithm/tree/Depth.java deleted file mode 100644 index f9fb609..0000000 --- a/src/main/java/algorithm/tree/Depth.java +++ /dev/null @@ -1,107 +0,0 @@ -package algorithm.tree; - -import algorithm.tree.model.TreeNode; -import algorithm.tree.model.TreeNodes; - -import java.util.LinkedList; -import java.util.Queue; - -/** - * @author Ethan Zhang - * @email ethan.zj@antfin.com - */ -public class Depth { - - private int min; - - private int max; - - public void DFS(TreeNode treeNode) { - if (treeNode == null) { - return; - } - - DFSImpl(treeNode, 1); - } - - private void DFSImpl(TreeNode treeNode, int i) { - if (treeNode.isLeaf()) { - if (min == 0 || max == 0) { - if (min == 0) { - min = i; - } - - if (max == 0) { - max = i; - } - } else { - if (i < min) { - min = i; - } - - if (i > max) { - max = i; - } - } - } - - - i++; - - if (treeNode.getLeft() != null) { - DFSImpl(treeNode.getLeft(), i); - } - - if (treeNode.getRight() != null) { - DFSImpl(treeNode.getRight(), i); - } - } - - public void BFS(TreeNode treeNode) { - if (treeNode == null) { - return; - } - - Queue queue = new LinkedList(); - queue.offer(treeNode); - - int currentLevel = 1; - while (!queue.isEmpty()) { - int size = queue.size(); - for (int i = 0; i < size; i++) { - TreeNode node = queue.poll(); - if (node.isLeaf()) { - if (min == 0) { - min = currentLevel; - } - - max = currentLevel; - } - - if (node.getLeft() != null) { - queue.offer(node.getLeft()); - } - - if (node.getRight() != null) { - queue.offer(node.getRight()); - } - } - - currentLevel++; - } - } - - public static void main(String[] args) { - TreeNode node = TreeNodes.generate(); - - Depth depth = new Depth(); - depth.DFS(node); - - System.out.println(depth.min + "----" + depth.max); - - depth = new Depth(); - depth.BFS(node); - - System.out.println(depth.min + "----" + depth.max); - } -} diff --git a/src/main/java/algorithm/tree/LevelOrder.java b/src/main/java/algorithm/tree/LevelOrder.java deleted file mode 100644 index c302bb2..0000000 --- a/src/main/java/algorithm/tree/LevelOrder.java +++ /dev/null @@ -1,53 +0,0 @@ -package algorithm.tree; - -import algorithm.tree.model.TreeNode; -import algorithm.tree.model.TreeNodes; - -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.Queue; - -/** - * @author Ethan Zhang - * @email ethan.zj@antfin.com - */ -public class LevelOrder { - - public List> levelOrder(TreeNode root) { - if (root == null) { - return new ArrayList<>(); - } - - Queue queue = new LinkedList<>(); - queue.offer(root); - - List> result = new ArrayList<>(); - while (!queue.isEmpty()) { - List temp = new ArrayList<>(); - int size = queue.size(); - for (int i = 0; i < size; i++) { - TreeNode node = queue.poll(); - - temp.add(node.val); - - if (node.left != null) { - queue.offer(node.left); - } - - if (node.right != null) { - queue.offer(node.right); - } - } - - result.add(temp); - } - - return result; - } - - public static void main(String[] args) { - TreeNode root = TreeNodes.generate2(); - System.out.println(new LevelOrder().levelOrder(root)); - } -} diff --git a/src/main/java/algorithm/tree/Traversal.java b/src/main/java/algorithm/tree/Traversal.java deleted file mode 100644 index 03d1dcb..0000000 --- a/src/main/java/algorithm/tree/Traversal.java +++ /dev/null @@ -1,108 +0,0 @@ -package algorithm.tree; - -import algorithm.tree.model.TreeNode; -import algorithm.tree.model.TreeNodes; - -import java.util.LinkedList; -import java.util.Queue; - -/** - * @author Ethan Zhang - * @email ethan.zj@antfin.com - */ -public class Traversal { - - /** - * 广度优先遍历 - */ - public void BFS(TreeNode treeNode) { - if (treeNode == null) { - return; - } - - Queue queue = new LinkedList(); - queue.offer(treeNode); - - while (!queue.isEmpty()) { - TreeNode node = queue.poll(); - if (node == null) { - continue; - } - - // handle current node - System.out.println(node.getVal()); - - if (node.getLeft() != null) { - queue.offer(node.getLeft()); - } - - if (node.getRight() != null) { - queue.offer(node.getRight()); - } - } - } - - /** - * 深度优先遍历 - */ - public void DFS(TreeNode treeNode) { - if (treeNode == null) { - return; - } - - System.out.println(treeNode.getVal()); - - DFS(treeNode.getLeft()); - DFS(treeNode.getRight()); - } - - public void preorder(TreeNode treeNode) { - if (treeNode == null) { - return; - } - - System.out.println(treeNode.getVal()); - inorder(treeNode.getLeft()); - inorder(treeNode.getRight()); - } - - public void inorder(TreeNode treeNode) { - if (treeNode == null) { - return; - } - - inorder(treeNode.getLeft()); - System.out.println(treeNode.getVal()); - inorder(treeNode.getRight()); - } - - public void postorder(TreeNode treeNode) { - if (treeNode == null) { - return; - } - - inorder(treeNode.getLeft()); - inorder(treeNode.getRight()); - System.out.println(treeNode.getVal()); - } - - /** - * 1 - * 2 3 - * 4 5 - * 6 - */ - public static void main(String[] args) { - TreeNode node = TreeNodes.generate(); - - new Traversal().BFS(node); - System.out.println("============"); - new Traversal().DFS(node); - System.out.println("============"); - new Traversal().preorder(node); - System.out.println("============"); - new Traversal().inorder(node); - System.out.println("============"); - new Traversal().postorder(node); - } -} diff --git a/src/main/java/algorithm/tree/model/TreeNode.java b/src/main/java/algorithm/tree/model/TreeNode.java deleted file mode 100644 index c1d6b05..0000000 --- a/src/main/java/algorithm/tree/model/TreeNode.java +++ /dev/null @@ -1,53 +0,0 @@ -package algorithm.tree.model; - -/** - * @author Ethan Zhang - * @email ethan.zj@antfin.com - */ -public class -TreeNode { - - public int val; - - public TreeNode left; - - public TreeNode right; - - public TreeNode(int val) { - this.val = val; - } - - public TreeNode(int val, TreeNode left, TreeNode right) { - this.val = val; - this.left = left; - this.right = right; - } - - public int getVal() { - return val; - } - - public void setVal(int val) { - this.val = val; - } - - public TreeNode getLeft() { - return left; - } - - public void setLeft(TreeNode left) { - this.left = left; - } - - public TreeNode getRight() { - return right; - } - - public void setRight(TreeNode right) { - this.right = right; - } - - public boolean isLeaf() { - return this.left == null && this.right == null; - } -} diff --git a/src/main/java/algorithm/tree/model/TreeNodes.java b/src/main/java/algorithm/tree/model/TreeNodes.java deleted file mode 100644 index 3f119a5..0000000 --- a/src/main/java/algorithm/tree/model/TreeNodes.java +++ /dev/null @@ -1,68 +0,0 @@ -package algorithm.tree.model; - -/** - * @author Ethan Zhang - * @email ethan.zj@antfin.com - */ -public class TreeNodes { - - public static TreeNode generate() { - TreeNode node1 = new TreeNode(1); - - TreeNode node2 = new TreeNode(2); - TreeNode node3 = new TreeNode(3); - - node1.setLeft(node2); - node1.setRight(node3); - - TreeNode node4 = new TreeNode(4); - node2.setLeft(node4); - - TreeNode node5 = new TreeNode(5); - node3.setRight(node5); - - TreeNode node6 = new TreeNode(6); - node5.setLeft(node6); - - return node1; - } - - public static TreeNode[] generate1() { - TreeNode node1 = new TreeNode(1); - - TreeNode node2 = new TreeNode(2); - TreeNode node3 = new TreeNode(3); - - node1.setLeft(node2); - node1.setRight(node3); - - TreeNode node4 = new TreeNode(4); - node2.setLeft(node4); - - TreeNode node5 = new TreeNode(5); - node3.setRight(node5); - - TreeNode node6 = new TreeNode(6); - node5.setLeft(node6); - - return new TreeNode[] {node1, node5, node6}; - } - - public static TreeNode generate2() { - TreeNode node1 = new TreeNode(1); - - TreeNode node2 = new TreeNode(2); - TreeNode node3 = new TreeNode(3); - - node1.setLeft(node2); - node1.setRight(node3); - - TreeNode node4 = new TreeNode(4); - node2.setLeft(node4); - - TreeNode node5 = new TreeNode(5); - node2.setRight(node5); - - return node1; - } -} \ No newline at end of file diff --git a/src/main/java/algorithm/union/QuickUnionUF.java b/src/main/java/algorithm/union/QuickUnionUF.java deleted file mode 100644 index a17a019..0000000 --- a/src/main/java/algorithm/union/QuickUnionUF.java +++ /dev/null @@ -1,38 +0,0 @@ -package algorithm.union; - -public class QuickUnionUF { - - private int[] roots; - - public QuickUnionUF(int N) { - roots = new int[N]; - for (int i = 0; i < roots.length; i++) { - roots[i] = i; - } - } - - private int findRoot(int i) { - int root = i; - while (root != roots[root]) { - root = roots[root]; - } - - while (i != roots[i]) { - int tmp = roots[i]; - roots[i] = root; - i = tmp; - } - - return root; - } - - public boolean connected(int p, int q) { - return findRoot(p) == findRoot(q); - } - - public void union(int p, int q) { - int qroot = findRoot(q); - int proot = findRoot(p); - roots[proot] = roots[qroot]; - } -} diff --git a/src/main/java/bit/OneSolitaryNumber.java b/src/main/java/bit/OneSolitaryNumber.java new file mode 100644 index 0000000..516c998 --- /dev/null +++ b/src/main/java/bit/OneSolitaryNumber.java @@ -0,0 +1,34 @@ +package bit; + +import sun.jvm.hotspot.utilities.Assert; + +/** + * @author Ethan Zhang + * @date 2022/2/11 + */ +public class OneSolitaryNumber { + + public static void main(String[] args) { + int[] input = null; + Assert.that(solitary(input) == -1, "illegal result"); + + input = new int[0]; + Assert.that(solitary(input) == -1, "illegal result"); + + input = new int[]{111, 111, 222, 222, 333, 333, 444, 444, 555}; + Assert.that(solitary(input) == 555, "illegal result"); + } + + public static int solitary(int[] nums) { + if (nums == null || nums.length == 0) { + return -1; + } + + int result = 0; + for (int i = 0; i < nums.length; i++) { + result ^= nums[i]; + } + + return result; + } +} diff --git a/src/main/java/bit/TwoSolitaryNumber.java b/src/main/java/bit/TwoSolitaryNumber.java new file mode 100644 index 0000000..2a655c2 --- /dev/null +++ b/src/main/java/bit/TwoSolitaryNumber.java @@ -0,0 +1,73 @@ +package bit; + +import com.google.common.collect.Lists; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import sun.jvm.hotspot.utilities.Assert; + +/** + * @author Ethan Zhang + * @date 2022/2/11 + */ +public class TwoSolitaryNumber { + + public static void main(String[] args) { + int[] input = null; + Assert.that(solitary(input) == null, "illegal result"); + + input = new int[0]; + Assert.that(solitary(input) == null, "illegal result"); + + input = new int[]{111, 111, 222, 222, 333, 333, 444, 444, 555, 666}; + Assert.that(Arrays.stream(solitary(input)).anyMatch(i -> i == 555), "illegal result"); + Assert.that(Arrays.stream(solitary(input)).anyMatch(i -> i == 666), "illegal result"); + } + + public static int[] solitary(int[] nums) { + if (nums == null || nums.length == 0) { + return null; + } + + int xor = xor(nums); + int mask = 2; + while ((xor ^ mask) == 0) { + mask *= 2; + } + + List a = Lists.newArrayList(); + List b = Lists.newArrayList(); + for (int i = 0; i < nums.length; i++) { + if ((nums[i] ^ mask) == 0) { + a.add(nums[i]); + } else { + b.add(nums[i]); + } + } + + int resultA = xor(a.stream() + .filter(Objects::nonNull) + .mapToInt(Integer::intValue) + .toArray()); + + int resultB = xor(b.stream() + .filter(Objects::nonNull) + .mapToInt(Integer::intValue) + .toArray()); + + return new int[]{resultA, resultB}; + } + + public static int xor(int[] nums) { + if (nums == null || nums.length == 0) { + return -1; + } + + int result = 0; + for (int i = 0; i < nums.length; i++) { + result ^= nums[i]; + } + + return result; + } +} diff --git "a/src/main/java/window/\346\234\200\345\260\217\350\246\206\347\233\226\345\255\220\344\270\262.java" "b/src/main/java/window/\346\234\200\345\260\217\350\246\206\347\233\226\345\255\220\344\270\262.java" new file mode 100644 index 0000000..9240c5b --- /dev/null +++ "b/src/main/java/window/\346\234\200\345\260\217\350\246\206\347\233\226\345\255\220\344\270\262.java" @@ -0,0 +1,65 @@ +package window; + +import java.util.Arrays; +import java.util.BitSet; + +/** + * @author Ethan Zhang + * @date 2022/2/11 + */ +public class 最小覆盖子串 { + + public static void main(String[] args) { + String s = "EBBANCF"; + String t = "ABC"; + + System.out.println(minSubStr(s, t)); + } + + public static String minSubStr(String s, String t) { + int[] need = new int[128]; + for (char c : t.toCharArray()) { + need[c]++; + } + + int left = 0; + int right = 0; + int valid = 0; + int start = 0; + int len = Integer.MAX_VALUE; + int[] window = new int[128]; + while (right < s.length()) { + final char c = s.charAt(right); + if (need[c] > 0) { + window[c]++; + if (window[c] == need[c]) + valid++; + } + + System.out.println(left + " " + right + " " + valid); + + while (valid == t.length()) { + if (right - left < len) { + start = left; + len = right; + + System.out.println(start + " " + len); + } + + final char l = s.charAt(left); + if (need[l] > 0) { + if (window[l] == need[l]) + valid--; + + window[l]--; + } + + left++; + } + + right++; + } + + return len == Integer.MAX_VALUE ? "" : s.substring(start, len + 1); + } +} From a87188b143205484596e11a6bd5a6ed83124796f Mon Sep 17 00:00:00 2001 From: Ethan Date: Sun, 20 Mar 2022 21:48:01 +0800 Subject: [PATCH 05/43] =?UTF-8?q?=E9=93=BE=E8=A1=A8practice?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\345\271\266\346\216\222\345\272\217.java" | 50 +++++++ .../bit/OneSolitaryNumber.java | 2 +- .../bit/TwoSolitaryNumber.java | 2 +- ...\345\220\246\347\233\270\344\272\244.java" | 134 ++++++++++++++++++ ...\347\232\204\351\223\276\350\241\250.java" | 30 ++++ ...350\241\250_\350\277\233\351\230\266.java" | 52 +++++++ ...\347\216\257\350\212\202\347\202\271.java" | 72 ++++++++++ ...\345\271\266\346\216\222\345\272\217.java" | 58 ++++++++ ...\345\217\263\350\276\271\345\244\247.java" | 81 +++++++++++ ...345\244\247_\350\277\233\351\230\266.java" | 79 +++++++++++ src/main/java/algorithm/package-info.java | 5 + src/main/java/algorithm/utils/ArrayUtils.java | 14 ++ src/main/java/algorithm/utils/LinkUtils.java | 77 ++++++++++ src/main/java/algorithm/utils/Node.java | 30 ++++ ...226\345\255\220\344\270\262_leetcode.java" | 37 +++-- 15 files changed, 708 insertions(+), 15 deletions(-) create mode 100644 "src/main/java/algorithm/array/\346\225\260\347\273\204\345\275\222\345\271\266\346\216\222\345\272\217.java" rename src/main/java/{ => algorithm}/bit/OneSolitaryNumber.java (97%) rename src/main/java/{ => algorithm}/bit/TwoSolitaryNumber.java (98%) create mode 100644 "src/main/java/algorithm/link/\344\270\244\344\270\252\345\215\225\351\223\276\350\241\250\346\230\257\345\220\246\347\233\270\344\272\244.java" create mode 100644 "src/main/java/algorithm/link/\345\244\215\345\210\266\345\220\253\346\234\211\351\232\217\346\234\272\350\212\202\347\202\271\347\232\204\351\223\276\350\241\250.java" create mode 100644 "src/main/java/algorithm/link/\345\244\215\345\210\266\345\220\253\346\234\211\351\232\217\346\234\272\350\212\202\347\202\271\347\232\204\351\223\276\350\241\250_\350\277\233\351\230\266.java" create mode 100644 "src/main/java/algorithm/link/\346\234\211\347\216\257\351\223\276\350\241\250\345\205\245\347\216\257\350\212\202\347\202\271.java" create mode 100644 "src/main/java/algorithm/link/\351\223\276\350\241\250\345\275\222\345\271\266\346\216\222\345\272\217.java" create mode 100644 "src/main/java/algorithm/link/\351\223\276\350\241\250\346\216\222\345\272\217_\345\267\246\350\276\271\345\260\217_\345\217\263\350\276\271\345\244\247.java" create mode 100644 "src/main/java/algorithm/link/\351\223\276\350\241\250\346\216\222\345\272\217_\345\267\246\350\276\271\345\260\217_\345\217\263\350\276\271\345\244\247_\350\277\233\351\230\266.java" create mode 100644 src/main/java/algorithm/package-info.java create mode 100644 src/main/java/algorithm/utils/ArrayUtils.java create mode 100644 src/main/java/algorithm/utils/LinkUtils.java create mode 100644 src/main/java/algorithm/utils/Node.java rename "src/main/java/window/\346\234\200\345\260\217\350\246\206\347\233\226\345\255\220\344\270\262.java" => "src/main/java/algorithm/window/\346\234\200\345\260\217\350\246\206\347\233\226\345\255\220\344\270\262_leetcode.java" (59%) diff --git "a/src/main/java/algorithm/array/\346\225\260\347\273\204\345\275\222\345\271\266\346\216\222\345\272\217.java" "b/src/main/java/algorithm/array/\346\225\260\347\273\204\345\275\222\345\271\266\346\216\222\345\272\217.java" new file mode 100644 index 0000000..a763dc8 --- /dev/null +++ "b/src/main/java/algorithm/array/\346\225\260\347\273\204\345\275\222\345\271\266\346\216\222\345\272\217.java" @@ -0,0 +1,50 @@ +package algorithm.array; + +/** + * TODO 待测试 + * + * @author Ethan Zhang + * @date 2022/3/20 + */ +public class 数组归并排序 { + + public void sort(int[] nums) { + if (nums == null) { + return; + } + + int[] temp = new int[nums.length]; + sortImpl(nums, 0, nums.length - 1, temp); + } + + private void sortImpl(int[] nums, int left, int right, int[] temp) { + if (left >= right) { + return; + } + + int mid = (left + right) / 2; + sortImpl(nums, left, mid, temp); + sortImpl(nums, mid + 1, right, temp); + + merge(nums, left, mid, right, temp); + } + + private void merge(int[] nums, int left, int mid, int right, int[] temp) { + int i = left; + int j = mid + 1; + int t = 0; + while (i <= mid && j <= right) { + if (nums[i] <= nums[j]) { + temp[t++] = nums[i++]; + } else { + temp[t++] = nums[j++]; + } + } + + // TODO 这里的复制没看懂,为什么不在外层一次做掉 + t = 0; + while (left <= right) { + nums[left++] = temp[t++]; + } + } +} diff --git a/src/main/java/bit/OneSolitaryNumber.java b/src/main/java/algorithm/bit/OneSolitaryNumber.java similarity index 97% rename from src/main/java/bit/OneSolitaryNumber.java rename to src/main/java/algorithm/bit/OneSolitaryNumber.java index 516c998..1e2093d 100644 --- a/src/main/java/bit/OneSolitaryNumber.java +++ b/src/main/java/algorithm/bit/OneSolitaryNumber.java @@ -1,4 +1,4 @@ -package bit; +package algorithm.bit; import sun.jvm.hotspot.utilities.Assert; diff --git a/src/main/java/bit/TwoSolitaryNumber.java b/src/main/java/algorithm/bit/TwoSolitaryNumber.java similarity index 98% rename from src/main/java/bit/TwoSolitaryNumber.java rename to src/main/java/algorithm/bit/TwoSolitaryNumber.java index 2a655c2..1ba3e3e 100644 --- a/src/main/java/bit/TwoSolitaryNumber.java +++ b/src/main/java/algorithm/bit/TwoSolitaryNumber.java @@ -1,4 +1,4 @@ -package bit; +package algorithm.bit; import com.google.common.collect.Lists; import java.util.Arrays; diff --git "a/src/main/java/algorithm/link/\344\270\244\344\270\252\345\215\225\351\223\276\350\241\250\346\230\257\345\220\246\347\233\270\344\272\244.java" "b/src/main/java/algorithm/link/\344\270\244\344\270\252\345\215\225\351\223\276\350\241\250\346\230\257\345\220\246\347\233\270\344\272\244.java" new file mode 100644 index 0000000..5d9fc59 --- /dev/null +++ "b/src/main/java/algorithm/link/\344\270\244\344\270\252\345\215\225\351\223\276\350\241\250\346\230\257\345\220\246\347\233\270\344\272\244.java" @@ -0,0 +1,134 @@ +package algorithm.link; + +import algorithm.utils.Node; + +/** + * @author Ethan Zhang + * @date 2022/3/20 + */ +public class 两个单链表是否相交 { + + public static Node isIntersect(Node head1, Node head2) { + if (head1 == null || head2 == null) { + return null; + } + + Node loop1 = getLoopNode(head1); + Node loop2 = getLoopNode(head2); + if (loop1 == null && loop2 == null) { + return noLoop(head1, head2); + } + + if (loop1 != null && loop2 != null) { + return bothLoop(head1, loop1, head2, loop2); + } + + return null; + } + + public static Node getLoopNode(Node head) { + Node slow, fast, encounter; + slow = fast = head; + encounter = null; + while (fast.next != null && fast.next.next != null) { + slow = slow.next; + fast = fast.next.next; + + if (slow == fast) { + encounter = slow; + break; + } + } + + if (encounter == null) { + return null; + } + + slow = head; + while (slow != fast) { + slow = slow.next; + fast = fast.next; + } + + return slow; + } + + public static Node noLoop(Node head1, Node head2) { + Node cur1 = head1; + int n = 0; + while (cur1 != null) { + n++; + cur1 = cur1.next; + } + + Node cur2 = head2; + while (cur2 != null) { + n--; + cur2 = cur2.next; + } + + if (cur1 != cur2) { + return null; + } + + cur1 = n > 0 ? head1 : head2; + cur2 = cur1 == head1 ? head2 : head1; + n = Math.abs(n); + while (n != 0) { + n--; + cur1 = cur1.next; + } + + while (cur1 != cur2) { + cur1 = cur1.next; + cur2 = cur2.next; + } + + return cur1; + } + + public static Node bothLoop(Node head1, Node loop1, Node head2, Node loop2) { + Node cur1 = null; + Node cur2 = null; + if (loop1 == loop2) { + int n = 0; + cur1 = head1; + cur2 = head2; + while (cur1 != loop1) { + n++; + cur1 = cur1.next; + } + + while (cur2 != loop2) { + n--; + cur2 = cur2.next; + } + + cur1 = n > 0 ? head1 : head2; + cur2 = cur1 == head1 ? head2 : head1; + n = Math.abs(n); + while (n != 0) { + n--; + cur1 = cur1.next; + } + + while (cur1 != cur2) { + cur1 = cur1.next; + cur2 = cur2.next; + } + + return cur1; + } else { + cur1 = loop1.next; + while (cur1 != loop1) { + if (cur1 == loop2) { + return loop1; + } + + cur1 = cur1.next; + } + + return null; + } + } +} diff --git "a/src/main/java/algorithm/link/\345\244\215\345\210\266\345\220\253\346\234\211\351\232\217\346\234\272\350\212\202\347\202\271\347\232\204\351\223\276\350\241\250.java" "b/src/main/java/algorithm/link/\345\244\215\345\210\266\345\220\253\346\234\211\351\232\217\346\234\272\350\212\202\347\202\271\347\232\204\351\223\276\350\241\250.java" new file mode 100644 index 0000000..87b0139 --- /dev/null +++ "b/src/main/java/algorithm/link/\345\244\215\345\210\266\345\220\253\346\234\211\351\232\217\346\234\272\350\212\202\347\202\271\347\232\204\351\223\276\350\241\250.java" @@ -0,0 +1,30 @@ +package algorithm.link; + +import algorithm.utils.Node; +import com.google.common.collect.Maps; +import java.util.Map; + +/** + * @author Ethan Zhang + * @date 2022/3/19 + */ +public class 复制含有随机节点的链表 { + + public Node copy(Node head) { + Map cache = Maps.newHashMap(); + Node cur = head; + while (cur != null) { + cache.put(cur, new Node(cur.value)); + cur = cur.next; + } + + cur = head; + while (cur != null) { + cache.get(cur).next = cache.get(cur.next); + cache.get(cur).rand = cache.get(cur.rand); + cur = cur.next; + } + + return cache.get(head); + } +} diff --git "a/src/main/java/algorithm/link/\345\244\215\345\210\266\345\220\253\346\234\211\351\232\217\346\234\272\350\212\202\347\202\271\347\232\204\351\223\276\350\241\250_\350\277\233\351\230\266.java" "b/src/main/java/algorithm/link/\345\244\215\345\210\266\345\220\253\346\234\211\351\232\217\346\234\272\350\212\202\347\202\271\347\232\204\351\223\276\350\241\250_\350\277\233\351\230\266.java" new file mode 100644 index 0000000..ae3bc33 --- /dev/null +++ "b/src/main/java/algorithm/link/\345\244\215\345\210\266\345\220\253\346\234\211\351\232\217\346\234\272\350\212\202\347\202\271\347\232\204\351\223\276\350\241\250_\350\277\233\351\230\266.java" @@ -0,0 +1,52 @@ +package algorithm.link; + +import algorithm.utils.Node; +import com.google.common.collect.Maps; +import java.util.Map; + +/** + * 额外 + * + * @author Ethan Zhang + * @date 2022/3/19 + */ +public class 复制含有随机节点的链表_进阶 { + + public Node copy(Node head) { + if (head == null) { + return null; + } + + // 设置链表为每个节点后紧跟着的是自己的副本节点 + Node cur = head; + while (cur != null) { + Node next = cur.next; + cur.next = new Node(cur.value); + cur.next.next = next; + cur = next; + } + + // 设置复制节点的rand指针 + cur = head; + while (cur != null) { + Node next = cur.next.next; + Node curCopy = cur.next; + curCopy.rand = cur.rand != null ? cur.rand.next : null; + + cur = next; + } + + Node res = head.next; + // 拆分链表 + cur = head; + while (cur != null) { + Node next = cur.next.next; + Node curCopy = cur.next; + cur.next = next; + curCopy.next = next != null ? next.next : null; + cur = next; + } + + return res; + } +} diff --git "a/src/main/java/algorithm/link/\346\234\211\347\216\257\351\223\276\350\241\250\345\205\245\347\216\257\350\212\202\347\202\271.java" "b/src/main/java/algorithm/link/\346\234\211\347\216\257\351\223\276\350\241\250\345\205\245\347\216\257\350\212\202\347\202\271.java" new file mode 100644 index 0000000..596c9c8 --- /dev/null +++ "b/src/main/java/algorithm/link/\346\234\211\347\216\257\351\223\276\350\241\250\345\205\245\347\216\257\350\212\202\347\202\271.java" @@ -0,0 +1,72 @@ +package algorithm.link; + +import algorithm.utils.LinkUtils; +import algorithm.utils.Node; + +/** + * @author Ethan Zhang + * @date 2022/3/20 + */ +public class 有环链表入环节点 { + + public static void main(String[] args) { + Node head = LinkUtils.generateListWithCycle(1, 5); + + Node start = getLoopNode(head); + + System.out.println(); + } + + public static Node getLoopNode(Node head) { + if (head == null || head.next == null || head.next.next == null) { + return null; + } + Node slow, fast; + slow = head.next; + fast = head.next.next; + while (slow != fast) { + if (fast.next == null || fast.next.next == null) { + // 走到了链表末尾,无环 + return null; + } + + slow = slow.next; + fast = fast.next.next; + } + + slow = head; + while (slow != fast) { + slow = slow.next; + fast = fast.next; + } + + return slow; + } + + public static Node getLoopNodeII(Node head) { + Node slow, fast, encounter; + slow = fast = head; + encounter = null; + while (fast.next != null && fast.next.next != null) { + slow = slow.next; + fast = fast.next.next; + + if (slow == fast) { + encounter = slow; + break; + } + } + + if (encounter == null) { + return null; + } + + slow = head; + while (slow != fast) { + slow = slow.next; + fast = fast.next; + } + + return slow; + } +} diff --git "a/src/main/java/algorithm/link/\351\223\276\350\241\250\345\275\222\345\271\266\346\216\222\345\272\217.java" "b/src/main/java/algorithm/link/\351\223\276\350\241\250\345\275\222\345\271\266\346\216\222\345\272\217.java" new file mode 100644 index 0000000..dd6f55a --- /dev/null +++ "b/src/main/java/algorithm/link/\351\223\276\350\241\250\345\275\222\345\271\266\346\216\222\345\272\217.java" @@ -0,0 +1,58 @@ +package algorithm.link; + +import algorithm.utils.Node; + +/** + * TODO 待测试 + * + * @author Ethan Zhang + * @date 2022/3/19 + */ +public class 链表归并排序 { + + public Node sort(Node head) { + if (head == null || head.next == null) { + return head; + } + + // 快慢指针找到中间节点 + Node slow, fast; + slow = fast = head; + while (fast.next != null && fast.next.next != null) { + slow = slow.next; + fast = fast.next.next; + } + Node mid = slow.next; + // 切断链表 + slow.next = null; + + Node left = sort(head); + Node right = sort(mid); + + return merge(left, right); + } + + private Node merge(Node left, Node right) { + Node head = new Node(0); + Node temp = head; + while (left != null && right != null) { + if (left.value < right.value) { + temp.next = left; + left = left.next; + } else { + temp.next = right; + right = right.next; + } + + temp = temp.next; + } + + if (left != null) { + temp.next = left; + } else { + temp.next = right; + } + + return head.next; + } +} diff --git "a/src/main/java/algorithm/link/\351\223\276\350\241\250\346\216\222\345\272\217_\345\267\246\350\276\271\345\260\217_\345\217\263\350\276\271\345\244\247.java" "b/src/main/java/algorithm/link/\351\223\276\350\241\250\346\216\222\345\272\217_\345\267\246\350\276\271\345\260\217_\345\217\263\350\276\271\345\244\247.java" new file mode 100644 index 0000000..5569eb1 --- /dev/null +++ "b/src/main/java/algorithm/link/\351\223\276\350\241\250\346\216\222\345\272\217_\345\267\246\350\276\271\345\260\217_\345\217\263\350\276\271\345\244\247.java" @@ -0,0 +1,81 @@ +package algorithm.link; + +import static algorithm.utils.LinkUtils.generateList; +import static algorithm.utils.LinkUtils.print; +import static algorithm.utils.LinkUtils.swap; + +import algorithm.utils.Node; + +/** + * 只是按照给定值,把小的放左边,大的放右边,进阶题目会对元素原来的顺序有要求 + * + * @author Ethan Zhang + * @date 2022/3/19 + */ +public class 链表排序_左边小_右边大 { + + public static void main(String[] args) { + Node head = generateList(10); + print(head); + + head = listPartition(head, 5); + + print(head); + } + + public static Node listPartition(Node node, int target) { + if (node == null || node.next == null) { + return node; + } + + int size = size(node); + Node[] arr = nodeArray(node, size); + + arrayPartition(arr, target); + // link nodes together + for (int i = 1; i < arr.length; i++) { + arr[i - 1].next = arr[i]; + } + // remember tail.next should be null + arr[size - 1].next = null; + + return arr[0]; + } + + private static void arrayPartition(Node[] arr, int target) { + int small = -1; + int big = arr.length; + int index = 0; + while (index != big) { + if (arr[index].value < target) { + swap(arr, ++small, index++); + } else if (arr[index].value == target) { + index++; + } else { + swap(arr, --big, index); + } + } + } + + private static Node[] nodeArray(Node node, int size) { + Node[] arr = new Node[size]; + Node cur = node; + for (int i = 0; i < size; i++) { + arr[i] = cur; + cur = cur.next; + } + + return arr; + } + + private static int size(Node node) { + int size = 0; + Node cur = node; + while (cur != null) { + size++; + cur = cur.next; + } + + return size; + } +} diff --git "a/src/main/java/algorithm/link/\351\223\276\350\241\250\346\216\222\345\272\217_\345\267\246\350\276\271\345\260\217_\345\217\263\350\276\271\345\244\247_\350\277\233\351\230\266.java" "b/src/main/java/algorithm/link/\351\223\276\350\241\250\346\216\222\345\272\217_\345\267\246\350\276\271\345\260\217_\345\217\263\350\276\271\345\244\247_\350\277\233\351\230\266.java" new file mode 100644 index 0000000..1e0a19c --- /dev/null +++ "b/src/main/java/algorithm/link/\351\223\276\350\241\250\346\216\222\345\272\217_\345\267\246\350\276\271\345\260\217_\345\217\263\350\276\271\345\244\247_\350\277\233\351\230\266.java" @@ -0,0 +1,79 @@ +package algorithm.link; + +import static algorithm.utils.LinkUtils.generateList; +import static algorithm.utils.LinkUtils.print; +import static algorithm.utils.LinkUtils.swap; + +import algorithm.utils.Node; + +/** + * 只是按照给定值,把小的放左边,大的放右边,空间复杂度为1,并且元素按链表里的顺序摆放 + * + * @author Ethan Zhang + * @date 2022/3/19 + */ +public class 链表排序_左边小_右边大_进阶 { + + public static void main(String[] args) { + Node head = generateList(5); + print(head); + + head = listPartition(head, 5); + + print(head); + } + + public static Node listPartition(Node node, int target) { + if (node == null || node.next == null) { + return node; + } + + Node sH = null; + Node sT = null; + Node eH = null; + Node eT = null; + Node bH = null; + Node bT = null; + Node head = node; + while (head != null) { + Node next = head.next; + head.next = null; + if (head.value < target) { + if (sH == null) { + sH = sT = head; + } else { + sT.next = head; + sT = head; + } + } else if (head.value == target) { + if (eH == null) { + eH = eT = head; + } else { + eT.next = head; + eT = head; + } + } else { + if (bH == null) { + bH = bT = head; + } else { + bT.next = head; + bT = head; + } + } + + head = next; + } + + // connect three list: any of them could be null + if (sT != null) { + sT.next = eH; + eT = eT == null ? sT : eT; + } + + if (eT != null) { + eT.next = bH; + } + + return sH != null ? sH : eH != null ? eH : bH; + } +} diff --git a/src/main/java/algorithm/package-info.java b/src/main/java/algorithm/package-info.java new file mode 100644 index 0000000..b7c298d --- /dev/null +++ b/src/main/java/algorithm/package-info.java @@ -0,0 +1,5 @@ +/** + * @author Ethan Zhang + * @date 2022/3/19 + */ +package algorithm; \ No newline at end of file diff --git a/src/main/java/algorithm/utils/ArrayUtils.java b/src/main/java/algorithm/utils/ArrayUtils.java new file mode 100644 index 0000000..984ee6e --- /dev/null +++ b/src/main/java/algorithm/utils/ArrayUtils.java @@ -0,0 +1,14 @@ +package algorithm.utils; + +/** + * @author Ethan Zhang + * @date 2022/3/19 + */ +public class ArrayUtils { + + public static void print(Object[] array) { + for (Object o : array) { + System.out.println(o.toString()); + } + } +} diff --git a/src/main/java/algorithm/utils/LinkUtils.java b/src/main/java/algorithm/utils/LinkUtils.java new file mode 100644 index 0000000..516faaa --- /dev/null +++ b/src/main/java/algorithm/utils/LinkUtils.java @@ -0,0 +1,77 @@ +package algorithm.utils; + +import com.google.common.base.Preconditions; +import java.util.Random; + +/** + * @author Ethan Zhang + * @date 2022/3/19 + */ +public class LinkUtils { + + public static void print(Node node) { + while (node != null) { + System.out.print(node.value + " " + (node.rand == null ? "" : node.rand.value)); + + node = node.next; + } + + System.out.print("========================"); + } + + public static void swap(Node[] array, int a, int b) { + Node temp = array[a]; + array[a] = array[b]; + array[b] = temp; + } + + public static Node generateList(int size) { + int cnt = 0; + Node head = null; + Node cur = null; + while (cnt < size) { + if (cur == null) { + head = cur = new Node(new Random().nextInt(10)); + } else { + cur.next = new Node(new Random().nextInt(10)); + cur = cur.next; + } + cnt++; + } + + return head; + } + + public static Node generateListWithCycle(int startIndex, int size) { + Preconditions.checkArgument(startIndex < size); + + int cnt = 0; + Node head = null; + Node cur = null; + // 入环点 + Node start = null; + while (cnt < size) { + if (head == null) { + head = cur = new Node(new Random().nextInt(10)); + } else { + cur.next = new Node(new Random().nextInt(10)); + cur = cur.next; + } + + if (cnt == startIndex) { + start = cur; + } + + cnt++; + } + + cur.next = start; + + return head; + } + + public static void main(String[] args) { + final Node head = generateListWithCycle(1, 3); + System.out.println(head); + } +} diff --git a/src/main/java/algorithm/utils/Node.java b/src/main/java/algorithm/utils/Node.java new file mode 100644 index 0000000..9e69caa --- /dev/null +++ b/src/main/java/algorithm/utils/Node.java @@ -0,0 +1,30 @@ +package algorithm.utils; + +/** + * @author Ethan Zhang + * @date 2022/3/19 + */ +public class Node { + + public int value; + + public Node next; + + public Node rand; + + public Node(int value) { + this.value = value; + } + + public Node(int value, Node next) { + this.value = value; + this.next = next; + } + + @Override + public String toString() { + return "Node{" + + "value=" + value + + '}'; + } +} diff --git "a/src/main/java/window/\346\234\200\345\260\217\350\246\206\347\233\226\345\255\220\344\270\262.java" "b/src/main/java/algorithm/window/\346\234\200\345\260\217\350\246\206\347\233\226\345\255\220\344\270\262_leetcode.java" similarity index 59% rename from "src/main/java/window/\346\234\200\345\260\217\350\246\206\347\233\226\345\255\220\344\270\262.java" rename to "src/main/java/algorithm/window/\346\234\200\345\260\217\350\246\206\347\233\226\345\255\220\344\270\262_leetcode.java" index 9240c5b..264965a 100644 --- "a/src/main/java/window/\346\234\200\345\260\217\350\246\206\347\233\226\345\255\220\344\270\262.java" +++ "b/src/main/java/algorithm/window/\346\234\200\345\260\217\350\246\206\347\233\226\345\255\220\344\270\262_leetcode.java" @@ -1,19 +1,27 @@ -package window; +package algorithm.window; -import java.util.Arrays; -import java.util.BitSet; +import java.math.BigDecimal; +import java.text.NumberFormat; +import java.util.Locale; /** + * https://leetcode-cn.com/problems/minimum-window-substring/ + * * @author Ethan Zhang * @date 2022/2/11 */ -public class 最小覆盖子串 { +public class 最小覆盖子串_leetcode { public static void main(String[] args) { - String s = "EBBANCF"; - String t = "ABC"; +// String s = "bbaa"; +// String t = "aba"; - System.out.println(minSubStr(s, t)); + // String s = "aa"; + // String t = "aa"; + String s = "cabwefgewcwaefgcf"; + String t = "cae"; + // baa + System.out.println(NumberFormat.getInstance(Locale.KOREA).format(new BigDecimal("10000000.123"))); } public static String minSubStr(String s, String t) { @@ -32,23 +40,28 @@ public static String minSubStr(String s, String t) { final char c = s.charAt(right); if (need[c] > 0) { window[c]++; - if (window[c] == need[c]) + + if (window[c] <= need[c]) valid++; } System.out.println(left + " " + right + " " + valid); + right++; + while (valid == t.length()) { if (right - left < len) { start = left; - len = right; + // 注意right已经自动+1,所以这里无需+1 + len = right - left; System.out.println(start + " " + len); } final char l = s.charAt(left); if (need[l] > 0) { - if (window[l] == need[l]) + // 可能有多个重复char被算进去,所以有这一步 + if (window[l] <= need[l]) valid--; window[l]--; @@ -56,10 +69,8 @@ public static String minSubStr(String s, String t) { left++; } - - right++; } - return len == Integer.MAX_VALUE ? "" : s.substring(start, len + 1); + return len == Integer.MAX_VALUE ? "" : s.substring(start, len + start); } } From 29913028b1a70303a28c5734f3b4fe64955cd67d Mon Sep 17 00:00:00 2001 From: Ethan Date: Sat, 2 Apr 2022 18:07:12 +0800 Subject: [PATCH 06/43] =?UTF-8?q?=E9=93=BE=E8=A1=A8practice?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/algorithm/bit/OneSolitaryNumber.java | 8 +-- .../java/algorithm/bit/TwoSolitaryNumber.java | 13 ++-- ...\345\244\215\350\212\202\347\202\271.java" | 61 +++++++++++++++++ ...\347\202\271\351\200\206\345\272\217.java" | 51 ++++++++++++++ ...45\244\215\346\235\202\345\272\246O1.java" | 67 +++++++++++++++++++ 5 files changed, 188 insertions(+), 12 deletions(-) create mode 100644 "src/main/java/algorithm/link/\345\210\240\351\231\244\351\207\215\345\244\215\350\212\202\347\202\271.java" create mode 100644 "src/main/java/algorithm/link/\346\257\217K\344\270\252\345\207\240\347\202\271\351\200\206\345\272\217.java" create mode 100644 "src/main/java/algorithm/link/\346\257\217K\344\270\252\345\207\240\347\202\271\351\200\206\345\272\217_\347\251\272\351\227\264\345\244\215\346\235\202\345\272\246O1.java" diff --git a/src/main/java/algorithm/bit/OneSolitaryNumber.java b/src/main/java/algorithm/bit/OneSolitaryNumber.java index 1e2093d..6e6a4e6 100644 --- a/src/main/java/algorithm/bit/OneSolitaryNumber.java +++ b/src/main/java/algorithm/bit/OneSolitaryNumber.java @@ -1,6 +1,6 @@ package algorithm.bit; -import sun.jvm.hotspot.utilities.Assert; +import org.springframework.util.Assert; /** * @author Ethan Zhang @@ -10,13 +10,13 @@ public class OneSolitaryNumber { public static void main(String[] args) { int[] input = null; - Assert.that(solitary(input) == -1, "illegal result"); + Assert.isTrue(solitary(input) == -1, "illegal result"); input = new int[0]; - Assert.that(solitary(input) == -1, "illegal result"); + Assert.isTrue(solitary(input) == -1, "illegal result"); input = new int[]{111, 111, 222, 222, 333, 333, 444, 444, 555}; - Assert.that(solitary(input) == 555, "illegal result"); + Assert.isTrue(solitary(input) == 555, "illegal result"); } public static int solitary(int[] nums) { diff --git a/src/main/java/algorithm/bit/TwoSolitaryNumber.java b/src/main/java/algorithm/bit/TwoSolitaryNumber.java index 1ba3e3e..3188411 100644 --- a/src/main/java/algorithm/bit/TwoSolitaryNumber.java +++ b/src/main/java/algorithm/bit/TwoSolitaryNumber.java @@ -4,7 +4,7 @@ import java.util.Arrays; import java.util.List; import java.util.Objects; -import sun.jvm.hotspot.utilities.Assert; +import org.springframework.util.Assert; /** * @author Ethan Zhang @@ -13,15 +13,12 @@ public class TwoSolitaryNumber { public static void main(String[] args) { - int[] input = null; - Assert.that(solitary(input) == null, "illegal result"); - - input = new int[0]; - Assert.that(solitary(input) == null, "illegal result"); + int[] input = new int[0]; + Assert.isTrue(solitary(input) == null, "illegal result"); input = new int[]{111, 111, 222, 222, 333, 333, 444, 444, 555, 666}; - Assert.that(Arrays.stream(solitary(input)).anyMatch(i -> i == 555), "illegal result"); - Assert.that(Arrays.stream(solitary(input)).anyMatch(i -> i == 666), "illegal result"); + Assert.isTrue(Arrays.stream(solitary(input)).anyMatch(i -> i == 555), "illegal result"); + Assert.isTrue(Arrays.stream(solitary(input)).anyMatch(i -> i == 666), "illegal result"); } public static int[] solitary(int[] nums) { diff --git "a/src/main/java/algorithm/link/\345\210\240\351\231\244\351\207\215\345\244\215\350\212\202\347\202\271.java" "b/src/main/java/algorithm/link/\345\210\240\351\231\244\351\207\215\345\244\215\350\212\202\347\202\271.java" new file mode 100644 index 0000000..59adbf6 --- /dev/null +++ "b/src/main/java/algorithm/link/\345\210\240\351\231\244\351\207\215\345\244\215\350\212\202\347\202\271.java" @@ -0,0 +1,61 @@ +package algorithm.link; + +import algorithm.utils.Node; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import java.util.Map; +import java.util.Set; + +/** + * @author Ethan Zhang + * @date 2022/4/2 + */ +public class 删除重复节点 { + + // 使用HashMap + public static void removeDup1(Node head) { + if (head == null || head.next == null) { + return; + } + + Set cache = Sets.newHashSet(); + cache.add(head.value); + + Node pre = head; + Node cur = head.next; + while (cur != null) { + if (cache.contains(cur.value)) { + pre.next = cur.next; + } else { + cache.add(cur.value); + pre = cur; + } + + cur = cur.next; + } + } + + // 时间复杂度O(N^2) 空间复杂度O(1) 类似选择排序 + public static void removeDup2(Node head) { + if (head == null || head.next == null) { + return; + } + + Node cur = head; + while (cur != null) { + Node pre = cur; + Node next = cur.next; + while (next != null) { + if (cur.value == next.value) { + pre.next = next.next; + } else { + pre = next; + } + + next = next.next; + } + + cur = cur.next; + } + } +} diff --git "a/src/main/java/algorithm/link/\346\257\217K\344\270\252\345\207\240\347\202\271\351\200\206\345\272\217.java" "b/src/main/java/algorithm/link/\346\257\217K\344\270\252\345\207\240\347\202\271\351\200\206\345\272\217.java" new file mode 100644 index 0000000..b1f4cd7 --- /dev/null +++ "b/src/main/java/algorithm/link/\346\257\217K\344\270\252\345\207\240\347\202\271\351\200\206\345\272\217.java" @@ -0,0 +1,51 @@ +package algorithm.link; + +import algorithm.utils.Node; +import java.util.Stack; + +/** + * TODO 测试 + * + * @author Ethan Zhang + * @date 2022/3/27 + */ +public class 每K个几点逆序 { + + public Node reverseKNode(Node head, int k) { + if (k < 2) { + return head; + } + + Stack stack = new Stack<>(); + Node newHead = head; + Node pre = null; + Node cur = head; + Node next = null; + while (cur != null) { + next = cur.next; + stack.push(cur); + if (stack.size() == k) { + pre = reverse(stack, pre, next); + newHead = newHead == head ? cur : newHead; + } + cur = next; + } + + return newHead; + } + + private Node reverse(Stack stack, Node left, Node right) { + Node cur = stack.pop(); + if (left != null) { + left.next = cur; + } + + while (!stack.isEmpty()) { + cur.next = stack.pop(); + cur = cur.next; + } + + cur.next = right; + return cur; + } +} diff --git "a/src/main/java/algorithm/link/\346\257\217K\344\270\252\345\207\240\347\202\271\351\200\206\345\272\217_\347\251\272\351\227\264\345\244\215\346\235\202\345\272\246O1.java" "b/src/main/java/algorithm/link/\346\257\217K\344\270\252\345\207\240\347\202\271\351\200\206\345\272\217_\347\251\272\351\227\264\345\244\215\346\235\202\345\272\246O1.java" new file mode 100644 index 0000000..c9a6f2c --- /dev/null +++ "b/src/main/java/algorithm/link/\346\257\217K\344\270\252\345\207\240\347\202\271\351\200\206\345\272\217_\347\251\272\351\227\264\345\244\215\346\235\202\345\272\246O1.java" @@ -0,0 +1,67 @@ +package algorithm.link; + +import algorithm.utils.LinkUtils; +import algorithm.utils.Node; +import java.util.Stack; + +/** + * TODO 测试 + * + * @author Ethan Zhang + * @date 2022/3/27 + */ +public class 每K个几点逆序_空间复杂度O1 { + + public static void main(String[] args) { + Node head = LinkUtils.generateList(6); + + head = reverseKNode(head, 2); + + System.out.println(); + } + + public static Node reverseKNode(Node head, int k) { + if (k < 2) { + return head; + } + + Node cur = head; + Node prev = null; + Node start = null; + Node next = null; + int cnt = 1; + while (cur != null) { + next = cur.next; + if (cnt == k) { + start = prev == null ? head : prev.next; + head = prev == null ? cur : head; + reverse(prev, start, cur, next); + prev = start; + cnt = 0; + } + + cnt++; + cur = next; + } + + return head; + } + + private static void reverse(Node left, Node start, Node end, Node right) { + Node pre = null; + Node cur = start.next; + Node next = null; + while (cur != right) { + next = cur.next; + cur.next = pre; + pre = cur; + cur = next; + } + + if (left != null) { + left.next = end; + } + + start.next = right; + } +} From 990de01c12e8e11eca288cf4c00588e8a6018d7b Mon Sep 17 00:00:00 2001 From: Ethan Date: Mon, 4 Apr 2022 14:57:00 +0800 Subject: [PATCH 07/43] =?UTF-8?q?=E9=93=BE=E8=A1=A8practice?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\351\231\244\346\226\271\345\274\217.java" | 24 +++++++ ...\347\232\204\350\212\202\347\202\271.java" | 67 +++++++++++++++++++ ...\346\226\260\350\212\202\347\202\271.java" | 35 ++++++++++ ...\345\220\221\351\223\276\350\241\250.java" | 48 +++++++++++++ ...\346\213\251\346\216\222\345\272\217.java" | 55 +++++++++++++++ src/main/java/algorithm/utils/TreeNode.java | 48 +++++++++++++ 6 files changed, 277 insertions(+) create mode 100644 "src/main/java/algorithm/link/\344\270\200\347\247\215\346\200\252\345\274\202\347\232\204\350\212\202\347\202\271\345\210\240\351\231\244\346\226\271\345\274\217.java" create mode 100644 "src/main/java/algorithm/link/\345\210\240\351\231\244\346\214\207\345\256\232\345\200\274\347\232\204\350\212\202\347\202\271.java" create mode 100644 "src/main/java/algorithm/link/\345\220\221\346\234\211\345\272\217\347\232\204\347\216\257\345\275\242\345\215\225\351\223\276\350\241\250\346\217\222\345\205\245\346\226\260\350\212\202\347\202\271.java" create mode 100644 "src/main/java/algorithm/link/\345\260\206\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\350\275\254\346\215\242\346\210\220\345\217\214\345\220\221\351\223\276\350\241\250.java" create mode 100644 "src/main/java/algorithm/link/\351\200\211\346\213\251\346\216\222\345\272\217.java" create mode 100644 src/main/java/algorithm/utils/TreeNode.java diff --git "a/src/main/java/algorithm/link/\344\270\200\347\247\215\346\200\252\345\274\202\347\232\204\350\212\202\347\202\271\345\210\240\351\231\244\346\226\271\345\274\217.java" "b/src/main/java/algorithm/link/\344\270\200\347\247\215\346\200\252\345\274\202\347\232\204\350\212\202\347\202\271\345\210\240\351\231\244\346\226\271\345\274\217.java" new file mode 100644 index 0000000..3dadf79 --- /dev/null +++ "b/src/main/java/algorithm/link/\344\270\200\347\247\215\346\200\252\345\274\202\347\232\204\350\212\202\347\202\271\345\210\240\351\231\244\346\226\271\345\274\217.java" @@ -0,0 +1,24 @@ +package algorithm.link; + +import algorithm.utils.Node; + +/** + * @author Ethan Zhang + * @date 2022/4/4 + */ +public class 一种怪异的节点删除方式 { + + public void remoteNodeWeird(Node node) { + if (node == null) { + return; + } + + Node next = node.next; + if (next == null) { + throw new RuntimeException(); + } + + node.value = next.value; + node.next = next.next; + } +} diff --git "a/src/main/java/algorithm/link/\345\210\240\351\231\244\346\214\207\345\256\232\345\200\274\347\232\204\350\212\202\347\202\271.java" "b/src/main/java/algorithm/link/\345\210\240\351\231\244\346\214\207\345\256\232\345\200\274\347\232\204\350\212\202\347\202\271.java" new file mode 100644 index 0000000..cc6135f --- /dev/null +++ "b/src/main/java/algorithm/link/\345\210\240\351\231\244\346\214\207\345\256\232\345\200\274\347\232\204\350\212\202\347\202\271.java" @@ -0,0 +1,67 @@ +package algorithm.link; + +import algorithm.utils.Node; +import java.util.Stack; + +/** + * @author Ethan Zhang + * @date 2022/4/2 + */ +public class 删除指定值的节点 { + + public Node removeNode1(Node head, int value) { + if (head == null) { + return null; + } + + Stack stack = new Stack<>(); + Node cur = head; + while (cur != null) { + if (cur.value == value) { + continue; + } + + stack.push(cur); + cur = cur.next; + } + + Node pre = null; + while (!stack.isEmpty()) { + stack.peek().next = pre; + pre = stack.pop(); + } + + return pre; + } + + public Node removeNode2(Node head, int value) { + if (head == null) { + return null; + } + + Node newHead = null; + while (head != null) { + if (head.value != value) { + newHead = head; + break; + } + + head = head.next; + } + + Node pre = newHead; + Node cur = newHead; + while (cur != null) { + Node next = cur.next; + if (cur.value == value) { + pre.next = next; + } else { + pre = cur; + } + + cur = cur.next; + } + + return pre; + } +} diff --git "a/src/main/java/algorithm/link/\345\220\221\346\234\211\345\272\217\347\232\204\347\216\257\345\275\242\345\215\225\351\223\276\350\241\250\346\217\222\345\205\245\346\226\260\350\212\202\347\202\271.java" "b/src/main/java/algorithm/link/\345\220\221\346\234\211\345\272\217\347\232\204\347\216\257\345\275\242\345\215\225\351\223\276\350\241\250\346\217\222\345\205\245\346\226\260\350\212\202\347\202\271.java" new file mode 100644 index 0000000..8f6922d --- /dev/null +++ "b/src/main/java/algorithm/link/\345\220\221\346\234\211\345\272\217\347\232\204\347\216\257\345\275\242\345\215\225\351\223\276\350\241\250\346\217\222\345\205\245\346\226\260\350\212\202\347\202\271.java" @@ -0,0 +1,35 @@ +package algorithm.link; + +import algorithm.utils.Node; + +/** + * @author Ethan Zhang + * @date 2022/4/4 + */ +public class 向有序的环形单链表插入新节点 { + + public Node insertNode(Node head, int num) { + Node waitToInsert = new Node(num); + if (head == null) { + waitToInsert.next = waitToInsert; + + return waitToInsert; + } + + Node pre = head; + Node cur = head.next; + while (cur != head) { + if (pre.value <= num && num <= cur.value) { + break; + } + + pre = cur; + cur = cur.next; + } + + pre.next = waitToInsert; + waitToInsert.next = cur; + + return waitToInsert.value > head.value ? head : waitToInsert; + } +} diff --git "a/src/main/java/algorithm/link/\345\260\206\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\350\275\254\346\215\242\346\210\220\345\217\214\345\220\221\351\223\276\350\241\250.java" "b/src/main/java/algorithm/link/\345\260\206\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\350\275\254\346\215\242\346\210\220\345\217\214\345\220\221\351\223\276\350\241\250.java" new file mode 100644 index 0000000..673565f --- /dev/null +++ "b/src/main/java/algorithm/link/\345\260\206\344\272\214\345\217\211\346\220\234\347\264\242\346\240\221\350\275\254\346\215\242\346\210\220\345\217\214\345\220\221\351\223\276\350\241\250.java" @@ -0,0 +1,48 @@ +package algorithm.link; + +import algorithm.utils.TreeNode; +import com.google.common.collect.Lists; +import java.util.LinkedList; +import java.util.List; + +/** + * @author Ethan Zhang + * @date 2022/4/3 + */ +public class 将二叉搜索树转换成双向链表 { + + public TreeNode treeToLink(TreeNode root) { + if (root == null) { + return root; + } + + LinkedList list = Lists.newLinkedList(); + inOrderToList(root, list); + + root = list.poll(); + TreeNode pre = root; + TreeNode cur = null; + while (!list.isEmpty()) { + cur = list.poll(); + + cur.left = pre; + pre.right = cur; + + pre = cur; + } + + pre.right = null; + + return root; + } + + private void inOrderToList(TreeNode root, List list) { + if (root == null) { + return; + } + + inOrderToList(root.left, list); + list.add(root); + inOrderToList(root.right, list); + } +} diff --git "a/src/main/java/algorithm/link/\351\200\211\346\213\251\346\216\222\345\272\217.java" "b/src/main/java/algorithm/link/\351\200\211\346\213\251\346\216\222\345\272\217.java" new file mode 100644 index 0000000..73b5a96 --- /dev/null +++ "b/src/main/java/algorithm/link/\351\200\211\346\213\251\346\216\222\345\272\217.java" @@ -0,0 +1,55 @@ +package algorithm.link; + +import algorithm.utils.Node; + +/** + * @author Ethan Zhang + * @date 2022/4/4 + */ +public class 选择排序 { + + public Node selectionSort(Node head) { + // 排序列表得尾巴节点 + Node tail = null; + Node small = null; + Node cur = head; + while (cur != null) { + small = cur; + Node smallPre = findSmallPre(cur); + if (smallPre != null) { + small = smallPre.next; + smallPre.next = small.next; + } + + // small值没变表示cur就是最小值 + cur = cur == small ? cur.next : cur; + if (tail == null) { + head = small; + } else { + tail.next = small; + } + + tail = small; + } + + return head; + } + + private Node findSmallPre(Node head) { + Node smallPre = null; + Node pre = head; + Node small = head; + Node cur = head.next; + while (cur != null) { + if (cur.value < small.value) { + smallPre = pre; + small = cur; + } + + pre = cur; + cur = cur.next; + } + + return smallPre; + } +} diff --git a/src/main/java/algorithm/utils/TreeNode.java b/src/main/java/algorithm/utils/TreeNode.java new file mode 100644 index 0000000..422c10a --- /dev/null +++ b/src/main/java/algorithm/utils/TreeNode.java @@ -0,0 +1,48 @@ +package algorithm.utils; + +/** + * @author Ethan Zhang + * @date 2022/3/19 + */ +public class TreeNode { + + public int value; + + public TreeNode left; + + public TreeNode right; + + public TreeNode(int value) { + this.value = value; + } + + public TreeNode(int value, TreeNode left, TreeNode right) { + this.value = value; + this.left = left; + this.right = right; + } + + public int getValue() { + return value; + } + + public void setValue(int value) { + this.value = value; + } + + public TreeNode getLeft() { + return left; + } + + public void setLeft(TreeNode left) { + this.left = left; + } + + public TreeNode getRight() { + return right; + } + + public void setRight(TreeNode right) { + this.right = right; + } +} From 6378fe96f17af2de94b882f49f986f3fb4d75b16 Mon Sep 17 00:00:00 2001 From: Ethan Date: Thu, 14 Apr 2022 02:52:18 +0800 Subject: [PATCH 08/43] binary tree practice --- ...\345\272\217\351\201\215\345\216\206.java" | 56 ++++++++++++++++ ...\345\272\217\351\201\215\345\216\206.java" | 53 +++++++++++++++ ...\345\272\217\351\201\215\345\216\206.java" | 61 +++++++++++++++++ ...\345\205\210\351\201\215\345\216\206.java" | 46 +++++++++++++ .../algorithm/data_structure/BinaryTree.java | 36 ++++++++++ .../data_structure/SortedBinaryTree.java | 66 +++++++++++++++++++ ...\345\272\217\351\223\276\350\241\250.java" | 38 +++++++++++ ...\345\220\210\351\223\276\350\241\250.java" | 40 +++++++++++ src/main/java/algorithm/utils/TreeUtils.java | 24 +++++++ 9 files changed, 420 insertions(+) create mode 100644 "src/main/java/algorithm/binary_tree/\344\270\255\345\272\217\351\201\215\345\216\206.java" create mode 100644 "src/main/java/algorithm/binary_tree/\345\211\215\345\272\217\351\201\215\345\216\206.java" create mode 100644 "src/main/java/algorithm/binary_tree/\345\220\216\345\272\217\351\201\215\345\216\206.java" create mode 100644 "src/main/java/algorithm/binary_tree/\345\271\277\345\272\246\344\274\230\345\205\210\351\201\215\345\216\206.java" create mode 100644 src/main/java/algorithm/data_structure/BinaryTree.java create mode 100644 src/main/java/algorithm/data_structure/SortedBinaryTree.java create mode 100644 "src/main/java/algorithm/link/\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250.java" create mode 100644 "src/main/java/algorithm/link/\346\214\211\347\205\247\345\267\246\345\217\263\345\215\212\345\214\272\347\232\204\346\226\271\345\274\217\347\273\204\345\220\210\351\223\276\350\241\250.java" create mode 100644 src/main/java/algorithm/utils/TreeUtils.java diff --git "a/src/main/java/algorithm/binary_tree/\344\270\255\345\272\217\351\201\215\345\216\206.java" "b/src/main/java/algorithm/binary_tree/\344\270\255\345\272\217\351\201\215\345\216\206.java" new file mode 100644 index 0000000..e280712 --- /dev/null +++ "b/src/main/java/algorithm/binary_tree/\344\270\255\345\272\217\351\201\215\345\216\206.java" @@ -0,0 +1,56 @@ +package algorithm.binary_tree; + +import algorithm.data_structure.BinaryTree; +import algorithm.utils.TreeNode; +import com.google.common.collect.Lists; +import java.util.Stack; + +/** + * 1 + * 2 3 + * 4 5 6 7 + * + * 4 2 5 1 6 3 7 + * @author Ethan Zhang + * @date 2022/4/13 + */ +public class 中序遍历 { + + public static void main(String[] args) { + TreeNode root = BinaryTree.create(Lists.newArrayList(1, 2, 3, 4, 5, 6, 7)); + + inOrder1(root); + } + + public static void inOrder1(TreeNode root) { + if (root == null) { + return; + } + + inOrder1(root.left); + + System.out.println(root.value); + + inOrder1(root.right); + } + + public static void inOrder2(TreeNode root) { + if (root == null) { + return; + } + + Stack stack = new Stack<>(); + while (!stack.isEmpty() || root != null) { + if (root != null) { + stack.push(root); + root = root.left; + } else { + TreeNode left = stack.pop(); + + System.out.println(left.value); + + stack.push(left.right); + } + } + } +} diff --git "a/src/main/java/algorithm/binary_tree/\345\211\215\345\272\217\351\201\215\345\216\206.java" "b/src/main/java/algorithm/binary_tree/\345\211\215\345\272\217\351\201\215\345\216\206.java" new file mode 100644 index 0000000..52a4b66 --- /dev/null +++ "b/src/main/java/algorithm/binary_tree/\345\211\215\345\272\217\351\201\215\345\216\206.java" @@ -0,0 +1,53 @@ +package algorithm.binary_tree; + +import algorithm.data_structure.BinaryTree; +import algorithm.utils.TreeNode; +import com.google.common.collect.Lists; +import java.util.Stack; + +/** + * 1 + * 2 3 + * 4 5 6 7 + * + * 1 2 4 5 3 6 7 + * @author Ethan Zhang + * @date 2022/4/13 + */ +public class 前序遍历 { + + public static void main(String[] args) { + TreeNode root = BinaryTree.create(Lists.newArrayList(1, 2, 3, 4, 5, 6, 7)); + + preOrder1(root); + } + + public static void preOrder1(TreeNode root) { + if (root == null) { + return; + } + + System.out.println(root.value); + + preOrder1(root.left); + preOrder1(root.right); + } + + public static void preOrder2(TreeNode root) { + Stack stack = new Stack<>(); + stack.push(root); + + while (!stack.isEmpty()) { + TreeNode cur = stack.pop(); + System.out.println(cur.value); + + if (cur.right != null) { + stack.push(cur.right); + } + + if (cur.left != null) { + stack.push(cur.left); + } + } + } +} diff --git "a/src/main/java/algorithm/binary_tree/\345\220\216\345\272\217\351\201\215\345\216\206.java" "b/src/main/java/algorithm/binary_tree/\345\220\216\345\272\217\351\201\215\345\216\206.java" new file mode 100644 index 0000000..46b3c39 --- /dev/null +++ "b/src/main/java/algorithm/binary_tree/\345\220\216\345\272\217\351\201\215\345\216\206.java" @@ -0,0 +1,61 @@ +package algorithm.binary_tree; + +import algorithm.data_structure.BinaryTree; +import algorithm.utils.TreeNode; +import com.google.common.collect.Lists; +import java.util.Stack; + +/** + * 1 + * 2 3 + * 4 5 6 7 + * + * 4 5 2 6 7 3 1 + * + * @author Ethan Zhang + * @date 2022/4/14 + */ +public class 后序遍历 { + + public static void main(String[] args) { + TreeNode root = BinaryTree.create(Lists.newArrayList(1, 2, 3, 4, 5, 6, 7)); + + postOrder1(root); + + postOrder2(root); + } + + public static void postOrder1(TreeNode root) { + if (root == null) { + return; + } + + postOrder1(root.left); + postOrder1(root.right); + + System.out.println(root.value); + } + + public static void postOrder2(TreeNode root) { + if (root == null) { + return; + } + + Stack stack = new Stack<>(); + stack.push(root); + + TreeNode top = null; + while (!stack.isEmpty()) { + top = stack.peek(); + if (top.left != null && root != top.left && root != top.right) { + stack.push(top.left); + } else if (top.right != null && root != top.right) { + stack.push(top.right); + } else { + System.out.println(stack.pop().value); + + root = top; + } + } + } +} diff --git "a/src/main/java/algorithm/binary_tree/\345\271\277\345\272\246\344\274\230\345\205\210\351\201\215\345\216\206.java" "b/src/main/java/algorithm/binary_tree/\345\271\277\345\272\246\344\274\230\345\205\210\351\201\215\345\216\206.java" new file mode 100644 index 0000000..006c83e --- /dev/null +++ "b/src/main/java/algorithm/binary_tree/\345\271\277\345\272\246\344\274\230\345\205\210\351\201\215\345\216\206.java" @@ -0,0 +1,46 @@ +package algorithm.binary_tree; + +import algorithm.data_structure.BinaryTree; +import algorithm.utils.TreeNode; +import com.google.common.collect.Lists; +import java.util.LinkedList; +import java.util.Queue; + +/** + * @author Ethan Zhang + * @date 2022/4/14 + */ +public class 广度优先遍历 { + + public static void main(String[] args) { + final TreeNode root = BinaryTree.create(Lists.newArrayList(1, 2, 3, 4, 5, 6, 7)); + + breadthFirstTraverse(root); + } + + public static void breadthFirstTraverse(TreeNode root) { + if (root == null) { + return; + } + + Queue queue = new LinkedList<>(); + queue.add(root); + + while (!queue.isEmpty()) { + final int size = queue.size(); + for (int i = 0; i < size; i++) { + final TreeNode cur = queue.poll(); + + System.out.println(cur.value); + + if (cur.left != null) { + queue.offer(cur.left); + } + + if (cur.right != null) { + queue.offer(cur.right); + } + } + } + } +} diff --git a/src/main/java/algorithm/data_structure/BinaryTree.java b/src/main/java/algorithm/data_structure/BinaryTree.java new file mode 100644 index 0000000..f929a92 --- /dev/null +++ b/src/main/java/algorithm/data_structure/BinaryTree.java @@ -0,0 +1,36 @@ +package algorithm.data_structure; + +import algorithm.utils.TreeNode; +import com.google.common.collect.Lists; +import java.util.List; + +/** + * @author Ethan Zhang + * @date 2022/4/14 + */ +public class BinaryTree { + + private TreeNode root; + + /** + * 第i个节点的left在2i + 1, right在2i + 2 + */ + private static TreeNode createRecursive(List nums, TreeNode cur, int i) { + if (i < nums.size()) { + cur = new TreeNode(nums.get(i)); + + cur.left = createRecursive(nums, cur.left, 2 * i + 1); + cur.right = createRecursive(nums, cur.right, 2 * i + 2); + } + + return cur; + } + + public static TreeNode create(List nums) { + BinaryTree binaryTree = new BinaryTree(); + binaryTree.root = createRecursive(Lists.newArrayList(1, 2, 3, 4, 5, 6, 7), binaryTree.root, 0); + + return binaryTree.root; + } + +} diff --git a/src/main/java/algorithm/data_structure/SortedBinaryTree.java b/src/main/java/algorithm/data_structure/SortedBinaryTree.java new file mode 100644 index 0000000..3c07f60 --- /dev/null +++ b/src/main/java/algorithm/data_structure/SortedBinaryTree.java @@ -0,0 +1,66 @@ +package algorithm.data_structure; + +import algorithm.utils.TreeNode; +import java.util.List; + +/** + * @author Ethan Zhang + * @date 2022/4/12 + */ +public class SortedBinaryTree { + + private TreeNode root; + + public void add(int value) { + root = addRecursive(root, value); + } + + private TreeNode addRecursive(TreeNode current, int value) { + if (current == null) { + return new TreeNode(value); + } + + if (value < current.value) { + current.left = addRecursive(current.left, value); + } else if (value > current.value) { + current.right = addRecursive(current.right, value); + } else { + return current; + } + + return current; + } + + public boolean contains(int value) { + return containsRecursive(root, value); + } + + private boolean containsRecursive(TreeNode current, int value) { + if (current == null) { + return false; + } + + if (current.value == value) { + return true; + } + + return value > current.value ? containsRecursive(current.right, value) : containsRecursive(current.left, value); + } + + public static TreeNode create(List values) { + if (values == null || values.isEmpty()) { + return null; + } + + SortedBinaryTree binaryTree = new SortedBinaryTree(); + for (Integer value : values) { + binaryTree.add(value); + } + + return binaryTree.root; + } + + public TreeNode getRoot() { + return root; + } +} diff --git "a/src/main/java/algorithm/link/\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250.java" "b/src/main/java/algorithm/link/\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250.java" new file mode 100644 index 0000000..1e77c68 --- /dev/null +++ "b/src/main/java/algorithm/link/\345\220\210\345\271\266\344\270\244\344\270\252\346\234\211\345\272\217\351\223\276\350\241\250.java" @@ -0,0 +1,38 @@ +package algorithm.link; + +import algorithm.utils.Node; + +/** + * @author Ethan Zhang + * @date 2022/4/4 + */ +public class 合并两个有序链表 { + + public Node mergeSort(Node head1, Node head2) { + if (head1 == null || head2 == null) { + return head1 == null ? head2 : head1; + } + + Node pre = null; + Node head = head1.value < head2.value ? head1 : head2; + Node cur1 = head == head1 ? head1 : head2; + Node cur2 = head == head2 ? head2 : head1; + Node next = null; + while (cur1 != null && cur2 != null) { + if (cur1.value < cur2.value) { + pre = cur1; + cur1 = cur1.next; + } else { + next = cur2.next; + pre.next = cur2; + cur2.next = cur1; + pre = cur2; + cur2 = next; + } + } + + pre.next = cur1 == null ? cur2 : cur1; + + return head; + } +} diff --git "a/src/main/java/algorithm/link/\346\214\211\347\205\247\345\267\246\345\217\263\345\215\212\345\214\272\347\232\204\346\226\271\345\274\217\347\273\204\345\220\210\351\223\276\350\241\250.java" "b/src/main/java/algorithm/link/\346\214\211\347\205\247\345\267\246\345\217\263\345\215\212\345\214\272\347\232\204\346\226\271\345\274\217\347\273\204\345\220\210\351\223\276\350\241\250.java" new file mode 100644 index 0000000..4b69a98 --- /dev/null +++ "b/src/main/java/algorithm/link/\346\214\211\347\205\247\345\267\246\345\217\263\345\215\212\345\214\272\347\232\204\346\226\271\345\274\217\347\273\204\345\220\210\351\223\276\350\241\250.java" @@ -0,0 +1,40 @@ +package algorithm.link; + +import algorithm.utils.Node; + +/** + * @author Ethan Zhang + * @date 2022/4/4 + */ +public class 按照左右半区的方式组合链表 { + + public void relocate(Node head) { + if (head == null || head.next == null) { + return; + } + + Node mid = head; + Node right = head.next; + while (right.next != null && right.next.next != null) { + mid = mid.next; + right = right.next.next; + } + + right = right.next; + mid.next = null; + merge(head, right); + } + + private void merge(Node left, Node right) { + Node next = null; + while (left.next != null) { + next = right.next; + right.next = left.next; + left.next = right; + left = right.next; + right = next; + } + + left.next = right; + } +} diff --git a/src/main/java/algorithm/utils/TreeUtils.java b/src/main/java/algorithm/utils/TreeUtils.java new file mode 100644 index 0000000..e1382e1 --- /dev/null +++ b/src/main/java/algorithm/utils/TreeUtils.java @@ -0,0 +1,24 @@ +package algorithm.utils; + +/** + * @author Ethan Zhang + * @date 2022/4/12 + */ +public class TreeUtils { + + public static TreeNode makeTree() { + TreeNode root = new TreeNode(5); + TreeNode node4 = new TreeNode(5); + TreeNode node3 = new TreeNode(5); + TreeNode node2 = new TreeNode(5); + TreeNode node1 = new TreeNode(5); + TreeNode node6 = new TreeNode(5); + TreeNode node7 = new TreeNode(5); + TreeNode node8 = new TreeNode(5); + TreeNode node9 = new TreeNode(5); + + root.left = node4; + + return null; + } +} From 77773fea7ac6bb6b2fb51f3b6def95641e550774 Mon Sep 17 00:00:00 2001 From: Ethan Date: Sat, 16 Apr 2022 01:44:05 +0800 Subject: [PATCH 09/43] binary tree traverse --- ...\345\272\217\351\201\215\345\216\206.java" | 7 ++-- ...\345\260\217\346\267\261\345\272\246.java" | 35 +++++++++++++++++++ ...\345\272\217\351\201\215\345\216\206.java" | 26 ++++++++++++++ 3 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 "src/main/java/algorithm/binary_tree/\344\272\214\345\217\211\346\240\221\347\232\204\346\234\200\345\260\217\346\267\261\345\272\246.java" diff --git "a/src/main/java/algorithm/binary_tree/\344\270\255\345\272\217\351\201\215\345\216\206.java" "b/src/main/java/algorithm/binary_tree/\344\270\255\345\272\217\351\201\215\345\216\206.java" index e280712..63b3d8e 100644 --- "a/src/main/java/algorithm/binary_tree/\344\270\255\345\272\217\351\201\215\345\216\206.java" +++ "b/src/main/java/algorithm/binary_tree/\344\270\255\345\272\217\351\201\215\345\216\206.java" @@ -20,6 +20,7 @@ public static void main(String[] args) { TreeNode root = BinaryTree.create(Lists.newArrayList(1, 2, 3, 4, 5, 6, 7)); inOrder1(root); + inOrder2(root); } public static void inOrder1(TreeNode root) { @@ -45,11 +46,11 @@ public static void inOrder2(TreeNode root) { stack.push(root); root = root.left; } else { - TreeNode left = stack.pop(); + root = stack.pop(); - System.out.println(left.value); + System.out.println(root.value); - stack.push(left.right); + stack.push(root.right); } } } diff --git "a/src/main/java/algorithm/binary_tree/\344\272\214\345\217\211\346\240\221\347\232\204\346\234\200\345\260\217\346\267\261\345\272\246.java" "b/src/main/java/algorithm/binary_tree/\344\272\214\345\217\211\346\240\221\347\232\204\346\234\200\345\260\217\346\267\261\345\272\246.java" new file mode 100644 index 0000000..1a543e5 --- /dev/null +++ "b/src/main/java/algorithm/binary_tree/\344\272\214\345\217\211\346\240\221\347\232\204\346\234\200\345\260\217\346\267\261\345\272\246.java" @@ -0,0 +1,35 @@ +package algorithm.binary_tree; + +import algorithm.utils.TreeNode; + +/** + * @author Ethan Zhang + * @date 2022/4/16 + */ +public class 二叉树的最小深度 { + + public int minDepth1(TreeNode root) { + if (root == null) { + return 0; + } + + return process(root, 1); + } + + private int process(TreeNode root, int level) { + if (root.left == null && root.right == null) { + return level; + } + + int ans = Integer.MAX_VALUE; + if (root.left != null) { + ans = Math.min(ans, process(root.left, level + 1)); + } + + if (root.right != null) { + ans = Math.min(ans, process(root.right, level + 1)); + } + + return ans; + } +} diff --git "a/src/main/java/algorithm/binary_tree/\345\220\216\345\272\217\351\201\215\345\216\206.java" "b/src/main/java/algorithm/binary_tree/\345\220\216\345\272\217\351\201\215\345\216\206.java" index 46b3c39..89a5652 100644 --- "a/src/main/java/algorithm/binary_tree/\345\220\216\345\272\217\351\201\215\345\216\206.java" +++ "b/src/main/java/algorithm/binary_tree/\345\220\216\345\272\217\351\201\215\345\216\206.java" @@ -58,4 +58,30 @@ public static void postOrder2(TreeNode root) { } } } + + public static void postOrder3(TreeNode root) { + if (root == null) { + return; + } + + Stack s1 = new Stack<>(); + Stack s2 = new Stack<>(); + s1.push(root); + while (!s1.isEmpty()) { + root = s1.pop(); + s2.push(root); + + if (root.left != null) { + s2.push(root.left); + } + + if (root.right != null) { + s2.push(root.right); + } + } + + while (!s2.isEmpty()) { + System.out.println(s2.pop().value); + } + } } From 4416b74088ca18edc6012fc670eed45a001b485d Mon Sep 17 00:00:00 2001 From: Ethan Date: Sun, 17 Apr 2022 01:51:23 +0800 Subject: [PATCH 10/43] =?UTF-8?q?Morris=E9=81=8D=E5=8E=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Morris\351\201\215\345\216\206.java" | 45 +++++++++++++++++++ ...\345\272\217\351\201\215\345\216\206.java" | 20 ++++----- ...\345\272\217\351\201\215\345\216\206.java" | 1 + 3 files changed, 56 insertions(+), 10 deletions(-) create mode 100644 "src/main/java/algorithm/binary_tree/Morris\351\201\215\345\216\206.java" diff --git "a/src/main/java/algorithm/binary_tree/Morris\351\201\215\345\216\206.java" "b/src/main/java/algorithm/binary_tree/Morris\351\201\215\345\216\206.java" new file mode 100644 index 0000000..f3afec7 --- /dev/null +++ "b/src/main/java/algorithm/binary_tree/Morris\351\201\215\345\216\206.java" @@ -0,0 +1,45 @@ +package algorithm.binary_tree; + +import algorithm.data_structure.BinaryTree; +import algorithm.utils.TreeNode; +import com.google.common.collect.Lists; + +/** + * @author Ethan Zhang + * @date 2022/4/16 + */ +public class Morris遍历 { + + public static void main(String[] args) { + TreeNode root = BinaryTree.create(Lists.newArrayList(1, 2, 3, 4, 5, 6, 7)); + + morrisTraverse(root); + } + + public static void morrisTraverse(TreeNode head) { + if (head == null) { + return; + } + + TreeNode cur = head; + TreeNode mostRight = null; + while (cur != null) { + mostRight = cur.left; + if (mostRight != null) { + while (mostRight.right != null && mostRight.right != cur) { + mostRight = mostRight.right; + } + + if (mostRight.right == null) { + mostRight.right = cur; + cur = cur.left; + continue; + } else { + mostRight.right = null; + } + } + + cur = cur.right; + } + } +} diff --git "a/src/main/java/algorithm/binary_tree/\344\270\255\345\272\217\351\201\215\345\216\206.java" "b/src/main/java/algorithm/binary_tree/\344\270\255\345\272\217\351\201\215\345\216\206.java" index 63b3d8e..5a7248e 100644 --- "a/src/main/java/algorithm/binary_tree/\344\270\255\345\272\217\351\201\215\345\216\206.java" +++ "b/src/main/java/algorithm/binary_tree/\344\270\255\345\272\217\351\201\215\345\216\206.java" @@ -17,7 +17,7 @@ public class 中序遍历 { public static void main(String[] args) { - TreeNode root = BinaryTree.create(Lists.newArrayList(1, 2, 3, 4, 5, 6, 7)); + TreeNode root = BinaryTree.create(Lists.newArrayList(1, 2, 3, 4, 5, 6)); inOrder1(root); inOrder2(root); @@ -35,22 +35,22 @@ public static void inOrder1(TreeNode root) { inOrder1(root.right); } - public static void inOrder2(TreeNode root) { - if (root == null) { + public static void inOrder2(TreeNode head) { + if (head == null) { return; } Stack stack = new Stack<>(); - while (!stack.isEmpty() || root != null) { - if (root != null) { - stack.push(root); - root = root.left; + while (!stack.isEmpty() || head != null) { + if (head != null) { + stack.push(head); + head = head.left; } else { - root = stack.pop(); + head = stack.pop(); - System.out.println(root.value); + System.out.println(head.value); - stack.push(root.right); + head = head.right; } } } diff --git "a/src/main/java/algorithm/binary_tree/\345\211\215\345\272\217\351\201\215\345\216\206.java" "b/src/main/java/algorithm/binary_tree/\345\211\215\345\272\217\351\201\215\345\216\206.java" index 52a4b66..53553f6 100644 --- "a/src/main/java/algorithm/binary_tree/\345\211\215\345\272\217\351\201\215\345\216\206.java" +++ "b/src/main/java/algorithm/binary_tree/\345\211\215\345\272\217\351\201\215\345\216\206.java" @@ -6,6 +6,7 @@ import java.util.Stack; /** + * * 1 * 2 3 * 4 5 6 7 From 5b6eb1e3f904d91178ab80a7b837444b23221157 Mon Sep 17 00:00:00 2001 From: Ethan Date: Sun, 17 Apr 2022 16:06:12 +0800 Subject: [PATCH 11/43] =?UTF-8?q?Morris=E9=81=8D=E5=8E=86=E5=88=B0?= =?UTF-8?q?=E5=90=8E=E5=BA=8F=E9=81=8D=E5=8E=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Morris\351\201\215\345\216\206.java" | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git "a/src/main/java/algorithm/binary_tree/Morris\351\201\215\345\216\206.java" "b/src/main/java/algorithm/binary_tree/Morris\351\201\215\345\216\206.java" index f3afec7..ff791fd 100644 --- "a/src/main/java/algorithm/binary_tree/Morris\351\201\215\345\216\206.java" +++ "b/src/main/java/algorithm/binary_tree/Morris\351\201\215\345\216\206.java" @@ -21,8 +21,56 @@ public static void morrisTraverse(TreeNode head) { return; } + TreeNode mostRight = null; TreeNode cur = head; + while (cur != null) { + mostRight = cur.left; + while (mostRight.right != null && mostRight.right != cur) { + mostRight = mostRight.right; + } + + if (mostRight.right == null) { + mostRight.right = cur; + cur = cur.left; + continue; + } else { + mostRight.right = null; + } + + cur = cur.right; + } + } + + public static void morrisTraverseToPreOrder(TreeNode head) { + TreeNode mostRight = null; + TreeNode cur = head; + while (cur != null) { + mostRight = cur.left; + if (mostRight != null) { + while (mostRight.right != null && mostRight.right != cur) { + mostRight = mostRight.right; + } + + if (mostRight.right == null) { + System.out.println(cur.value); + + mostRight.right = cur; + cur = cur.left; + continue; + } else { + mostRight.right = null; + } + } else { + System.out.println(cur.value); + } + + cur = cur.right; + } + } + + public static void morrisTraverseToInOrder(TreeNode head) { TreeNode mostRight = null; + TreeNode cur = head; while (cur != null) { mostRight = cur.left; if (mostRight != null) { @@ -39,7 +87,65 @@ public static void morrisTraverse(TreeNode head) { } } + System.out.println(cur.value); + + cur = cur.right; + } + } + + public static void morrisTraverseToPostOrder(TreeNode head) { + if (head == null) { + return; + } + + TreeNode mostRight = null; + TreeNode cur = head; + while (cur != null) { + mostRight = cur.left; + if (mostRight != null) { + if (mostRight.right != null && mostRight.right != cur) { + mostRight = mostRight.right; + } + + if (mostRight.right == null) { + mostRight.right = cur; + cur = cur.left; + continue; + } else { + mostRight.right = null; + + printEdge(cur.left); + } + } + cur = cur.right; } + + printEdge(head); + } + + private static void printEdge(TreeNode head) { + TreeNode tail = reverseEdge(head); + TreeNode cur = tail; + while (cur != null) { + System.out.println(cur.value); + + cur = cur.right; + } + + reverseEdge(tail); + } + + private static TreeNode reverseEdge(TreeNode head) { + TreeNode pre = null; + TreeNode cur = head; + while (cur != null) { + TreeNode next = cur.right; + cur.right = pre; + pre = cur; + cur = next; + } + + return pre; } } From b33b86cf35e4e5636cbed8bd363b9f4f70f47f21 Mon Sep 17 00:00:00 2001 From: Ethan Date: Sun, 17 Apr 2022 16:23:08 +0800 Subject: [PATCH 12/43] refactoring class name --- .../array/\345\211\215\347\274\200\345\222\214.java" | 8 ++++---- ...\345\275\222\345\271\266\346\216\222\345\272\217.java" | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) rename src/main/java/algorithm/array/NumArray.java => "src/main/java/algorithm/array/\345\211\215\347\274\200\345\222\214.java" (73%) rename "src/main/java/algorithm/array/\346\225\260\347\273\204\345\275\222\345\271\266\346\216\222\345\272\217.java" => "src/main/java/algorithm/array/\345\275\222\345\271\266\346\216\222\345\272\217.java" (97%) diff --git a/src/main/java/algorithm/array/NumArray.java "b/src/main/java/algorithm/array/\345\211\215\347\274\200\345\222\214.java" similarity index 73% rename from src/main/java/algorithm/array/NumArray.java rename to "src/main/java/algorithm/array/\345\211\215\347\274\200\345\222\214.java" index a860887..95cd630 100644 --- a/src/main/java/algorithm/array/NumArray.java +++ "b/src/main/java/algorithm/array/\345\211\215\347\274\200\345\222\214.java" @@ -8,11 +8,11 @@ * @author Ethan Zhang * @date 2022/1/20 */ -public class NumArray { +public class 前缀和 { private final int[] nums; - public NumArray(int[] nums) { + public 前缀和(int[] nums) { this.nums = new int[nums.length + 1]; int sum = this.nums[0]; @@ -32,7 +32,7 @@ public int sumRange(int left, int right) { } public static void main(String[] args) { - System.out.println(new NumArray(new int[]{1, 2, 3, 4, 5}).sumRange(0, 4)); - System.out.println(new NumArray(new int[]{1, 2, 3, 4, 5}).sumRange(0, 2)); + System.out.println(new 前缀和(new int[]{1, 2, 3, 4, 5}).sumRange(0, 4)); + System.out.println(new 前缀和(new int[]{1, 2, 3, 4, 5}).sumRange(0, 2)); } } diff --git "a/src/main/java/algorithm/array/\346\225\260\347\273\204\345\275\222\345\271\266\346\216\222\345\272\217.java" "b/src/main/java/algorithm/array/\345\275\222\345\271\266\346\216\222\345\272\217.java" similarity index 97% rename from "src/main/java/algorithm/array/\346\225\260\347\273\204\345\275\222\345\271\266\346\216\222\345\272\217.java" rename to "src/main/java/algorithm/array/\345\275\222\345\271\266\346\216\222\345\272\217.java" index a763dc8..0777935 100644 --- "a/src/main/java/algorithm/array/\346\225\260\347\273\204\345\275\222\345\271\266\346\216\222\345\272\217.java" +++ "b/src/main/java/algorithm/array/\345\275\222\345\271\266\346\216\222\345\272\217.java" @@ -6,7 +6,7 @@ * @author Ethan Zhang * @date 2022/3/20 */ -public class 数组归并排序 { +public class 归并排序 { public void sort(int[] nums) { if (nums == null) { From f0f977e68e638349e05694304ec21fc1bd7e3638 Mon Sep 17 00:00:00 2001 From: Ethan Date: Sun, 17 Apr 2022 16:55:33 +0800 Subject: [PATCH 13/43] =?UTF-8?q?=E7=B4=AF=E5=8A=A0=E5=92=8C=E4=B8=BA?= =?UTF-8?q?=E6=8C=87=E5=AE=9A=E5=80=BC=E7=9A=84=E6=9C=80=E9=95=BF=E5=AD=90?= =?UTF-8?q?=E6=95=B0=E7=BB=84=E9=95=BF=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\345\210\227\351\227\256\351\242\230.java" | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 "src/main/java/algorithm/array/\346\234\252\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\347\264\257\345\212\240\345\222\214\344\270\272\347\273\231\345\256\232\345\200\274\347\232\204\346\234\200\351\225\277\345\255\220\346\225\260\347\273\204\347\263\273\345\210\227\351\227\256\351\242\230.java" diff --git "a/src/main/java/algorithm/array/\346\234\252\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\347\264\257\345\212\240\345\222\214\344\270\272\347\273\231\345\256\232\345\200\274\347\232\204\346\234\200\351\225\277\345\255\220\346\225\260\347\273\204\347\263\273\345\210\227\351\227\256\351\242\230.java" "b/src/main/java/algorithm/array/\346\234\252\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\347\264\257\345\212\240\345\222\214\344\270\272\347\273\231\345\256\232\345\200\274\347\232\204\346\234\200\351\225\277\345\255\220\346\225\260\347\273\204\347\263\273\345\210\227\351\227\256\351\242\230.java" new file mode 100644 index 0000000..22f476c --- /dev/null +++ "b/src/main/java/algorithm/array/\346\234\252\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\347\264\257\345\212\240\345\222\214\344\270\272\347\273\231\345\256\232\345\200\274\347\232\204\346\234\200\351\225\277\345\255\220\346\225\260\347\273\204\347\263\273\345\210\227\351\227\256\351\242\230.java" @@ -0,0 +1,41 @@ +package algorithm.array; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author Ethan Zhang + * @date 2022/4/17 + */ +public class 未排序数组中累加和为给定值的最长子数组系列问题 { + + public static void main(String[] args) { + int[] array = new int[]{1, 2, 3, -3, 3}; + + System.out.println(maxLength(array, 6)); + } + + public static int maxLength(int[] array, int target) { + if (array == null || array.length == 0) { + return 0; + } + + Map cache = new HashMap<>(); + cache.put(0, -1); + + int maxLen = 0; + int sum = 0; + for (int i = 0; i < array.length; i++) { + sum += array[i]; + if (cache.containsKey(sum - target)) { + maxLen = Math.max(maxLen, i - cache.get(sum - target)); + } + + if (!cache.containsKey(sum)) { + cache.put(sum, i); + } + } + + return maxLen; + } +} From 03999da541ea9076975208614a909816e6586fc3 Mon Sep 17 00:00:00 2001 From: Ethan Date: Sun, 17 Apr 2022 18:31:15 +0800 Subject: [PATCH 14/43] =?UTF-8?q?=E4=BA=8C=E5=8F=89=E6=A0=91=E7=B4=AF?= =?UTF-8?q?=E5=8A=A0=E5=92=8C=E6=9C=80=E9=95=BF=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\345\210\227\351\227\256\351\242\230.java" | 5 ++ ...\345\276\204\351\225\277\345\272\246.java" | 60 +++++++++++++++++++ ...226\345\255\220\344\270\262_leetcode.java" | 2 +- 3 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 "src/main/java/algorithm/binary_tree/\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\346\211\276\345\210\260\347\264\257\345\212\240\345\222\214\345\220\210\344\270\272\346\214\207\345\256\232\345\200\274\347\232\204\346\234\200\351\225\277\350\267\257\345\276\204\351\225\277\345\272\246.java" rename "src/main/java/algorithm/window/\346\234\200\345\260\217\350\246\206\347\233\226\345\255\220\344\270\262_leetcode.java" => "src/main/java/algorithm/sliding_window/\346\234\200\345\260\217\350\246\206\347\233\226\345\255\220\344\270\262_leetcode.java" (98%) diff --git "a/src/main/java/algorithm/array/\346\234\252\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\347\264\257\345\212\240\345\222\214\344\270\272\347\273\231\345\256\232\345\200\274\347\232\204\346\234\200\351\225\277\345\255\220\346\225\260\347\273\204\347\263\273\345\210\227\351\227\256\351\242\230.java" "b/src/main/java/algorithm/array/\346\234\252\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\347\264\257\345\212\240\345\222\214\344\270\272\347\273\231\345\256\232\345\200\274\347\232\204\346\234\200\351\225\277\345\255\220\346\225\260\347\273\204\347\263\273\345\210\227\351\227\256\351\242\230.java" index 22f476c..3033d8d 100644 --- "a/src/main/java/algorithm/array/\346\234\252\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\347\264\257\345\212\240\345\222\214\344\270\272\347\273\231\345\256\232\345\200\274\347\232\204\346\234\200\351\225\277\345\255\220\346\225\260\347\273\204\347\263\273\345\210\227\351\227\256\351\242\230.java" +++ "b/src/main/java/algorithm/array/\346\234\252\346\216\222\345\272\217\346\225\260\347\273\204\344\270\255\347\264\257\345\212\240\345\222\214\344\270\272\347\273\231\345\256\232\345\200\274\347\232\204\346\234\200\351\225\277\345\255\220\346\225\260\347\273\204\347\263\273\345\210\227\351\227\256\351\242\230.java" @@ -13,8 +13,12 @@ public static void main(String[] args) { int[] array = new int[]{1, 2, 3, -3, 3}; System.out.println(maxLength(array, 6)); + System.out.println(maxLength(array, -100)); } + /** + * @see algorithm.binary_tree.在二叉树中找到累加和合为指定值的最长路径长度 + */ public static int maxLength(int[] array, int target) { if (array == null || array.length == 0) { return 0; @@ -31,6 +35,7 @@ public static int maxLength(int[] array, int target) { maxLen = Math.max(maxLen, i - cache.get(sum - target)); } + // TODO 顺序有关系吗 if (!cache.containsKey(sum)) { cache.put(sum, i); } diff --git "a/src/main/java/algorithm/binary_tree/\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\346\211\276\345\210\260\347\264\257\345\212\240\345\222\214\345\220\210\344\270\272\346\214\207\345\256\232\345\200\274\347\232\204\346\234\200\351\225\277\350\267\257\345\276\204\351\225\277\345\272\246.java" "b/src/main/java/algorithm/binary_tree/\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\346\211\276\345\210\260\347\264\257\345\212\240\345\222\214\345\220\210\344\270\272\346\214\207\345\256\232\345\200\274\347\232\204\346\234\200\351\225\277\350\267\257\345\276\204\351\225\277\345\272\246.java" new file mode 100644 index 0000000..db4b9c5 --- /dev/null +++ "b/src/main/java/algorithm/binary_tree/\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\346\211\276\345\210\260\347\264\257\345\212\240\345\222\214\345\220\210\344\270\272\346\214\207\345\256\232\345\200\274\347\232\204\346\234\200\351\225\277\350\267\257\345\276\204\351\225\277\345\272\246.java" @@ -0,0 +1,60 @@ +package algorithm.binary_tree; + +import algorithm.data_structure.BinaryTree; +import algorithm.utils.TreeNode; +import com.google.common.collect.Lists; +import java.util.HashMap; +import java.util.Map; + +/** + * @author Ethan Zhang + * @date 2022/4/17 + */ +public class 在二叉树中找到累加和合为指定值的最长路径长度 { + + public static void main(String[] args) { + TreeNode head = BinaryTree.create(Lists.newArrayList(1, 2, 3, -3, -3, 6, 7)); + + System.out.println(getMaxLen(head, 0)); + } + + /** + * @see algorithm.array.未排序数组中累加和为给定值的最长子数组系列问题 + */ + public static int getMaxLen(TreeNode head, int target) { + if (head == null) { + return 0; + } + + Map cache = new HashMap<>(); + cache.put(0, 0); + + return getMaxLenRecursive(head, target, 0, 1, 0, cache); + } + + private static int getMaxLenRecursive(TreeNode head, int target, int preSum, int level, int maxLen, + Map cache) { + if (head == null) { + return maxLen; + } + + int sum = preSum + head.value; + if (!cache.containsKey(sum)) { + cache.put(sum, level); + } + + // 注意和上面if的顺序 + if (cache.containsKey(sum - target)) { + maxLen = Math.max(maxLen, cache.get(sum - target)); + } + + maxLen = getMaxLenRecursive(head.left, target, sum, level + 1, maxLen, cache); + maxLen = getMaxLenRecursive(head.right, target, sum, level + 1, maxLen, cache); + + if (level == cache.get(sum)) { + cache.remove(sum); + } + + return maxLen; + } +} diff --git "a/src/main/java/algorithm/window/\346\234\200\345\260\217\350\246\206\347\233\226\345\255\220\344\270\262_leetcode.java" "b/src/main/java/algorithm/sliding_window/\346\234\200\345\260\217\350\246\206\347\233\226\345\255\220\344\270\262_leetcode.java" similarity index 98% rename from "src/main/java/algorithm/window/\346\234\200\345\260\217\350\246\206\347\233\226\345\255\220\344\270\262_leetcode.java" rename to "src/main/java/algorithm/sliding_window/\346\234\200\345\260\217\350\246\206\347\233\226\345\255\220\344\270\262_leetcode.java" index 264965a..c00dd94 100644 --- "a/src/main/java/algorithm/window/\346\234\200\345\260\217\350\246\206\347\233\226\345\255\220\344\270\262_leetcode.java" +++ "b/src/main/java/algorithm/sliding_window/\346\234\200\345\260\217\350\246\206\347\233\226\345\255\220\344\270\262_leetcode.java" @@ -1,4 +1,4 @@ -package algorithm.window; +package algorithm.sliding_window; import java.math.BigDecimal; import java.text.NumberFormat; From 2147a5ec6a901edefe8be570dabe95f0b19814d4 Mon Sep 17 00:00:00 2001 From: Ethan Date: Sun, 17 Apr 2022 20:16:01 +0800 Subject: [PATCH 15/43] =?UTF-8?q?=E6=89=BE=E5=88=B0=E4=BA=8C=E5=8F=89?= =?UTF-8?q?=E6=A0=91=E6=9C=80=E5=A4=A7BST?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\345\276\204\351\225\277\345\272\246.java" | 1 + ...\345\217\211\345\255\220\346\240\221.java" | 60 +++++++++++++++++++ .../algorithm/data_structure/BinaryTree.java | 2 +- 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 "src/main/java/algorithm/binary_tree/\346\211\276\345\210\260\344\272\214\345\217\211\346\240\221\344\270\255\347\232\204\346\234\200\345\244\247\346\220\234\347\264\242\344\272\214\345\217\211\345\255\220\346\240\221.java" diff --git "a/src/main/java/algorithm/binary_tree/\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\346\211\276\345\210\260\347\264\257\345\212\240\345\222\214\345\220\210\344\270\272\346\214\207\345\256\232\345\200\274\347\232\204\346\234\200\351\225\277\350\267\257\345\276\204\351\225\277\345\272\246.java" "b/src/main/java/algorithm/binary_tree/\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\346\211\276\345\210\260\347\264\257\345\212\240\345\222\214\345\220\210\344\270\272\346\214\207\345\256\232\345\200\274\347\232\204\346\234\200\351\225\277\350\267\257\345\276\204\351\225\277\345\272\246.java" index db4b9c5..cd2f849 100644 --- "a/src/main/java/algorithm/binary_tree/\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\346\211\276\345\210\260\347\264\257\345\212\240\345\222\214\345\220\210\344\270\272\346\214\207\345\256\232\345\200\274\347\232\204\346\234\200\351\225\277\350\267\257\345\276\204\351\225\277\345\272\246.java" +++ "b/src/main/java/algorithm/binary_tree/\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\346\211\276\345\210\260\347\264\257\345\212\240\345\222\214\345\220\210\344\270\272\346\214\207\345\256\232\345\200\274\347\232\204\346\234\200\351\225\277\350\267\257\345\276\204\351\225\277\345\272\246.java" @@ -51,6 +51,7 @@ private static int getMaxLenRecursive(TreeNode head, int target, int preSum, int maxLen = getMaxLenRecursive(head.left, target, sum, level + 1, maxLen, cache); maxLen = getMaxLenRecursive(head.right, target, sum, level + 1, maxLen, cache); + // 防止冲突 if (level == cache.get(sum)) { cache.remove(sum); } diff --git "a/src/main/java/algorithm/binary_tree/\346\211\276\345\210\260\344\272\214\345\217\211\346\240\221\344\270\255\347\232\204\346\234\200\345\244\247\346\220\234\347\264\242\344\272\214\345\217\211\345\255\220\346\240\221.java" "b/src/main/java/algorithm/binary_tree/\346\211\276\345\210\260\344\272\214\345\217\211\346\240\221\344\270\255\347\232\204\346\234\200\345\244\247\346\220\234\347\264\242\344\272\214\345\217\211\345\255\220\346\240\221.java" new file mode 100644 index 0000000..e94cb95 --- /dev/null +++ "b/src/main/java/algorithm/binary_tree/\346\211\276\345\210\260\344\272\214\345\217\211\346\240\221\344\270\255\347\232\204\346\234\200\345\244\247\346\220\234\347\264\242\344\272\214\345\217\211\345\255\220\346\240\221.java" @@ -0,0 +1,60 @@ +package algorithm.binary_tree; + +import algorithm.data_structure.BinaryTree; +import algorithm.utils.TreeNode; +import com.google.common.collect.Lists; + +/** + * @author Ethan Zhang + * @date 2022/4/17 + */ +public class 找到二叉树中的最大搜索二叉子树 { + + public static void main(String[] args) { + TreeNode head = BinaryTree.create(Lists.newArrayList(9, 10, 13, 4, 14, 20, 16, 2, 5, 11, 15)); + + TreeNode maxBSTHead = findMaxBST(head); + System.out.println(maxBSTHead.value); + } + + public static TreeNode findMaxBST(TreeNode head) { + return findSearchTreeRecursive(head).maxBSTHead; + } + + private static ReturnType findSearchTreeRecursive(TreeNode head) { + if (head == null) { + return new ReturnType(null, 0, Integer.MAX_VALUE, Integer.MIN_VALUE); + } + + ReturnType left = findSearchTreeRecursive(head.left); + ReturnType right = findSearchTreeRecursive(head.right); + + int min = Math.min(head.value, Math.min(left.min, right.min)); + int max = Math.max(head.value, Math.max(left.max, right.max)); + int maxBSTSize = Math.max(left.maxBSTSize, right.maxBSTSize); + TreeNode maxBSTHead = left.maxBSTSize > right.maxBSTSize ? left.maxBSTHead : right.maxBSTHead; + if (left.maxBSTHead == head.left && left.max < head.value && right.maxBSTHead == head.right && right.min > head.value) { + maxBSTSize = left.maxBSTSize + right.maxBSTSize + 1; + maxBSTHead = head; + } + + return new ReturnType(maxBSTHead, maxBSTSize, min, max); + } + + private static class ReturnType { + private final TreeNode maxBSTHead; + + private final int maxBSTSize; + + private final int min; + + private final int max; + + private ReturnType(TreeNode maxBSTHead, int maxBSTSize, int min, int max) { + this.maxBSTHead = maxBSTHead; + this.maxBSTSize = maxBSTSize; + this.min = min; + this.max = max; + } + } +} diff --git a/src/main/java/algorithm/data_structure/BinaryTree.java b/src/main/java/algorithm/data_structure/BinaryTree.java index f929a92..90dbeb9 100644 --- a/src/main/java/algorithm/data_structure/BinaryTree.java +++ b/src/main/java/algorithm/data_structure/BinaryTree.java @@ -28,7 +28,7 @@ private static TreeNode createRecursive(List nums, TreeNode cur, int i) public static TreeNode create(List nums) { BinaryTree binaryTree = new BinaryTree(); - binaryTree.root = createRecursive(Lists.newArrayList(1, 2, 3, 4, 5, 6, 7), binaryTree.root, 0); + binaryTree.root = createRecursive(nums, binaryTree.root, 0); return binaryTree.root; } From c38c4a483415a89fbbdae45535e5f0dbc20717d0 Mon Sep 17 00:00:00 2001 From: Ethan Zhang Date: Tue, 19 Apr 2022 23:56:49 +0800 Subject: [PATCH 16/43] =?UTF-8?q?=E4=BA=8C=E5=8F=89=E6=A0=91=E6=9C=80?= =?UTF-8?q?=E5=A4=A7=E6=8B=93=E6=89=91=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...223\346\211\221\347\273\223\346\236\204.java" | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 "src/main/java/algorithm/binary_tree/\346\211\276\345\210\260\344\272\214\345\217\211\346\240\221\344\270\255\347\254\246\345\220\210\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221\346\235\241\344\273\266\347\232\204\346\234\200\345\244\247\346\213\223\346\211\221\347\273\223\346\236\204.java" diff --git "a/src/main/java/algorithm/binary_tree/\346\211\276\345\210\260\344\272\214\345\217\211\346\240\221\344\270\255\347\254\246\345\220\210\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221\346\235\241\344\273\266\347\232\204\346\234\200\345\244\247\346\213\223\346\211\221\347\273\223\346\236\204.java" "b/src/main/java/algorithm/binary_tree/\346\211\276\345\210\260\344\272\214\345\217\211\346\240\221\344\270\255\347\254\246\345\220\210\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221\346\235\241\344\273\266\347\232\204\346\234\200\345\244\247\346\213\223\346\211\221\347\273\223\346\236\204.java" new file mode 100644 index 0000000..704428f --- /dev/null +++ "b/src/main/java/algorithm/binary_tree/\346\211\276\345\210\260\344\272\214\345\217\211\346\240\221\344\270\255\347\254\246\345\220\210\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221\346\235\241\344\273\266\347\232\204\346\234\200\345\244\247\346\213\223\346\211\221\347\273\223\346\236\204.java" @@ -0,0 +1,16 @@ +package algorithm.binary_tree; + +import algorithm.utils.TreeNode; + +/** + * @author Ethan Zhang + * @date 2022/4/19 + */ +public class 找到二叉树中符合搜索二叉树条件的最大拓扑结构 { + + public int bstTopSize1(TreeNode head) { + + + return 0; + } +} From 5b8b095e4bcdb68b6104846d7311fdacbf46c4c7 Mon Sep 17 00:00:00 2001 From: Ethan Zhang Date: Wed, 20 Apr 2022 00:20:10 +0800 Subject: [PATCH 17/43] =?UTF-8?q?=E4=BA=8C=E5=8F=89=E6=A0=91=E6=9C=80?= =?UTF-8?q?=E5=A4=A7=E6=8B=93=E6=89=91=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\346\211\221\347\273\223\346\236\204.java" | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git "a/src/main/java/algorithm/binary_tree/\346\211\276\345\210\260\344\272\214\345\217\211\346\240\221\344\270\255\347\254\246\345\220\210\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221\346\235\241\344\273\266\347\232\204\346\234\200\345\244\247\346\213\223\346\211\221\347\273\223\346\236\204.java" "b/src/main/java/algorithm/binary_tree/\346\211\276\345\210\260\344\272\214\345\217\211\346\240\221\344\270\255\347\254\246\345\220\210\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221\346\235\241\344\273\266\347\232\204\346\234\200\345\244\247\346\213\223\346\211\221\347\273\223\346\236\204.java" index 704428f..6a37874 100644 --- "a/src/main/java/algorithm/binary_tree/\346\211\276\345\210\260\344\272\214\345\217\211\346\240\221\344\270\255\347\254\246\345\220\210\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221\346\235\241\344\273\266\347\232\204\346\234\200\345\244\247\346\213\223\346\211\221\347\273\223\346\236\204.java" +++ "b/src/main/java/algorithm/binary_tree/\346\211\276\345\210\260\344\272\214\345\217\211\346\240\221\344\270\255\347\254\246\345\220\210\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221\346\235\241\344\273\266\347\232\204\346\234\200\345\244\247\346\213\223\346\211\221\347\273\223\346\236\204.java" @@ -8,9 +8,35 @@ */ public class 找到二叉树中符合搜索二叉树条件的最大拓扑结构 { - public int bstTopSize1(TreeNode head) { + public int bstTopoSize1(TreeNode head) { + if (head == null) { + return 0; + } + int maxTopoSize = maxTopo(head, head); + maxTopoSize = Math.max(bstTopoSize1(head.left), maxTopoSize); + maxTopoSize = Math.max(bstTopoSize1(head.right), maxTopoSize); + + return maxTopoSize; + } + + private int maxTopo(TreeNode h, TreeNode n) { + if (h != null && n != null && isBSTNode(h, n, n.value)) { + return maxTopo(h, n.left) + maxTopo(h, n.right) + 1; + } return 0; } + + private boolean isBSTNode(TreeNode h, TreeNode n, int value) { + if (h == null) { + return false; + } + + if (h == n) { + return true; + } + + return isBSTNode(value > h.value ? h.right : h.left, n, value); + } } From 10c642657084103b6e58414dd6139999f86ee712 Mon Sep 17 00:00:00 2001 From: Ethan Zhang Date: Wed, 20 Apr 2022 23:34:55 +0800 Subject: [PATCH 18/43] =?UTF-8?q?=E4=BA=8C=E5=8F=89=E6=A0=91=E6=9C=80?= =?UTF-8?q?=E5=A4=A7=E6=8B=93=E6=89=91=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\346\211\221\347\273\223\346\236\204.java" | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git "a/src/main/java/algorithm/binary_tree/\346\211\276\345\210\260\344\272\214\345\217\211\346\240\221\344\270\255\347\254\246\345\220\210\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221\346\235\241\344\273\266\347\232\204\346\234\200\345\244\247\346\213\223\346\211\221\347\273\223\346\236\204.java" "b/src/main/java/algorithm/binary_tree/\346\211\276\345\210\260\344\272\214\345\217\211\346\240\221\344\270\255\347\254\246\345\220\210\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221\346\235\241\344\273\266\347\232\204\346\234\200\345\244\247\346\213\223\346\211\221\347\273\223\346\236\204.java" index 6a37874..b78458e 100644 --- "a/src/main/java/algorithm/binary_tree/\346\211\276\345\210\260\344\272\214\345\217\211\346\240\221\344\270\255\347\254\246\345\220\210\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221\346\235\241\344\273\266\347\232\204\346\234\200\345\244\247\346\213\223\346\211\221\347\273\223\346\236\204.java" +++ "b/src/main/java/algorithm/binary_tree/\346\211\276\345\210\260\344\272\214\345\217\211\346\240\221\344\270\255\347\254\246\345\220\210\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221\346\235\241\344\273\266\347\232\204\346\234\200\345\244\247\346\213\223\346\211\221\347\273\223\346\236\204.java" @@ -1,6 +1,8 @@ package algorithm.binary_tree; import algorithm.utils.TreeNode; +import java.util.HashMap; +import java.util.Map; /** * @author Ethan Zhang @@ -39,4 +41,65 @@ private boolean isBSTNode(TreeNode h, TreeNode n, int value) { return isBSTNode(value > h.value ? h.right : h.left, n, value); } + + public int bstTopoSize2(TreeNode head) { + Map cache = new HashMap<>(); + + return postOrder(head, cache); + } + + private int postOrder(TreeNode head, Map cache) { + if (head == null) { + return 0; + } + + int left = postOrder(head.left, cache); + int right = postOrder(head.right, cache); + + modifyMap(head.left, head.value, cache, true); + modifyMap(head.right, head.value, cache, false); + + Record lr = cache.get(head.left); + Record rr = cache.get(head.right); + + int lbst = lr == null ? 0 : lr.leftCnt + lr.rightCnt + 1; + int rbst = rr == null ? 0 : rr.leftCnt + rr.rightCnt + 1; + cache.put(head, new Record(lbst, rbst)); + + return Math.max(lbst + rbst + 1, Math.max(left, right)); + } + + private int modifyMap(TreeNode n, int v, Map cache, boolean s) { + if (n == null || (!cache.containsKey(n))) { + return 0; + } + + Record r = cache.get(n); + if ((s && n.value > v) || (!(s) && n.value < v)) { + cache.remove(n); + return r.leftCnt + r.rightCnt + 1; + } else { + int minus = modifyMap(s ? n.right : n.left, v, cache, s); + if (s) { + r.rightCnt = r.rightCnt - minus; + } else { + r.leftCnt = r.leftCnt - minus; + } + + cache.put(n, r); + + return minus; + } + } + + private static class Record { + public int leftCnt; + + public int rightCnt; + + private Record(int leftCnt, int rightCnt) { + this.leftCnt = leftCnt; + this.rightCnt = rightCnt; + } + } } From 8c08c7e09b42d5a0666ccde88942624bb048a506 Mon Sep 17 00:00:00 2001 From: Ethan Zhang Date: Thu, 21 Apr 2022 23:19:32 +0800 Subject: [PATCH 19/43] =?UTF-8?q?=E4=BA=8C=E5=8F=89=E6=A0=91=E6=9C=80?= =?UTF-8?q?=E5=A4=A7=E6=8B=93=E6=89=91=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\346\213\223\346\211\221\347\273\223\346\236\204.java" | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git "a/src/main/java/algorithm/binary_tree/\346\211\276\345\210\260\344\272\214\345\217\211\346\240\221\344\270\255\347\254\246\345\220\210\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221\346\235\241\344\273\266\347\232\204\346\234\200\345\244\247\346\213\223\346\211\221\347\273\223\346\236\204.java" "b/src/main/java/algorithm/binary_tree/\346\211\276\345\210\260\344\272\214\345\217\211\346\240\221\344\270\255\347\254\246\345\220\210\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221\346\235\241\344\273\266\347\232\204\346\234\200\345\244\247\346\213\223\346\211\221\347\273\223\346\236\204.java" index b78458e..fe33096 100644 --- "a/src/main/java/algorithm/binary_tree/\346\211\276\345\210\260\344\272\214\345\217\211\346\240\221\344\270\255\347\254\246\345\220\210\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221\346\235\241\344\273\266\347\232\204\346\234\200\345\244\247\346\213\223\346\211\221\347\273\223\346\236\204.java" +++ "b/src/main/java/algorithm/binary_tree/\346\211\276\345\210\260\344\272\214\345\217\211\346\240\221\344\270\255\347\254\246\345\220\210\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221\346\235\241\344\273\266\347\232\204\346\234\200\345\244\247\346\213\223\346\211\221\347\273\223\346\236\204.java" @@ -1,8 +1,10 @@ package algorithm.binary_tree; import algorithm.utils.TreeNode; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; +import org.apache.commons.lang3.StringUtils; /** * @author Ethan Zhang @@ -10,6 +12,12 @@ */ public class 找到二叉树中符合搜索二叉树条件的最大拓扑结构 { + public static void main(String[] args) { + String[] strs = StringUtils.split("[UG1, UG2, UG3]", "[] ,"); + + System.out.println(Arrays.toString(strs)); + } + public int bstTopoSize1(TreeNode head) { if (head == null) { return 0; From 4ab5a1bba9cb7ff2d39b7a806c49e4f4c5a02c0f Mon Sep 17 00:00:00 2001 From: Ethan Zhang Date: Sat, 23 Apr 2022 20:14:07 +0800 Subject: [PATCH 20/43] =?UTF-8?q?=E4=BA=8C=E5=88=86=E6=9F=A5=E6=89=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\345\210\206\346\237\245\346\211\276.java" | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 "src/main/java/algorithm/array/\344\272\214\345\210\206\346\237\245\346\211\276.java" diff --git "a/src/main/java/algorithm/array/\344\272\214\345\210\206\346\237\245\346\211\276.java" "b/src/main/java/algorithm/array/\344\272\214\345\210\206\346\237\245\346\211\276.java" new file mode 100644 index 0000000..795fdb5 --- /dev/null +++ "b/src/main/java/algorithm/array/\344\272\214\345\210\206\346\237\245\346\211\276.java" @@ -0,0 +1,35 @@ +package algorithm.array; + +/** + * @author Ethan Zhang + * @date 2022/4/21 + */ +public class 二分查找 { + + public static void main(String[] args) { + int[] array = new int[] {1, 2, 3, 4, 5, 6}; + + System.out.println(binarySearch(array, 1)); + } + + public static int binarySearch(int[] array, int target) { + if (array == null || array.length == 0) { + return -1; + } + + int left = 0; + int right = array.length - 1; + while (left <= right) { + int mid = (left + right) / 2; + if (array[mid] == target) { + return mid; + } else if (array[mid] < target) { + left = mid; + } else { + right = mid; + } + } + + return -1; + } +} From 7f3fa24403f238149c896fe988ca8ba2063a0be5 Mon Sep 17 00:00:00 2001 From: Ethan Zhang Date: Sun, 24 Apr 2022 21:45:35 +0800 Subject: [PATCH 21/43] =?UTF-8?q?=E4=BA=8C=E5=88=86=E6=9F=A5=E6=89=BE?= =?UTF-8?q?=E5=B7=A6=E8=BE=B9=E7=95=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\345\210\206\346\237\245\346\211\276.java" | 4 +-- ...\345\267\246\350\276\271\347\225\214.java" | 34 +++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 "src/main/java/algorithm/array/\344\272\214\345\210\206\346\237\245\346\211\276\345\267\246\350\276\271\347\225\214.java" diff --git "a/src/main/java/algorithm/array/\344\272\214\345\210\206\346\237\245\346\211\276.java" "b/src/main/java/algorithm/array/\344\272\214\345\210\206\346\237\245\346\211\276.java" index 795fdb5..2de7f51 100644 --- "a/src/main/java/algorithm/array/\344\272\214\345\210\206\346\237\245\346\211\276.java" +++ "b/src/main/java/algorithm/array/\344\272\214\345\210\206\346\237\245\346\211\276.java" @@ -24,9 +24,9 @@ public static int binarySearch(int[] array, int target) { if (array[mid] == target) { return mid; } else if (array[mid] < target) { - left = mid; + left = mid + 1; } else { - right = mid; + right = mid - 1; } } diff --git "a/src/main/java/algorithm/array/\344\272\214\345\210\206\346\237\245\346\211\276\345\267\246\350\276\271\347\225\214.java" "b/src/main/java/algorithm/array/\344\272\214\345\210\206\346\237\245\346\211\276\345\267\246\350\276\271\347\225\214.java" new file mode 100644 index 0000000..f820f9d --- /dev/null +++ "b/src/main/java/algorithm/array/\344\272\214\345\210\206\346\237\245\346\211\276\345\267\246\350\276\271\347\225\214.java" @@ -0,0 +1,34 @@ +package algorithm.array; + +/** + * @author Ethan Zhang + * @date 2022/4/23 + */ +public class 二分查找左边界 { + + public static int leftBoundary(int[] array, int target) { + if (array == null || array.length == 0) { + return -1; + } + + int left = 0; + int right = array.length - 1; + while (left <= right) { + int mid = (left + right) / 2; + if (target < array[mid]) { + right = mid - 1; + } else if (target > array[mid]) { + left = mid + 1; + } else { + right = mid - 1; + } + } + + // 检查target比数组所有元素都大的越界情况以及非越界情况但找不到target的情况 + if (left >= array.length || array[left] != target) { + return -1; + } + + return left; + } +} From 64c66060bc4f7ecb7fb40c3b5e006e79bf9dc908 Mon Sep 17 00:00:00 2001 From: Ethan Zhang Date: Mon, 25 Apr 2022 21:20:10 +0800 Subject: [PATCH 22/43] =?UTF-8?q?=E4=BA=8C=E5=8F=89=E6=A0=91=E7=9A=84?= =?UTF-8?q?=E6=8C=89=E5=B1=82=E6=89=93=E5=8D=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\345\261\202\346\211\223\345\215\260.java" | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 "src/main/java/algorithm/binary_tree/\344\272\214\345\217\211\346\240\221\347\232\204\346\214\211\345\261\202\346\211\223\345\215\260.java" diff --git "a/src/main/java/algorithm/binary_tree/\344\272\214\345\217\211\346\240\221\347\232\204\346\214\211\345\261\202\346\211\223\345\215\260.java" "b/src/main/java/algorithm/binary_tree/\344\272\214\345\217\211\346\240\221\347\232\204\346\214\211\345\261\202\346\211\223\345\215\260.java" new file mode 100644 index 0000000..43fe260 --- /dev/null +++ "b/src/main/java/algorithm/binary_tree/\344\272\214\345\217\211\346\240\221\347\232\204\346\214\211\345\261\202\346\211\223\345\215\260.java" @@ -0,0 +1,58 @@ +package algorithm.binary_tree; + +import algorithm.data_structure.BinaryTree; +import algorithm.utils.TreeNode; +import com.google.common.collect.Lists; +import java.util.Deque; +import java.util.LinkedList; + +/** + * @author Ethan Zhang + * @date 2022/4/24 + */ +public class 二叉树的按层打印 { + + public static void main(String[] args) { + TreeNode head = BinaryTree.create(Lists.newArrayList(1, 2, 3, 4, 5, 6, 7)); + + printByLevel(head); + } + + public static void printByLevel(TreeNode head) { + if (head == null) { + return; + } + + Deque queue = new LinkedList<>(); + queue.offer(head); + + int level = 1; + + System.out.print(String.format("Level %d:", level++)); + + TreeNode last = head; + TreeNode nLast = null; + while (!queue.isEmpty()) { + TreeNode cur = queue.poll(); + + System.out.print(cur.value); + + if (cur.left != null) { + nLast = cur.left; + queue.offer(cur.left); + } + + if (cur.right != null) { + nLast = cur.right; + queue.offer(cur.right); + } + + // 最后一行就不打印了 + if (last == cur && !queue.isEmpty()) { + last = nLast; + + System.out.print(String.format("\nLevel %d:", level++)); + } + } + } +} From 4211ca7b309d304cfa783562011230683e3d00e0 Mon Sep 17 00:00:00 2001 From: Ethan Zhang Date: Tue, 26 Apr 2022 22:33:21 +0800 Subject: [PATCH 23/43] =?UTF-8?q?=E4=BA=8C=E5=8F=89=E6=A0=91=E7=9A=84?= =?UTF-8?q?=E6=8C=89Zigzag=E6=89=93=E5=8D=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...14\211Zigzag\346\211\223\345\215\260.java" | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 "src/main/java/algorithm/binary_tree/\344\272\214\345\217\211\346\240\221\346\214\211Zigzag\346\211\223\345\215\260.java" diff --git "a/src/main/java/algorithm/binary_tree/\344\272\214\345\217\211\346\240\221\346\214\211Zigzag\346\211\223\345\215\260.java" "b/src/main/java/algorithm/binary_tree/\344\272\214\345\217\211\346\240\221\346\214\211Zigzag\346\211\223\345\215\260.java" new file mode 100644 index 0000000..6cdb7e5 --- /dev/null +++ "b/src/main/java/algorithm/binary_tree/\344\272\214\345\217\211\346\240\221\346\214\211Zigzag\346\211\223\345\215\260.java" @@ -0,0 +1,77 @@ +package algorithm.binary_tree; + +import algorithm.data_structure.BinaryTree; +import algorithm.utils.TreeNode; +import com.google.common.collect.Lists; +import java.util.Deque; +import java.util.LinkedList; + +/** + * @author Ethan Zhang + * @date 2022/4/24 + */ +public class 二叉树按Zigzag打印 { + + public static void main(String[] args) { + TreeNode head = BinaryTree.create(Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); + + printByZigzag1(head); + } + + public static void printByZigzag1(TreeNode head) { + if (head == null) { + return; + } + + Deque deque = new LinkedList<>(); + deque.offerFirst(head); + + int level = 0; + boolean positive = true; + + printLevel(level++, positive); + + TreeNode last = head; + TreeNode nLast = null; + while (!deque.isEmpty()) { + if (positive) { + head = deque.pollFirst(); + if (head.left != null) { + nLast = nLast == null ? head.left : nLast; + deque.offerLast(head.left); + } + + if (head.right != null) { + nLast = nLast == null ? head.right : nLast; + deque.offerLast(head.right); + } + } else { + head = deque.pollLast(); + if (head.right != null) { + nLast = nLast == null ? head.right : nLast; + deque.offerFirst(head.right); + } + + if (head.left != null) { + nLast = nLast == null ? head.left : nLast; + deque.offerFirst(head.left); + } + } + + System.out.print(head.value + " "); + if (last == head && !deque.isEmpty()) { + last = nLast; + nLast = null; + positive = !positive; + + System.out.println(); + printLevel(level++, positive); + } + } + } + + public static void printLevel(int level, boolean positive) { + System.out.print("Level " + level + " from "); + System.out.print(positive ? "left to right:" : "right to left"); + } +} From a29408abd7d8ce501bf2647a9395e7fc6bebbb46 Mon Sep 17 00:00:00 2001 From: Ethan Zhang Date: Tue, 26 Apr 2022 23:36:34 +0800 Subject: [PATCH 24/43] refactoring --- .../{SortedBinaryTree.java => BinarySearchTree.java} | 4 ++-- src/main/java/algorithm/data_structure/BinaryTree.java | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) rename src/main/java/algorithm/data_structure/{SortedBinaryTree.java => BinarySearchTree.java} (93%) diff --git a/src/main/java/algorithm/data_structure/SortedBinaryTree.java b/src/main/java/algorithm/data_structure/BinarySearchTree.java similarity index 93% rename from src/main/java/algorithm/data_structure/SortedBinaryTree.java rename to src/main/java/algorithm/data_structure/BinarySearchTree.java index 3c07f60..1664606 100644 --- a/src/main/java/algorithm/data_structure/SortedBinaryTree.java +++ b/src/main/java/algorithm/data_structure/BinarySearchTree.java @@ -7,7 +7,7 @@ * @author Ethan Zhang * @date 2022/4/12 */ -public class SortedBinaryTree { +public class BinarySearchTree { private TreeNode root; @@ -52,7 +52,7 @@ public static TreeNode create(List values) { return null; } - SortedBinaryTree binaryTree = new SortedBinaryTree(); + BinarySearchTree binaryTree = new BinarySearchTree(); for (Integer value : values) { binaryTree.add(value); } diff --git a/src/main/java/algorithm/data_structure/BinaryTree.java b/src/main/java/algorithm/data_structure/BinaryTree.java index 90dbeb9..be4db70 100644 --- a/src/main/java/algorithm/data_structure/BinaryTree.java +++ b/src/main/java/algorithm/data_structure/BinaryTree.java @@ -1,6 +1,7 @@ package algorithm.data_structure; import algorithm.utils.TreeNode; +import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import java.util.List; @@ -27,10 +28,17 @@ private static TreeNode createRecursive(List nums, TreeNode cur, int i) } public static TreeNode create(List nums) { + Preconditions.checkNotNull(nums); + BinaryTree binaryTree = new BinaryTree(); binaryTree.root = createRecursive(nums, binaryTree.root, 0); return binaryTree.root; } + public static TreeNode create(Integer... nums) { + Preconditions.checkNotNull(nums); + + return create(Lists.newArrayList(nums)); + } } From 608d16d3b17b7670e8251f2cbe1c491c0b480fab Mon Sep 17 00:00:00 2001 From: Ethan Zhang Date: Tue, 26 Apr 2022 23:38:29 +0800 Subject: [PATCH 25/43] refactoring --- .../algorithm/data_structure/BinarySearchTree.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/algorithm/data_structure/BinarySearchTree.java b/src/main/java/algorithm/data_structure/BinarySearchTree.java index 1664606..f9eab5b 100644 --- a/src/main/java/algorithm/data_structure/BinarySearchTree.java +++ b/src/main/java/algorithm/data_structure/BinarySearchTree.java @@ -1,6 +1,8 @@ package algorithm.data_structure; import algorithm.utils.TreeNode; +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; import java.util.List; /** @@ -48,9 +50,7 @@ private boolean containsRecursive(TreeNode current, int value) { } public static TreeNode create(List values) { - if (values == null || values.isEmpty()) { - return null; - } + Preconditions.checkNotNull(values); BinarySearchTree binaryTree = new BinarySearchTree(); for (Integer value : values) { @@ -60,6 +60,12 @@ public static TreeNode create(List values) { return binaryTree.root; } + public static TreeNode create(Integer... values) { + Preconditions.checkNotNull(values); + + return create(Lists.newArrayList(values)); + } + public TreeNode getRoot() { return root; } From 52d8540b2e897134caa5030d8848a81e5aaa5e06 Mon Sep 17 00:00:00 2001 From: Ethan Zhang Date: Wed, 27 Apr 2022 22:53:39 +0800 Subject: [PATCH 26/43] t1's topology contains t2 --- ...\346\211\221\347\273\223\346\236\204.java" | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 "src/main/java/algorithm/binary_tree/\345\210\244\346\226\255t1\346\240\221\346\230\257\345\220\246\345\214\205\345\220\253t2\346\240\221\347\232\204\345\205\250\351\203\250\346\213\223\346\211\221\347\273\223\346\236\204.java" diff --git "a/src/main/java/algorithm/binary_tree/\345\210\244\346\226\255t1\346\240\221\346\230\257\345\220\246\345\214\205\345\220\253t2\346\240\221\347\232\204\345\205\250\351\203\250\346\213\223\346\211\221\347\273\223\346\236\204.java" "b/src/main/java/algorithm/binary_tree/\345\210\244\346\226\255t1\346\240\221\346\230\257\345\220\246\345\214\205\345\220\253t2\346\240\221\347\232\204\345\205\250\351\203\250\346\213\223\346\211\221\347\273\223\346\236\204.java" new file mode 100644 index 0000000..2b4fffa --- /dev/null +++ "b/src/main/java/algorithm/binary_tree/\345\210\244\346\226\255t1\346\240\221\346\230\257\345\220\246\345\214\205\345\220\253t2\346\240\221\347\232\204\345\205\250\351\203\250\346\213\223\346\211\221\347\273\223\346\236\204.java" @@ -0,0 +1,44 @@ +package algorithm.binary_tree; + +import algorithm.data_structure.BinaryTree; +import algorithm.utils.TreeNode; + +/** + * @author Ethan Zhang + * @date 2022/4/26 + */ +public class 判断t1树是否包含t2树的全部拓扑结构 { + + public static void main(String[] args) { + final TreeNode t1 = BinaryTree.create(1, 2, 3, 4, 5, 6, 7, 8); + final TreeNode t2 = BinaryTree.create(3, 4, 5, 8); + final TreeNode t3 = BinaryTree.create(2, 4, 5, 8); + + System.out.println(contains(t1, t2)); + System.out.println(contains(t1, t3)); + } + + public static boolean contains(TreeNode t1, TreeNode t2) { + if (t2 == null) { + return true; + } + + if (t1 == null) { + return false; + } + + return containsRecursive(t1, t2) || contains(t1.left, t2) || contains(t1.right, t2); + } + + private static boolean containsRecursive(TreeNode t1, TreeNode t2) { + if (t2 == null) { + return true; + } + + if (t1 == null || t1.value != t2.value) { + return false; + } + + return containsRecursive(t1.left, t2.left) && containsRecursive(t1.right, t2.right); + } +} From dff6ff9c111b8c0b24bf70456385d38a56ef31a5 Mon Sep 17 00:00:00 2001 From: Ethan Zhang Date: Thu, 28 Apr 2022 22:54:08 +0800 Subject: [PATCH 27/43] =?UTF-8?q?=E4=BA=8C=E5=8F=89=E6=A0=91=E4=B8=AD?= =?UTF-8?q?=E4=B8=A4=E4=B8=AA=E9=94=99=E8=AF=AF=E8=8A=82=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\347\232\204\350\212\202\347\202\271.java" | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 "src/main/java/algorithm/binary_tree/\350\260\203\346\225\264\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221\344\270\255\344\270\244\344\270\252\351\224\231\350\257\257\347\232\204\350\212\202\347\202\271.java" diff --git "a/src/main/java/algorithm/binary_tree/\350\260\203\346\225\264\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221\344\270\255\344\270\244\344\270\252\351\224\231\350\257\257\347\232\204\350\212\202\347\202\271.java" "b/src/main/java/algorithm/binary_tree/\350\260\203\346\225\264\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221\344\270\255\344\270\244\344\270\252\351\224\231\350\257\257\347\232\204\350\212\202\347\202\271.java" new file mode 100644 index 0000000..52465d2 --- /dev/null +++ "b/src/main/java/algorithm/binary_tree/\350\260\203\346\225\264\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221\344\270\255\344\270\244\344\270\252\351\224\231\350\257\257\347\232\204\350\212\202\347\202\271.java" @@ -0,0 +1,60 @@ +package algorithm.binary_tree; + +import algorithm.data_structure.BinarySearchTree; +import algorithm.utils.TreeNode; +import java.util.Arrays; +import java.util.Stack; + +/** + * @author Ethan Zhang + * @date 2022/4/26 + */ +public class 调整搜索二叉树中两个错误的节点 { + + public static void main(String[] args) { + TreeNode head = BinarySearchTree.create(5, 6, 3, 2, 1, 4, 9, 7, 8); + head.left.left.left.value = 9; + head.right.right.value = 1; + + System.out.println(Arrays.toString(correct(head))); + + head = BinarySearchTree.create(5, 6, 3, 2, 1, 4, 9, 7, 8); + head.left.left.value = 4; + head.left.right.value = 2; + + System.out.println(Arrays.toString(correct(head))); + } + + public static Integer[] correct(TreeNode head) { + if (head == null) { + return null; + } + + return inOrder(head); + } + + public static Integer[] inOrder(TreeNode head) { + TreeNode pre = null; + Integer[] result = new Integer[2]; + Stack stack = new Stack<>(); + while (!stack.isEmpty() || head != null) { + if (head != null) { + stack.push(head); + head = head.left; + } else { + head = stack.pop(); + + if (pre != null && pre.value > head.value) { + // 考虑两个错误的数字挨着的情况 + result[0] = result[0] == null ? pre.value : result[0]; + result[1] = head.value; + } + + pre = head; + head = head.right; + } + } + + return result; + } +} From 3d7c1c5f205f6102fb0ba524146462596328c6dc Mon Sep 17 00:00:00 2001 From: Ethan Zhang Date: Sun, 1 May 2022 23:03:07 +0800 Subject: [PATCH 28/43] =?UTF-8?q?=E4=BA=8C=E5=8F=89=E6=A0=91=E5=BA=8F?= =?UTF-8?q?=E5=88=97=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\345\272\217\345\210\227\345\214\226.java" | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 "src/main/java/algorithm/binary_tree/\344\272\214\345\217\211\346\240\221\347\232\204\345\272\217\345\210\227\345\214\226\345\222\214\345\217\215\345\272\217\345\210\227\345\214\226.java" diff --git "a/src/main/java/algorithm/binary_tree/\344\272\214\345\217\211\346\240\221\347\232\204\345\272\217\345\210\227\345\214\226\345\222\214\345\217\215\345\272\217\345\210\227\345\214\226.java" "b/src/main/java/algorithm/binary_tree/\344\272\214\345\217\211\346\240\221\347\232\204\345\272\217\345\210\227\345\214\226\345\222\214\345\217\215\345\272\217\345\210\227\345\214\226.java" new file mode 100644 index 0000000..4202e20 --- /dev/null +++ "b/src/main/java/algorithm/binary_tree/\344\272\214\345\217\211\346\240\221\347\232\204\345\272\217\345\210\227\345\214\226\345\222\214\345\217\215\345\272\217\345\210\227\345\214\226.java" @@ -0,0 +1,60 @@ +package algorithm.binary_tree; + +import algorithm.data_structure.BinaryTree; +import algorithm.utils.TreeNode; +import com.google.common.collect.Lists; +import java.util.Stack; + +/** + * @author Ethan Zhang + * @date 2022/4/27 + */ +public class 二叉树的序列化和反序列化 { + + public static void main(String[] args) { + TreeNode head = BinaryTree.create(Lists.newArrayList(1, 2, 3, 4, 5, 6)); + + System.out.println(preSerialize(head)); + System.out.println(preSerialize1(head)); + } + + public static String preSerialize(TreeNode head) { + if (head == null) { + return ""; + } + + Stack stack = new Stack<>(); + stack.push(head); + + StringBuilder builder = new StringBuilder(); + while (!stack.isEmpty()) { + TreeNode cur = stack.pop(); + + if (cur == null) { + builder.append("#!"); + } else { + builder.append(cur.value) + .append("!"); + } + + if (cur != null) { + stack.push(cur.right); + stack.push(cur.left); + } + } + + return builder.toString(); + } + + public static String preSerialize1(TreeNode head) { + if (head == null) { + return "#!"; + } + + String result = head.value + "!"; + result += preSerialize1(head.left); + result += preSerialize1(head.right); + + return result; + } +} From 5d9d313d25c2049edb854d87df341a5d3dea7c55 Mon Sep 17 00:00:00 2001 From: Ethan Zhang Date: Mon, 2 May 2022 22:22:31 +0800 Subject: [PATCH 29/43] deserialize binary tree --- ...\345\272\217\345\210\227\345\214\226.java" | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git "a/src/main/java/algorithm/binary_tree/\344\272\214\345\217\211\346\240\221\347\232\204\345\272\217\345\210\227\345\214\226\345\222\214\345\217\215\345\272\217\345\210\227\345\214\226.java" "b/src/main/java/algorithm/binary_tree/\344\272\214\345\217\211\346\240\221\347\232\204\345\272\217\345\210\227\345\214\226\345\222\214\345\217\215\345\272\217\345\210\227\345\214\226.java" index 4202e20..dafb4f8 100644 --- "a/src/main/java/algorithm/binary_tree/\344\272\214\345\217\211\346\240\221\347\232\204\345\272\217\345\210\227\345\214\226\345\222\214\345\217\215\345\272\217\345\210\227\345\214\226.java" +++ "b/src/main/java/algorithm/binary_tree/\344\272\214\345\217\211\346\240\221\347\232\204\345\272\217\345\210\227\345\214\226\345\222\214\345\217\215\345\272\217\345\210\227\345\214\226.java" @@ -3,6 +3,8 @@ import algorithm.data_structure.BinaryTree; import algorithm.utils.TreeNode; import com.google.common.collect.Lists; +import java.util.LinkedList; +import java.util.Queue; import java.util.Stack; /** @@ -11,6 +13,8 @@ */ public class 二叉树的序列化和反序列化 { + private static final String EMPTY_NODE = "#"; + public static void main(String[] args) { TreeNode head = BinaryTree.create(Lists.newArrayList(1, 2, 3, 4, 5, 6)); @@ -18,7 +22,9 @@ public static void main(String[] args) { System.out.println(preSerialize1(head)); } + public static String preSerialize(TreeNode head) { + // 先序遍历序列化 if (head == null) { return ""; } @@ -47,6 +53,7 @@ public static String preSerialize(TreeNode head) { } public static String preSerialize1(TreeNode head) { + // 先序遍历序列化 if (head == null) { return "#!"; } @@ -57,4 +64,31 @@ public static String preSerialize1(TreeNode head) { return result; } + + public static TreeNode preDeserialize(String str) { + if (str == null || str.length() == 0) { + return null; + } + + String[] segments = str.split("!"); + Queue queue = new LinkedList<>(); + for (String segment : segments) { + queue.offer(segment); + } + + return preDeserializeRecursive(queue); + } + + private static TreeNode preDeserializeRecursive(Queue queue) { + String value = queue.poll(); + if (EMPTY_NODE.equals(value)) { + return null; + } + + TreeNode head = new TreeNode(Integer.parseInt(value)); + head.left = preDeserializeRecursive(queue); + head.right = preDeserializeRecursive(queue); + + return head; + } } From b40f2ccb9120056eb88481267339bbf9db557327 Mon Sep 17 00:00:00 2001 From: Ethan Zhang Date: Tue, 3 May 2022 17:57:50 +0800 Subject: [PATCH 30/43] serialize/deserialize binary tree by level --- ...\345\272\217\345\210\227\345\214\226.java" | 71 ++++++++++++++++++- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git "a/src/main/java/algorithm/binary_tree/\344\272\214\345\217\211\346\240\221\347\232\204\345\272\217\345\210\227\345\214\226\345\222\214\345\217\215\345\272\217\345\210\227\345\214\226.java" "b/src/main/java/algorithm/binary_tree/\344\272\214\345\217\211\346\240\221\347\232\204\345\272\217\345\210\227\345\214\226\345\222\214\345\217\215\345\272\217\345\210\227\345\214\226.java" index dafb4f8..41e31d5 100644 --- "a/src/main/java/algorithm/binary_tree/\344\272\214\345\217\211\346\240\221\347\232\204\345\272\217\345\210\227\345\214\226\345\222\214\345\217\215\345\272\217\345\210\227\345\214\226.java" +++ "b/src/main/java/algorithm/binary_tree/\344\272\214\345\217\211\346\240\221\347\232\204\345\272\217\345\210\227\345\214\226\345\222\214\345\217\215\345\272\217\345\210\227\345\214\226.java" @@ -13,7 +13,7 @@ */ public class 二叉树的序列化和反序列化 { - private static final String EMPTY_NODE = "#"; + private static final String EMPTY_VALUE = "#"; public static void main(String[] args) { TreeNode head = BinaryTree.create(Lists.newArrayList(1, 2, 3, 4, 5, 6)); @@ -81,7 +81,7 @@ public static TreeNode preDeserialize(String str) { private static TreeNode preDeserializeRecursive(Queue queue) { String value = queue.poll(); - if (EMPTY_NODE.equals(value)) { + if (EMPTY_VALUE.equals(value)) { return null; } @@ -91,4 +91,71 @@ private static TreeNode preDeserializeRecursive(Queue queue) { return head; } + + public static String serializeByLevel(TreeNode head) { + if (head == null) { + return EMPTY_VALUE; + } + + String res = head.value + "!"; + + Queue queue = new LinkedList<>(); + queue.offer(head); + + while (!queue.isEmpty()) { + head = queue.poll(); + if (head.left != null) { + res += head.left.value + "!"; + queue.offer(head.left); + } else { + res += EMPTY_VALUE; + } + + if (head.right != null) { + res += head.right.value + "!"; + queue.offer(head.right); + } else { + res += EMPTY_VALUE; + } + } + + return res; + } + + public static TreeNode deserializeByLevel(String str) { + String[] segments = str.split("!"); + + int index = 0; + + TreeNode head = generateNode(segments[index++]); + + Queue queue = new LinkedList<>(); + if (head != null) { + queue.offer(head); + } + + while (!queue.isEmpty()) { + TreeNode cur = queue.poll(); + cur.left = generateNode(segments[index++]); + cur.right = generateNode(segments[index++]); + + if (cur.left != null) { + queue.offer(cur.left); + } + + if (cur.right != null) { + queue.offer(cur.right); + } + } + + return head; + } + + private static TreeNode generateNode(String segment) { + if (segment.equals("#")) { + return null; + } + + return new TreeNode(Integer.parseInt(segment)); + } } From e82a2ee9eea26c895950f89d89ab636ce9ea1cfa Mon Sep 17 00:00:00 2001 From: Ethan Zhang Date: Wed, 4 May 2022 23:30:56 +0800 Subject: [PATCH 31/43] t1 contains sub tree same to t2 --- .../Morris\351\201\215\345\216\206.java" | 27 ++++--- ...\347\232\204\345\255\220\346\240\221.java" | 80 +++++++++++++++++++ 2 files changed, 96 insertions(+), 11 deletions(-) create mode 100644 "src/main/java/algorithm/binary_tree/\345\210\244\346\226\255t1\346\240\221\344\270\255\346\230\257\345\220\246\346\234\211\344\270\216t2\346\240\221\346\213\223\346\211\221\347\273\223\346\236\204\345\256\214\345\205\250\347\233\270\345\220\214\347\232\204\345\255\220\346\240\221.java" diff --git "a/src/main/java/algorithm/binary_tree/Morris\351\201\215\345\216\206.java" "b/src/main/java/algorithm/binary_tree/Morris\351\201\215\345\216\206.java" index ff791fd..e83beca 100644 --- "a/src/main/java/algorithm/binary_tree/Morris\351\201\215\345\216\206.java" +++ "b/src/main/java/algorithm/binary_tree/Morris\351\201\215\345\216\206.java" @@ -1,5 +1,6 @@ package algorithm.binary_tree; +import algorithm.data_structure.BinarySearchTree; import algorithm.data_structure.BinaryTree; import algorithm.utils.TreeNode; import com.google.common.collect.Lists; @@ -11,9 +12,11 @@ public class Morris遍历 { public static void main(String[] args) { - TreeNode root = BinaryTree.create(Lists.newArrayList(1, 2, 3, 4, 5, 6, 7)); + TreeNode head = BinarySearchTree.create(Lists.newArrayList(1, 2, 3, 4, 5, 6, 7)); - morrisTraverse(root); + morrisTraverse(head); + morrisTraverseToPreOrder(head); + morrisTraverseToInOrder(head); } public static void morrisTraverse(TreeNode head) { @@ -25,16 +28,18 @@ public static void morrisTraverse(TreeNode head) { TreeNode cur = head; while (cur != null) { mostRight = cur.left; - while (mostRight.right != null && mostRight.right != cur) { - mostRight = mostRight.right; - } + if (mostRight != null) { + while (mostRight.right != null && mostRight.right != cur) { + mostRight = mostRight.right; + } - if (mostRight.right == null) { - mostRight.right = cur; - cur = cur.left; - continue; - } else { - mostRight.right = null; + if (mostRight.right == null) { + mostRight.right = cur; + cur = cur.left; + continue; + } else { + mostRight.right = null; + } } cur = cur.right; diff --git "a/src/main/java/algorithm/binary_tree/\345\210\244\346\226\255t1\346\240\221\344\270\255\346\230\257\345\220\246\346\234\211\344\270\216t2\346\240\221\346\213\223\346\211\221\347\273\223\346\236\204\345\256\214\345\205\250\347\233\270\345\220\214\347\232\204\345\255\220\346\240\221.java" "b/src/main/java/algorithm/binary_tree/\345\210\244\346\226\255t1\346\240\221\344\270\255\346\230\257\345\220\246\346\234\211\344\270\216t2\346\240\221\346\213\223\346\211\221\347\273\223\346\236\204\345\256\214\345\205\250\347\233\270\345\220\214\347\232\204\345\255\220\346\240\221.java" new file mode 100644 index 0000000..135629e --- /dev/null +++ "b/src/main/java/algorithm/binary_tree/\345\210\244\346\226\255t1\346\240\221\344\270\255\346\230\257\345\220\246\346\234\211\344\270\216t2\346\240\221\346\213\223\346\211\221\347\273\223\346\236\204\345\256\214\345\205\250\347\233\270\345\220\214\347\232\204\345\255\220\346\240\221.java" @@ -0,0 +1,80 @@ +package algorithm.binary_tree; + +import algorithm.utils.TreeNode; + +/** + * @author Ethan Zhang + * @date 2022/5/3 + */ +public class 判断t1树中是否有与t2树拓扑结构完全相同的子树 { + + public static boolean contains(TreeNode t1, TreeNode t2) { + String str1 = serializeByPre(t1); + String str2 = serializeByPre(t2); + + return kmp(str1, str2) != -1; + } + + private static int kmp(String str1, String str2) { + if (str1 == null || str2 == null || str2.length() < 1 || str1.length() < str2.length()) { + return -1; + } + + int s1 = 0; + int s2 = 0; + char[] ss = str1.toCharArray(); + char[] tt = str2.toCharArray(); + int[] next = getNextArray(ss); + while (s1 < ss.length && s2 < tt.length) { + if (ss[s1] == tt[s2]) { + s1++; + s2++; + } else if (next[s2] == -1) { + // 第一位就不想等的情况 + s1++; + } else { + s2 = next[s2]; + } + } + + return s2 == tt.length ? s2 - s1 : -1; + } + + private static int[] getNextArray(char[] ss) { + if (ss.length == 1) { + return new int[]{-1}; + } + + int[] res = new int[ss.length]; + res[0] = -1; + res[1] = 0; + + int cnt = 0; + int pos = 2; + while (pos < ss.length) { + if (ss[cnt] == ss[pos]) { + res[pos++] = ++cnt; + // TODO + } else if (cnt > 0) { + // 不想等但是有共同前缀,退到相同前缀部分的下一位继续比较,如果一直都不匹配,最终会退到cnt=0 + cnt = res[cnt]; + } else { + res[pos++] = 0; + } + } + + return new int[0]; + } + + private static String serializeByPre(TreeNode head) { + if (head == null) { + return "#!"; + } + + String res = head.value + "!"; + res += serializeByPre(head.left); + res += serializeByPre(head.right); + + return res; + } +} From 459ebdecd07dd3607e7d04e8586bbb5f082ceebf Mon Sep 17 00:00:00 2001 From: Ethan Zhang Date: Thu, 5 May 2022 23:30:46 +0800 Subject: [PATCH 32/43] if a tree is balanced binary tree or not --- ...\344\272\214\345\217\211\346\240\221.java" | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 "src/main/java/algorithm/binary_tree/\345\210\244\346\226\255\344\270\200\351\242\227\344\272\214\345\217\211\346\240\221\346\230\257\345\220\246\344\270\272\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221\345\222\214\345\256\214\345\205\250\344\272\214\345\217\211\346\240\221.java" diff --git "a/src/main/java/algorithm/binary_tree/\345\210\244\346\226\255\344\270\200\351\242\227\344\272\214\345\217\211\346\240\221\346\230\257\345\220\246\344\270\272\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221\345\222\214\345\256\214\345\205\250\344\272\214\345\217\211\346\240\221.java" "b/src/main/java/algorithm/binary_tree/\345\210\244\346\226\255\344\270\200\351\242\227\344\272\214\345\217\211\346\240\221\346\230\257\345\220\246\344\270\272\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221\345\222\214\345\256\214\345\205\250\344\272\214\345\217\211\346\240\221.java" new file mode 100644 index 0000000..d0e99f5 --- /dev/null +++ "b/src/main/java/algorithm/binary_tree/\345\210\244\346\226\255\344\270\200\351\242\227\344\272\214\345\217\211\346\240\221\346\230\257\345\220\246\344\270\272\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221\345\222\214\345\256\214\345\205\250\344\272\214\345\217\211\346\240\221.java" @@ -0,0 +1,58 @@ +package algorithm.binary_tree; + +import algorithm.data_structure.BinarySearchTree; +import algorithm.data_structure.BinaryTree; +import algorithm.utils.TreeNode; +import com.google.common.collect.Lists; + +/** + * @author Ethan Zhang + * @date 2022/5/5 + */ +public class 判断一颗二叉树是否为搜索二叉树和完全二叉树 { + + public static void main(String[] args) { + TreeNode head = BinarySearchTree.create(Lists.newArrayList(1, 2, 3, 4, 5, 6, 7)); + + System.out.println(isBST(head)); + + head = BinaryTree.create(Lists.newArrayList(1, 3, 2, 4, 0, 6, 7)); + + System.out.println(isBST(head)); + } + + public static boolean isBST(TreeNode head) { + if (head == null) { + return true; + } + + boolean result = true; + TreeNode pre = null; + TreeNode mostRight = null; + while (head != null) { + mostRight = head.left; + if (mostRight != null) { + while (mostRight.right != null && mostRight.right != head) { + mostRight = mostRight.right; + } + + if (mostRight.right == null) { + mostRight.right = head; + head = head.left; + continue; + } else { + mostRight.right = null; + } + } + + if (pre != null && pre.value > head.value) { + result = false; + } + + pre = head; + head = head.right; + } + + return result; + } +} From 43263c1ebfa21a89894d98c5ce6ce94dd2a362a9 Mon Sep 17 00:00:00 2001 From: Ethan Zhang Date: Fri, 6 May 2022 21:53:57 +0800 Subject: [PATCH 33/43] whether a tree is BST/CST or not --- ...\344\272\214\345\217\211\346\240\221.java" | 33 +++++++++++++++++++ ...\344\270\252\350\212\202\347\202\271.java" | 30 +++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 "src/main/java/algorithm/link/\350\277\224\345\233\236\351\223\276\350\241\250\347\254\254K\344\270\252\350\212\202\347\202\271.java" diff --git "a/src/main/java/algorithm/binary_tree/\345\210\244\346\226\255\344\270\200\351\242\227\344\272\214\345\217\211\346\240\221\346\230\257\345\220\246\344\270\272\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221\345\222\214\345\256\214\345\205\250\344\272\214\345\217\211\346\240\221.java" "b/src/main/java/algorithm/binary_tree/\345\210\244\346\226\255\344\270\200\351\242\227\344\272\214\345\217\211\346\240\221\346\230\257\345\220\246\344\270\272\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221\345\222\214\345\256\214\345\205\250\344\272\214\345\217\211\346\240\221.java" index d0e99f5..978fb35 100644 --- "a/src/main/java/algorithm/binary_tree/\345\210\244\346\226\255\344\270\200\351\242\227\344\272\214\345\217\211\346\240\221\346\230\257\345\220\246\344\270\272\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221\345\222\214\345\256\214\345\205\250\344\272\214\345\217\211\346\240\221.java" +++ "b/src/main/java/algorithm/binary_tree/\345\210\244\346\226\255\344\270\200\351\242\227\344\272\214\345\217\211\346\240\221\346\230\257\345\220\246\344\270\272\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221\345\222\214\345\256\214\345\205\250\344\272\214\345\217\211\346\240\221.java" @@ -4,6 +4,8 @@ import algorithm.data_structure.BinaryTree; import algorithm.utils.TreeNode; import com.google.common.collect.Lists; +import java.util.LinkedList; +import java.util.Queue; /** * @author Ethan Zhang @@ -55,4 +57,35 @@ public static boolean isBST(TreeNode head) { return result; } + + public static boolean isCST(TreeNode head) { + if (head == null) { + return true; + } + + boolean leaf = false; + Queue queue = new LinkedList<>(); + queue.offer(head); + while (!queue.isEmpty()) { + head = queue.poll(); + + TreeNode left = head.left; + TreeNode right = head.right; + if ((leaf && (left != null || right != null)) || (left == null && right != null)) { + return false; + } + + if (left != null) { + queue.offer(left); + } + + if (right != null) { + queue.offer(right); + } else { + leaf = true; + } + } + + return true; + } } diff --git "a/src/main/java/algorithm/link/\350\277\224\345\233\236\351\223\276\350\241\250\347\254\254K\344\270\252\350\212\202\347\202\271.java" "b/src/main/java/algorithm/link/\350\277\224\345\233\236\351\223\276\350\241\250\347\254\254K\344\270\252\350\212\202\347\202\271.java" new file mode 100644 index 0000000..372b142 --- /dev/null +++ "b/src/main/java/algorithm/link/\350\277\224\345\233\236\351\223\276\350\241\250\347\254\254K\344\270\252\350\212\202\347\202\271.java" @@ -0,0 +1,30 @@ +package algorithm.link; + +import algorithm.utils.Node; + +/** + * @author Ethan Zhang + * @date 2022/5/6 + */ +public class 返回链表第K个节点 { + + public static Node k(Node head, int k) { + if (head == null || k < 1) { + return null; + } + + Node slow, fast; + slow = fast = head; + while (k > 0) { + k--; + fast = fast.next; + } + + while (fast != null) { + slow = slow.next; + fast = fast.next; + } + + return slow; + } +} From ca1eb7eec4abb46fbcea641d44ee5df2f06f6d1a Mon Sep 17 00:00:00 2001 From: Ethan Zhang Date: Sat, 7 May 2022 22:59:56 +0800 Subject: [PATCH 34/43] generate balanced BST --- ...\344\272\214\345\217\211\346\240\221.java" | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 "src/main/java/algorithm/binary_tree/\351\200\232\350\277\207\346\234\211\345\272\217\346\225\260\347\273\204\347\224\237\346\210\220\345\271\263\350\241\241\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221.java" diff --git "a/src/main/java/algorithm/binary_tree/\351\200\232\350\277\207\346\234\211\345\272\217\346\225\260\347\273\204\347\224\237\346\210\220\345\271\263\350\241\241\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221.java" "b/src/main/java/algorithm/binary_tree/\351\200\232\350\277\207\346\234\211\345\272\217\346\225\260\347\273\204\347\224\237\346\210\220\345\271\263\350\241\241\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221.java" new file mode 100644 index 0000000..d192904 --- /dev/null +++ "b/src/main/java/algorithm/binary_tree/\351\200\232\350\277\207\346\234\211\345\272\217\346\225\260\347\273\204\347\224\237\346\210\220\345\271\263\350\241\241\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221.java" @@ -0,0 +1,31 @@ +package algorithm.binary_tree; + +import algorithm.utils.TreeNode; + +/** + * @author Ethan Zhang + * @date 2022/5/6 + */ +public class 通过有序数组生成平衡搜索二叉树 { + + public static TreeNode generateBST(int[] sortedArray) { + if (sortedArray == null || sortedArray.length == 0) { + return null; + } + + return generateBSTRecursive(sortedArray, 0, sortedArray.length - 1); + } + + private static TreeNode generateBSTRecursive(int[] sortedArray, int start, int end) { + if (start > end) { + return null; + } + + int mid = (start + end) / 2; + TreeNode head = new TreeNode(sortedArray[mid]); + head.left = generateBSTRecursive(sortedArray, 0, mid - 1); + head.right = generateBSTRecursive(sortedArray, mid + 1, end); + + return head; + } +} From 530175bb4772a9c5e19596bc574aa94945f790c7 Mon Sep 17 00:00:00 2001 From: Ethan Zhang Date: Sun, 8 May 2022 22:26:29 +0800 Subject: [PATCH 35/43] if a tree is balanced tree --- ...\344\272\214\345\217\211\346\240\221.java" | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 "src/main/java/algorithm/binary_tree/\345\210\244\346\226\255\344\272\214\345\217\211\346\240\221\346\230\257\345\220\246\344\270\272\345\271\263\350\241\241\344\272\214\345\217\211\346\240\221.java" diff --git "a/src/main/java/algorithm/binary_tree/\345\210\244\346\226\255\344\272\214\345\217\211\346\240\221\346\230\257\345\220\246\344\270\272\345\271\263\350\241\241\344\272\214\345\217\211\346\240\221.java" "b/src/main/java/algorithm/binary_tree/\345\210\244\346\226\255\344\272\214\345\217\211\346\240\221\346\230\257\345\220\246\344\270\272\345\271\263\350\241\241\344\272\214\345\217\211\346\240\221.java" new file mode 100644 index 0000000..ccd0852 --- /dev/null +++ "b/src/main/java/algorithm/binary_tree/\345\210\244\346\226\255\344\272\214\345\217\211\346\240\221\346\230\257\345\220\246\344\270\272\345\271\263\350\241\241\344\272\214\345\217\211\346\240\221.java" @@ -0,0 +1,41 @@ +package algorithm.binary_tree; + +import algorithm.utils.TreeNode; + +/** + * @author Ethan Zhang + * @date 2022/5/4 + */ +public class 判断二叉树是否为平衡二叉树 { + + public static boolean isBalanced(TreeNode head) { + return process(head).isBalanced; + } + + private static ReturnType process(TreeNode head) { + if (head == null) { + return new ReturnType(true, 0); + } + + ReturnType left = process(head.left); + ReturnType right = process(head.right); + + int height = Math.max(left.height, right.height) + 1; + + boolean balanced = left.isBalanced && right.isBalanced && Math.abs(left.height - right.height) < 2; + + return new ReturnType(balanced, height); + } + + + private static class ReturnType { + public boolean isBalanced; + + public int height; + + public ReturnType(boolean isBalanced, int height) { + this.isBalanced = isBalanced; + this.height = height; + } + } +} From 4ee17e172338c298683bb6c64f445374706a4184 Mon Sep 17 00:00:00 2001 From: Ethan Zhang Date: Mon, 9 May 2022 22:54:52 +0800 Subject: [PATCH 36/43] find nearest common parent node --- ...\345\205\261\347\245\226\345\205\210.java" | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 "src/main/java/algorithm/binary_tree/\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\346\211\276\345\210\260\344\270\244\344\270\252\350\212\202\347\202\271\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.java" diff --git "a/src/main/java/algorithm/binary_tree/\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\346\211\276\345\210\260\344\270\244\344\270\252\350\212\202\347\202\271\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.java" "b/src/main/java/algorithm/binary_tree/\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\346\211\276\345\210\260\344\270\244\344\270\252\350\212\202\347\202\271\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.java" new file mode 100644 index 0000000..a505cf4 --- /dev/null +++ "b/src/main/java/algorithm/binary_tree/\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\346\211\276\345\210\260\344\270\244\344\270\252\350\212\202\347\202\271\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.java" @@ -0,0 +1,24 @@ +package algorithm.binary_tree; + +import algorithm.utils.TreeNode; + +/** + * @author Ethan Zhang + * @date 2022/5/9 + */ +public class 在二叉树中找到两个节点的最近公共祖先 { + + public static TreeNode findParent(TreeNode head, TreeNode o1, TreeNode o2) { + if (head == null || head == o1 || head == o2) { + return head; + } + + TreeNode left = findParent(head.left, o1, o2); + TreeNode right = findParent(head.right, o1, o2); + if (left != null && right != null) { + return head; + } + + return left != null ? left : right; + } +} From 6e024bc76942acbe82d7dfe5ae18cba42507cbd0 Mon Sep 17 00:00:00 2001 From: Ethan Zhang Date: Tue, 10 May 2022 22:23:06 +0800 Subject: [PATCH 37/43] find common parent node with data-driven style --- ...\345\205\261\347\245\226\345\205\210.java" | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git "a/src/main/java/algorithm/binary_tree/\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\346\211\276\345\210\260\344\270\244\344\270\252\350\212\202\347\202\271\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.java" "b/src/main/java/algorithm/binary_tree/\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\346\211\276\345\210\260\344\270\244\344\270\252\350\212\202\347\202\271\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.java" index a505cf4..b46dd68 100644 --- "a/src/main/java/algorithm/binary_tree/\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\346\211\276\345\210\260\344\270\244\344\270\252\350\212\202\347\202\271\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.java" +++ "b/src/main/java/algorithm/binary_tree/\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\346\211\276\345\210\260\344\270\244\344\270\252\350\212\202\347\202\271\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.java" @@ -1,6 +1,10 @@ package algorithm.binary_tree; import algorithm.utils.TreeNode; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; /** * @author Ethan Zhang @@ -8,6 +12,9 @@ */ public class 在二叉树中找到两个节点的最近公共祖先 { + public static void main(String[] args) { + } + public static TreeNode findParent(TreeNode head, TreeNode o1, TreeNode o2) { if (head == null || head == o1 || head == o2) { return head; @@ -21,4 +28,53 @@ public static TreeNode findParent(TreeNode head, TreeNode o1, TreeNode o2) { return left != null ? left : right; } + + public static TreeNode findParent1(TreeNode head, TreeNode o1, TreeNode o2) { + ParentFinder finder = new ParentFinder(head); + return finder.find(o1, o2); + } + + private static class ParentFinder { + private Map cache; + + public ParentFinder(TreeNode head) { + this.cache = new HashMap<>(); + if (head != null) { + this.cache.put(head, null); + } + + setMap(head); + } + + private void setMap(TreeNode head) { + if (head == null) { + return; + } + + if (head.left != null) { + this.cache.put(head.left, head); + } + + if (head.right != null) { + this.cache.put(head.right, head); + } + + setMap(head.left); + setMap(head.right); + } + + public TreeNode find(TreeNode o1, TreeNode o2) { + Set path = new HashSet<>(); + while (this.cache.containsKey(o1)) { + path.add(o1); + o1 = this.cache.get(o1); + } + + while (!path.contains(o2)) { + o2 = this.cache.get(o2); + } + + return o2; + } + } } From f51eb598978f54051919ce759f6ee1a650ce441a Mon Sep 17 00:00:00 2001 From: Ethan Zhang Date: Tue, 10 May 2022 22:36:48 +0800 Subject: [PATCH 38/43] find common parent test cases --- ...\205\254\345\205\261\347\245\226\345\205\210.java" | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git "a/src/main/java/algorithm/binary_tree/\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\346\211\276\345\210\260\344\270\244\344\270\252\350\212\202\347\202\271\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.java" "b/src/main/java/algorithm/binary_tree/\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\346\211\276\345\210\260\344\270\244\344\270\252\350\212\202\347\202\271\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.java" index b46dd68..b33f8a8 100644 --- "a/src/main/java/algorithm/binary_tree/\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\346\211\276\345\210\260\344\270\244\344\270\252\350\212\202\347\202\271\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.java" +++ "b/src/main/java/algorithm/binary_tree/\345\234\250\344\272\214\345\217\211\346\240\221\344\270\255\346\211\276\345\210\260\344\270\244\344\270\252\350\212\202\347\202\271\347\232\204\346\234\200\350\277\221\345\205\254\345\205\261\347\245\226\345\205\210.java" @@ -1,10 +1,12 @@ package algorithm.binary_tree; +import algorithm.data_structure.BinaryTree; import algorithm.utils.TreeNode; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import org.springframework.util.Assert; /** * @author Ethan Zhang @@ -13,6 +15,15 @@ public class 在二叉树中找到两个节点的最近公共祖先 { public static void main(String[] args) { + TreeNode head = BinaryTree.create(1, 2, 3, 4, 5, 6, 7); + + TreeNode parent = findParent1(head, new TreeNode(2), new TreeNode(4)); + + Assert.isTrue(parent.equals(new TreeNode(2))); + + parent = findParent1(head, new TreeNode(2), new TreeNode(7)); + + Assert.isTrue(parent.equals(new TreeNode(1))); } public static TreeNode findParent(TreeNode head, TreeNode o1, TreeNode o2) { From 3711653a5a580af68300d5e628dfcbcae556e69e Mon Sep 17 00:00:00 2001 From: Ethan Zhang Date: Wed, 11 May 2022 23:10:36 +0800 Subject: [PATCH 39/43] restore BST by post array --- ...\344\272\214\345\217\211\346\240\221.java" | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 "src/main/java/algorithm/binary_tree/\346\240\271\346\215\256\345\220\216\345\272\217\346\225\260\347\273\204\351\207\215\345\273\272\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221.java" diff --git "a/src/main/java/algorithm/binary_tree/\346\240\271\346\215\256\345\220\216\345\272\217\346\225\260\347\273\204\351\207\215\345\273\272\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221.java" "b/src/main/java/algorithm/binary_tree/\346\240\271\346\215\256\345\220\216\345\272\217\346\225\260\347\273\204\351\207\215\345\273\272\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221.java" new file mode 100644 index 0000000..f901d03 --- /dev/null +++ "b/src/main/java/algorithm/binary_tree/\346\240\271\346\215\256\345\220\216\345\272\217\346\225\260\347\273\204\351\207\215\345\273\272\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221.java" @@ -0,0 +1,45 @@ +package algorithm.binary_tree; + +import algorithm.utils.TreeNode; + +/** + * @author Ethan Zhang + * @date 2022/5/4 + */ +public class 根据后序数组重建搜索二叉树 { + + public static void main(String[] args) { + + } + + public static TreeNode restoreByPost(int[] array) { + if (array == null || array.length == 0) { + return null; + } + + return restoreByPostRecursively(array, 0, array.length - 1); + } + + private static TreeNode restoreByPostRecursively(int[] array, int start, int end) { + if (start > end) { + return null; + } + + int less = start; + int more = end; + for (int i = start; i < end; i++) { + if (array[end] > array[i]) { + less = i; + } else { + more = more == end ? end - 1 : i; + } + } + + int mid = (start + end) / 2; + TreeNode head = new TreeNode(array[end]); + head.left = restoreByPostRecursively(array, start, less); + head.right = restoreByPostRecursively(array, more, end - 1); + + return head; + } +} From aa490ecfd2f53542a8c73d26b8a657dcba63b592 Mon Sep 17 00:00:00 2001 From: Ethan Zhang Date: Thu, 12 May 2022 23:41:21 +0800 Subject: [PATCH 40/43] restore BST test cases --- ...242\344\272\214\345\217\211\346\240\221.java" | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git "a/src/main/java/algorithm/binary_tree/\346\240\271\346\215\256\345\220\216\345\272\217\346\225\260\347\273\204\351\207\215\345\273\272\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221.java" "b/src/main/java/algorithm/binary_tree/\346\240\271\346\215\256\345\220\216\345\272\217\346\225\260\347\273\204\351\207\215\345\273\272\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221.java" index f901d03..83cfd43 100644 --- "a/src/main/java/algorithm/binary_tree/\346\240\271\346\215\256\345\220\216\345\272\217\346\225\260\347\273\204\351\207\215\345\273\272\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221.java" +++ "b/src/main/java/algorithm/binary_tree/\346\240\271\346\215\256\345\220\216\345\272\217\346\225\260\347\273\204\351\207\215\345\273\272\346\220\234\347\264\242\344\272\214\345\217\211\346\240\221.java" @@ -1,6 +1,7 @@ package algorithm.binary_tree; import algorithm.utils.TreeNode; +import org.springframework.util.Assert; /** * @author Ethan Zhang @@ -9,7 +10,17 @@ public class 根据后序数组重建搜索二叉树 { public static void main(String[] args) { + int[] post = new int[]{1, 3, 2, 5, 7, 6, 4}; + TreeNode head = restoreByPost(post); + + Assert.isTrue(head.value == 4); + Assert.isTrue(head.left.value == 2); + Assert.isTrue(head.right.value == 6); + + head = restoreByPost(new int[0]); + + Assert.isTrue(head == null); } public static TreeNode restoreByPost(int[] array) { @@ -35,8 +46,11 @@ private static TreeNode restoreByPostRecursively(int[] array, int start, int end } } - int mid = (start + end) / 2; TreeNode head = new TreeNode(array[end]); + if (more == less) { + return head; + } + head.left = restoreByPostRecursively(array, start, less); head.right = restoreByPostRecursively(array, more, end - 1); From ee91dfb05480ef47cacdd50176e6d778a823858f Mon Sep 17 00:00:00 2001 From: Ethan Zhang Date: Sat, 14 May 2022 21:19:24 +0800 Subject: [PATCH 41/43] restore BST test cases --- pom.xml | 6 +-- ...\350\241\250\347\233\270\345\212\240.java" | 37 +++++++++++++++++++ src/main/java/algorithm/utils/TreeNode.java | 19 ++++++++++ 3 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 "src/main/java/algorithm/link/\344\270\244\344\270\252\351\223\276\350\241\250\347\233\270\345\212\240.java" diff --git a/pom.xml b/pom.xml index b0cf76c..bfef018 100644 --- a/pom.xml +++ b/pom.xml @@ -20,9 +20,9 @@ 4.1.32.Final - org.junit.jupiter - junit-jupiter-engine - 5.6.2 + junit + junit + 4.13.2 test diff --git "a/src/main/java/algorithm/link/\344\270\244\344\270\252\351\223\276\350\241\250\347\233\270\345\212\240.java" "b/src/main/java/algorithm/link/\344\270\244\344\270\252\351\223\276\350\241\250\347\233\270\345\212\240.java" new file mode 100644 index 0000000..adc0793 --- /dev/null +++ "b/src/main/java/algorithm/link/\344\270\244\344\270\252\351\223\276\350\241\250\347\233\270\345\212\240.java" @@ -0,0 +1,37 @@ +package algorithm.link; + +import algorithm.utils.Node; +import java.util.LinkedList; +import java.util.Queue; + +/** + * @author Ethan Zhang + * @date 2022/5/6 + */ +public class 两个链表相加 { + + public Node add(Node head1, Node head2) { + if (head1 == null || head2 == null) { + return head1 == null ? head2 : head1; + } + + Queue queue = new LinkedList<>(); + Node cur = head1; + while (cur != null) { + queue.add(cur); + cur = cur.next; + } + + cur = head2; + while (cur != null) { + Node adder = queue.poll(); + if (adder != null) { + + } + + cur = cur.next; + } + } + + +} diff --git a/src/main/java/algorithm/utils/TreeNode.java b/src/main/java/algorithm/utils/TreeNode.java index 422c10a..9175f42 100644 --- a/src/main/java/algorithm/utils/TreeNode.java +++ b/src/main/java/algorithm/utils/TreeNode.java @@ -22,6 +22,25 @@ public TreeNode(int value, TreeNode left, TreeNode right) { this.right = right; } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + TreeNode treeNode = (TreeNode) o; + + return value == treeNode.value; + } + + @Override + public int hashCode() { + return value; + } + public int getValue() { return value; } From 539aa2a513cdd04a5f6471616219c176fab2375e Mon Sep 17 00:00:00 2001 From: Ethan Zhang Date: Mon, 16 May 2022 23:52:33 +0800 Subject: [PATCH 42/43] add two linked list --- ...\350\241\250\347\233\270\345\212\240.java" | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git "a/src/main/java/algorithm/link/\344\270\244\344\270\252\351\223\276\350\241\250\347\233\270\345\212\240.java" "b/src/main/java/algorithm/link/\344\270\244\344\270\252\351\223\276\350\241\250\347\233\270\345\212\240.java" index adc0793..12f937f 100644 --- "a/src/main/java/algorithm/link/\344\270\244\344\270\252\351\223\276\350\241\250\347\233\270\345\212\240.java" +++ "b/src/main/java/algorithm/link/\344\270\244\344\270\252\351\223\276\350\241\250\347\233\270\345\212\240.java" @@ -11,26 +11,37 @@ public class 两个链表相加 { public Node add(Node head1, Node head2) { - if (head1 == null || head2 == null) { - return head1 == null ? head2 : head1; + if (head1 == null) { + return head2; } - Queue queue = new LinkedList<>(); - Node cur = head1; - while (cur != null) { - queue.add(cur); - cur = cur.next; + if (head2 == null) { + return head1; } - cur = head2; - while (cur != null) { - Node adder = queue.poll(); - if (adder != null) { + int adder = 0; + Node dummy = new Node(0); + Node head = dummy; + while (head1 != null || head2 != null || adder != 0) { + int val1 = head1 == null ? 0 : head1.value; + int val2 = head2 == null ? 0 : head2.value; + int sum = val1 + val2 + adder; + head.next = new Node(sum % 10); + head = head.next; + + adder = sum / 10; + + if (head1 != null) { + head1 = head1.next; } - cur = cur.next; + if (head2 != null) { + head2 = head2.next; + } } + + return dummy.next; } From 326d00fbe381bf6fc50b25ee2d794b4ed51e11e8 Mon Sep 17 00:00:00 2001 From: Ethan Zhang Date: Wed, 18 May 2022 23:41:25 +0800 Subject: [PATCH 43/43] BST max distance --- ...\347\246\273\351\227\256\351\242\230.java" | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 "src/main/java/algorithm/binary_tree/\344\272\214\345\217\211\346\240\221\350\212\202\347\202\271\351\227\264\347\232\204\346\234\200\345\244\247\350\267\235\347\246\273\351\227\256\351\242\230.java" diff --git "a/src/main/java/algorithm/binary_tree/\344\272\214\345\217\211\346\240\221\350\212\202\347\202\271\351\227\264\347\232\204\346\234\200\345\244\247\350\267\235\347\246\273\351\227\256\351\242\230.java" "b/src/main/java/algorithm/binary_tree/\344\272\214\345\217\211\346\240\221\350\212\202\347\202\271\351\227\264\347\232\204\346\234\200\345\244\247\350\267\235\347\246\273\351\227\256\351\242\230.java" new file mode 100644 index 0000000..b26176a --- /dev/null +++ "b/src/main/java/algorithm/binary_tree/\344\272\214\345\217\211\346\240\221\350\212\202\347\202\271\351\227\264\347\232\204\346\234\200\345\244\247\350\267\235\347\246\273\351\227\256\351\242\230.java" @@ -0,0 +1,43 @@ +package algorithm.binary_tree; + +import algorithm.utils.TreeNode; + +/** + * @author Ethan Zhang + * @date 2022/5/18 + */ +public class 二叉树节点间的最大距离问题 { + + public static void main(String[] args) { + + } + + public int maxDistance(TreeNode head) { + return maxDistanceRecursive(head).maxDistance; + } + + public ReturnType maxDistanceRecursive(TreeNode head) { + if (head == null) { + return new ReturnType(0, 0); + } + + ReturnType left = maxDistanceRecursive(head.left); + ReturnType right = maxDistanceRecursive(head.right); + + int height = Math.max(left.height, right.height) + 1; + int maxDistance = Math.max(left.height + right.height + 1, Math.max(left.maxDistance, right.maxDistance)); + + return new ReturnType(maxDistance, height); + } + + private static class ReturnType { + private final int maxDistance; + + private final int height; + + public ReturnType(int maxDistance, int height) { + this.maxDistance = maxDistance; + this.height = height; + } + } +}