diff --git a/pom.xml b/pom.xml index e19b6e5..b2bc770 100644 --- a/pom.xml +++ b/pom.xml @@ -8,5 +8,19 @@ leetcode-question 1.0-SNAPSHOT + + UTF-8 + UTF-8 + 15 + 15 + + + + + com.alibaba + fastjson + 1.2.69 + + \ No newline at end of file diff --git a/src/main/java/com/shuzijun/leetcode/ListNodeUtils.java b/src/main/java/com/shuzijun/leetcode/ListNodeUtils.java new file mode 100644 index 0000000..8bebb4c --- /dev/null +++ b/src/main/java/com/shuzijun/leetcode/ListNodeUtils.java @@ -0,0 +1,51 @@ +package com.shuzijun.leetcode; + +/** + * @author : CAOMU + * @version : 1.0 + * @since : 2021/02/19, Fri, 10:09 + */ +public class ListNodeUtils { + public static int[] stringToIntegerArray(String input) { + input = input.trim(); + input = input.substring(1, input.length() - 1); + if (input.length() == 0) { + return new int[0]; + } + + String[] parts = input.split(","); + int[] output = new int[parts.length]; + for (int index = 0; index < parts.length; index++) { + String part = parts[index].trim(); + output[index] = Integer.parseInt(part); + } + return output; + } + + public static ListNode stringToListNode(String input) { + // Generate array from the input + int[] nodeValues = stringToIntegerArray(input); + + // Now convert that list into linked list + ListNode dummyRoot = new ListNode(0); + ListNode ptr = dummyRoot; + for (int item : nodeValues) { + ptr.next = new ListNode(item); + ptr = ptr.next; + } + return dummyRoot.next; + } + + public static void prettyPrintLinkedList(ListNode node) { + while (node != null && node.next != null) { + System.out.print(node.val + "->"); + node = node.next; + } + + if (node != null) { + System.out.println(node.val); + } else { + System.out.println("Empty LinkedList"); + } + } +} diff --git a/src/main/java/com/shuzijun/leetcode/Node.java b/src/main/java/com/shuzijun/leetcode/Node.java new file mode 100644 index 0000000..b7ac98a --- /dev/null +++ b/src/main/java/com/shuzijun/leetcode/Node.java @@ -0,0 +1,25 @@ +package com.shuzijun.leetcode; + +import java.util.List; + +/** + * @author : CAOMU + * @version : 1.0 + * @since : 2021/02/11, Thu, 1:21 + */ +public class Node { + public int val; + public List children; + + public Node() { + } + + public Node(int _val) { + this.val = _val; + } + + public Node(int _val, List _children) { + this.val = _val; + this.children = _children; + } +} diff --git a/src/main/java/com/shuzijun/leetcode/TreeNode.java b/src/main/java/com/shuzijun/leetcode/TreeNode.java new file mode 100644 index 0000000..1fc99ad --- /dev/null +++ b/src/main/java/com/shuzijun/leetcode/TreeNode.java @@ -0,0 +1,25 @@ +package com.shuzijun.leetcode; + +/** + * @author : CAOMU + * @version : 1.0 + * @since : 2021/02/10, 水, 18:07 + */ +public class TreeNode { + public TreeNode left; + public TreeNode right; + public int val; + + TreeNode() { + } + + public TreeNode(int val) { + this.val = val; + } + + public TreeNode(int val, TreeNode left, TreeNode right) { + this.val = val; + this.left = left; + this.right = right; + } +} diff --git a/src/main/java/com/shuzijun/leetcode/TreeNodeUtils.java b/src/main/java/com/shuzijun/leetcode/TreeNodeUtils.java new file mode 100644 index 0000000..682d8fc --- /dev/null +++ b/src/main/java/com/shuzijun/leetcode/TreeNodeUtils.java @@ -0,0 +1,99 @@ +package com.shuzijun.leetcode; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * @author : CAOMU + * @version : 1.0 + * @since : 2021/02/19, Fri, 10:08 + */ +public class TreeNodeUtils { + public static String treeNodeToString(TreeNode root) { + if (root == null) { + return "[]"; + } + + String output = ""; + Queue nodeQueue = new LinkedList<>(); + nodeQueue.add(root); + while (!nodeQueue.isEmpty()) { + TreeNode node = nodeQueue.remove(); + + if (node == null) { + output += "null, "; + continue; + } + + output += String.valueOf(node.val) + ", "; + nodeQueue.add(node.left); + nodeQueue.add(node.right); + } + return "[" + output.substring(0, output.length() - 2) + "]"; + } + + public static TreeNode stringToTreeNode(String input) { + input = input.trim(); + input = input.substring(1, input.length() - 1); + if (input.length() == 0) { + return null; + } + + String[] parts = input.split(","); + String item = parts[0]; + TreeNode root = new TreeNode(Integer.parseInt(item)); + Queue nodeQueue = new LinkedList<>(); + nodeQueue.add(root); + + int index = 1; + while (!nodeQueue.isEmpty()) { + TreeNode node = nodeQueue.remove(); + + if (index == parts.length) { + break; + } + + item = parts[index++]; + item = item.trim(); + if (!item.equals("null")) { + int leftNumber = Integer.parseInt(item); + node.left = new TreeNode(leftNumber); + nodeQueue.add(node.left); + } + + if (index == parts.length) { + break; + } + + item = parts[index++]; + item = item.trim(); + if (!item.equals("null")) { + int rightNumber = Integer.parseInt(item); + node.right = new TreeNode(rightNumber); + nodeQueue.add(node.right); + } + } + return root; + } + + public static void prettyPrintTree(TreeNode node, String prefix, boolean isLeft) { + if (node == null) { + System.out.println("Empty tree"); + return; + } + + if (node.right != null) { + prettyPrintTree(node.right, prefix + (isLeft ? "│ " : " "), false); + } + + System.out.println(prefix + (isLeft ? "└── " : "┌── ") + node.val); + + if (node.left != null) { + prettyPrintTree(node.left, prefix + (isLeft ? " " : "│ "), true); + } + } + + public static void prettyPrintTree(TreeNode node) { + prettyPrintTree(node, "", true); + } +} diff --git a/src/main/java/com/shuzijun/leetcode/Trie.java b/src/main/java/com/shuzijun/leetcode/Trie.java new file mode 100644 index 0000000..56d3799 --- /dev/null +++ b/src/main/java/com/shuzijun/leetcode/Trie.java @@ -0,0 +1,64 @@ +package com.shuzijun.leetcode; + +/** + * @author : CAOMU + * @version : 1.0 + * @since : 2021/02/16, Tue, 12:36 + */ +public class Trie { + Trie[] children; + boolean isWord; + + /** + * Initialize your data structure here. + */ + public Trie() { + this.children = new Trie[26]; + this.isWord = false; + } + + /** + * Inserts a word into the trie. + */ + public void insert(String word) { + this.insert(word.toCharArray()); + } + + public void insert(char[] chars) { + Trie curr = this; + for (int i = 0; i < chars.length; i++) { + char c = chars[i]; + if (curr.children[c - 'a'] == null) { + curr.children[c - 'a'] = new Trie(); + } + curr = curr.children[c - 'a']; + } + curr.isWord = true; + } + + /** + * Returns if the word is in the trie. + */ + public boolean search(String word) { + Trie leaf = this.findLeafTrie(word); + return leaf != null && leaf.isWord; + } + + /** + * Returns if there is any word in the trie that starts with the given prefix. + */ + public boolean startsWith(String prefix) { + return this.findLeafTrie(prefix) != null; + } + + private Trie findLeafTrie(String word) { + Trie curr = this; + for (int i = 0; i < word.length(); i++) { + curr = curr.children[word.charAt(i) - 'a']; + if (curr == null) { + return null; + } + } + return curr; + } +} \ No newline at end of file diff --git a/src/main/java/com/shuzijun/leetcode/UnionFind.java b/src/main/java/com/shuzijun/leetcode/UnionFind.java new file mode 100644 index 0000000..d62ef23 --- /dev/null +++ b/src/main/java/com/shuzijun/leetcode/UnionFind.java @@ -0,0 +1,57 @@ +package com.shuzijun.leetcode; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import java.util.stream.IntStream; + +/** + * @author : CAOMU + * @version : 1.0 + * @since : 2021/02/14, Sun, 14:56 + */ +public class UnionFind { + private int[] roots; + + protected UnionFind(int n) { + this.roots = IntStream.range(0, n).toArray(); + } + + protected int[] getRoots() { + return this.roots; + } + + protected void union(int p, int q) { + this.roots[this.findRoot(p)] = this.findRoot(q); + } + + protected void union(int... p) { + for (int i = 1; i < p.length; i++) { + this.union(p[i], p[0]); + } + } + + protected int findRoot(int i) { + int root = i; + while (root != this.roots[root]) { + root = this.roots[root]; + } + int t; + while (i != this.roots[root]) { + t = this.roots[i]; + this.roots[i] = root; + i = t; + } + return root; + } + + protected boolean isConnected(int p, int q) { + return this.findRoot(p) == this.findRoot(q); + } + + protected int getCount() { + Set rootSet = new HashSet<>(); + Arrays.stream(this.roots).forEach(root -> rootSet.add(this.findRoot(root))); + return rootSet.size(); + } +} diff --git a/src/main/java/com/shuzijun/leetcode/Utils.java b/src/main/java/com/shuzijun/leetcode/Utils.java new file mode 100644 index 0000000..a63b36a --- /dev/null +++ b/src/main/java/com/shuzijun/leetcode/Utils.java @@ -0,0 +1,79 @@ +package com.shuzijun.leetcode; + + +import com.alibaba.fastjson.JSONArray; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author : CAOMU + * @version : 1.0 + * @since : 2021/02/10, 水, 18:06 + */ +public class Utils { + public static TreeNode arrayToTreeNode(String s) { + List array = Arrays.stream(s.substring(s.indexOf("[") + 1, s.lastIndexOf("]")).split(",")).map(i -> + i.equals("null") ? null : Integer.valueOf(i) + ).collect(Collectors.toList()); + return list2TreeNode(array); + } + + public static TreeNode list2TreeNode(List array) { + if (array.isEmpty()) { + return null; + } + TreeNode root = new TreeNode(array.get(0)); + Queue queue = new LinkedList<>(); + queue.add(root); + boolean isLeft = true; + for (int i = 1; i < array.size(); i++) { + TreeNode node = queue.peek(); + if (isLeft) { + if (array.get(i) != null) { + node.left = new TreeNode(array.get(i)); + queue.offer(node.left); + } + isLeft = false; + } else { + if (array.get(i) != null) { + node.right = new TreeNode(array.get(i)); + queue.offer(node.right); + } + queue.poll(); + isLeft = true; + } + } + return root; + } + + public static int[] stringToArray(String s) { + return Arrays.stream(s.substring( + s.indexOf("[") + 1, s.lastIndexOf("]")).split(",")).mapToInt(Integer::valueOf).toArray(); + } + + public static String[] stringToStringArray(String s) { + return ((JSONArray) JSONArray.parse(s)).toArray(new String[]{}); + } + + public static int[][] stringTo2DArray(String s) { + JSONArray[] arr = ((JSONArray) JSONArray.parse(s)).toArray(new JSONArray[]{}); + int[][] result = new int[arr.length][Arrays.stream(arr).mapToInt(JSONArray::size).max().orElse(0)]; + for (int i = 0; i < arr.length; i++) { + result[i] = Arrays.stream(arr[i].toArray()).mapToInt(o -> (int) o).toArray(); + System.out.println(Arrays.toString(result[i])); + } + return result; + } + + public static List> stringTo2DStringList(String s) { + JSONArray[] arr = ((JSONArray) JSONArray.parse(s)).toArray(new JSONArray[]{}); + List> result = new ArrayList<>(); + for (JSONArray objects : arr) { + List list = Arrays.stream(objects.toArray()).map(String::valueOf).collect(Collectors.toList()); + result.add(list); + System.out.println(list); + } + return result; + } +} diff --git a/src/main/java/com/shuzijun/leetcode/WeightUnionFind.java b/src/main/java/com/shuzijun/leetcode/WeightUnionFind.java new file mode 100644 index 0000000..bac448b --- /dev/null +++ b/src/main/java/com/shuzijun/leetcode/WeightUnionFind.java @@ -0,0 +1,62 @@ +package com.shuzijun.leetcode; + +import java.util.stream.IntStream; + +/** + * @author : CAOMU + * @version : 1.0 + * @since : 2021/02/14, Sun, 14:55 + */ +public class WeightUnionFind { + + private int[] parent; + + /** + * 指向的父结点的权值 + */ + private double[] weight; + + + public WeightUnionFind(int n) { + this.parent = IntStream.range(0, n).toArray(); + this.weight = new double[n]; + IntStream.range(0, n).forEach(i -> this.weight[i] = 1.0d); + } + + public void union(int x, int y, double value) { + int rootX = this.find(x); + int rootY = this.find(y); + if (rootX == rootY) { + return; + } + + this.parent[rootX] = rootY; + // 关系式的推导请见「参考代码」下方的示意图 + this.weight[rootX] = this.weight[y] * value / this.weight[x]; + } + + /** + * 路径压缩 + * + * @param x + * @return 根结点的 id + */ + public int find(int x) { + if (x != this.parent[x]) { + int origin = this.parent[x]; + this.parent[x] = this.find(this.parent[x]); + this.weight[x] *= this.weight[origin]; + } + return this.parent[x]; + } + + public double isConnected(int x, int y) { + int rootX = this.find(x); + int rootY = this.find(y); + if (rootX == rootY) { + return this.weight[x] / this.weight[y]; + } else { + return -1.0d; + } + } +}