diff --git a/AccountMerge.py b/AccountMerge.py new file mode 100644 index 0000000..84d7657 --- /dev/null +++ b/AccountMerge.py @@ -0,0 +1,50 @@ +from typing import List + + +class Solution: + def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]: + reverse_dict = dict() + result = dict() + uf = UnionFind(len(accounts)) + + for index, emails in enumerate(accounts): + for email in emails[1::]: + if email in reverse_dict: + uf.union(reverse_dict[email], index) + reverse_dict[email] = index + + for index, emails in enumerate(accounts): + root_index = uf.find_root(index) + if root_index not in result: + result[root_index] = set() + + result[root_index].update(set(emails[1::])) + + return [[accounts[k][0]] + sorted(list(v)) for k, v in result.items()] + + +class UnionFind: + def __init__(self, length): + self.list = list(range(length)) + + def find_root(self, n): + while n != self.list[n]: + n = self.list[n] + return n + + def union(self, i, j): + i_root = self.find_root(i) + j_root = self.find_root(j) + if j_root < i_root: + j_root, i_root = i_root, j_root + + self.list[j_root] = i_root + + +if __name__ == "__main__": + accounts = [["David", "David0@m.co", "David1@m.co"], + ["David", "David3@m.co", "David4@m.co"], + ["David", "David4@m.co", "David5@m.co"], + ["David", "David2@m.co", "David3@m.co"], + ["David", "David1@m.co", "David2@m.co"]] + print(Solution().accountsMerge(accounts)) diff --git a/DPI.java b/DPI.java new file mode 100644 index 0000000..90949ae --- /dev/null +++ b/DPI.java @@ -0,0 +1,93 @@ +public class DPI { + /** + * Fibonacci Number + *
+ * Get the Kth number in the Fibonacci Sequence. (K is 0-indexed, the 0th + * Fibonacci number is 0 and the 1st Fibonacci number is 1). + */ + public long fibonacci(int K) { + long a = 0; + long b = 1; + while (K-- > 0) { + long temp = a + b; + a = b; + b = temp; + } + return a; + } + + /** + * Longest Ascending SubArray + *
+ * Given an unsorted array, find the length of the longest subarray in which the + * numbers are in ascending order. + */ + public int longest(int[] array) { + int max = 0; + int cur = 0; + int prev = 0; + for (int i = 0; i < array.length; i++) { + if (i == 0) { + max = 1; + cur = 1; + prev = array[0]; + } else { + if (array[i] > prev) { + cur++; + prev = array[i]; + if (cur > max) { + max = cur; + } + } else { + prev = array[i]; + cur = 1; + } + } + } + return max; + } + + /** + * Max Product Of Cutting Rope + *
+ * Given a rope with positive integer-length n, how to cut the rope into m + * integer-length parts with length p[0], p[1], ...,p[m-1], in order to get the + * maximal product of p[0]*p[1]* ... *p[m-1]? m is determined by you and must be + * greater than 0 (at least one cut must be made). Return the max product you + * can have. + */ + public int maxProduct(int length) { + int[] dp = new int[length]; + dp[0] = 1; + if (length <= 3) { + return length - 1; + } + for (int i = 1; i < length; i++) { + dp[i] = i + 1; + for (int j = 1; j <= i; j++) { + dp[i] = Math.max(dp[i], j * dp[i - j]); + } + } + return dp[length - 1]; + } + + /** + * Array Hopper I + *
+ * Given an array A of non-negative integers, you are initially positioned at + * index 0 of the array. A[i] means the maximum jump distance from that position + * (you can only jump towards the end of the array). Determine if you are able + * to reach the last index. + */ + public boolean canJump(int[] array) { + int max = array[0]; + for (int i = 0; i < array.length; i++) { + if (i > max) { + return false; + } else { + max = Math.max(max, i + array[i]); + } + } + return true; + } +} diff --git a/DPII.java b/DPII.java new file mode 100644 index 0000000..eef8112 --- /dev/null +++ b/DPII.java @@ -0,0 +1,165 @@ +import java.util.*; + +public class DPII { + public static void main(String[] args) { + int[][] matrix = new int[][] { + {0, 1, 1, 1}, + {1, 1, 0, 1}, + {0, 1, 0, 1}, + {1, 1, 1, 1}, + }; + DPII d = new DPII(); + d.largest(matrix); + + } + /** + * Array Hopper II + *
+ * Given an array A of non-negative integers, you are initially positioned at + * index 0 of the array. A[i] means the maximum jump distance from index i (you + * can only jump towards the end of the array). Determine the minimum number of + * jumps you need to reach the end of array. If you can not reach the end of the + * array, return -1. + */ + public int minJump(int[] array) { + int[] dp = new int[array.length]; + dp[0] = 1; + + for (int i = 0; i < array.length; i++) { + if (dp[i] == 0) { + return -1; + } else { + for (int j = i + 1; j <= i + array[i] && j < array.length; j++) { + if (dp[j] == 0) { + dp[j] = dp[i] + 1; + } else { + dp[j] = Math.min(dp[i] + 1, dp[j]); + } + } + } + } + return dp[array.length - 1] - 1; + } + + /** + * Largest SubArray Sum + *
+ * Given an unsorted integer array, find the subarray that has the greatest sum. + * Return the sum. + */ + public int largestSum(int[] array) { + int cur = 0; + int max = Integer.MIN_VALUE; + for (int i = 0; i < array.length; i++) { + cur += array[i]; + max = Math.max(cur, max); + if (cur < 0) { + cur = 0; + } + } + return max; + } + + /** + * Dictionary Word I + *
+ * Given a word and a dictionary, determine if it can be composed by
+ * concatenating words from the given dictionary.
+ */
+ public boolean canBreak(String input, String[] dict) {
+ Set
+ * Given two strings of alphanumeric characters, determine the minimum number of
+ * Replace, Delete, and Insert operations needed to transform one string into
+ * the other.
+ */
+ public int editDistance(String one, String two) {
+ int l1 = one.length();
+ int l2 = two.length();
+ int[][] dp = new int[l1 + 1][l2 + 1];
+ dp[0][0] = 0;
+
+ for (int i = 1; i <= l1; i++) {
+ dp[i][0] = i;
+ }
+
+ for (int j = 0; j <= l2; j++) {
+ dp[0][j] = j;
+ }
+
+ for (int i = 1; i <= l1; i++) {
+ for (int j = 1; j <= l2; j++) {
+ if (one.charAt(i - 1) == two.charAt(j - 1)) {
+ dp[i][j] = dp[i - 1][j - 1];
+ } else {
+ dp[i][j] = dp[i - 1][j - 1] + 1;
+ }
+ dp[i][j] = Math.min(dp[i][j], dp[i - 1][j] + 1);
+ dp[i][j] = Math.min(dp[i][j], dp[i][j - 1] + 1);
+ }
+ }
+
+ return dp[l1][l2];
+ }
+
+ /**
+ * Largest Square Of 1s
+ *
+ * Determine the largest square of 1s in a binary matrix (a binary matrix only
+ * contains 0 and 1), return the length of the largest square.
+ */
+ public int largest(int[][] matrix) {
+ int max = 0;
+ int H = matrix.length;
+ int W = matrix[0].length;
+
+ int[][] dp = new int[H][W];
+
+ for (int i = 0; i < H; i++) {
+ for (int j = 0; j < W; j++) {
+ if (matrix[i][j] == 1) {
+ if (i == 0 || j == 0) {
+ dp[i][j] = 1;
+ } else {
+ dp[i][j] = Math.min(Math.min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1;
+ }
+
+ max = Math.max(dp[i][j], max);
+ }
+ }
+ }
+
+ for (int i = 0; i < H; i++) {
+ System.out.print("|");
+ for (int j = 0; j < W; j++) {
+ System.out.print(dp[i][j]);
+ System.out.print(" ");
+ }
+ System.out.println("|");
+ }
+
+ return max;
+ }
+}
diff --git a/DPIII.java b/DPIII.java
new file mode 100644
index 0000000..d2681e1
--- /dev/null
+++ b/DPIII.java
@@ -0,0 +1,93 @@
+public class DPIII {
+ /**
+ * Longest Consecutive 1s
+ *
+ * Given an array containing only 0s and 1s, find the length of the longest
+ * subarray of consecutive 1s.
+ */
+ public int longest(int[] array) {
+ int max = 0;
+ int cur = 0;
+ for (int num : array) {
+ if (num == 1) {
+ cur++;
+ max = Math.max(max, cur);
+ } else {
+ cur = 0;
+ }
+ }
+ return max;
+ }
+
+ /**
+ * Longest Cross Of 1s
+ *
+ * Given a matrix that contains only 1s and 0s, find the largest cross which
+ * contains only 1s, with the same arm lengths and the four arms joining at the
+ * central point.
+ *
+ * Return the arm length of the largest cross.
+ */
+ public int largest(int[][] matrix) {
+ int H = matrix.length;
+ int W = matrix[0].length;
+
+ int[][] right = new int[H][W];
+ int[][] left = new int[H][W];
+ int[][] up = new int[H][W];
+ int[][] down = new int[H][W];
+
+ int max = 0;
+
+ for (int i = 0; i < H; i++) {
+ for (int j = 0; j < W; j++) {
+ if (matrix[i][j] == 1) {
+ if (j == 0) {
+ left[i][j] = 1;
+ } else {
+ left[i][j] = left[i][j - 1] + 1;
+ }
+ }
+ }
+ }
+ for (int i = 0; i < H; i++) {
+ for (int j = 0; j < W; j++) {
+ if (matrix[i][j] == 1) {
+ if (i == 0) {
+ up[i][j] = 1;
+ } else {
+ up[i][j] = up[i - 1][j] + 1;
+ }
+ }
+ }
+ }
+ for (int i = 0; i < H; i++) {
+ for (int j = W - 1; j >= 0; j--) {
+ if (matrix[i][j] == 1) {
+ if (j == W - 1) {
+ right[i][j] = 1;
+ } else {
+ right[i][j] = right[i][j + 1] + 1;
+ }
+ }
+ }
+ }
+ for (int i = H - 1; i >= 0; i--) {
+ for (int j = 0; j < W; j++) {
+ if (matrix[i][j] == 1) {
+ if (i == H - 1) {
+ down[i][j] = 1;
+ } else {
+ down[i][j] = down[i + 1][j] + 1;
+ }
+ }
+ }
+ }
+ for (int i = 0; i < H; i++) {
+ for (int j = 0; j < W; j++) {
+ max = Math.max(Math.min(Math.min(up[i][j], down[i][j]), Math.min(left[i][j], right[i][j])), max);
+ }
+ }
+ return max;
+ }
+}
diff --git a/RecursionII.java b/RecursionII.java
index cffd09f..052b2eb 100644
--- a/RecursionII.java
+++ b/RecursionII.java
@@ -164,10 +164,10 @@ public int numNodesLeftHelper(TreeNode root) {
}
/**
- * Lowest Common Ancestor I
- *
- * Given two nodes in a binary tree, find their lowest common ancestor.
- */
+ * Lowest Common Ancestor I
+ *
+ * Given two nodes in a binary tree, find their lowest common ancestor.
+ */
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode one, TreeNode two) {
if (root == null || root == one || root == two) {
return root;
@@ -183,4 +183,65 @@ public TreeNode lowestCommonAncestor(TreeNode root, TreeNode one, TreeNode two)
return root;
}
}
+
+ /**
+ * Spiral Order Traverse II
+ *
+ * Traverse an M * N 2D array in spiral order clock-wise starting from the top left corner. Return the list of traversal sequence.
+ */
+ public List
+ * Given a binary tree where all the right nodes are leaf nodes, flip it upside down and turn it into a tree with left leaf nodes as the root.
+ */
+ public TreeNode reverse(TreeNode root) {
+ if (root == null || root.left == null) {
+ return root;
+ }
+ TreeNode left = root.left;
+ TreeNode newHead = reverse(root.left);
+ left.left = root;
+ root.left = null;
+ left.right = root.right;
+ root.right = null;
+ return newHead;
+ }
}