thisRow = new ArrayList<>();
+ for (int j = 0; j < col; j++) {
+ thisRow.add(nums[i][j]);
+ }
+ result.add(thisRow);
+ }
+ return result;
+ }
+}
diff --git a/src/main/java/com/fishercoder/common/utils/TreeUtils.java b/src/main/java/com/fishercoder/common/utils/TreeUtils.java
index 34869fd771..458e030037 100644
--- a/src/main/java/com/fishercoder/common/utils/TreeUtils.java
+++ b/src/main/java/com/fishercoder/common/utils/TreeUtils.java
@@ -15,7 +15,7 @@
public class TreeUtils {
/**
* This method is to construct a normal binary tree. The input reads like
-* this for [5, 3, 6, 2, 4, null, null, 1]:
+* this for [5, 3, 6, 2, 4, null, null, 1], i.e. preorder:
5
/ \
3 6
diff --git a/src/main/java/com/fishercoder/solutions/_1.java b/src/main/java/com/fishercoder/solutions/_1.java
index 81e43b3e2a..a787638b3b 100644
--- a/src/main/java/com/fishercoder/solutions/_1.java
+++ b/src/main/java/com/fishercoder/solutions/_1.java
@@ -5,32 +5,31 @@
/**
* 1. Two Sum
- *
+ *
* Given an array of integers, return indices of the two numbers such that they add up to a specific target.
- *
* You may assume that each input would have exactly one solution, and you may not use the same element twice.
- *
* Example:
* Given nums = [2, 7, 11, 15], target = 9,
- *
* Because nums[0] + nums[1] = 2 + 7 = 9,
* return [0, 1].
*/
public class _1 {
- public int[] twoSum(int[] nums, int target) {
- Map map = new HashMap();
- int[] result = new int[2];
- for (int i = 0; i < nums.length; i++) {
- if (map.containsKey(target - nums[i])) {
- result[0] = map.get(target - nums[i]);
- result[1] = i;
- break;
- } else {
- map.put(nums[i], i);
+ public static class Solution1 {
+ public int[] twoSum(int[] nums, int target) {
+ Map map = new HashMap();
+ int[] result = new int[2];
+ for (int i = 0; i < nums.length; i++) {
+ if (map.containsKey(target - nums[i])) {
+ result[0] = map.get(target - nums[i]);
+ result[1] = i;
+ break;
+ } else {
+ map.put(nums[i], i);
+ }
}
+ return result;
}
- return result;
}
}
diff --git a/src/main/java/com/fishercoder/solutions/_10.java b/src/main/java/com/fishercoder/solutions/_10.java
index 6a0299c85e..1c7a4d296e 100644
--- a/src/main/java/com/fishercoder/solutions/_10.java
+++ b/src/main/java/com/fishercoder/solutions/_10.java
@@ -25,32 +25,34 @@
public class _10 {
- public boolean isMatch(String s, String p) {
- if (s == null || p == null) {
- return false;
- }
- boolean[][] dp = new boolean[s.length() + 1][p.length() + 1];
- dp[0][0] = true;
- for (int i = 0; i < p.length(); i++) {
- if (p.charAt(i) == '*' && dp[0][i - 1]) {
- dp[0][i + 1] = true;
+ public static class Solution1 {
+ public boolean isMatch(String s, String p) {
+ if (s == null || p == null) {
+ return false;
}
- }
- for (int i = 0; i < s.length(); i++) {
- for (int j = 0; j < p.length(); j++) {
- if (p.charAt(j) == '.' || p.charAt(j) == s.charAt(i)) {
- dp[i + 1][j + 1] = dp[i][j];
+ boolean[][] dp = new boolean[s.length() + 1][p.length() + 1];
+ dp[0][0] = true;
+ for (int i = 0; i < p.length(); i++) { //here's the p's length, not s's
+ if (p.charAt(i) == '*' && dp[0][i - 1]) {
+ dp[0][i + 1] = true; //here's y axis should be i+1
}
- if (p.charAt(j) == '*') {
- if (p.charAt(j - 1) != s.charAt(i) && p.charAt(j - 1) != '.') {
- dp[i + 1][j + 1] = dp[i + 1][j - 1];
- } else {
- dp[i + 1][j + 1] = (dp[i + 1][j] || dp[i][j + 1] || dp[i + 1][j - 1]);
+ }
+ for (int i = 0; i < s.length(); i++) {
+ for (int j = 0; j < p.length(); j++) {
+ if (p.charAt(j) == '.' || p.charAt(j) == s.charAt(i)) {
+ dp[i + 1][j + 1] = dp[i][j];
+ }
+ if (p.charAt(j) == '*') {
+ if (p.charAt(j - 1) != s.charAt(i) && p.charAt(j - 1) != '.') {
+ dp[i + 1][j + 1] = dp[i + 1][j - 1];
+ } else {
+ dp[i + 1][j + 1] = (dp[i + 1][j] || dp[i][j + 1] || dp[i + 1][j - 1]);
+ }
}
}
}
+ return dp[s.length()][p.length()];
}
- return dp[s.length()][p.length()];
}
}
diff --git a/src/main/java/com/fishercoder/solutions/_100.java b/src/main/java/com/fishercoder/solutions/_100.java
index 24fe2bab4c..f090633936 100644
--- a/src/main/java/com/fishercoder/solutions/_100.java
+++ b/src/main/java/com/fishercoder/solutions/_100.java
@@ -4,18 +4,19 @@
/**
* 100. Same Tree
- *
- * Given two binary trees, write a function to check if they are equal or not.
- *
- * Two binary trees are considered equal if they are structurally identical and the nodes have the same value.
+ *
+ * Given two binary trees, write a function to check if they are equal or not. Two binary trees are
+ * considered equal if they are structurally identical and the nodes have the same value.
*/
public class _100 {
- //recursion idea flows out naturally.
+
+ public static class Solution1 {
public boolean isSameTree(TreeNode p, TreeNode q) {
- if (p == null || q == null) {
- return p == q;
- }
- return p.val == q.val && isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
+ if (p == null || q == null) {
+ return p == q;
+ }
+ return p.val == q.val && isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_101.java b/src/main/java/com/fishercoder/solutions/_101.java
index 8c3c1bbdff..5df025af81 100644
--- a/src/main/java/com/fishercoder/solutions/_101.java
+++ b/src/main/java/com/fishercoder/solutions/_101.java
@@ -23,29 +23,26 @@ Given a binary tree, check whether it is a mirror of itself (ie, symmetric aroun
3 3
Note:
-Bonus points if you could solve it both recursively and iteratively. */
+Bonus points if you could solve it both recursively and iteratively.
+ */
+
public class _101 {
- //a very natural idea flows out using recursion. Cheers.
- public boolean isSymmetric(TreeNode root) {
- if (root == null) {
- return true;
+ public static class Solution1 {
+ public boolean isSymmetric(TreeNode root) {
+ if (root == null) {
+ return true;
+ }
+ return isSymmetric(root.left, root.right);
}
- return isSymmetric(root.left, root.right);
- }
- private boolean isSymmetric(TreeNode left, TreeNode right) {
- if (left == null || right == null) {
- return left == right;
- }
- if (left.val != right.val) {
- return false;
+ private boolean isSymmetric(TreeNode left, TreeNode right) {
+ if (left == null || right == null) {
+ return left == right;
+ }
+ if (left.val != right.val) {
+ return false;
+ }
+ return isSymmetric(left.left, right.right) && isSymmetric(left.right, right.left);
}
- return isSymmetric(left.left, right.right) && isSymmetric(left.right, right.left);
- }
-
- public static void main(String... strings) {
- _101 test = new _101();
- TreeNode root = new TreeNode(1);
- System.out.println(test.isSymmetric(root));
}
}
diff --git a/src/main/java/com/fishercoder/solutions/_102.java b/src/main/java/com/fishercoder/solutions/_102.java
index cbc29f9c3c..bdcd76f6b0 100644
--- a/src/main/java/com/fishercoder/solutions/_102.java
+++ b/src/main/java/com/fishercoder/solutions/_102.java
@@ -31,29 +31,30 @@
*/
public class _102 {
- public List> levelOrder(TreeNode root) {
- List> result = new ArrayList<>();
- if (root == null) {
- return result;
- }
- Queue q = new LinkedList();
- q.offer(root);
- while (!q.isEmpty()) {
- List thisLevel = new ArrayList();
- int qSize = q.size();
- for (int i = 0; i < qSize; i++) {
- TreeNode curr = q.poll();
- thisLevel.add(curr.val);
- if (curr.left != null) {
- q.offer(curr.left);
- }
- if (curr.right != null) {
- q.offer(curr.right);
- }
- }
- result.add(thisLevel);
- }
- return result;
- }
-
+ public static class Solution1 {
+ public List> levelOrder(TreeNode root) {
+ List> result = new ArrayList<>();
+ if (root == null) {
+ return result;
+ }
+ Queue q = new LinkedList();
+ q.offer(root);
+ while (!q.isEmpty()) {
+ List thisLevel = new ArrayList();
+ int qSize = q.size();
+ for (int i = 0; i < qSize; i++) {
+ TreeNode curr = q.poll();
+ thisLevel.add(curr.val);
+ if (curr.left != null) {
+ q.offer(curr.left);
+ }
+ if (curr.right != null) {
+ q.offer(curr.right);
+ }
+ }
+ result.add(thisLevel);
+ }
+ return result;
+ }
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_103.java b/src/main/java/com/fishercoder/solutions/_103.java
index d59c33a36b..5a6e12e145 100644
--- a/src/main/java/com/fishercoder/solutions/_103.java
+++ b/src/main/java/com/fishercoder/solutions/_103.java
@@ -8,10 +8,9 @@
import java.util.List;
import java.util.Queue;
-
/**
- * 103. Binary Tree Zigzag Level Order Traversal
- *
+ * 103. Binary Tree Zigzag Level Order Traversal
+ *
Given a binary tree, return the zigzag level order traversal of its nodes' values.
(ie, from left to right, then right to left for the next level and alternate between).
@@ -30,36 +29,38 @@
]
*/
public class _103 {
- public List> zigzagLevelOrder(TreeNode root) {
- Queue q = new LinkedList();
- List> levels = new ArrayList();
- if (root == null) {
- return levels;
- }
- q.offer(root);
- boolean forward = true;
- while (!q.isEmpty()) {
- int size = q.size();
- List level = new ArrayList();
- for (int i = 0; i < size; i++) {
- TreeNode curr = q.poll();
- level.add(curr.val);
- if (curr.left != null) {
- q.offer(curr.left);
+ public static class Solution1 {
+ public List> zigzagLevelOrder(TreeNode root) {
+ Queue q = new LinkedList();
+ List> levels = new ArrayList();
+ if (root == null) {
+ return levels;
+ }
+ q.offer(root);
+ boolean forward = true;
+ while (!q.isEmpty()) {
+ int size = q.size();
+ List level = new ArrayList();
+ for (int i = 0; i < size; i++) {
+ TreeNode curr = q.poll();
+ level.add(curr.val);
+ if (curr.left != null) {
+ q.offer(curr.left);
+ }
+ if (curr.right != null) {
+ q.offer(curr.right);
+ }
}
- if (curr.right != null) {
- q.offer(curr.right);
+ if (forward) {
+ forward = false;
+ levels.add(level);
+ } else {
+ Collections.reverse(level);
+ levels.add(level);
+ forward = true;
}
}
- if (forward) {
- forward = false;
- levels.add(level);
- } else {
- Collections.reverse(level);
- levels.add(level);
- forward = true;
- }
+ return levels;
}
- return levels;
}
}
diff --git a/src/main/java/com/fishercoder/solutions/_104.java b/src/main/java/com/fishercoder/solutions/_104.java
index 070e5e2c72..17a6c994a4 100644
--- a/src/main/java/com/fishercoder/solutions/_104.java
+++ b/src/main/java/com/fishercoder/solutions/_104.java
@@ -4,16 +4,19 @@
/**
* 104. Maximum Depth of Binary Tree
+ *
* Given a binary tree, find its maximum depth.
* The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.
*/
public class _104 {
+ public static class Solution1 {
public int maxDepth(TreeNode root) {
- if (root == null) {
- return 0;
- }
- return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
+ if (root == null) {
+ return 0;
+ }
+ return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_105.java b/src/main/java/com/fishercoder/solutions/_105.java
index 68ed169425..3d2666737e 100644
--- a/src/main/java/com/fishercoder/solutions/_105.java
+++ b/src/main/java/com/fishercoder/solutions/_105.java
@@ -5,47 +5,51 @@
import java.util.HashMap;
import java.util.Map;
-/**Given preorder and inorder traversal of a tree, construct the binary tree.
+/**
+ * 105. Construct Binary Tree from Preorder and Inorder Traversal
+ * Given preorder and inorder traversal of a tree, construct the binary tree.
Note:
- You may assume that duplicates do not exist in the tree.*/
+ You may assume that duplicates do not exist in the tree.
+ */
public class _105 {
- /**
- * credit: https://discuss.leetcode.com/topic/29838/5ms-java-clean-solution-with-caching
- * use HashMap as the cache so that accessing inorder index becomes O(1) time
- *
- * Note: The first element of preorder array is the root!
- */
- public TreeNode buildTree(int[] preorder, int[] inorder) {
- Map inorderMap = new HashMap();
- for (int i = 0; i < inorder.length; i++) {
- inorderMap.put(inorder[i], i);
+ public static class Solution1 {
+ /**
+ * credit: https://discuss.leetcode.com/topic/29838/5ms-java-clean-solution-with-caching use
+ * HashMap as the cache so that accessing inorder index becomes O(1) time Note: The first
+ * element of preorder array is the root!
+ */
+ public TreeNode buildTree(int[] preorder, int[] inorder) {
+ Map inorderMap = new HashMap();
+ for (int i = 0; i < inorder.length; i++) {
+ inorderMap.put(inorder[i], i);
+ }
+
+ /**At the beginning, both start from 0 to nums.length-1*/
+ return buildTree(preorder, 0, preorder.length - 1, inorderMap, 0, inorder.length - 1);
}
- /**At the beginning, both start from 0 to nums.length-1*/
- return buildTree(preorder, 0, preorder.length - 1, 0, inorder.length - 1, inorderMap);
- }
-
- private TreeNode buildTree(int[] preorder, int preStart, int preEnd, int inStart, int inEnd, Map inorderMap) {
- if (preStart > preEnd || inStart > inEnd) {
- return null;
+ private TreeNode buildTree(int[] preorder, int preStart, int preEnd,
+ Map inorderMap, int inStart, int inEnd) {
+ if (preStart > preEnd || inStart > inEnd) {
+ return null;
+ }
+
+ TreeNode root = new TreeNode(preorder[preStart]);
+ int inRoot = inorderMap.get(preorder[preStart]);
+ int numsLeft = inRoot - inStart;
+
+ /**It's easy to understand and remember:
+ * for the indices of inorder array:
+ * root.left should be inStart and inRoot-1 as new start and end indices
+ * root.right should be inRoot+1 and inEnd as new start and end indices
+ *
+ * since inRoot is being used already in this recursion call, that's why we use inRoot-1 and inRoot+1
+ * this part is the same for both Leetcode 105 and Leetcode 106.*/
+ root.left = buildTree(preorder, preStart + 1, preStart + numsLeft, inorderMap, inStart, inRoot - 1);
+ root.right = buildTree(preorder, preStart + numsLeft + 1, preEnd, inorderMap, inRoot + 1, inEnd);
+ return root;
}
-
- TreeNode root = new TreeNode(preorder[preStart]);
- int inRoot = inorderMap.get(preorder[preStart]);
- int numsLeft = inRoot - inStart;
-
- /**It's easy to understand and remember:
- * for the indices of inorder array:
- * root.left should be inStart and inRoot-1 as new start and end indices
- * root.right should be inRoot+1 and inEnd as new start and end indices
- *
- * since inRoot is being used already in this recursion call, that's why we use inRoot-1 and inRoot+1
- * this part is the same for both Leetcode 105 and Leetcode 106.*/
- root.left = buildTree(preorder, preStart + 1, preStart + numsLeft, inStart, inRoot - 1, inorderMap);
- root.right = buildTree(preorder, preStart + numsLeft + 1, preEnd, inRoot + 1, inEnd, inorderMap);
- return root;
}
-
}
diff --git a/src/main/java/com/fishercoder/solutions/_106.java b/src/main/java/com/fishercoder/solutions/_106.java
index 5345d2a760..4e13b2324b 100644
--- a/src/main/java/com/fishercoder/solutions/_106.java
+++ b/src/main/java/com/fishercoder/solutions/_106.java
@@ -12,56 +12,58 @@
Note:
You may assume that duplicates do not exist in the tree.
-
*/
public class _106 {
+ public static class Solution1 {
- /**
- * https://discuss.leetcode.com/topic/3296/my-recursive-java-code-with-o-n-time-and-o-n-space
- *
- * Note: the last element of postorder array is the root!
- *
- * The idea is to take the last element in postorder as the root; find the position of the root in the inorder array;
- * then locate the range for left sub-tree and right sub-tree and do recursion,
- * use a hashmap to record the index of root in the inorder array.
- */
- public TreeNode buildTree(int[] inorder, int[] postorder) {
- if (inorder == null || postorder == null || inorder.length != postorder.length) {
- return null;
- }
- HashMap inorderMap = new HashMap<>();
- for (int i = 0; i < inorder.length; i++) {
- inorderMap.put(inorder[i], i);
+ /**
+ * https://discuss.leetcode.com/topic/3296/my-recursive-java-code-with-o-n-time-and-o-n-space
+ *
+ * Note: the last element of postorder array is the root!
+ *
+ * The idea is to take the last element in postorder as the root; find the position of the root
+ * in the inorder array; then locate the range for left sub-tree and right sub-tree and do
+ * recursion, use a hashmap to record the index of root in the inorder array.
+ */
+ public TreeNode buildTree(int[] inorder, int[] postorder) {
+ if (inorder == null || postorder == null || inorder.length != postorder.length) {
+ return null;
+ }
+ HashMap inorderMap = new HashMap<>();
+ for (int i = 0; i < inorder.length; i++) {
+ inorderMap.put(inorder[i], i);
+ }
+ /**At the beginning, both start from 0 to nums.length-1*/
+ return buildTreeRecursively(inorderMap, 0, inorder.length - 1, postorder, 0,
+ postorder.length - 1);
}
- /**At the beginning, both start from 0 to nums.length-1*/
- return buildTreeRecursively(0, inorder.length - 1, postorder, 0, postorder.length - 1, inorderMap);
- }
- private TreeNode buildTreeRecursively(int inorderStart, int inorderEnd, int[] postorder, int postorderStart, int postorderEnd, Map inorderMap) {
- if (postorderStart > postorderEnd || inorderStart > inorderEnd) {
- return null;
- }
- TreeNode root = new TreeNode(postorder[postorderEnd]);
- int inRoot = inorderMap.get(postorder[postorderEnd]);
- int numsLeft = inRoot - inorderStart;
+ private TreeNode buildTreeRecursively(Map inorderMap, int inorderStart,
+ int inorderEnd, int[] postorder, int postorderStart, int postorderEnd) {
+ if (postorderStart > postorderEnd || inorderStart > inorderEnd) {
+ return null;
+ }
+ TreeNode root = new TreeNode(postorder[postorderEnd]);
+ int inRoot = inorderMap.get(postorder[postorderEnd]);
+ int numsLeft = inRoot - inorderStart;
- /**It's easy to understand and remember:
- * for the indices of inorder array:
- * inStart and inRoot-1 as new start and end indices
- * inRoot+1 and inEnd as new start and end indices
- *
- * this is easy to understand and remember: since inRoot is already been used in this recursion call, so we're going to use inRoot-1 and inRoot+1 for next recursion call
- *
- * for the indices of postorder array:
- * postorderStart and postorderStart+numsLeft-1 should be the new start and end indices
- * postorderStart+numsLeft and postorderEnd-1 should be the new start and end indices
- *
- * this is also easy to understand and remember:
- * since the last one in postorder is the root and we have used it in this recursion call already, so the end is definitely postorderEnd-1;
- * then the postorderEnd for root.left is contiguous to the postorderStart of root.right, :)*/
- root.left = buildTreeRecursively(inorderStart, inRoot - 1, postorder, postorderStart, postorderStart + numsLeft - 1, inorderMap);
- root.right = buildTreeRecursively(inRoot + 1, inorderEnd, postorder, postorderStart + numsLeft, postorderEnd - 1, inorderMap);
- return root;
+ /**It's easy to understand and remember:
+ * for the indices of inorder array:
+ * inStart and inRoot-1 as new start and end indices
+ * inRoot+1 and inEnd as new start and end indices
+ *
+ * this is easy to understand and remember: since inRoot is already been used in this recursion call, so we're going to use inRoot-1 and inRoot+1 for next recursion call
+ *
+ * for the indices of postorder array:
+ * postorderStart and postorderStart+numsLeft-1 should be the new start and end indices
+ * postorderStart+numsLeft and postorderEnd-1 should be the new start and end indices
+ *
+ * this is also easy to understand and remember:
+ * since the last one in postorder is the root and we have used it in this recursion call already, so the end is definitely postorderEnd-1;
+ * then the postorderEnd for root.left is contiguous to the postorderStart of root.right, :)*/
+ root.left = buildTreeRecursively(inorderMap, inorderStart, inRoot - 1, postorder, postorderStart, postorderStart + numsLeft - 1);
+ root.right = buildTreeRecursively(inorderMap, inRoot + 1, inorderEnd, postorder, postorderStart + numsLeft, postorderEnd - 1);
+ return root;
+ }
}
-
}
diff --git a/src/main/java/com/fishercoder/solutions/_107.java b/src/main/java/com/fishercoder/solutions/_107.java
index 1688d5f49b..200b1f148c 100644
--- a/src/main/java/com/fishercoder/solutions/_107.java
+++ b/src/main/java/com/fishercoder/solutions/_107.java
@@ -8,7 +8,6 @@
import java.util.List;
import java.util.Queue;
-
/**107. Binary Tree Level Order Traversal II
Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root).
@@ -32,30 +31,32 @@
*/
public class _107 {
- public List> levelOrder(TreeNode root) {
- List> result = new ArrayList();
- if (root == null) {
- return result;
- }
+ public static class Solution1 {
+ public List> levelOrder(TreeNode root) {
+ List> result = new ArrayList();
+ if (root == null) {
+ return result;
+ }
- Queue q = new LinkedList();
- q.offer(root);
- while (!q.isEmpty()) {
- List thisLevel = new ArrayList();
- int qSize = q.size();
- for (int i = 0; i < qSize; i++) {
- TreeNode curr = q.poll();
- thisLevel.add(curr.val);
- if (curr.left != null) {
- q.offer(curr.left);
- }
- if (curr.right != null) {
- q.offer(curr.right);
+ Queue q = new LinkedList();
+ q.offer(root);
+ while (!q.isEmpty()) {
+ List thisLevel = new ArrayList();
+ int qSize = q.size();
+ for (int i = 0; i < qSize; i++) {
+ TreeNode curr = q.poll();
+ thisLevel.add(curr.val);
+ if (curr.left != null) {
+ q.offer(curr.left);
+ }
+ if (curr.right != null) {
+ q.offer(curr.right);
+ }
}
+ result.add(thisLevel);
}
- result.add(thisLevel);
+ Collections.reverse(result);
+ return result;
}
- Collections.reverse(result);//this is the only line that gets added/changed to the previous solution.
- return result;
}
}
diff --git a/src/main/java/com/fishercoder/solutions/_108.java b/src/main/java/com/fishercoder/solutions/_108.java
index adebb527e6..808fdc4926 100644
--- a/src/main/java/com/fishercoder/solutions/_108.java
+++ b/src/main/java/com/fishercoder/solutions/_108.java
@@ -3,23 +3,26 @@
import com.fishercoder.common.classes.TreeNode;
/**
+ * 108. Convert Sorted Array to Binary Search Tree
+ *
* Given an array where elements are sorted in ascending order, convert it to a height balanced BST.
*/
public class _108 {
+ public static class Solution1 {
public TreeNode sortedArrayToBST(int[] num) {
- return rec(num, 0, num.length - 1);
+ return rec(num, 0, num.length - 1);
}
public TreeNode rec(int[] num, int low, int high) {
- if (low > high) {
- return null;
- }
- int mid = low + (high - low) / 2;
- TreeNode root = new TreeNode(num[mid]);
- root.left = rec(num, low, mid - 1);
- root.right = rec(num, mid + 1, high);
- return root;
+ if (low > high) {
+ return null;
+ }
+ int mid = low + (high - low) / 2;
+ TreeNode root = new TreeNode(num[mid]);
+ root.left = rec(num, low, mid - 1);
+ root.right = rec(num, mid + 1, high);
+ return root;
}
-
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_11.java b/src/main/java/com/fishercoder/solutions/_11.java
index 4aaf34dc43..4336f09ebf 100644
--- a/src/main/java/com/fishercoder/solutions/_11.java
+++ b/src/main/java/com/fishercoder/solutions/_11.java
@@ -1,30 +1,34 @@
package com.fishercoder.solutions;
/**
- * Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.
+ * 11. Container With Most Water
+ *
+ * Given n non-negative integers a1, a2, ..., an,
+ * where each represents a point at coordinate (i, ai).
+ * n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0).
+ * Find two lines, which together with x-axis forms a container, such that the container contains the most water.
Note: You may not slant the container and n is at least 2.
*/
public class _11 {
- public int maxArea(int[] height) {
- int max = Integer.MIN_VALUE;
- int len = height.length;
- int i = 0;
- int j = len - 1;
- while (i < j) {
- if (Math.min(height[i], height[j]) * (j - i) > max) {
- max = Math.min(height[i], height[j]) * (j - i);
- }
- if (height[i] <= height[j]) {
- // we need to find the shorter one,
- // then calculate its area
- i++;
- } else {
- j--;
+ public static class Solution1 {
+ public int maxArea(int[] height) {
+ int max = 0;
+ int i = 0;
+ int j = height.length - 1;
+ while (i < j) {
+ max = Math.max(Math.min(height[i], height[j]) * (j - i), max);
+ if (height[i] <= height[j]) {
+ // we need to find the shorter one,
+ // then calculate its area
+ i++;
+ } else {
+ j--;
+ }
}
+ return max;
}
- return max;
}
}
diff --git a/src/main/java/com/fishercoder/solutions/_110.java b/src/main/java/com/fishercoder/solutions/_110.java
index 2fee5112a0..c3c8b0d3dc 100644
--- a/src/main/java/com/fishercoder/solutions/_110.java
+++ b/src/main/java/com/fishercoder/solutions/_110.java
@@ -3,13 +3,39 @@
import com.fishercoder.common.classes.TreeNode;
/**
+ * 110. Balanced Binary Tree
+ *
* Given a binary tree, determine if it is height-balanced.
+ * For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.
- For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.*/
+ Example 1:
+ Given the following tree [3,9,20,null,null,15,7]:
+
+ 3
+ / \
+ 9 20
+ / \
+ 15 7
+
+ Return true.
+
+ Example 2:
+ Given the following tree [1,2,2,3,3,null,null,4,4]:
+
+ 1
+ / \
+ 2 2
+ / \
+ 3 3
+/ \
+4 4
+
+ Return false.
+ */
public class _110 {
- class Solution1 {
+ public static class Solution1 {
//recursively get the height of each subtree of each node, compare their difference, if greater than 1, then return false
//although this is working, but it's not efficient, since it repeatedly computes the heights of each node every time
//Its time complexity is O(n^2).
@@ -34,7 +60,7 @@ private int getH(TreeNode root) {
}
}
- class Solution2 {
+ public static class Solution2 {
public boolean isBalanced(TreeNode root) {
return getH(root) != -1;
@@ -59,4 +85,4 @@ private int getH(TreeNode root) {
}
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/com/fishercoder/solutions/_111.java b/src/main/java/com/fishercoder/solutions/_111.java
index fb40e2c01b..8bae3ba544 100644
--- a/src/main/java/com/fishercoder/solutions/_111.java
+++ b/src/main/java/com/fishercoder/solutions/_111.java
@@ -7,62 +7,56 @@
/**
* 111. Minimum Depth of Binary Tree
+ *
* Given a binary tree, find its minimum depth.
* The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node.
* */
public class _111 {
- /**
- * We can solve this problem using both BFS and DFS:
- * DFS is to visit every single root to leaf path and return the shortest one.
- * BFS is to visit every level and return whenever we find the first leaf node.
- */
-
- public static class DFSSolution {
-
- public int minDepth(TreeNode root) {
- if (root == null) {
- return 0;
- }
- int left = minDepth(root.left);
- int right = minDepth(root.right);
- if (left == 0) {
- return right + 1;
- }
- if (right == 0) {
- return left + 1;
- }
- return Math.min(left, right) + 1;
+ public static class Solution1 {
+ /**DFS*/
+ public int minDepth(TreeNode root) {
+ if (root == null) {
+ return 0;
}
-
+ int left = minDepth(root.left);
+ int right = minDepth(root.right);
+ if (left == 0) {
+ return right + 1;
+ }
+ if (right == 0) {
+ return left + 1;
+ }
+ return Math.min(left, right) + 1;
+ }
}
- public static class BFSSolution {
-
- public int minDepth_BFS(TreeNode root) {
- if (root == null) {
- return 0;
- }
- Queue q = new LinkedList();
- q.offer(root);
- int level = 0;
- while (!q.isEmpty()) {
- level++;
- int size = q.size();
- for (int i = 0; i < size; i++) {
- TreeNode curr = q.poll();
- if (curr.left != null) {
- q.offer(curr.left);
- }
- if (curr.right != null) {
- q.offer(curr.right);
- }
- if (curr.left == null && curr.right == null) {
- return level;
- }
- }
- }
+ public static class Solution2 {
+ /**BFS*/
+ public int minDepth(TreeNode root) {
+ if (root == null) {
+ return 0;
+ }
+ Queue q = new LinkedList();
+ q.offer(root);
+ int level = 0;
+ while (!q.isEmpty()) {
+ level++;
+ int size = q.size();
+ for (int i = 0; i < size; i++) {
+ TreeNode curr = q.poll();
+ if (curr.left != null) {
+ q.offer(curr.left);
+ }
+ if (curr.right != null) {
+ q.offer(curr.right);
+ }
+ if (curr.left == null && curr.right == null) {
return level;
+ }
}
+ }
+ return level;
}
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_112.java b/src/main/java/com/fishercoder/solutions/_112.java
index 717d1b1aeb..138fa5d325 100644
--- a/src/main/java/com/fishercoder/solutions/_112.java
+++ b/src/main/java/com/fishercoder/solutions/_112.java
@@ -2,11 +2,14 @@
import com.fishercoder.common.classes.TreeNode;
-/**112. Path Sum
+/**
+ * 112. Path Sum
+
Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.
For example:
Given the below binary tree and sum = 22,
+
5
/ \
4 8
@@ -14,16 +17,18 @@
11 13 4
/ \ \
7 2 1
-return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22.*/
+
+ return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22.*/
public class _112 {
+ public static class Solution1 {
public boolean hasPathSum(TreeNode root, int sum) {
- if (root == null) {
- return false;
- }
- if (root.val == sum && root.left == null && root.right == null) {
- return true;
- }
- return hasPathSum(root.left, sum - root.val) || hasPathSum(root.right, sum - root.val);
+ if (root == null) {
+ return false;
+ }
+ if (root.val == sum && root.left == null && root.right == null) {
+ return true;
+ }
+ return hasPathSum(root.left, sum - root.val) || hasPathSum(root.right, sum - root.val);
}
-
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_113.java b/src/main/java/com/fishercoder/solutions/_113.java
index afa0bb7a34..e3b328c408 100644
--- a/src/main/java/com/fishercoder/solutions/_113.java
+++ b/src/main/java/com/fishercoder/solutions/_113.java
@@ -5,8 +5,10 @@
import java.util.ArrayList;
import java.util.List;
-/**113. Path Sum II
-Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum.
+/**
+ * 113. Path Sum II
+
+ Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum.
For example:
Given the below binary tree and sum = 22,
@@ -17,7 +19,8 @@
11 13 4
/ \ / \
7 2 5 1
-return
+
+ return
[
[5,4,11,2],
[5,8,4,5]
@@ -25,30 +28,31 @@
*/
public class _113 {
+ public static class Solution1 {
public List> pathSum(TreeNode root, int sum) {
- List> allPaths = new ArrayList();
- if (root == null) {
- return allPaths;
- }
- dfs(root, new ArrayList(), allPaths, sum);
+ List> allPaths = new ArrayList();
+ if (root == null) {
return allPaths;
+ }
+ dfs(root, new ArrayList(), allPaths, sum);
+ return allPaths;
}
-
private void dfs(TreeNode root, List path, List> allPaths, int sum) {
- path.add(root.val);
- if (root.left != null) {
- dfs(root.left, path, allPaths, sum - root.val);
- }
- if (root.right != null) {
- dfs(root.right, path, allPaths, sum - root.val);
- }
- if (root.left == null && root.right == null) {
- /**Check if sum equals root.val, not sum equals zero!*/
- if (sum == root.val) {
- allPaths.add(new ArrayList(path));
- }
+ path.add(root.val);
+ if (root.left != null) {
+ dfs(root.left, path, allPaths, sum - root.val);
+ }
+ if (root.right != null) {
+ dfs(root.right, path, allPaths, sum - root.val);
+ }
+ if (root.left == null && root.right == null) {
+ /**Check if sum equals root.val, not sum equals zero!*/
+ if (sum == root.val) {
+ allPaths.add(new ArrayList(path));
}
- path.remove(path.size() - 1);
+ }
+ path.remove(path.size() - 1);
}
-}
\ No newline at end of file
+ }
+}
diff --git a/src/main/java/com/fishercoder/solutions/_114.java b/src/main/java/com/fishercoder/solutions/_114.java
index d99b5012d7..327766b73d 100644
--- a/src/main/java/com/fishercoder/solutions/_114.java
+++ b/src/main/java/com/fishercoder/solutions/_114.java
@@ -3,6 +3,8 @@
import com.fishercoder.common.classes.TreeNode;
/**
+ * 114. Flatten Binary Tree to Linked List
+ *
* Given a binary tree, flatten it to a linked list in-place.
For example,
@@ -13,6 +15,7 @@
2 5
/ \ \
3 4 6
+
The flattened tree should look like:
1
\
@@ -31,31 +34,20 @@
*/
public class _114 {
- public void flatten(TreeNode root) {
- while (root != null) {
- if (root.left != null) {
- TreeNode previousNode = root.left;
- while (previousNode.right != null) {
- previousNode = previousNode.right;
+ public static class Solution1 {
+ public void flatten(TreeNode root) {
+ while (root != null) {
+ if (root.left != null) {
+ TreeNode previousNode = root.left;
+ while (previousNode.right != null) {
+ previousNode = previousNode.right;
+ }
+ previousNode.right = root.right;
+ root.right = root.left;
+ root.left = null;
}
- previousNode.right = root.right;
- root.right = root.left;
- root.left = null;
+ root = root.right;
}
- root = root.right;
}
}
-
- public static void main(String... args) {
- TreeNode root = new TreeNode(1);
- root.left = new TreeNode(2);
- root.left.left = new TreeNode(3);
- root.left.right = new TreeNode(4);
- root.right = new TreeNode(5);
- root.right.right = new TreeNode(6);
-
- _114 test = new _114();
- test.flatten(root);
- }
-
}
diff --git a/src/main/java/com/fishercoder/solutions/_115.java b/src/main/java/com/fishercoder/solutions/_115.java
index 62f8dc3eee..e993375fc8 100644
--- a/src/main/java/com/fishercoder/solutions/_115.java
+++ b/src/main/java/com/fishercoder/solutions/_115.java
@@ -1,42 +1,44 @@
package com.fishercoder.solutions;
-public class _115 {
- /**This is a typical DP problem, illustrated in Jiuzhang.
- *
- * I've drawn out the 2d matrix on the whiteboard:
- *
- * 1. initialize a 2d matrix of size (m+1)*(n+1)
- * 2. initialize row 0, it should be 1,0,0,0,0... this is because when S is an empty string, only when T is empty, it could be a subsequence
- * 3. initialize column 0, it should be 1,1,1,1,1,1...
- * 4. starting from (1,1)*/
+/**
+ * 115. Distinct Subsequences
+ *
+ * Given a string S and a string T, count the number of distinct subsequences of S which equals T. A
+ * subsequence of a string is a new string which is formed from the original string by deleting some
+ * (can be none) of the characters without disturbing the relative positions of the remaining
+ * characters. (ie, "ACE" is a subsequence of "ABCDE" while "AEC" is not).
+ *
+ * Here is an example: S = "rabbbit", T = "rabbit" Return 3.
+ */
+public class _115 {
+ public static class Solution1 {
public int numDistinct(String s, String t) {
- int m = s.length();
- int n = t.length();
- int[][] dp = new int[m + 1][n + 1];
+ int m = s.length();
+ int n = t.length();
+ int[][] dp = new int[m + 1][n + 1];
- char[] schar = s.toCharArray();
- char[] tchar = t.toCharArray();
+ char[] schar = s.toCharArray();
+ char[] tchar = t.toCharArray();
- for (int i = 0; i <= m; i++) {
- dp[i][0] = 1;
- }
+ for (int i = 0; i <= m; i++) {
+ dp[i][0] = 1;
+ }
- for (int j = 1; j <= n; j++) {
- dp[0][j] = 0;
- }
+ for (int j = 1; j <= n; j++) {
+ dp[0][j] = 0;
+ }
- for (int i = 1; i <= m; i++) {
- for (int j = 1; j <= n; j++) {
- if (schar[i - 1] == tchar[j - 1]) {
- dp[i][j] = dp[i - 1][j] + dp[i - 1][j - 1];
- } else {
- dp[i][j] = dp[i - 1][j];
- }
- }
+ for (int i = 1; i <= m; i++) {
+ for (int j = 1; j <= n; j++) {
+ if (schar[i - 1] == tchar[j - 1]) {
+ dp[i][j] = dp[i - 1][j] + dp[i - 1][j - 1];
+ } else {
+ dp[i][j] = dp[i - 1][j];
+ }
}
-
- return dp[m][n];
+ }
+ return dp[m][n];
}
-
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_116.java b/src/main/java/com/fishercoder/solutions/_116.java
index c1e4b8bdd1..6dbb24551c 100644
--- a/src/main/java/com/fishercoder/solutions/_116.java
+++ b/src/main/java/com/fishercoder/solutions/_116.java
@@ -2,7 +2,10 @@
import com.fishercoder.common.classes.TreeLinkNode;
-/** Given a binary tree
+/**
+ * 116. Populating Next Right Pointers in Each Node
+
+ Given a binary tree
struct TreeLinkNode {
TreeLinkNode *left;
@@ -24,60 +27,55 @@ You may assume that it is a perfect binary tree (ie, all leaves are at the same
2 3
/ \ / \
4 5 6 7
+
After calling your function, the tree should look like:
1 -> NULL
/ \
2 -> 3 -> NULL
/ \ / \
- 4->5->6->7 -> NULL */
+ 4->5->6->7 -> NULL
+ */
public class _116 {
- //credit: https://discuss.leetcode.com/topic/1106/o-1-space-o-n-complexity-iterative-solution
- //based on level order traversal
- public static void connect(TreeLinkNode root) {
+ public static class Solution1 {
+ /**
+ * credit: https://discuss.leetcode.com/topic/1106/o-1-space-o-n-complexity-iterative-solution
+ * based on level order traversal
+ */
+ public void connect(TreeLinkNode root) {
- TreeLinkNode head = null; //head of the next level
- TreeLinkNode prev = null; //the leading node on the next level
- TreeLinkNode curr = root; //current node of current level
+ TreeLinkNode head = null; //head of the next level
+ TreeLinkNode prev = null; //the leading node on the next level
+ TreeLinkNode curr = root; //current node of current level
- while (curr != null) {
- while (curr != null) { //iterate on the current level
- //left child
- if (curr.left != null) {
- if (prev != null) {
- prev.next = curr.left;
- } else {
- head = curr.left;
- }
- prev = curr.left;
- }
- //right child
- if (curr.right != null) {
- if (prev != null) {
- prev.next = curr.right;
- } else {
- head = curr.right;
- }
- prev = curr.right;
- }
- //move to next node
- curr = curr.next;
+ while (curr != null) {
+ while (curr != null) { //iterate on the current level
+ //left child
+ if (curr.left != null) {
+ if (prev != null) {
+ prev.next = curr.left;
+ } else {
+ head = curr.left;
+ }
+ prev = curr.left;
+ }
+ //right child
+ if (curr.right != null) {
+ if (prev != null) {
+ prev.next = curr.right;
+ } else {
+ head = curr.right;
}
- //move to next level
- curr = head;
- head = null;
- prev = null;
+ prev = curr.right;
+ }
+ //move to next node
+ curr = curr.next;
}
-
- }
-
- public static void main(String... args) {
- TreeLinkNode root = new TreeLinkNode(1);
- root.left = new TreeLinkNode(2);
- root.right = new TreeLinkNode(3);
- root.left.left = new TreeLinkNode(4);
- root.left.right = new TreeLinkNode(5);
- root.right.right = new TreeLinkNode(7);
- connect(root);
+ //move to next level
+ curr = head;
+ head = null;
+ prev = null;
+ }
}
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_117.java b/src/main/java/com/fishercoder/solutions/_117.java
index 6aea5ee6c6..50bc950af3 100644
--- a/src/main/java/com/fishercoder/solutions/_117.java
+++ b/src/main/java/com/fishercoder/solutions/_117.java
@@ -3,9 +3,10 @@
import com.fishercoder.common.classes.TreeLinkNode;
/**
- * /* Follow up for problem "Populating Next Right Pointers in Each Node".
-
- What if the given tree could be any binary tree? Would your previous solution still work?
+ * 117. Populating Next Right Pointers in Each Node II
+ *
+ * Follow up for problem "Populating Next Right Pointers in Each Node".
+ * What if the given tree could be any binary tree? Would your previous solution still work?
Note:
@@ -25,56 +26,45 @@
4-> 5 -> 7 -> NULL */
public class _117 {
- //copied this post: https://discuss.leetcode.com/topic/1106/o-1-space-o-n-complexity-iterative-solution
- //very clever and concise to make it in O(1) space
-
- //based on level order traversal
- public static void connect(TreeLinkNode root) {
+ public static class Solution1 {
+ /**credit: https://discuss.leetcode.com/topic/1106/o-1-space-o-n-complexity-iterative-solution
+ O(1) space, based on level order traversal*/
+ public void connect(TreeLinkNode root) {
- TreeLinkNode head = null; //head of the next level
- TreeLinkNode prev = null; //the leading node on the next level
- TreeLinkNode cur = root; //current node of current level
+ TreeLinkNode head = null; //head of the next level
+ TreeLinkNode prev = null; //the leading node on the next level
+ TreeLinkNode cur = root; //current node of current level
- while (cur != null) {
+ while (cur != null) {
- while (cur != null) { //iterate on the current level
- //left child
- if (cur.left != null) {
- if (prev != null) {
- prev.next = cur.left;
- } else {
- head = cur.left;
+ while (cur != null) { //iterate on the current level
+ //left child
+ if (cur.left != null) {
+ if (prev != null) {
+ prev.next = cur.left;
+ } else {
+ head = cur.left;
+ }
+ prev = cur.left;
}
- prev = cur.left;
- }
- //right child
- if (cur.right != null) {
- if (prev != null) {
- prev.next = cur.right;
- } else {
- head = cur.right;
+ //right child
+ if (cur.right != null) {
+ if (prev != null) {
+ prev.next = cur.right;
+ } else {
+ head = cur.right;
+ }
+ prev = cur.right;
}
- prev = cur.right;
+ //move to next node
+ cur = cur.next;
}
- //move to next node
- cur = cur.next;
- }
- //move to next level
- cur = head;
- head = null;
- prev = null;
+ //move to next level
+ cur = head;
+ head = null;
+ prev = null;
+ }
}
-
- }
-
- public static void main(String... args) {
- TreeLinkNode root = new TreeLinkNode(1);
- root.left = new TreeLinkNode(2);
- root.right = new TreeLinkNode(3);
- root.left.left = new TreeLinkNode(4);
- root.left.right = new TreeLinkNode(5);
- root.right.right = new TreeLinkNode(7);
- connect(root);
}
}
diff --git a/src/main/java/com/fishercoder/solutions/_118.java b/src/main/java/com/fishercoder/solutions/_118.java
index 27f5d8599f..64b32d0fa3 100644
--- a/src/main/java/com/fishercoder/solutions/_118.java
+++ b/src/main/java/com/fishercoder/solutions/_118.java
@@ -1,6 +1,5 @@
package com.fishercoder.solutions;
-
import java.util.ArrayList;
import java.util.List;
@@ -22,24 +21,26 @@
*/
public class _118 {
+ public static class Solution1 {
public List> generate(int numRows) {
- List> result = new ArrayList();
- int len = 1;
- for (int i = 0; i < numRows; i++) {
- List row = new ArrayList(len);
- row.add(1);
- if (i > 0) {
- List lastRow = result.get(i - 1);
- for (int j = 1; j < len; j++) {
- if (j < lastRow.size()) {
- row.add(lastRow.get(j - 1) + lastRow.get(j));
- }
- }
- row.add(1);
+ List> result = new ArrayList();
+ int len = 1;
+ for (int i = 0; i < numRows; i++) {
+ List row = new ArrayList(len);
+ row.add(1);
+ if (i > 0) {
+ List lastRow = result.get(i - 1);
+ for (int j = 1; j < len; j++) {
+ if (j < lastRow.size()) {
+ row.add(lastRow.get(j - 1) + lastRow.get(j));
}
- result.add(row);
- len++;
+ }
+ row.add(1);
}
- return result;
+ result.add(row);
+ len++;
+ }
+ return result;
}
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_119.java b/src/main/java/com/fishercoder/solutions/_119.java
index db7f0988ce..f79b6c4c8b 100644
--- a/src/main/java/com/fishercoder/solutions/_119.java
+++ b/src/main/java/com/fishercoder/solutions/_119.java
@@ -1,6 +1,5 @@
package com.fishercoder.solutions;
-
import java.util.ArrayList;
import java.util.List;
@@ -17,40 +16,40 @@ Could you optimize your algorithm to use only O(k) extra space?
public class _119 {
- public static class Solution1 {
- public List getRow(int rowIndex) {
- if (rowIndex < 0) {
- return new ArrayList();
- }
- List> result = new ArrayList();
- List row = new ArrayList();
- row.add(1);
- result.add(row);
- for (int i = 1; i <= rowIndex; i++) {
- List newRow = new ArrayList();
- newRow.add(1);
- List lastRow = result.get(i - 1);
- for (int j = 1; j < lastRow.size(); j++) {
- newRow.add(lastRow.get(j - 1) + lastRow.get(j));
- }
- newRow.add(1);
- result.add(newRow);
- }
- return result.get(result.size() - 1);
+ public static class Solution1 {
+ public List getRow(int rowIndex) {
+ if (rowIndex < 0) {
+ return new ArrayList();
+ }
+ List> result = new ArrayList();
+ List row = new ArrayList();
+ row.add(1);
+ result.add(row);
+ for (int i = 1; i <= rowIndex; i++) {
+ List newRow = new ArrayList();
+ newRow.add(1);
+ List lastRow = result.get(i - 1);
+ for (int j = 1; j < lastRow.size(); j++) {
+ newRow.add(lastRow.get(j - 1) + lastRow.get(j));
}
+ newRow.add(1);
+ result.add(newRow);
+ }
+ return result.get(result.size() - 1);
}
-
- public static class SolutionOkSpace {
- public List getRow(int rowIndex) {
- List row = new ArrayList<>();
- for (int i = 0; i < rowIndex + 1; i++) {
- row.add(0, 1);
- for (int j = 1; j < row.size() - 1; j++) {
- row.set(j, row.get(j) + row.get(j + 1));
- }
- }
- return row;
+ }
+
+ public static class Solution2 {
+ /** O(k) space */
+ public List getRow(int rowIndex) {
+ List row = new ArrayList<>();
+ for (int i = 0; i < rowIndex + 1; i++) {
+ row.add(0, 1);
+ for (int j = 1; j < row.size() - 1; j++) {
+ row.set(j, row.get(j) + row.get(j + 1));
}
+ }
+ return row;
}
-
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_12.java b/src/main/java/com/fishercoder/solutions/_12.java
index a63e0269c8..1310b7cddd 100644
--- a/src/main/java/com/fishercoder/solutions/_12.java
+++ b/src/main/java/com/fishercoder/solutions/_12.java
@@ -1,17 +1,21 @@
package com.fishercoder.solutions;
/**
+ * 12. Integer to Roman
+ *
* Given an integer, convert it to a roman numeral.
* Input is guaranteed to be within the range from 1 to 3999.
*/
public class _12 {
- //looked at this post: https://discuss.leetcode.com/topic/12384/simple-solution
- public String intToRoman(int num) {
- String[] M = new String[]{"", "m", "MM", "MMM"};
- String[] C = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
- String[] X = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
- String[] I = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
- return M[num / 1000] + C[(num % 1000) / 100] + X[(num % 100) / 10] + I[num % 10];
+
+ public static class Solution1 {
+ public String intToRoman(int num) {
+ String[] M = new String[]{"", "M", "MM", "MMM"};
+ String[] C = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
+ String[] X = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
+ String[] I = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
+ return M[num / 1000] + C[(num % 1000) / 100] + X[(num % 100) / 10] + I[num % 10];
+ }
}
}
diff --git a/src/main/java/com/fishercoder/solutions/_120.java b/src/main/java/com/fishercoder/solutions/_120.java
index f9a3276c47..3d44f0fac4 100644
--- a/src/main/java/com/fishercoder/solutions/_120.java
+++ b/src/main/java/com/fishercoder/solutions/_120.java
@@ -1,10 +1,11 @@
package com.fishercoder.solutions;
-import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
-/**Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.
+/**
+ * 120. Triangle
+
+ Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.
For example, given the following triangle
[
@@ -17,31 +18,22 @@
Note:
Bonus point if you are able to do this using only O(n) extra space, where n is the total number of rows in the triangle.*/
-public class _120 {
- public static int minimumTotal(List> triangle) {
- /**https://discuss.leetcode.com/topic/1669/dp-solution-for-triangle, @stellari has a very excellent explanation.
- * Basically, we use the bottom-up approach, starting from the bottom row of this triangle, and we only need to store the shortest path of each node
- * from its last row, and keep overwriting it until we reach the top.*/
- int n = triangle.size();
- List cache = triangle.get(n - 1);
-
- for (int layer = n - 2; layer >= 0; layer--) {
- //for each layer
- for (int i = 0; i <= layer; i++) {
- //check its very node
- int value = Math.min(cache.get(i), cache.get(i + 1)) + triangle.get(layer).get(i);
- cache.set(i, value);
- }
+public class _120 {
+ public static class Solution1 {
+ public int minimumTotal(List> triangle) {
+ int n = triangle.size();
+ List cache = triangle.get(n - 1);
+
+ for (int layer = n - 2; layer >= 0; layer--) {
+ //for each layer
+ for (int i = 0; i <= layer; i++) {
+ //check its very node
+ int value = Math.min(cache.get(i), cache.get(i + 1)) + triangle.get(layer).get(i);
+ cache.set(i, value);
}
- return cache.get(0);
+ }
+ return cache.get(0);
}
-
- public static void main(String... strings) {
- List> triangle = new ArrayList();
- triangle.add(Arrays.asList(1));
- triangle.add(Arrays.asList(2, 3));
- System.out.println(minimumTotal(triangle));
- }
-
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_121.java b/src/main/java/com/fishercoder/solutions/_121.java
index 5e56560081..5fb350fa71 100644
--- a/src/main/java/com/fishercoder/solutions/_121.java
+++ b/src/main/java/com/fishercoder/solutions/_121.java
@@ -2,55 +2,47 @@
/**
* 121. Best Time to Buy and Sell Stock
- *
+ *
* Say you have an array for which the ith element is the price of a given stock on day i.
- *
+ *
* If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock),
* design an algorithm to find the maximum profit.
- *
+ *
* Example 1:
* Input: [7, 1, 5, 3, 6, 4]
* Output: 5
- *
+ *
* max. difference = 6-1 = 5 (not 7-1 = 6, as selling price needs to be larger than buying price)
- *
- *
+ *
* Example 2:
* Input: [7, 6, 4, 3, 1]
* Output: 0
- *
+ *
* In this case, no transaction is done, i.e. max profit = 0.
*/
public class _121 {
- /**Pretty straightforward, sell before you buy, keep a global maxProfit variable, update it along the way if necessary.*/
-
- /**
- * The key here is that you'll have to buy first, before you can sell.
- * That means, if the lower price comes after a higher price, their combination won't work! Since you cannot sell first
- * before you buy it.
- */
- public int maxProfit(int[] prices) {
- if (prices == null || prices.length < 2) {
- return 0;
- }
- int minBuy = prices[0];
- int maxSell = prices[1];
- int maxProfit = (maxSell - minBuy) > 0 ? (maxSell - minBuy) : 0;
- for (int i = 1; i < prices.length; i++) {
- minBuy = Math.min(minBuy, prices[i]);
- maxProfit = Math.max(maxProfit, prices[i] - minBuy);
+ public static class Solution1 {
+ /**
+ * The key here is that you'll have to buy first, before you can sell. That means, if the lower
+ * price comes after a higher price, their combination won't work! Since you cannot sell first
+ * before you buy it.
+ */
+ public int maxProfit(int[] prices) {
+ if (prices == null || prices.length == 0) {
+ return 0;
+ }
+ int buy = prices[0];
+ int maxProfit = 0;
+ for (int i = 1; i < prices.length; i++) {
+ if (prices[i] < buy) {
+ buy = prices[i];
+ } else {
+ maxProfit = Math.max(maxProfit, prices[i] - buy);
+ }
+ }
+ return maxProfit;
}
- return maxProfit;
- }
-
- public static void main(String... strings) {
-// int[] prices = new int[]{7,1,5,3,6,4};
-// int[] prices = new int[]{7,6,4,3,1};
-// int[] prices = new int[]{2,4,1};
- int[] prices = new int[]{1, 2};
- _121 test = new _121();
- System.out.println(test.maxProfit(prices));
}
}
diff --git a/src/main/java/com/fishercoder/solutions/_122.java b/src/main/java/com/fishercoder/solutions/_122.java
index 0dc72c8366..e7707f2f9c 100644
--- a/src/main/java/com/fishercoder/solutions/_122.java
+++ b/src/main/java/com/fishercoder/solutions/_122.java
@@ -1,21 +1,45 @@
package com.fishercoder.solutions;
-/**Say you have an array for which the ith element is the price of a given stock on day i.
+/**
+ * 122. Best Time to Buy and Sell Stock II
+ *
+ * Say you have an array for which the ith element is the price of a given stock on day i.
+ * Design an algorithm to find the maximum profit. You may complete as many transactions as you like
+ * (ie, buy one and sell one share of the stock multiple times).
+ * However, you may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
+ * */
- Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times). However, you may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).*/
public class _122 {
-
- /**
- * It turns out to be a super simple one, it's really a greedy one! Just keep being greedy if it's possible.
- */
- public int maxProfit(int[] prices) {
- int pro = 0;
- for (int i = 0; i < prices.length - 1; i++) {
- if (prices[i + 1] > prices[i]) {
- pro += prices[i + 1] - prices[i];
+ public static class Solution1 {
+ //peak and valley approach
+ public int maxProfit(int[] prices) {
+ int pro = 0;
+ int i = 0;
+ while (i < prices.length - 1) {
+ while (i < prices.length - 1 && prices[i] >= prices[i + 1]) {
+ i++;
+ }
+ int valley = prices[i];
+ while (i < prices.length - 1 && prices[i] <= prices[i + 1]) {
+ i++;
+ }
+ int peak = prices[i];
+ pro += peak - valley;
}
+ return pro;
}
- return pro;
}
+ public static class Solution2 {
+ //simple one pass approach: the above solution could be simplied as below
+ public int maxProfit(int[] prices) {
+ int pro = 0;
+ for (int i = 0; i < prices.length - 1; i++) {
+ if (prices[i + 1] > prices[i]) {
+ pro += prices[i + 1] - prices[i];
+ }
+ }
+ return pro;
+ }
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_123.java b/src/main/java/com/fishercoder/solutions/_123.java
index 229cb7ba54..4ec308124d 100644
--- a/src/main/java/com/fishercoder/solutions/_123.java
+++ b/src/main/java/com/fishercoder/solutions/_123.java
@@ -1,144 +1,31 @@
package com.fishercoder.solutions;
-
-/**123. Best Time to Buy and Sell Stock III
-Say you have an array for which the ith element is the price of a given stock on day i.
-
-Design an algorithm to find the maximum profit. You may complete at most two transactions.
+/**
+ * 123. Best Time to Buy and Sell Stock III
+ *
+ * Say you have an array for which the ith element is the price of a given stock on day i.
+ * Design an algorithm to find the maximum profit. You may complete at most two transactions.
Note:
-You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).*/
-public class _123 {
-
- //this is a very clear solution and very highly upvoted in Discuss, but not extensibel to K solution.
- public int maxProfit(int[] prices) {
- if (prices.length < 2) {
- return 0;
- }
- int buy1 = Integer.MIN_VALUE;
- int buy2 = Integer.MIN_VALUE;//we use negative numbers to denote buy1 and buy2, thus use Integer.MIN_VALUE here is more convenient.
- int sell1 = 0;
- int sell2 = 0;
- for (int i = 0; i < prices.length; i++) {
- buy1 = Math.max(buy1, -prices[i]);
- sell1 = Math.max(sell1, buy1 + prices[i]);
- buy2 = Math.max(buy2, sell1 - prices[i]);
- sell2 = Math.max(sell2, buy2 + prices[i]);
- }
- return sell2;
- }
-
- //this one could make it AC'ed on OJ, but when I use this one to BestTimeToBuyAndSellStockIV, it got Memory Limit Exceeded.
- //this one is optimized from maxProfit_optimized() below
- public int maxProfit_optimized(int[] prices) {
- if (prices.length < 2) {
- return 0;
- }
- int K = 2;
- int[][] dp = new int[K + 1][prices.length];
- for (int i = 1; i <= K; i++) {
- int maxDiff = -prices[0];
- for (int j = 1; j < prices.length; j++) {
- dp[i][j] = Math.max(dp[i][j - 1], prices[j] + maxDiff);
- maxDiff = Math.max(maxDiff, dp[i - 1][j] - prices[j]);
- }
- }
- return dp[K][prices.length - 1];
- }
+You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
+ */
- //
- public int maxProfit_TLE(int[] prices) {
- /**
- * Thanks to this post: https://discuss.leetcode.com/topic/4766/a-clean-dp-solution-which-generalizes-to-k-transactions/29
- * and Tushar's video:https://www.youtube.com/watch?v=oDhu5uGq_ic&feature=youtu.be
- *
- * use this dp strategy:
- *
- * dp[i][j] = Math.max(dp[i][j-1], (prices[i] - prices[m]) + dp[i-1][m]) with m in (0, j-1)
- * row is price
- * column is day
- * dp[i][j] means the max profit you can make on day j by doing a max of i transactions.
- *
- * dp[i][j-1]
- * means no transaction on day j, so the max profit you could get is on the previous day j-1
- *
- * (prices[i] - prices[m]) + dp[i-1][m]
- * (prices[i] - prices[m]) means you'll sell on day j, this means you'll do one transaction on day j with sell price: prices[m],
- * and the buy price could be any price that is on the day prior to day j, we call it day m, thus m is
- * in this range: (0, j-1)
- * dp[i-1][m] means you'll have i-1 transaction to do on day m to make up to i transactions, since you do one transaction on day j, that's why
- * we deduct 1 from i
- *
- * */
- if (prices.length < 2) {
- return 0;
- } else {
- /**First row should be zero because it means, you're allowed to make ZERO transaction, so no profit
- * First column should be zero because it means, on day ZERO, you could only buy and make no profit*/
- int K = 2;//number of allowed transactions.
- int[][] dp = new int[K + 1][prices.length];
- for (int i = 1; i <= K; i++) {
- for (int j = 1; j < prices.length; j++) {
- int maxProfitOnDayJ = 0;
- for (int m = 0; m < j; m++) {
- maxProfitOnDayJ = Math.max(maxProfitOnDayJ, prices[j] - prices[m] + dp[i - 1][m]);
- }
- dp[i][j] = Math.max(dp[i][j - 1], maxProfitOnDayJ);
- }
- }
- return dp[K][prices.length - 1];
- }
- }
-
- public static void main(String... strings) {
-// int[] prices = new int[]{6,1,3,2,4,7};
-// int[] prices = new int[]{1,2,4,2,5,7,2,4,9,0};//(7-2)+(9-2) = 5+7 = 12 is wrong, it should be (7-1)+(9-2) = 6+7 = 13
- int[] prices = new int[]{2, 5, 7, 1, 4, 3, 1, 3};
- _123 test = new _123();
- System.out.println(test.maxProfit(prices));
- }
-
- /**
- * I try to find the regional max price, then compute the profit, but failed at this test case:
- * 1,2,4,2,5,7,2,4,9,0
- */
- public int maxProfit_2nd_attempt(int[] prices) {
- int[] profits = new int[2];
- boolean flip = false;
- for (int i = 1; i < prices.length; i++) {
- int buyPrice = prices[i - 1];
- if (prices[i] > prices[i - 1]) {
- flip = true;
- }
- while (i < prices.length && prices[i] > prices[i - 1]) {
- i++;
- }
- if (flip) {
- i--;
- }
- int profit = prices[i] - buyPrice;
- //update the smaller profit in profits array
- int smallerIndex = profits[0] < profits[1] ? 0 : 1;
- profits[smallerIndex] = Math.max(profits[smallerIndex], profit);
- flip = false;
- }
- return profits[0] + profits[1];
- }
+public class _123 {
- /**
- * Greedy approach won't work like Best Time to Buy and Sell Stock II because:
- * 1. we need to track a regional min buy price instead of just the previous one;
- * 2. we're allowed to do only TWO transactions.
- * e.g test case: 6,1,3,2,4,7
- */
- public int maxProfit_1st_attempt(int[] prices) {
- int[] profits = new int[2];
- for (int i = 1; i < prices.length; i++) {
- if (prices[i] > prices[i - 1]) {
- int smallerIndex = profits[0] > profits[1] ? 1 : 0;
- profits[smallerIndex] = Math.max(prices[i] - prices[i - 1], profits[smallerIndex]);
+ public static class Solution1 {
+ //this is a very clear solution and very highly upvoted in Discuss, but not extensible to K solution.
+ public int maxProfit(int[] prices) {
+ int buy1 = Integer.MIN_VALUE;
+ int buy2 = Integer.MIN_VALUE;
+ int sell1 = 0;
+ int sell2 = 0;
+ for (int i = 0; i < prices.length; i++) {
+ buy1 = Math.max(buy1, -prices[i]);
+ sell1 = Math.max(sell1, buy1 + prices[i]);
+ buy2 = Math.max(buy2, sell1 - prices[i]);
+ sell2 = Math.max(sell2, buy2 + prices[i]);
}
+ return sell2;
}
- return profits[0] + profits[1];
}
-}
+}
\ No newline at end of file
diff --git a/src/main/java/com/fishercoder/solutions/_124.java b/src/main/java/com/fishercoder/solutions/_124.java
index 98ff3e627a..2d30908531 100644
--- a/src/main/java/com/fishercoder/solutions/_124.java
+++ b/src/main/java/com/fishercoder/solutions/_124.java
@@ -2,9 +2,13 @@
import com.fishercoder.common.classes.TreeNode;
+import java.util.HashMap;
+import java.util.Map;
+
/**
- * Given a binary tree, find the maximum path sum.
+ * 124. Binary Tree Maximum Path Sum
+ Given a binary tree, find the maximum path sum.
For this problem, a path is defined as any sequence of nodes from some starting node to any node
in the tree along the parent-child connections.
@@ -21,24 +25,54 @@
*/
public class _124 {
+ public static class Solution1 {
int max = Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
- dfs(root);
- return max;
+ dfs(root);
+ return max;
}
private int dfs(TreeNode root) {
- if (root == null) {
- return 0;
- }
+ if (root == null) {
+ return 0;
+ }
- int left = Math.max(dfs(root.left), 0);
- int right = Math.max(dfs(root.right), 0);
+ int left = Math.max(dfs(root.left), 0);
+ int right = Math.max(dfs(root.right), 0);
- max = Math.max(max, root.val + left + right);
+ max = Math.max(max, root.val + left + right);
- return root.val + Math.max(left, right);
+ return root.val + Math.max(left, right);
}
+ }
+
+ public static class Solution2 {
+ /**
+ * This one uses a map to cache, but surprisingly, it's 10% slower than all submissions compared
+ * with solution1
+ */
+ int max = Integer.MIN_VALUE;
+ public int maxPathSum(TreeNode root) {
+ Map map = new HashMap<>();
+ dfs(root, map);
+ return max;
+ }
+
+ private int dfs(TreeNode root, Map map) {
+ if (root == null) {
+ return 0;
+ }
+ if (map.containsKey(root)) {
+ return map.get(root);
+ }
+ int left = Math.max(0, dfs(root.left, map));
+ int right = Math.max(0, dfs(root.right, map));
+ max = Math.max(max, root.val + left + right);
+ int pathSum = root.val + Math.max(left, right);
+ map.put(root, pathSum);
+ return pathSum;
+ }
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_125.java b/src/main/java/com/fishercoder/solutions/_125.java
index e34292831a..b849b4017b 100644
--- a/src/main/java/com/fishercoder/solutions/_125.java
+++ b/src/main/java/com/fishercoder/solutions/_125.java
@@ -1,6 +1,9 @@
package com.fishercoder.solutions;
-/**Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases.
+/**
+ * 125. Valid Palindrome
+
+ Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases.
For example,
"A man, a plan, a canal: Panama" is a palindrome.
@@ -8,28 +11,30 @@
Note:
Have you consider that the string might be empty? This is a good question to ask during an interview.
+ For the purpose of this problem, we define empty string as valid palindrome.
+ */
- For the purpose of this problem, we define empty string as valid palindrome.*/
public class _125 {
+ public static class Solution1 {
public boolean isPalindrome(String s) {
- int i = 0;
- int j = s.length() - 1;
- char[] chars = s.toCharArray();
- while (i < j) {
- while (i < j && !Character.isLetterOrDigit(chars[i])) {
- i++;
- }
- while (i < j && !Character.isLetterOrDigit(chars[j])) {
- j--;
- }
- if (Character.toLowerCase(chars[i]) != Character.toLowerCase(chars[j])) {
- return false;
- }
- i++;
- j--;
+ int i = 0;
+ int j = s.length() - 1;
+ char[] chars = s.toCharArray();
+ while (i < j) {
+ while (i < j && !Character.isLetterOrDigit(chars[i])) {
+ i++;
+ }
+ while (i < j && !Character.isLetterOrDigit(chars[j])) {
+ j--;
}
- return true;
+ if (Character.toLowerCase(chars[i]) != Character.toLowerCase(chars[j])) {
+ return false;
+ }
+ i++;
+ j--;
+ }
+ return true;
}
-
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_126.java b/src/main/java/com/fishercoder/solutions/_126.java
index 0d4e116d39..78427b71ec 100644
--- a/src/main/java/com/fishercoder/solutions/_126.java
+++ b/src/main/java/com/fishercoder/solutions/_126.java
@@ -1,6 +1,5 @@
package com.fishercoder.solutions;
-
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.HashMap;
@@ -11,9 +10,9 @@
/**
* 126. Word Ladder II
- *
- * Given two words (beginWord and endWord), and a dictionary's word list,
- * find all shortest transformation sequence(s) from beginWord to endWord, such that:
+
+ Given two words (beginWord and endWord), and a dictionary's word list,
+ find all shortest transformation sequence(s) from beginWord to endWord, such that:
Only one letter can be changed at a time
Each transformed word must exist in the word list. Note that beginWord is not a transformed word.
@@ -37,106 +36,109 @@
You may assume no duplicates in the word list.
You may assume beginWord and endWord are non-empty and are not the same.
*/
+
public class _126 {
- /**Reference: https://discuss.leetcode.com/topic/2857/share-two-similar-java-solution-that-accpted-by-oj*/
- Map> map;
- List> results;
+ public static class Solution1 {
+ /** Reference: https://discuss.leetcode.com/topic/2857/share-two-similar-java-solution-that-accpted-by-oj */
- public List> findLadders(String start, String end, List dict) {
- results = new ArrayList<>();
- if (dict.size() == 0) {
- return results;
- }
+ Map> map;
+ List> results;
- int min = Integer.MAX_VALUE;
+ public List> findLadders(String start, String end, List dict) {
+ results = new ArrayList<>();
+ if (dict.size() == 0) {
+ return results;
+ }
- Queue queue = new ArrayDeque<>();
- queue.add(start);
+ int min = Integer.MAX_VALUE;
- map = new HashMap<>();
+ Queue queue = new ArrayDeque<>();
+ queue.add(start);
- Map ladder = new HashMap<>();
- for (String string : dict) {
- ladder.put(string, Integer.MAX_VALUE);
- }
- ladder.put(start, 0);
+ map = new HashMap<>();
- dict.add(end);
- //BFS: Dijisktra search
- while (!queue.isEmpty()) {
+ Map ladder = new HashMap<>();
+ for (String string : dict) {
+ ladder.put(string, Integer.MAX_VALUE);
+ }
+ ladder.put(start, 0);
- String word = queue.poll();
+ dict.add(end);
+ //BFS: Dijisktra search
+ while (!queue.isEmpty()) {
- int step = ladder.get(word) + 1;//'step' indicates how many steps are needed to travel to one word.
+ String word = queue.poll();
- if (step > min) {
- break;
- }
+ int step = ladder.get(word)
+ + 1;//'step' indicates how many steps are needed to travel to one word.
- for (int i = 0; i < word.length(); i++) {
- StringBuilder builder = new StringBuilder(word);
- for (char ch = 'a'; ch <= 'z'; ch++) {
- builder.setCharAt(i, ch);
- String newWord = builder.toString();
- if (ladder.containsKey(newWord)) {
-
- if (step > ladder.get(newWord)) {
- //Check if it is the shortest path to one word.
- continue;
- } else if (step < ladder.get(newWord)) {
- queue.add(newWord);
- ladder.put(newWord, step);
- } else {
- // It is a KEY line. If one word already appeared in one ladder,
- // Do not insert the same word inside the queue twice. Otherwise it gets TLE.
- }
- if (map.containsKey(newWord)) {
- //Build adjacent Graph
- map.get(newWord).add(word);
- } else {
- List list = new LinkedList();
- list.add(word);
- map.put(newWord, list);
- //It is possible to write three lines in one:
- //map.put(new_word,new LinkedList(Arrays.asList(new String[]{word})));
- //Which one is better?
- }
+ if (step > min) {
+ break;
+ }
- if (newWord.equals(end)) {
- min = step;
+ for (int i = 0; i < word.length(); i++) {
+ StringBuilder builder = new StringBuilder(word);
+ for (char ch = 'a'; ch <= 'z'; ch++) {
+ builder.setCharAt(i, ch);
+ String newWord = builder.toString();
+ if (ladder.containsKey(newWord)) {
+
+ if (step > ladder.get(newWord)) {
+ //Check if it is the shortest path to one word.
+ continue;
+ } else if (step < ladder.get(newWord)) {
+ queue.add(newWord);
+ ladder.put(newWord, step);
+ } else {
+ // It is a KEY line. If one word already appeared in one ladder,
+ // Do not insert the same word inside the queue twice. Otherwise it gets TLE.
+ }
+ if (map.containsKey(newWord)) {
+ //Build adjacent Graph
+ map.get(newWord).add(word);
+ } else {
+ List list = new LinkedList();
+ list.add(word);
+ map.put(newWord, list);
+ //It is possible to write three lines in one:
+ //map.put(new_word,new LinkedList(Arrays.asList(new String[]{word})));
+ //Which one is better?
+ }
+
+ if (newWord.equals(end)) {
+ min = step;
+ }
}
-
+ //End if dict contains new_word
}
- //End if dict contains new_word
+ //End:Iteration from 'a' to 'z'
}
- //End:Iteration from 'a' to 'z'
+ //End:Iteration from the first to the last
}
- //End:Iteration from the first to the last
- }
- //End While
-
- //BackTracking
- LinkedList result = new LinkedList<>();
- backTrace(end, start, result);
+ //End While
- return results;
- }
+ //BackTracking
+ LinkedList result = new LinkedList<>();
+ backTrace(end, start, result);
- private void backTrace(String word, String start, List list) {
- if (word.equals(start)) {
- list.add(0, start);
- results.add(new ArrayList<>(list));
- list.remove(0);
- return;
+ return results;
}
- list.add(0, word);
- if (map.get(word) != null) {
- for (String s : map.get(word)) {
- backTrace(s, start, list);
+
+ private void backTrace(String word, String start, List list) {
+ if (word.equals(start)) {
+ list.add(0, start);
+ results.add(new ArrayList<>(list));
+ list.remove(0);
+ return;
+ }
+ list.add(0, word);
+ if (map.get(word) != null) {
+ for (String s : map.get(word)) {
+ backTrace(s, start, list);
+ }
}
+ list.remove(0);
}
- list.remove(0);
}
-
}
diff --git a/src/main/java/com/fishercoder/solutions/_127.java b/src/main/java/com/fishercoder/solutions/_127.java
index eb25bf9e29..5c2f4ed775 100644
--- a/src/main/java/com/fishercoder/solutions/_127.java
+++ b/src/main/java/com/fishercoder/solutions/_127.java
@@ -7,8 +7,7 @@
/**
* 127. Word Ladder
*
- * Given two words (beginWord and endWord),
- * and a dictionary's word list,
+ * Given two words (beginWord and endWord), and a dictionary's word list,
* find the length of shortest transformation sequence from beginWord to endWord, such that:
* Only one letter can be changed at a time.
* Each transformed word must exist in the word list. Note that beginWord is not a transformed word.
@@ -32,55 +31,47 @@
*/
public class _127 {
+ public static class Solution1 {
- /**this one https://discuss.leetcode.com/topic/29303/two-end-bfs-in-java-31ms fails by test case _127Test.test1().
- * All transformed words, including endWord must be in wordList.
- *
- * And we can share a visited set from both ends since we cannot remove word from dict.*/
- public int ladderLength(String beginWord, String endWord, List wordList) {
- Set beginSet = new HashSet<>();
- Set endSet = new HashSet<>();
- Set visited = new HashSet<>();
- Set dict = new HashSet<>(wordList);
- int len = 1;
+ public int ladderLength(String beginWord, String endWord, List wordList) {
+ Set beginSet = new HashSet<>();
+ Set endSet = new HashSet<>();
+ Set visited = new HashSet<>();
+ Set dict = new HashSet<>(wordList);
+ int len = 1;
- beginSet.add(beginWord);
+ beginSet.add(beginWord);
- if (dict.contains(endWord)) {
- endSet.add(endWord);
- }
-
- while (!beginSet.isEmpty() && !endSet.isEmpty()) {
- if (beginSet.size() > endSet.size()) {
- Set temp = beginSet;
- beginSet = endSet;
- endSet = temp;
+ if (dict.contains(endWord)) {
+ endSet.add(endWord);
}
- Set temp = new HashSet<>();
- for (String word : beginSet) {
- char[] chars = word.toCharArray();
- for (int i = 0; i < chars.length; i++) {
- for (char c = 'a'; c <= 'z'; c++) {
- char old = chars[i];
- chars[i] = c;
- String newWord = new String(chars);
- if (endSet.contains(newWord)) {
- return len + 1;
- }
+ while (!beginSet.isEmpty() && !endSet.isEmpty()) {
+ Set nextBeginSet = new HashSet<>();
+ for (String word : beginSet) {
+ char[] chars = word.toCharArray();
+ for (int i = 0; i < chars.length; i++) {
+ for (char c = 'a'; c <= 'z'; c++) {
+ char old = chars[i];
+ chars[i] = c;
+ String newWord = new String(chars);
+ if (endSet.contains(newWord)) {
+ return len + 1;
+ }
- if (!visited.contains(newWord) && dict.contains(newWord)) {
- visited.add(newWord);
- temp.add(newWord);
+ if (!visited.contains(newWord) && dict.contains(newWord)) {
+ visited.add(newWord);
+ nextBeginSet.add(newWord);
+ }
+ chars[i] = old;
}
- chars[i] = old;
}
}
- }
- beginSet = temp;
- len++;
+ beginSet = nextBeginSet;
+ len++;
+ }
+ return 0;
}
- return 0;
}
}
diff --git a/src/main/java/com/fishercoder/solutions/_128.java b/src/main/java/com/fishercoder/solutions/_128.java
index 0bd6e33dd3..f23cff3b54 100644
--- a/src/main/java/com/fishercoder/solutions/_128.java
+++ b/src/main/java/com/fishercoder/solutions/_128.java
@@ -6,7 +6,9 @@
import java.util.Set;
/**
- * Given an unsorted array of integers, find the length of the longest consecutive elements sequence.
+ * 128. Longest Consecutive Sequence
+
+ Given an unsorted array of integers, find the length of the longest consecutive elements sequence.
For example,
Given [100, 4, 200, 1, 3, 2],
@@ -15,99 +17,100 @@
Your algorithm should run in O(n) complexity.
*/
public class _128 {
- //inspired by this solution: https://discuss.leetcode.com/topic/29286/my-java-solution-using-unionfound
+ public static class Solution1 {
public int longestConsecutive(int[] nums) {
- Map map = new HashMap();
- //
- UnionFind uf = new UnionFind(nums);
- for (int i = 0; i < nums.length; i++) {
- if (map.containsKey(nums[i])) {
- continue;
- }
- map.put(nums[i], i);
- if (map.containsKey(nums[i] - 1)) {
- uf.union(i, map.get(nums[i] - 1));
- //note: we want to union this index and nums[i]-1's root index which we can get from the map
- }
- if (map.containsKey(nums[i] + 1)) {
- uf.union(i, map.get(nums[i] + 1));
- }
+ Map map = new HashMap();
+ //
+ UnionFind uf = new UnionFind(nums);
+ for (int i = 0; i < nums.length; i++) {
+ if (map.containsKey(nums[i])) {
+ continue;
+ }
+ map.put(nums[i], i);
+ if (map.containsKey(nums[i] - 1)) {
+ uf.union(i, map.get(nums[i] - 1));
+ //note: we want to union this index and nums[i]-1's root index which we can get from the map
}
- return uf.maxUnion();
+ if (map.containsKey(nums[i] + 1)) {
+ uf.union(i, map.get(nums[i] + 1));
+ }
+ }
+ return uf.maxUnion();
}
class UnionFind {
- int[] ids;
+ int[] ids;
- public UnionFind(int[] nums) {
- ids = new int[nums.length];
- for (int i = 0; i < nums.length; i++) {
- ids[i] = i;
- }
+ public UnionFind(int[] nums) {
+ ids = new int[nums.length];
+ for (int i = 0; i < nums.length; i++) {
+ ids[i] = i;
}
+ }
- public void union(int i, int j) {
- int x = find(ids, i);
- int y = find(ids, j);
- ids[x] = y;
- }
+ public void union(int i, int j) {
+ int x = find(ids, i);
+ int y = find(ids, j);
+ ids[x] = y;
+ }
- public int find(int[] ids, int i) {
- while (i != ids[i]) {
- ids[i] = ids[ids[i]];
- i = ids[i];
- }
- return i;
+ public int find(int[] ids, int i) {
+ while (i != ids[i]) {
+ ids[i] = ids[ids[i]];
+ i = ids[i];
}
+ return i;
+ }
- public boolean connected(int i, int j) {
- return find(ids, i) == find(ids, j);
- }
+ public boolean connected(int i, int j) {
+ return find(ids, i) == find(ids, j);
+ }
- public int maxUnion() {
- //this is O(n)
- int max = 0;
- int[] count = new int[ids.length];
- for (int i = 0; i < ids.length; i++) {
- count[find(ids, i)]++;
- max = max < count[find(ids, i)] ? count[find(ids, i)] : max;
- }
- return max;
+ public int maxUnion() {
+ //this is O(n)
+ int max = 0;
+ int[] count = new int[ids.length];
+ for (int i = 0; i < ids.length; i++) {
+ count[find(ids, i)]++;
+ max = max < count[find(ids, i)] ? count[find(ids, i)] : max;
}
+ return max;
+ }
}
+ }
+
+ public static class Solution2 {
+ //inspired by this solution: https://discuss.leetcode.com/topic/25493/simple-fast-java-solution-using-set
+ public int longestConsecutive(int[] nums) {
+ if (nums == null || nums.length == 0) {
+ return 0;
+ }
+
+ Set set = new HashSet();
+ for (int i : nums) {
+ set.add(i);
+ }
+ int max = 1;
+
+ for (int num : nums) {
+ if (set.remove(num)) {
+ int val = num;
+ int count = 1;
+ while (set.remove(val - 1)) {
+ val--;//we find all numbers that are smaller than num and remove them from the set
+ }
+ count += num - val;
+
+ val = num;
+ while (set.remove(val + 1)) {
+ val++;//then we find all numbers that are bigger than num and also remove them from the set
+ }
+ count += val - num;
- class SolutionUsingHashSet {
- //inspired by this solution: https://discuss.leetcode.com/topic/25493/simple-fast-java-solution-using-set
- public int longestConsecutive(int[] nums) {
- if (nums == null || nums.length == 0) {
- return 0;
- }
-
- Set set = new HashSet();
- for (int i : nums) {
- set.add(i);
- }
- int max = 1;
-
- for (int num : nums) {
- if (set.remove(num)) {
- int val = num;
- int count = 1;
- while (set.remove(val - 1)) {
- val--;//we find all numbers that are smaller than num and remove them from the set
- }
- count += num - val;
-
- val = num;
- while (set.remove(val + 1)) {
- val++;//then we find all numbers that are bigger than num and also remove them from the set
- }
- count += val - num;
-
- max = Math.max(max, count);
- }
- }
- return max;
+ max = Math.max(max, count);
}
+ }
+ return max;
}
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_129.java b/src/main/java/com/fishercoder/solutions/_129.java
index f66184215c..f8cbae5e28 100644
--- a/src/main/java/com/fishercoder/solutions/_129.java
+++ b/src/main/java/com/fishercoder/solutions/_129.java
@@ -5,7 +5,10 @@
import java.util.ArrayList;
import java.util.List;
-/**Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number.
+/**
+ * 129. Sum Root to Leaf Numbers
+ *
+ * Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number.
An example is the root-to-leaf path 1->2->3 which represents the number 123.
@@ -23,47 +26,49 @@
*/
public class _129 {
+ public static class Solution1 {
public int sumNumbers(TreeNode root) {
- if (root == null) {
- return 0;
- }
- List allNumbers = new ArrayList();
- dfs(root, new StringBuilder(), allNumbers);
- int sum = 0;
- for (int i : allNumbers) {
- sum += i;
- }
- return sum;
+ if (root == null) {
+ return 0;
+ }
+ List allNumbers = new ArrayList();
+ dfs(root, new StringBuilder(), allNumbers);
+ int sum = 0;
+ for (int i : allNumbers) {
+ sum += i;
+ }
+ return sum;
}
private void dfs(TreeNode root, StringBuilder sb, List allNumbers) {
- sb.append(root.val);
- if (root.left != null) {
- dfs(root.left, sb, allNumbers);
- }
- if (root.right != null) {
- dfs(root.right, sb, allNumbers);
- }
- if (root.left == null && root.right == null) {
- allNumbers.add(Integer.parseInt(sb.toString()));
- }
- sb.deleteCharAt(sb.length() - 1);
+ sb.append(root.val);
+ if (root.left != null) {
+ dfs(root.left, sb, allNumbers);
+ }
+ if (root.right != null) {
+ dfs(root.right, sb, allNumbers);
+ }
+ if (root.left == null && root.right == null) {
+ allNumbers.add(Integer.parseInt(sb.toString()));
+ }
+ sb.deleteCharAt(sb.length() - 1);
}
+ }
- class MoreConciseVersion {
- public int sumNumbers(TreeNode root) {
- return dfs(root, 0);
- }
+ public static class Solution2 {
+ public int sumNumbers(TreeNode root) {
+ return dfs(root, 0);
+ }
- private int dfs(TreeNode root, int sum) {
- if (root == null) {
- return 0;
- }
- if (root.left == null && root.right == null) {
- return sum * 10 + root.val;
- }
- return dfs(root.left, sum * 10 + root.val) + dfs(root.right, sum * 10 + root.val);
- }
+ private int dfs(TreeNode root, int sum) {
+ if (root == null) {
+ return 0;
+ }
+ if (root.left == null && root.right == null) {
+ return sum * 10 + root.val;
+ }
+ return dfs(root.left, sum * 10 + root.val) + dfs(root.right, sum * 10 + root.val);
}
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_13.java b/src/main/java/com/fishercoder/solutions/_13.java
index fb26c0280f..0538c63848 100644
--- a/src/main/java/com/fishercoder/solutions/_13.java
+++ b/src/main/java/com/fishercoder/solutions/_13.java
@@ -3,31 +3,36 @@
import java.util.HashMap;
import java.util.Map;
-/**Given a roman numeral, convert it to an integer.
+/**
+ * 13. Roman to Integer
+ *
+ * Given a roman numeral, convert it to an integer.
+ * Input is guaranteed to be within the range from 1 to 3999.
+ * */
- Input is guaranteed to be within the range from 1 to 3999.*/
public class _13 {
- public int romanToInt(String s) {
- Map map = new HashMap();
- map.put('I', 1);
- map.put('V', 5);
- map.put('X', 10);
- map.put('L', 50);
- map.put('C', 100);
- map.put('D', 500);
- map.put('M', 1000);
+ public static class Solution1 {
+ public int romanToInt(String s) {
+ Map map = new HashMap();
+ map.put('I', 1);
+ map.put('V', 5);
+ map.put('X', 10);
+ map.put('L', 50);
+ map.put('C', 100);
+ map.put('D', 500);
+ map.put('M', 1000);
- char[] schar = s.toCharArray();
- int result = 0;
- for (int i = 0; i < s.length(); i++) {
- if (i > 0 && map.get(schar[i]) > map.get(schar[i - 1])) {
- result = result + map.get(schar[i]) - 2 * map.get(schar[i - 1]);
- } else {
- result = result + map.get(schar[i]);
+ int result = 0;
+ for (int i = 0; i < s.length(); i++) {
+ if (i > 0 && map.get(s.charAt(i)) > map.get(s.charAt(i - 1))) {
+ result += map.get(s.charAt(i)) - 2 * map.get(s.charAt(i - 1));
+ } else {
+ result += map.get(s.charAt(i));
+ }
}
+ return result;
}
- return result;
}
}
diff --git a/src/main/java/com/fishercoder/solutions/_130.java b/src/main/java/com/fishercoder/solutions/_130.java
index ac4451063d..6d97060e67 100644
--- a/src/main/java/com/fishercoder/solutions/_130.java
+++ b/src/main/java/com/fishercoder/solutions/_130.java
@@ -25,72 +25,72 @@
*/
public class _130 {
- /**
- * I won't call this problem hard, it's just confusing, you'll definitely want to clarify what the problem means before coding.
- * This problem eactually means:
- * any grid that is 'O' but on the four edges, will never be marked to 'X';
- * furthermore, any grid that is 'O' and that is connected with the above type of 'O' will never be marked to 'X' as well;
- * only all other nodes that has any one direct neighbor that is an 'X' will be marked to 'X'.
- */
+ public static class Solution1 {
+ /**
+ * I won't call this problem hard, it's just confusing, you'll definitely want to clarify what
+ * the problem means before coding. This problem eactually means: any grid that is 'O' but on
+ * the four edges, will never be marked to 'X'; furthermore, any grid that is 'O' and that is
+ * connected with the above type of 'O' will never be marked to 'X' as well; only all other
+ * nodes that has any one direct neighbor that is an 'X' will be marked to 'X'.
+ */
- int[] dirs = new int[]{0, 1, 0, -1, 0};
-
- public void solve(char[][] board) {
- if (board == null || board.length == 0 || board[0].length == 0) {
- return;
- }
- int m = board.length;
- int n = board[0].length;
- Queue queue = new LinkedList();
- //check first row and last row and mark all those '0' on these two rows to be '+' to let them be different from other 'O',
- //at the same time, we put them into the queue to get ready for a BFS to mark all those adjacent 'O' nodes to '+' as well
- for (int j = 0; j < n; j++) {
- if (board[0][j] == 'O') {
- board[0][j] = '+';
- queue.offer(new int[]{0, j});
+ int[] dirs = new int[] {0, 1, 0, -1, 0};
+ public void solve(char[][] board) {
+ if (board == null || board.length == 0 || board[0].length == 0) {
+ return;
}
- if (board[m - 1][j] == 'O') {
- board[m - 1][j] = '+';
- queue.offer(new int[]{m - 1, j});
+ int m = board.length;
+ int n = board[0].length;
+ Queue queue = new LinkedList();
+ //check first row and last row and mark all those '0' on these two rows to be '+' to let them be different from other 'O',
+ //at the same time, we put them into the queue to get ready for a BFS to mark all those adjacent 'O' nodes to '+' as well
+ for (int j = 0; j < n; j++) {
+ if (board[0][j] == 'O') {
+ board[0][j] = '+';
+ queue.offer(new int[] {0, j});
+ }
+ if (board[m - 1][j] == 'O') {
+ board[m - 1][j] = '+';
+ queue.offer(new int[] {m - 1, j});
+ }
}
- }
- //check first column and last column too
- for (int i = 0; i < m; i++) {
- if (board[i][0] == 'O') {
- board[i][0] = '+';
- queue.offer(new int[]{i, 0});
- }
- if (board[i][n - 1] == 'O') {
- board[i][n - 1] = '+';
- queue.offer(new int[]{i, n - 1});
+ //check first column and last column too
+ for (int i = 0; i < m; i++) {
+ if (board[i][0] == 'O') {
+ board[i][0] = '+';
+ queue.offer(new int[] {i, 0});
+ }
+ if (board[i][n - 1] == 'O') {
+ board[i][n - 1] = '+';
+ queue.offer(new int[] {i, n - 1});
+ }
}
- }
- while (!queue.isEmpty()) {
- int[] curr = queue.poll();
- for (int i = 0; i < 4; i++) {
- int x = curr[0] + dirs[i];
- int y = curr[1] + dirs[i + 1];
- if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] == 'O') {
- board[x][y] = '+';
- queue.offer(new int[]{x, y});
+ while (!queue.isEmpty()) {
+ int[] curr = queue.poll();
+ for (int i = 0; i < 4; i++) {
+ int x = curr[0] + dirs[i];
+ int y = curr[1] + dirs[i + 1];
+ if (x >= 0 && x < m && y >= 0 && y < n && board[x][y] == 'O') {
+ board[x][y] = '+';
+ queue.offer(new int[] {x, y});
+ }
}
}
- }
- //now we can safely mark all other 'O' to 'X', also remember to put those '+' back to 'O'
- for (int i = 0; i < m; i++) {
- for (int j = 0; j < n; j++) {
- if (board[i][j] == 'O') {
- board[i][j] = 'X';
- } else if (board[i][j] == '+') {
- board[i][j] = 'O';
+ //now we can safely mark all other 'O' to 'X', also remember to put those '+' back to 'O'
+ for (int i = 0; i < m; i++) {
+ for (int j = 0; j < n; j++) {
+ if (board[i][j] == 'O') {
+ board[i][j] = 'X';
+ } else if (board[i][j] == '+') {
+ board[i][j] = 'O';
+ }
}
}
}
}
-
}
diff --git a/src/main/java/com/fishercoder/solutions/_131.java b/src/main/java/com/fishercoder/solutions/_131.java
index d6f31a2448..b8882d7a0d 100644
--- a/src/main/java/com/fishercoder/solutions/_131.java
+++ b/src/main/java/com/fishercoder/solutions/_131.java
@@ -3,7 +3,10 @@
import java.util.ArrayList;
import java.util.List;
-/**Given a string s, partition s such that every substring of the partition is a palindrome.
+/**
+ * 131. Palindrome Partitioning
+
+ Given a string s, partition s such that every substring of the partition is a palindrome.
Return all possible palindrome partitioning of s.
@@ -13,62 +16,52 @@
[
["aa","b"],
["a","a","b"]
- ]*/
+ ]
+
+ */
public class _131 {
+ public static class Solution1 {
public List> partition(String s) {
- List> result = new ArrayList();
- int n = s.length();
- boolean[][] dp = new boolean[n][n];
- for (int i = 0; i < n; i++) {
- for (int j = 0; j <= i; j++) {
- if (s.charAt(j) == s.charAt(i) && (j + 1 >= i - 1 || dp[j + 1][i - 1])) {
- // j+1 >= i-1 means j and i are adjance to each other or only one char apart from each other
- //dp[j+1][i-1] means its inner substring is a palindrome, so as long as s.charAt(j) == s.charAt(i), then dp[j][i] must be a palindrome.
- dp[j][i] = true;
- }
- }
+ List> result = new ArrayList();
+ int n = s.length();
+ boolean[][] dp = new boolean[n][n];
+ for (int i = 0; i < n; i++) {
+ for (int j = 0; j <= i; j++) {
+ if (s.charAt(j) == s.charAt(i) && (j + 1 >= i - 1 || dp[j + 1][i - 1])) {
+ // j+1 >= i-1 means j and i are adjance to each other or only one char apart from each other
+ //dp[j+1][i-1] means its inner substring is a palindrome, so as long as s.charAt(j) == s.charAt(i), then dp[j][i] must be a palindrome.
+ dp[j][i] = true;
+ }
}
+ }
- for (boolean[] list : dp) {
- for (boolean b : list) {
- System.out.print(b + ", ");
- }
- System.out.println();
+ for (boolean[] list : dp) {
+ for (boolean b : list) {
+ System.out.print(b + ", ");
}
System.out.println();
+ }
+ System.out.println();
- backtracking(s, 0, dp, new ArrayList(), result);
+ backtracking(s, 0, dp, new ArrayList(), result);
- return result;
+ return result;
}
void backtracking(String s, int start, boolean[][] dp, List temp,
- List> result) {
- if (start == s.length()) {
- List newTemp = new ArrayList(temp);
- result.add(newTemp);
- }
- for (int i = start; i < s.length(); i++) {
- if (dp[start][i]) {
- temp.add(s.substring(start, i + 1));
- backtracking(s, i + 1, dp, temp, result);
- temp.remove(temp.size() - 1);
- }
- }
- }
-
-
- public static void main(String... strings) {
- _131 test = new _131();
- String s = "aab";
- List> result = test.partition(s);
- for (List list : result) {
- for (String str : list) {
- System.out.print(str + ", ");
- }
- System.out.println();
+ List> result) {
+ if (start == s.length()) {
+ List newTemp = new ArrayList(temp);
+ result.add(newTemp);
+ }
+ for (int i = start; i < s.length(); i++) {
+ if (dp[start][i]) {
+ temp.add(s.substring(start, i + 1));
+ backtracking(s, i + 1, dp, temp, result);
+ temp.remove(temp.size() - 1);
}
+ }
}
-
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_132.java b/src/main/java/com/fishercoder/solutions/_132.java
index ac8aefa354..b1773b986a 100644
--- a/src/main/java/com/fishercoder/solutions/_132.java
+++ b/src/main/java/com/fishercoder/solutions/_132.java
@@ -1,6 +1,9 @@
package com.fishercoder.solutions;
-/**Given a string s, partition s such that every substring of the partition is a palindrome.
+/**
+ * 132. Palindrome Partitioning II
+
+ Given a string s, partition s such that every substring of the partition is a palindrome.
Return the minimum cuts needed for a palindrome partitioning of s.
@@ -9,32 +12,35 @@
*/
public class _132 {
- /**This solution is cooler than Jiuzhang: https://discuss.leetcode.com/topic/32575/easiest-java-dp-solution-97-36*/
-
- //cut[i] stands for the minimum number of cut needed to cut [0, i] into palindromes
- //we initiazlie cut[i] with its max possible value which is i, this is because a single char is naturally a palindrome, so, we'll cut this string into all single-char substrings, which is the max cuts needed
-
- //dp[j][i] == true stands for s.substring(j,i) is a palindrome
- public int minCut(String s) {
+
+ /**This solution is cooler than Jiuzhang: https://discuss.leetcode.com/topic/32575/easiest-java-dp-solution-97-36*/
+
+ public static class Solution1 {
+ //cut[i] stands for the minimum number of cut needed to cut [0, i] into palindromes
+ //we initiazlie cut[i] with its max possible value which is i, this is because a single char is naturally a palindrome, so, we'll cut this string into all single-char substrings, which is the max cuts needed
+
+ //dp[j][i] == true stands for s.substring(j,i) is a palindrome
+ public int minCut(String s) {
int n = s.length();
char[] c = s.toCharArray();
boolean[][] dp = new boolean[n][n];
int[] cut = new int[n];
for (int i = 0; i < n; i++) {
- cut[i] = i;
- for (int j = 0; j <= i; j++) {
- if (c[i] == c[j] && (j + 1 > i - 1 || dp[j + 1][i - 1])) {
- dp[j][i] = true;
- if (j == 0) {
- cut[i] = 0;
- } else {
- cut[i] = (cut[i] < cut[j - 1] + 1) ? cut[i] : cut[j - 1] + 1;
- }
- }
+ cut[i] = i;
+ for (int j = 0; j <= i; j++) {
+ if (c[i] == c[j] && (j + 1 > i - 1 || dp[j + 1][i - 1])) {
+ dp[j][i] = true;
+ if (j == 0) {
+ cut[i] = 0;
+ } else {
+ cut[i] = (cut[i] < cut[j - 1] + 1) ? cut[i] : cut[j - 1] + 1;
+ }
}
+ }
}
return cut[n - 1];
+ }
}
}
diff --git a/src/main/java/com/fishercoder/solutions/_133.java b/src/main/java/com/fishercoder/solutions/_133.java
index eb675df733..35b1ea2dee 100644
--- a/src/main/java/com/fishercoder/solutions/_133.java
+++ b/src/main/java/com/fishercoder/solutions/_133.java
@@ -8,7 +8,10 @@
import java.util.Queue;
/**
- * Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors.
+ * 133. Clone Graph
+
+ Clone an undirected graph.
+ Each node in the graph contains a label and a list of its neighbors.
OJ's undirected graph serialization:
@@ -34,28 +37,29 @@
*/
public class _133 {
+ public static class Solution1 {
public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) {
- if (node == null) {
- return node;
- }
+ if (node == null) {
+ return node;
+ }
- Map map = new HashMap();
- Queue queue = new LinkedList();
- UndirectedGraphNode root = new UndirectedGraphNode(node.label);
- map.put(root.label, root);
- queue.offer(node);
- //remember to offer the original input node into the queue which contains all the information
- while (!queue.isEmpty()) {
- UndirectedGraphNode curr = queue.poll();
- for (UndirectedGraphNode eachNode : curr.neighbors) {
- if (!map.containsKey(eachNode.label)) {
- map.put(eachNode.label, new UndirectedGraphNode(eachNode.label));
- queue.offer(eachNode);
- }
- map.get(curr.label).neighbors.add(map.get(eachNode.label));
- }
+ Map map = new HashMap();
+ Queue queue = new LinkedList();
+ UndirectedGraphNode root = new UndirectedGraphNode(node.label);
+ map.put(root.label, root);
+ queue.offer(node);
+ //remember to offer the original input node into the queue which contains all the information
+ while (!queue.isEmpty()) {
+ UndirectedGraphNode curr = queue.poll();
+ for (UndirectedGraphNode eachNode : curr.neighbors) {
+ if (!map.containsKey(eachNode.label)) {
+ map.put(eachNode.label, new UndirectedGraphNode(eachNode.label));
+ queue.offer(eachNode);
+ }
+ map.get(curr.label).neighbors.add(map.get(eachNode.label));
}
- return root;
+ }
+ return root;
}
-
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_134.java b/src/main/java/com/fishercoder/solutions/_134.java
index ca8c788d4e..8513854eba 100644
--- a/src/main/java/com/fishercoder/solutions/_134.java
+++ b/src/main/java/com/fishercoder/solutions/_134.java
@@ -14,22 +14,23 @@ You have a car with an unlimited gas tank and it costs cost[i] of gas to travel
*/
public class _134 {
- /**Credit: https://discuss.leetcode.com/topic/5088/my-ac-is-o-1-space-o-n-running-time-solution-does-anybody-have-posted-this-solution*/
+ public static class Solution1 {
+ /** Credit: https://discuss.leetcode.com/topic/5088/my-ac-is-o-1-space-o-n-running-time-solution-does-anybody-have-posted-this-solution */
public int canCompleteCircuit(int[] gas, int[] cost) {
- int start = gas.length - 1;
- int end = 0;
- int sum = gas[start] - cost[start];
- while (start > end) {
- if (sum >= 0) {
- sum += gas[end] - cost[end];
- end++;
- } else {
- start--;
- sum += gas[start] - cost[start];
- }
+ int start = gas.length - 1;
+ int end = 0;
+ int sum = gas[start] - cost[start];
+ while (start > end) {
+ if (sum >= 0) {
+ sum += gas[end] - cost[end];
+ end++;
+ } else {
+ start--;
+ sum += gas[start] - cost[start];
}
- return sum >= 0 ? start : -1;
+ }
+ return sum >= 0 ? start : -1;
}
-
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_135.java b/src/main/java/com/fishercoder/solutions/_135.java
index 71d7bd087d..94c705c233 100644
--- a/src/main/java/com/fishercoder/solutions/_135.java
+++ b/src/main/java/com/fishercoder/solutions/_135.java
@@ -1,7 +1,9 @@
package com.fishercoder.solutions;
/**
- * There are N children standing in a line. Each child is assigned a rating value.
+ * 135. Candy
+
+ There are N children standing in a line. Each child is assigned a rating value.
You are giving candies to these children subjected to the following requirements:
@@ -11,30 +13,31 @@
*/
public class _135 {
+ public static class Solution1 {
public int candy(int[] ratings) {
- int[] candy = new int[ratings.length];
- for (int i = 0; i < ratings.length; i++) {
- candy[i] = 1;
+ int[] candy = new int[ratings.length];
+ for (int i = 0; i < ratings.length; i++) {
+ candy[i] = 1;
+ }
+
+ for (int i = 0; i < ratings.length - 1; i++) {
+ if (ratings[i] < ratings[i + 1]) {
+ candy[i + 1] = candy[i] + 1;
}
+ }
- for (int i = 0; i < ratings.length - 1; i++) {
- if (ratings[i] < ratings[i + 1]) {
- candy[i + 1] = candy[i] + 1;
- }
+ for (int i = ratings.length - 1; i > 0; i--) {
+ if (ratings[i] < ratings[i - 1]) {
+ candy[i - 1] = Math.max(candy[i - 1], candy[i] + 1);
}
+ }
- for (int i = ratings.length - 1; i > 0; i--) {
- if (ratings[i] < ratings[i - 1]) {
- candy[i - 1] = Math.max(candy[i - 1], candy[i] + 1);
- }
- }
+ int sum = 0;
+ for (int i : candy) {
+ sum += i;
+ }
- int sum = 0;
- for (int i : candy) {
- sum += i;
- }
-
- return sum;
+ return sum;
}
-
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_136.java b/src/main/java/com/fishercoder/solutions/_136.java
index 6f4fb6d2f3..29d66eb856 100644
--- a/src/main/java/com/fishercoder/solutions/_136.java
+++ b/src/main/java/com/fishercoder/solutions/_136.java
@@ -5,38 +5,46 @@
import java.util.Set;
/**136. Single Number
+
Given an array of integers, every element appears twice except for one. Find that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
-
*/
public class _136 {
- //approach 1: use set, since this problem explicitly states that every element appears twice and only one appears once
- //so, we could safely remove the ones that are already in the set, O(n) time and O(n) space.
- //HashTable approach works similarly like this one, but it could be more easily extend to follow-up questions.
- public int singleNumber_using_set(int[] nums) {
- Set set = new HashSet();
- for (int i : nums) {
- if (!set.add(i)) {
- set.remove(i);
- }
- }
- Iterator it = set.iterator();
- return it.next();
- }
-
- //approach 2: bit manipulation, use exclusive or ^ to solve this problem:
- //we're using the trick here: every number ^ itself will become zero, so, the only remaining element will be the one that
- //appeared only once.
- public int singleNumber_using_bit(int[] nums) {
- int res = 0;
- for (int i : nums) {
- res ^= i;
+ public static class Solution1 {
+ /**
+ * Approach 1: use set, since this problem explicitly states that every element appears twice
+ * and only one appears once so, we could safely remove the ones that are already in the set,
+ * O(n) time and O(n) space. HashTable approach works similarly like this one, but it could be
+ * more easily extend to follow-up questions.
+ */
+ public int singleNumber(int[] nums) {
+ Set set = new HashSet();
+ for (int i : nums) {
+ if (!set.add(i)) {
+ set.remove(i);
}
- return res;
+ }
+ Iterator it = set.iterator();
+ return it.next();
}
-
+ }
+
+ public static class Solution2 {
+ /**
+ * Approach 2: bit manipulation, use exclusive or ^ to solve this problem: we're using the trick
+ * here: every number ^ itself will become zero, so, the only remaining element will be the one
+ * that appeared only once.
+ */
+ public int singleNumber(int[] nums) {
+ int res = 0;
+ for (int i : nums) {
+ res ^= i;
+ }
+ return res;
+ }
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_137.java b/src/main/java/com/fishercoder/solutions/_137.java
index 274d875484..f88c2e600e 100644
--- a/src/main/java/com/fishercoder/solutions/_137.java
+++ b/src/main/java/com/fishercoder/solutions/_137.java
@@ -3,32 +3,45 @@
import java.util.HashMap;
import java.util.Map;
-/**137. Single Number II
+/**
+ * 137. Single Number II
+
Given an array of integers, every element appears three times except for one. Find that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
-
*/
public class _137 {
+ public static class Solution1 {
public int singleNumber(int[] nums) {
- Map map = new HashMap();
- for (int i : nums) {
- map.put(i, map.getOrDefault(i, 0) + 1);
- }
- for (int key : map.keySet()) {
- if (map.get(key) != 3) {
- return key;
- }
+ Map map = new HashMap();
+ for (int i : nums) {
+ map.put(i, map.getOrDefault(i, 0) + 1);
+ }
+ for (int key : map.keySet()) {
+ if (map.get(key) != 3) {
+ return key;
}
- return 0;
+ }
+ return 0;
}
+ }
- public static void main(String... strings) {
- int[] nums = new int[]{2, 2, 3, 2};
- _137 test = new _137();
- System.out.println(test.singleNumber(nums));
+ public static class Solution2 {
+ /** Credit: https://discuss.leetcode.com/topic/11877/detailed-explanation-and-generalization-of-the-bitwise-operation-method-for-single-numbers/2 */
+ public int singleNumber(int[] nums) {
+ int counter1 = 0;
+ int counter2 = 0;
+ int mask = 0;
+ for (int num : nums) {
+ counter2 ^= counter1 & num;
+ counter1 ^= num;
+ mask = ~(counter1 & counter2);
+ counter1 &= mask;
+ counter2 &= mask;
+ }
+ return counter1;
}
-
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_138.java b/src/main/java/com/fishercoder/solutions/_138.java
index ec150c544c..75037b07d1 100644
--- a/src/main/java/com/fishercoder/solutions/_138.java
+++ b/src/main/java/com/fishercoder/solutions/_138.java
@@ -3,44 +3,48 @@
import java.util.HashMap;
import java.util.Map;
-/**138. Copy List with Random Pointer
+/**
+ * 138. Copy List with Random Pointer
+ *
* A linked list is given such that each node contains an additional random
* pointer which could point to any node in the list or null.
- * Return a deep copy of the list.*/
+ * Return a deep copy of the list.
+ * */
public class _138 {
-
+ public static class Solution1 {
public RandomListNode copyRandomList(RandomListNode head) {
- /**Key is the original nodes, value is the new nodes we're deep copying to.*/
- Map map = new HashMap();
- RandomListNode node = head;
-
- //loop for the first time: copy the node themselves with only labels
- while (node != null) {
- map.put(node, new RandomListNode(node.label));
- node = node.next;
- }
-
- //loop for the second time: copy random and next pointers
- node = head;
- while (node != null) {
- map.get(node).next = map.get(node.next);
- map.get(node).random = map.get(node.random);
- node = node.next;
- }
-
- return map.get(head);
+ /**Key is the original nodes, value is the new nodes we're deep copying to.*/
+ Map map = new HashMap();
+ RandomListNode node = head;
+
+ //loop for the first time: copy the node themselves with only labels
+ while (node != null) {
+ map.put(node, new RandomListNode(node.label));
+ node = node.next;
+ }
+
+ //loop for the second time: copy random and next pointers
+ node = head;
+ while (node != null) {
+ map.get(node).next = map.get(node.next);
+ map.get(node).random = map.get(node.random);
+ node = node.next;
+ }
+
+ return map.get(head);
}
// Definition for singly-linked list with a random pointer.
class RandomListNode {
- int label;
+ int label;
- RandomListNode next;
- RandomListNode random;
+ RandomListNode next;
+ RandomListNode random;
- RandomListNode(int x) {
- this.label = x;
- }
+ RandomListNode(int x) {
+ this.label = x;
+ }
}
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_139.java b/src/main/java/com/fishercoder/solutions/_139.java
index 933f6437e1..c7e61f1035 100644
--- a/src/main/java/com/fishercoder/solutions/_139.java
+++ b/src/main/java/com/fishercoder/solutions/_139.java
@@ -1,10 +1,10 @@
package com.fishercoder.solutions;
import java.util.List;
-import java.util.Set;
/**
* 139. Word Break
+ *
* Given a non-empty string s and a dictionary wordDict containing a list of non-empty words,
* determine if s can be segmented into a space-separated sequence of one or more dictionary words.
* You may assume the dictionary does not contain duplicate words.
@@ -22,10 +22,8 @@ The wordDict parameter had been changed to a list of strings (instead of a set o
public class _139 {
- public static class PureDPSolution {
- /**
- * This beats 70.10% submissions.
- */
+ public static class Solution1 {
+ /** this beats 70.46% submission. */
public boolean wordBreak(String s, List wordDict) {
int n = s.length();
boolean[] dp = new boolean[n + 1];
@@ -42,9 +40,10 @@ public boolean wordBreak(String s, List wordDict) {
}
}
- public static class ModifiedDPAndPruningSolution {
+ public static class Solution2 {
/**
- * This beats 86.09% submissions.
+ * Added pruning.
+ * this beats 89.91% submissions.
*/
public boolean wordBreak(String s, List wordDict) {
int maxLen = Integer.MIN_VALUE;
@@ -70,11 +69,12 @@ public boolean wordBreak(String s, List wordDict) {
}
}
- public static class DPAndPruningSolution {
+ public static class Solution3 {
/**
- * This beats 97.08% submissions.
+ * Added pruning, plus start from the end to check.
+ * This beats 95.20% submissions.
*/
- public boolean wordBreak(String s, Set wordDict) {
+ public boolean wordBreak(String s, List wordDict) {
int maxLen = Integer.MIN_VALUE;
for (String word : wordDict) {
maxLen = (word.length() > maxLen) ? word.length() : maxLen;
@@ -84,7 +84,8 @@ public boolean wordBreak(String s, Set wordDict) {
boolean[] dp = new boolean[n + 1];
dp[0] = true;
for (int i = 1; i <= n; i++) {
- for (int lastWordLength = 1; lastWordLength <= i && lastWordLength <= maxLen; lastWordLength++) {
+ for (int lastWordLength = 1; lastWordLength <= i && lastWordLength <= maxLen;
+ lastWordLength++) {
if (!dp[i - lastWordLength]) {
continue;
}
diff --git a/src/main/java/com/fishercoder/solutions/_14.java b/src/main/java/com/fishercoder/solutions/_14.java
index d910c54c1b..adf1f0e4a7 100644
--- a/src/main/java/com/fishercoder/solutions/_14.java
+++ b/src/main/java/com/fishercoder/solutions/_14.java
@@ -1,39 +1,78 @@
package com.fishercoder.solutions;
-/**Write a function to find the longest common prefix string amongst an array of strings.*/
+
+/**
+ * 14. Longest Common Prefix
+ *
+ * Write a function to find the longest common prefix string amongst an array of strings.
+ */
+
public class _14 {
- public static String longestCommonPrefix(String[] strs) {
- if (strs.length == 0) {
- return "";
+ public static class Solution1 {
+ public String longestCommonPrefix(String[] strs) {
+ if (strs.length == 0) {
+ return "";
+ }
+
+ int i = 0;
+ String prefix = "";
+ String result;
+ boolean broken = false;
+ while (true) {
+ i++;
+ result = prefix;
+ if (i > strs[0].length()) {
+ break;//this will break out the while loop
+ }
+ prefix = strs[0].substring(0, i);
+ for (String word : strs) {
+ if (i > word.length() || !word.startsWith(prefix)) {
+ broken = true;
+ break;//this will only break out of the for loop
+ }
+ }
+ if (broken) {
+ break;//this will break out the while loop
+ }
+ }
+ return result;
}
+ }
- int i = 0;
- String prefix = "";
- String result = "";
- boolean broken = false;
- while (true) {
- i++;
- result = prefix;
- if (i > strs[0].length()) {
- break;//this will break out the while loop
+ public static class Solution2 {
+ //horizontal scan
+ public String longestCommonPrefix(String[] strs) {
+ if (strs.length == 0) {
+ return "";
}
- prefix = strs[0].substring(0, i);
- for (String word : strs) {
- if (i > word.length() || !word.startsWith(prefix)) {
- broken = true;
- break;//this will only break out of the for loop
+ String prefix = strs[0];
+ for (int i = 1; i < strs.length; i++) {
+ while (strs[i].indexOf(prefix) != 0) {
+ prefix = prefix.substring(0, prefix.length() - 1);
+ if (prefix.isEmpty()) {
+ return "";
+ }
}
}
- if (broken) {
- break;//this will break out the while loop
- }
+ return prefix;
}
- return result;
}
- public static void main(String... strings) {
-// String[] strs = new String[]{"a"};
- String[] strs = new String[]{"a", "b"};
- System.out.println(longestCommonPrefix(strs));
+ public static class Solution3 {
+ //vertical scan
+ public String longestCommonPrefix(String[] strs) {
+ if (strs.length == 0) {
+ return "";
+ }
+ for (int i = 0; i < strs[0].length(); i++) {
+ char c = strs[0].charAt(i);
+ for (int j = 1; j < strs.length; j++) {
+ if (i == strs[j].length() || strs[j].charAt(i) != c) {
+ return strs[0].substring(0, i);
+ }
+ }
+ }
+ return strs[0];
+ }
}
}
diff --git a/src/main/java/com/fishercoder/solutions/_140.java b/src/main/java/com/fishercoder/solutions/_140.java
index 2b3c1dbd36..3bf5043a26 100644
--- a/src/main/java/com/fishercoder/solutions/_140.java
+++ b/src/main/java/com/fishercoder/solutions/_140.java
@@ -2,71 +2,80 @@
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
/**
- * Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each word is a valid dictionary word.
+ * 140. Word Break II
+ Given a non-empty string s and a dictionary wordDict containing a list of non-empty words,
+ add spaces in s to construct a sentence where each word is a valid dictionary word.
Return all such possible sentences.
- For example, given
- s = "catsanddog",
- dict = ["cat", "cats", "and", "sand", "dog"].
+ Note:
- A solution is ["cats and dog", "cat sand dog"].
+ The same word in the dictionary may be reused multiple times in the segmentation.
+ You may assume the dictionary does not contain duplicate words.
- */
-public class _140 {
- public List wordBreak(String s, Set wordDict) {
- return dfs(s, wordDict, new HashMap>());
- }
+ Example 1:
- private List dfs(String s, Set wordDict,
- HashMap> map) {
- if (map.containsKey(s)) {
- return map.get(s);
- }
+ Input:
+ s = "catsanddog"
+ wordDict = ["cat", "cats", "and", "sand", "dog"]
+ Output:
+ [
+ "cats and dog",
+ "cat sand dog"
+ ]
- ArrayList res = new ArrayList();
- if (s.length() == 0) {
- res.add("");
- return res;
- }
+ Example 2:
- for (String word : wordDict) {
- if (s.startsWith(word)) {
- List subList = dfs(s.substring(word.length()), wordDict, map);
- for (String sub : subList) {
- res.add(word + (sub.length() == 0 ? "" : " ") + sub);
- }
- }
- }
- map.put(s, res);
- return res;
+ Input:
+ s = "pineapplepenapple"
+ wordDict = ["apple", "pen", "applepen", "pine", "pineapple"]
+ Output:
+ [
+ "pine apple pen apple",
+ "pineapple pen apple",
+ "pine applepen apple"
+ ]
+ Explanation: Note that you are allowed to reuse a dictionary word.
+
+ Example 3:
+
+ Input:
+ s = "catsandog"
+ wordDict = ["cats", "dog", "sand", "and", "cat"]
+ Output:
+ []
+ */
+
+public class _140 {
+ public static class Solution1 {
+ public List wordBreak(String s, List wordDict) {
+ return dfs(s, wordDict, new HashMap<>());
}
- public static void main(String... strings) {
- List temp = new ArrayList();
- System.out.println(temp);
- List temp2 = new ArrayList(temp);
- temp2.add("");
- System.out.println(temp2);
+ List dfs(String s, List wordDict, HashMap> map) {
+ if (map.containsKey(s)) {
+ return map.get(s);
+ }
+
+ ArrayList result = new ArrayList<>();
+ if (s.length() == 0) {
+ result.add("");
+ return result;
+ }
- _140 test = new _140();
- Set wordDict = new HashSet();
- wordDict.add("cat");
- wordDict.add("cats");
- wordDict.add("sand");
- wordDict.add("and");
- wordDict.add("dog");
- String s = "catsanddog";
-// List list = test.wordBreak(s, wordDict);
- List list = test.wordBreak(s, wordDict);
- for (String word : list) {
- System.out.print(word + ", ");
+ for (String word : wordDict) {
+ if (s.startsWith(word)) {
+ List subList = dfs(s.substring(word.length()), wordDict, map);
+ for (String sub : subList) {
+ result.add(word + (sub.length() == 0 ? "" : " ") + sub);
+ }
}
- System.out.println();
+ }
+ map.put(s, result);
+ return result;
}
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_141.java b/src/main/java/com/fishercoder/solutions/_141.java
index 63f94e1931..c172a40b3d 100644
--- a/src/main/java/com/fishercoder/solutions/_141.java
+++ b/src/main/java/com/fishercoder/solutions/_141.java
@@ -2,29 +2,27 @@
import com.fishercoder.common.classes.ListNode;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.HashSet;
+import java.util.Set;
/**
* 141. Linked List Cycle
+
Given a linked list, determine if it has a cycle in it.
Follow up:
Can you solve it without using extra space?
- *
*/
public class _141 {
public static class Solution1 {
public boolean hasCycle(ListNode head) {
- ListNode slow = head;
- ListNode fast = head;
- while (fast != null && fast.next != null) {
- fast = fast.next.next;
- slow = slow.next;
- if (fast == slow) {
+ Set set = new HashSet();
+ while (head != null) {
+ if (!set.add(head)) {
return true;
}
+ head = head.next;
}
return false;
}
@@ -32,17 +30,16 @@ public boolean hasCycle(ListNode head) {
public static class Solution2 {
public boolean hasCycle(ListNode head) {
- Map visited = new HashMap();
- ListNode temp = head;
- while (temp != null) {
- if (visited.containsKey(temp)) {
+ ListNode slow = head;
+ ListNode fast = head;
+ while (fast != null && fast.next != null) {
+ fast = fast.next.next;
+ slow = slow.next;
+ if (fast == slow) {
return true;
}
- visited.put(temp, true);
- temp = temp.next;
}
return false;
}
}
-
}
diff --git a/src/main/java/com/fishercoder/solutions/_142.java b/src/main/java/com/fishercoder/solutions/_142.java
index 88af0563ef..dbe1235e9f 100644
--- a/src/main/java/com/fishercoder/solutions/_142.java
+++ b/src/main/java/com/fishercoder/solutions/_142.java
@@ -2,29 +2,35 @@
import com.fishercoder.common.classes.ListNode;
-/**Given a linked list, return the node where the cycle begins. If there is no cycle, return null.
+/**
+ * 142. Linked List Cycle II
+
+ Given a linked list, return the node where the cycle begins. If there is no cycle, return null.
Note: Do not modify the linked list.
Follow up:
- Can you solve it without using extra space?*/
+ Can you solve it without using extra space?
+ */
public class _142 {
+ public static class Solution1 {
public ListNode detectCycle(ListNode head) {
- ListNode slow = head;
- ListNode fast = head;
- while (fast != null && fast.next != null) {
+ ListNode slow = head;
+ ListNode fast = head;
+ while (fast != null && fast.next != null) {
+ slow = slow.next;
+ fast = fast.next.next;
+ if (slow == fast) {
+ ListNode slow2 = head;
+ while (slow2 != slow) {
slow = slow.next;
- fast = fast.next.next;
- if ( slow == fast) {
- ListNode slow2 = head;
- while (slow2 != slow) {
- slow = slow.next;
- slow2 = slow2.next;
- }
- return slow;
- }
+ slow2 = slow2.next;
+ }
+ return slow;
}
- return null;
+ }
+ return null;
}
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_143.java b/src/main/java/com/fishercoder/solutions/_143.java
index 4b9cdae789..c467d9237f 100644
--- a/src/main/java/com/fishercoder/solutions/_143.java
+++ b/src/main/java/com/fishercoder/solutions/_143.java
@@ -15,51 +15,52 @@
*/
public class _143 {
- public void reorderList(ListNode head) {
- if (head == null || head.next == null) {
- return;
- }
- /* first we use two pointers to separate this list into two parts */
- ListNode slowNode = head;
- ListNode fastNode = head;
- while (fastNode.next != null) {
- fastNode = fastNode.next;
- if (fastNode.next != null) {
+ public static class Solution1 {
+ public void reorderList(ListNode head) {
+ if (head == null || head.next == null) {
+ return;
+ }
+ /* first we use two pointers to separate this list into two parts */
+ ListNode slowNode = head;
+ ListNode fastNode = head;
+ while (fastNode.next != null) {
fastNode = fastNode.next;
- } else {
- break;
+ if (fastNode.next != null) {
+ fastNode = fastNode.next;
+ } else {
+ break;
+ }
+ slowNode = slowNode.next;
}
- slowNode = slowNode.next;
- }
- // two sublist heads
- ListNode head1 = head;
- ListNode head2 = slowNode.next;
- // detach the two sublists;
- slowNode.next = null;
+ // two sublist heads
+ ListNode head1 = head;
+ ListNode head2 = slowNode.next;
+ // detach the two sublists;
+ slowNode.next = null;
- // reverse the second sublist
- ListNode cur = head2;
- ListNode post = cur.next;
- cur.next = null;
- while (post != null) {
- ListNode temp = post.next;
- post.next = cur;
- cur = post;
- post = temp;
- }
- head2 = cur;// the new head of the reversed sublist
+ // reverse the second sublist
+ ListNode cur = head2;
+ ListNode post = cur.next;
+ cur.next = null;
+ while (post != null) {
+ ListNode temp = post.next;
+ post.next = cur;
+ cur = post;
+ post = temp;
+ }
+ head2 = cur;// the new head of the reversed sublist
- // merge the two sublists as required
- ListNode p = head1;
- ListNode q = head2;
- while (q != null) {
- ListNode temp1 = p.next;
- ListNode temp2 = q.next;
- p.next = q;
- q.next = temp1;
- p = temp1;
- q = temp2;
+ // merge the two sublists as required
+ ListNode p = head1;
+ ListNode q = head2;
+ while (q != null) {
+ ListNode temp1 = p.next;
+ ListNode temp2 = q.next;
+ p.next = q;
+ q.next = temp1;
+ p = temp1;
+ q = temp2;
+ }
}
}
-
}
diff --git a/src/main/java/com/fishercoder/solutions/_144.java b/src/main/java/com/fishercoder/solutions/_144.java
index ce88a4d169..95ee0d8c5c 100644
--- a/src/main/java/com/fishercoder/solutions/_144.java
+++ b/src/main/java/com/fishercoder/solutions/_144.java
@@ -7,10 +7,10 @@
import java.util.Deque;
import java.util.List;
-
/**
* 144. Binary Tree Preorder Traversal
- * Given a binary tree, return the preorder traversal of its nodes' values.
+
+ Given a binary tree, return the preorder traversal of its nodes' values.
For example:
Given binary tree {1,#,2,3},
@@ -24,42 +24,44 @@
Note: Recursive solution is trivial, could you do it iteratively?*/
public class _144 {
-
- public List preorderTraversal_iterative(TreeNode root) {
- List list = new ArrayList();
- if (root == null) {
- return list;
+ public static class Solution1 {
+ public List preorderTraversal(TreeNode root) {
+ List list = new ArrayList();
+ if (root == null) {
+ return list;
+ }
+ Deque stack = new ArrayDeque<>();
+ stack.push(root);
+ while (!stack.isEmpty()) {
+ TreeNode curr = stack.pop();
+ list.add(curr.val);
+ /**We push right nodes onto the stack first, since they'll be popped out later than
+ * the left nodes, to meet the preorder: root -> left -> right. */
+ if (curr.right != null) {
+ stack.push(curr.right);
}
- Deque stack = new ArrayDeque<>();
- stack.push(root);
- while (!stack.isEmpty()) {
- TreeNode curr = stack.pop();
- list.add(curr.val);
- /**We push right nodes onto the stack first, since they'll be popped out later than
- * the left nodes, to meet the preorder: root -> left -> right. */
- if (curr.right != null) {
- stack.push(curr.right);
- }
- if (curr.left != null) {
- stack.push(curr.left);
- }
+ if (curr.left != null) {
+ stack.push(curr.left);
}
- return list;
+ }
+ return list;
}
+ }
- public List preorderTraversal_recursive(TreeNode root) {
- List list = new ArrayList();
- return pre(root, list);
+ public static class Solution2 {
+ public List preorderTraversal(TreeNode root) {
+ List list = new ArrayList();
+ return pre(root, list);
}
List pre(TreeNode root, List list) {
- if (root == null) {
- return list;
- }
- list.add(root.val);
- pre(root.left, list);
- pre(root.right, list);
+ if (root == null) {
return list;
+ }
+ list.add(root.val);
+ pre(root.left, list);
+ pre(root.right, list);
+ return list;
}
-
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_145.java b/src/main/java/com/fishercoder/solutions/_145.java
index 008c17cc76..54448849b8 100644
--- a/src/main/java/com/fishercoder/solutions/_145.java
+++ b/src/main/java/com/fishercoder/solutions/_145.java
@@ -7,7 +7,10 @@
import java.util.List;
import java.util.Stack;
-/**Given a binary tree, return the postorder traversal of its nodes' values.
+/**
+ * 145. Binary Tree Postorder Traversal
+
+ Given a binary tree, return the postorder traversal of its nodes' values.
For example:
Given binary tree {1,#,2,3},
@@ -21,40 +24,48 @@
Note: Recursive solution is trivial, could you do it iteratively?*/
public class _145 {
- /**A tricky one: Modify the code for pre-order traversal so that it becomes root->right->left, and then reverse the result to get left->right->root.*/
- public static List postorderTraversal_iterative(TreeNode root) {
- List result = new ArrayList();
- if (root == null) {
- return result;
+ public static class Solution1 {
+ /**
+ * A tricky one: Modify the code for pre-order traversal
+ * so that it becomes root->right->left,
+ * and then reverse the result to get left->right->root.
+ */
+ public static List postorderTraversal(TreeNode root) {
+ List result = new ArrayList();
+ if (root == null) {
+ return result;
+ }
+ Stack stack = new Stack();
+ stack.push(root);
+ while (!stack.isEmpty()) {
+ root = stack.pop();
+ result.add(root.val);
+ if (root.left != null) {
+ stack.push(root.left);
}
- Stack stack = new Stack();
- stack.push(root);
- while (!stack.isEmpty()) {
- root = stack.pop();
- result.add(root.val);
- if (root.left != null) {
- stack.push(root.left);
- }
- if (root.right != null) {
- stack.push(root.right);
- }
+ if (root.right != null) {
+ stack.push(root.right);
}
- Collections.reverse(result);
- return result;
+ }
+ Collections.reverse(result);
+ return result;
}
+ }
- public List postorderTraversal_recursive(TreeNode root) {
- List result = new ArrayList();
- return post(root, result);
+ public static class Solution2 {
+ public List postorderTraversal(TreeNode root) {
+ List result = new ArrayList();
+ return post(root, result);
}
List post(TreeNode root, List result) {
- if (root == null) {
- return result;
- }
- post(root.left, result);
- post(root.right, result);
- result.add(root.val);
+ if (root == null) {
return result;
+ }
+ post(root.left, result);
+ post(root.right, result);
+ result.add(root.val);
+ return result;
}
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_146.java b/src/main/java/com/fishercoder/solutions/_146.java
index 9b6f83ded2..9e9de2768f 100644
--- a/src/main/java/com/fishercoder/solutions/_146.java
+++ b/src/main/java/com/fishercoder/solutions/_146.java
@@ -33,132 +33,139 @@ Could you do both operations in O(1) time complexity?
public class _146 {
- public class LinkedHashMapSolution {
- /**
- * The shortest implementation is to use LinkedHashMap:
- * specify a size of the linkedHashMap;
- * override the removeEldestEntry method when its size exceeds max size:
- * https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashMap.html#removeEldestEntry-java.util.Map.Entry-
- * in the constructor, set the last boolean variable to be true: it means the ordering mode,
- * if we set it to be true, it means in access order, false, means it's in insertion order:
- * https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashMap.html#LinkedHashMap-int-float-boolean-
- */
-
- private Map cache;
- private final int max;
-
- public LinkedHashMapSolution(int capacity) {
- max = capacity;
- cache = new LinkedHashMap(capacity, 1.0f, true) {
- public boolean removeEldestEntry(Map.Entry eldest) {
- return cache.size() > max;
- }
- };
- }
+ public class Solution1 {
+ public class LRUCache {
+ /**
+ * The shortest implementation is to use LinkedHashMap:
+ * specify a size of the linkedHashMap;
+ * override the removeEldestEntry method when its size exceeds max size:
+ * https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashMap.html#removeEldestEntry-java.util.Map.Entry-
+ * in the constructor, set the last boolean variable to be true: it means the ordering mode,
+ * if we set it to be true, it means in access order, false, means it's in insertion order:
+ * https://docs.oracle.com/javase/8/docs/api/java/util/LinkedHashMap.html#LinkedHashMap-int-float-boolean-
+ */
+
+ private Map cache;
+ private final int max;
+
+ public LRUCache(int capacity) {
+ max = capacity;
+ cache = new LinkedHashMap(capacity, 1.0f, true) {
+ public boolean removeEldestEntry(Map.Entry eldest) {
+ return cache.size() > max;
+ }
+ };
+ }
- public int get(int key) {
- return cache.getOrDefault(key, -1);
- }
+ public int get(int key) {
+ return cache.getOrDefault(key, -1);
+ }
- public void set(int key, int value) {
- cache.put(key, value);
+ public void set(int key, int value) {
+ cache.put(key, value);
+ }
}
}
- public class DoublyLinkedListPlusHashMapSolution {
- private class Node {
- int key;
- int value;
-
- DoublyLinkedListPlusHashMapSolution.Node prev;
- DoublyLinkedListPlusHashMapSolution.Node next;
+ public class Solution2 {
+ public class LRUCache {
+ /**
+ * The more verbose solution is to write a doubly linked list plus a map.
+ */
+ private class Node {
+ int key;
+ int value;
+
+ LRUCache.Node prev;
+ LRUCache.Node next;
+
+ Node(int k, int v) {
+ this.key = k;
+ this.value = v;
+ }
- Node(int k, int v) {
- this.key = k;
- this.value = v;
+ Node() {
+ this.key = 0;
+ this.value = 0;
+ }
}
- Node() {
- this.key = 0;
- this.value = 0;
+ private int capacity;
+ private int count;
+ private LRUCache.Node head;
+ private LRUCache.Node tail;
+ private Map map;
+ // ATTN: the value should be Node type! This is the whole point of having a class called Node!
+
+ public LRUCache(int capacity) {
+ this.capacity = capacity;
+ this.count = 0;// we need a count to keep track of the number of elements in the cache so
+ // that we know when to evict the LRU one from the cache
+ this.map = new HashMap();
+ head = new LRUCache.Node();
+ tail = new LRUCache.Node();
+ head.next = tail;
+ tail.prev = head;
}
- }
-
- private int capacity;
- private int count;
- private DoublyLinkedListPlusHashMapSolution.Node head;
- private DoublyLinkedListPlusHashMapSolution.Node tail;
- private Map map;
- // ATTN: the value should be Node type! This is the whole point of having a class called Node!
-
- public DoublyLinkedListPlusHashMapSolution(int capacity) {
- this.capacity = capacity;
- this.count = 0;// we need a count to keep track of the number of elements in the cache so
- // that we know when to evict the LRU one from the cache
- this.map = new HashMap();
- head = new DoublyLinkedListPlusHashMapSolution.Node();
- tail = new DoublyLinkedListPlusHashMapSolution.Node();
- head.next = tail;
- tail.prev = head;
- }
- public int get(int key) {
- DoublyLinkedListPlusHashMapSolution.Node node = map.get(key);
- // HashMap allows value to be null, this is superior than HashTable!
- if (node == null) {
- return -1;
- } else {
-
- /**Do two operations: this makes the process more clear:
- * remove the old node first, and then
- * just add the node again.
- * This will guarantee that this node will be at the latest position:
- * the most recently used position.*/
- remove(node);
- add(node);
-
- return node.value;
+ public int get(int key) {
+ LRUCache.Node node = map.get(key);
+ // HashMap allows value to be null, this is superior than HashTable!
+ if (node == null) {
+ return -1;
+ } else {
+
+ /**Do two operations: this makes the process more clear:
+ * remove the old node first, and then
+ * just add the node again.
+ * This will guarantee that this node will be at the latest position:
+ * the most recently used position.*/
+ remove(node);
+ add(node);
+
+ return node.value;
+ }
}
- }
- public void set(int key, int value) {
- DoublyLinkedListPlusHashMapSolution.Node node = map.get(key);
- if (node == null) {
- node = new DoublyLinkedListPlusHashMapSolution.Node(key, value);
- map.put(key, node);
- add(node);
- count++;
-
- if (count > capacity) {
- /** ATTN: It's tail.prev, not tail, because tail is always an invalid node, it
- doesn't contain anything, it's always the tail.prev that is the last node in the
- cache*/
- DoublyLinkedListPlusHashMapSolution.Node toDelete = tail.prev;
- map.remove(toDelete.key);
- remove(toDelete);
- count--;
+ public void set(int key, int value) {
+ LRUCache.Node node = map.get(key);
+ if (node == null) {
+ node = new LRUCache.Node(key, value);
+ map.put(key, node);
+ add(node);
+ count++;
+
+ if (count > capacity) {
+ /** ATTN: It's tail.prev, not tail, because tail is always an invalid node, it
+ doesn't contain anything, it's always the tail.prev that is the last node in the
+ cache*/
+ LRUCache.Node toDelete = tail.prev;
+ map.remove(toDelete.key);
+ remove(toDelete);
+ count--;
+ }
+ } else {
+ remove(node);
+ node.value = value;
+ add(node);
}
- } else {
- remove(node);
- node.value = value;
- add(node);
}
- }
- private void remove(DoublyLinkedListPlusHashMapSolution.Node node) {
- DoublyLinkedListPlusHashMapSolution.Node next = node.next;
- DoublyLinkedListPlusHashMapSolution.Node prev = node.prev;
- prev.next = next;
- next.prev = prev;
- }
+ private void remove(LRUCache.Node node) {
+ LRUCache.Node next = node.next;
+ LRUCache.Node prev = node.prev;
+ prev.next = next;
+ next.prev = prev;
+ }
- private void add(DoublyLinkedListPlusHashMapSolution.Node node) {
- // ATTN: we'll always add the node into the first position: head.next!!!!
- DoublyLinkedListPlusHashMapSolution.Node next = head.next;
- head.next = node;
- node.next = next;
- node.prev = head;
- next.prev = node;
+ private void add(LRUCache.Node node) {
+ // ATTN: we'll always add the node into the first position: head.next!!!!
+ LRUCache.Node next = head.next;
+ head.next = node;
+ node.next = next;
+ node.prev = head;
+ next.prev = node;
+ }
}
}
}
\ No newline at end of file
diff --git a/src/main/java/com/fishercoder/solutions/_147.java b/src/main/java/com/fishercoder/solutions/_147.java
index 61077dc0fa..ea4b20ecdc 100644
--- a/src/main/java/com/fishercoder/solutions/_147.java
+++ b/src/main/java/com/fishercoder/solutions/_147.java
@@ -6,33 +6,53 @@
import java.util.List;
/**
+ * 147. Insertion Sort List
+ *
* Sort a linked list using insertion sort.
+ *
+ * Algorithm of Insertion Sort:
+ *
+ * Insertion sort iterates, consuming one input element each repetition, and growing a sorted output list.
+ * At each iteration, insertion sort removes one element from the input data, finds the location it belongs within the sorted list, and inserts it there.
+ * It repeats until no input elements remain.
+ *
+ *
+ * Example 1:
+ *
+ * Input: 4->2->1->3
+ * Output: 1->2->3->4
+ *
+ * Example 2:
+ *
+ * Input: -1->5->3->4->0
+ * Output: -1->0->3->4->5
*/
public class _147 {
+ public static class Solution1 {
public ListNode insertionSortList(ListNode head) {
- ListNode temp = head;
- List list = new ArrayList();
- while (temp != null) {
- list.add(temp.val);
- temp = temp.next;
+ ListNode temp = head;
+ List list = new ArrayList<>();
+ while (temp != null) {
+ list.add(temp.val);
+ temp = temp.next;
+ }
+ Integer[] nums = list.toArray(new Integer[list.size()]);
+ for (int i = 1; i < list.size(); i++) {
+ for (int j = i - 1; j >= 0; j--) {
+ if (nums[j] > nums[j + 1]) {
+ int tempNum = nums[j];
+ nums[j] = nums[j + 1];
+ nums[j + 1] = tempNum;
+ }
}
- Integer[] nums = list.toArray(new Integer[list.size()]);
- for (int i = 1; i < list.size(); i++) {
- for (int j = i - 1; j >= 0; j--) {
- if (nums[j] > nums[j + 1]) {
- int tempNum = nums[j];
- nums[j] = nums[j + 1];
- nums[j + 1] = tempNum;
- }
- }
- }
- ListNode newHead = head;
- for (int i = 0; i < nums.length; i++) {
- newHead.val = nums[i];
- newHead = newHead.next;
- }
- return head;
+ }
+ ListNode newHead = head;
+ for (int i = 0; i < nums.length; i++) {
+ newHead.val = nums[i];
+ newHead = newHead.next;
+ }
+ return head;
}
-
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_148.java b/src/main/java/com/fishercoder/solutions/_148.java
index 234f185778..0136db30f6 100644
--- a/src/main/java/com/fishercoder/solutions/_148.java
+++ b/src/main/java/com/fishercoder/solutions/_148.java
@@ -9,54 +9,57 @@
*/
public class _148 {
- /**Credit: https://discuss.leetcode.com/topic/18100/java-merge-sort-solution
- * But this is not using constant space.*/
- public ListNode sortList(ListNode head) {
- if (head == null || head.next == null) {
- return head;
- }
+ public static class Solution1 {
+ /**
+ * Credit: https://discuss.leetcode.com/topic/18100/java-merge-sort-solution
+ * But this is not using constant space.
+ */
+ public ListNode sortList(ListNode head) {
+ if (head == null || head.next == null) {
+ return head;
+ }
- //Step 1: split the list into halves
- ListNode prev = null;
- ListNode slow = head;
- ListNode fast = head;
- while (fast != null && fast.next != null) {
- prev = slow;
- fast = fast.next.next;
- slow = slow.next;
- }
- prev.next = null;
+ //Step 1: split the list into halves
+ ListNode prev = null;
+ ListNode slow = head;
+ ListNode fast = head;
+ while (fast != null && fast.next != null) {
+ prev = slow;
+ fast = fast.next.next;
+ slow = slow.next;
+ }
+ prev.next = null;
- //step 2: sort each half
- ListNode l1 = sortList(head);
- ListNode l2 = sortList(slow);
+ //step 2: sort each half
+ ListNode l1 = sortList(head);
+ ListNode l2 = sortList(slow);
- //step 3: merge the two halves
- return merge(l1, l2);
- }
+ //step 3: merge the two halves
+ return merge(l1, l2);
+ }
- private ListNode merge(ListNode l1, ListNode l2) {
- ListNode result = new ListNode(0);
- ListNode tmp = result;
+ private ListNode merge(ListNode l1, ListNode l2) {
+ ListNode result = new ListNode(0);
+ ListNode tmp = result;
- while (l1 != null && l2 != null) {
- if (l1.val < l2.val) {
+ while (l1 != null && l2 != null) {
+ if (l1.val < l2.val) {
+ tmp.next = l1;
+ l1 = l1.next;
+ } else {
+ tmp.next = l2;
+ l2 = l2.next;
+ }
+ tmp = tmp.next;
+ }
+
+ if (l1 != null) {
tmp.next = l1;
- l1 = l1.next;
- } else {
+ }
+ if (l2 != null) {
tmp.next = l2;
- l2 = l2.next;
}
- tmp = tmp.next;
- }
-
- if (l1 != null) {
- tmp.next = l1;
- }
- if (l2 != null) {
- tmp.next = l2;
+ return result.next;
}
- return result.next;
}
-
}
diff --git a/src/main/java/com/fishercoder/solutions/_149.java b/src/main/java/com/fishercoder/solutions/_149.java
index 2f668bf371..a2be015baf 100644
--- a/src/main/java/com/fishercoder/solutions/_149.java
+++ b/src/main/java/com/fishercoder/solutions/_149.java
@@ -1,85 +1,95 @@
package com.fishercoder.solutions;
import com.fishercoder.common.classes.Point;
+import java.util.HashMap;
+import java.util.Map;
/**
+ * 149. Max Points on a Line
+ *
* Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.
+ *
+ * Example 1:
+ * Input: [[1,1],[2,2],[3,3]]
+ * Output: 3
+ * Explanation:
+ * ^
+ * |
+ * | o
+ * | o
+ * | o
+ * +------------->
+ * 0 1 2 3 4
+ *
+ * Example 2:
+ * Input: [[1,1],[3,2],[5,3],[4,1],[2,3],[1,4]]
+ * Output: 4
+ * Explanation:
+ * ^
+ * |
+ * | o
+ * | o o
+ * | o
+ * | o o
+ * +------------------->
+ * 0 1 2 3 4 5 6
+ *
*/
public class _149 {
+ public static class Solution1 {
+ /** credit: https://leetcode.com/problems/max-points-on-a-line/discuss/47113/A-java-solution-with-notes */
public int maxPoints(Point[] points) {
- int max = 0;
- if (points.length == 0) {
- max = 0;
- } else if (points.length == 1) {
- max = 1;
- } else if (points.length == 2) {
- max = 2;
- } else if (points.length == 3) {
- max = 2;
- if ((points[0].x - points[1].x) * (points[1].y - points[2].y) == (points[0].y - points[1].y)
- * (points[1].x - points[2].x)) {
- max++;
- }
- } else {
- int[][] maxPoints = new int[points.length][points.length];
- for (int i = 0; i < points.length; i++) {
- for (int j = 0; j < points.length && j != i; j++) {
- maxPoints[i][j] = 2;
- // System.out.print(maxPoints[i][j] + " ");
- }
- }
+ if (points == null) {
+ return 0;
+ }
+ if (points.length <= 2) {
+ return points.length;
+ }
- for (int i = 0; i < points.length; i++) {
- for (int j = 0; (j < points.length) && (j != i); j++) {
- if (((points[i].x == points[j].x) && (points[i].y == points[j].y))) {
- for (int k = 0; (k < points.length); k++) {
- if ((k != i) && (k != j)) {
- if (((points[k].x == points[i].x) && (points[k].y == points[i].y))) {
- maxPoints[i][j]++;
- }
- }
- }
- } else {
- for (int k = 0; (k < points.length); k++) {
- /*
- * Here, I must put the judgment (k!=i) && (k!=j) in the
- * if statement instead of in the for, otherwise, when k
- * equals i or j, it will stop traversing the rest of
- * the points that k represents!
- *
- * This is the key to solving this problem and Siyuan
- * Song helped me spot this error!
- *
- * It took me an hour and couldn't find any clue!
- */
- if ((k != i) && (k != j)) {
- if (((points[k].x == points[i].x) && (points[k].y == points[i].y))) {
- maxPoints[i][j]++;
- } else if (((points[k].x == points[j].x) && (points[k].y == points[j].y))) {
- maxPoints[i][j]++;
- } else if ((points[i].x - points[j].x)
- * (points[k].y - points[j].y) == (points[i].y - points[j].y)
- * (points[k].x - points[j].x)) {
- maxPoints[i][j]++;
+ Map> map = new HashMap<>();
+ int result = 0;
+ for (int i = 0; i < points.length; i++) {
+ map.clear();
+ int overlap = 0;
+ int max = 0;
+ for (int j = i + 1; j < points.length; j++) {
+ int x = points[j].x - points[i].x;
+ int y = points[j].y - points[i].y;
+ if (x == 0 && y == 0) {
+ overlap++;
+ continue;
+ }
+ int gcd = generateGCD(x, y);
+ if (gcd != 0) {
+ x /= gcd;
+ y /= gcd;
+ }
- }
- }
- }
- }
- }
- }
- for (int m = 0; m < points.length; m++) {
- for (int n = 0; n < points.length; n++) {
- if (maxPoints[m][n] > max) {
- // System.out.print("maxPoints[" + m + "][" + n +"]:" +
- // maxPoints[m][n] + "\t");
- max = maxPoints[m][n];
- }
- }
+ if (map.containsKey(x)) {
+ if (map.get(x).containsKey(y)) {
+ map.get(x).put(y, map.get(x).get(y) + 1);
+ } else {
+ map.get(x).put(y, 1);
}
+ } else {
+ Map m = new HashMap<>();
+ m.put(y, 1);
+ map.put(x, m);
+ }
+ max = Math.max(max, map.get(x).get(y));
}
- return max;
+ result = Math.max(result, max + overlap + 1);
+ }
+ return result;
}
+ private int generateGCD(int a, int b) {
+ if (b == 0) {
+ return a;
+ } else {
+ return generateGCD(b, a % b);
+ }
+ }
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_15.java b/src/main/java/com/fishercoder/solutions/_15.java
index d61e2ceabc..800ffcc9e0 100644
--- a/src/main/java/com/fishercoder/solutions/_15.java
+++ b/src/main/java/com/fishercoder/solutions/_15.java
@@ -6,10 +6,11 @@
/**
* 15. 3Sum
+ *
* Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0?
* Find all unique triplets in the array which gives the sum of zero.
-
- Note: The solution set must not contain duplicate triplets.
+ *
+ * Note: The solution set must not contain duplicate triplets.
For example, given array S = [-1, 0, 1, 2, -1, -4],
@@ -22,38 +23,38 @@
public class _15 {
- public List> threeSum(int[] nums) {
- List> result = new ArrayList<>();
- if (nums == null || nums.length == 0) {
- return result;
- }
- Arrays.sort(nums);
- for (int i = 0; i < nums.length; i++) {
- if (i >= 1 && nums[i] == nums[i - 1]) {
- continue;
- }
- int left = i + 1;
- int right = nums.length - 1;
- while (left < right) {
- int sum = nums[i] + nums[left] + nums[right];
- if (sum == 0) {
- result.add(Arrays.asList(nums[i], nums[left], nums[right]));
- /**be sure to skip duplicates*/
- while (left + 1 < right && nums[left] == nums[left + 1]) {
+ public static class Solution1 {
+ public List> threeSum(int[] nums) {
+ Arrays.sort(nums);
+ List> result = new ArrayList<>();
+ for (int i = 0; i < nums.length - 2; i++) {
+ if (i >= 1 && nums[i] == nums[i - 1]) {
+ continue;
+ }
+ int left = i + 1;
+ int right = nums.length - 1;
+ while (left < right) {
+ int sum = nums[i] + nums[left] + nums[right];
+ if (sum == 0) {
+ result.add(Arrays.asList(nums[i], nums[left], nums[right]));
+
+ while (left + 1 < right && nums[left] == nums[left + 1]) {
+ left++;
+ }
+
+ while (right - 1 > left && nums[right] == nums[right - 1]) {
+ right--;
+ }
left++;
- }
- while (right - 1 > left && nums[right] == nums[right - 1]) {
right--;
+ } else if (sum > 0) {
+ right--;
+ } else {
+ left++;
}
- left++;
- right--;
- } else if (sum > 0) {
- right--;
- } else {
- left++;
}
}
+ return result;
}
- return result;
}
}
diff --git a/src/main/java/com/fishercoder/solutions/_150.java b/src/main/java/com/fishercoder/solutions/_150.java
index c8e7abfbd9..98899aee98 100644
--- a/src/main/java/com/fishercoder/solutions/_150.java
+++ b/src/main/java/com/fishercoder/solutions/_150.java
@@ -5,61 +5,88 @@
import java.util.Stack;
/**
- * Evaluate the value of an arithmetic expression in Reverse Polish Notation.
-
- Valid operators are +, -, *, /. Each operand may be an integer or another expression.
-
- Some examples:
-
- ["2", "1", "+", "3", "*"] -> ((2 + 1) * 3) -> 9
- ["4", "13", "5", "/", "+"] -> (4 + (13 / 5)) -> 6
-
+ * 150. Evaluate Reverse Polish Notation
+ *
+ * Evaluate the value of an arithmetic expression in Reverse Polish Notation.
+ *
+ * Valid operators are +, -, *, /. Each operand may be an integer or another expression.
+ *
+ * Note:
+ *
+ * Division between two integers should truncate toward zero.
+ * The given RPN expression is always valid. That means the expression would always evaluate to a result and there won't be any divide by zero operation.
+ *
+ * Example 1:
+ *
+ * Input: ["2", "1", "+", "3", "*"]
+ * Output: 9
+ * Explanation: ((2 + 1) * 3) = 9
+ *
+ * Example 2:
+ *
+ * Input: ["4", "13", "5", "/", "+"]
+ * Output: 6
+ * Explanation: (4 + (13 / 5)) = 6
+ *
+ * Example 3:
+ *
+ * Input: ["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"]
+ * Output: 22
+ * Explanation:
+ * ((10 * (6 / ((9 + 3) * -11))) + 17) + 5
+ * = ((10 * (6 / (12 * -11))) + 17) + 5
+ * = ((10 * (6 / -132)) + 17) + 5
+ * = ((10 * 0) + 17) + 5
+ * = (0 + 17) + 5
+ * = 17 + 5
+ * = 22
*/
public class _150 {
- public int evalRPN(String[] tokens) {
- Stack stack = new Stack();
- Set op = new HashSet();
- op.add("+");
- op.add("-");
- op.add("*");
- op.add("/");
+ public static class Solution1 {
+ public int evalRPN(String[] tokens) {
+ Stack stack = new Stack<>();
+ Set op = new HashSet();
+ op.add("+");
+ op.add("-");
+ op.add("*");
+ op.add("/");
- int exp = 0;
- String operand1 = "";
- String operand2 = "";
- for (int i = 0; i < tokens.length;) {
- while ((i < tokens.length) && (!op.contains(tokens[i]))) {
- stack.push(tokens[i]);
- i++;
- }
- if (i == tokens.length) {
- if (!stack.isEmpty()) {
- return Integer.parseInt(stack.pop());
- }
- } else if (op.contains(tokens[i])) {
- if (!stack.isEmpty()) {
- operand2 = stack.pop();
+ int exp = 0;
+ String operand1 = "";
+ String operand2 = "";
+ for (int i = 0; i < tokens.length; ) {
+ while ((i < tokens.length) && (!op.contains(tokens[i]))) {
+ stack.push(tokens[i]);
+ i++;
}
- if (!stack.isEmpty() && !op.contains(stack.peek())) {
- operand1 = stack.pop();
+ if (i == tokens.length) {
+ if (!stack.isEmpty()) {
+ return Integer.parseInt(stack.pop());
+ }
+ } else if (op.contains(tokens[i])) {
+ if (!stack.isEmpty()) {
+ operand2 = stack.pop();
+ }
+ if (!stack.isEmpty() && !op.contains(stack.peek())) {
+ operand1 = stack.pop();
+ }
+ if (tokens[i].equals("+")) {
+ exp = Integer.parseInt(operand1) + Integer.parseInt(operand2);
+ } else if (tokens[i].equals("-")) {
+ exp = Integer.parseInt(operand1) - Integer.parseInt(operand2);
+ } else if (tokens[i].equals("*")) {
+ exp = Integer.parseInt(operand1) * Integer.parseInt(operand2);
+ } else if (tokens[i].equals("/")) {
+ exp = Integer.parseInt(operand1) / Integer.parseInt(operand2);
+ } else {
+ exp = Integer.parseInt(operand2);
+ }
+ stack.push(String.valueOf(exp));
+ i++;
}
- if (tokens[i].equals("+")) {
- exp = Integer.parseInt(operand1) + Integer.parseInt(operand2);
- } else if (tokens[i].equals("-")) {
- exp = Integer.parseInt(operand1) - Integer.parseInt(operand2);
- } else if (tokens[i].equals("*")) {
- exp = Integer.parseInt(operand1) * Integer.parseInt(operand2);
- } else if (tokens[i].equals("/")) {
- exp = Integer.parseInt(operand1) / Integer.parseInt(operand2);
- } else {
- exp = Integer.parseInt(operand2);
- }
- stack.push(String.valueOf(exp));
- i++;
}
+ return Integer.parseInt(stack.pop());
}
- return Integer.parseInt(stack.pop());
}
-
}
diff --git a/src/main/java/com/fishercoder/solutions/_151.java b/src/main/java/com/fishercoder/solutions/_151.java
index fb77f70a44..41c06e2a1f 100644
--- a/src/main/java/com/fishercoder/solutions/_151.java
+++ b/src/main/java/com/fishercoder/solutions/_151.java
@@ -1,57 +1,48 @@
package com.fishercoder.solutions;
-import com.fishercoder.common.utils.CommonUtils;
-
import java.util.ArrayDeque;
import java.util.Deque;
/**
* 151. Reverse Words in a String
- * Given an input string, reverse the string word by word.
-For example,
-Given s = "the sky is blue",
-return "blue is sky the".
+
+ Given an input string, reverse the string word by word.
+ For example,
+ Given s = "the sky is blue",
+ return "blue is sky the".
Clarification:
+
What constitutes a word?
A sequence of non-space characters constitutes a word.
Could the input string contain leading or trailing spaces?
Yes. However, your reversed string should not contain leading or trailing spaces.
How about multiple spaces between two words?
Reduce them to a single space in the reversed string.
-
*/
public class _151 {
-
+ public static class Solution1 {
public String reverseWords(String s) {
- s.trim();
- if (s == null || s.length() == 0) {
- return "";
+ s.trim();
+ if (s == null || s.length() == 0) {
+ return "";
+ }
+ String[] words = s.split(" ");
+ if (words == null || words.length == 0) {
+ return "";
+ }
+ Deque stack = new ArrayDeque<>();
+ for (String word : words) {
+ if (!word.equals("")) {
+ stack.offer(word);
}
- String[] words = s.split(" ");
- if (words == null || words.length == 0) {
- return "";
- }
- Deque stack = new ArrayDeque<>();
- for (String word : words) {
- if (!word.equals("")) {
- stack.offer(word);
- }
- }
- StringBuilder stringBuilder = new StringBuilder();
- while (!stack.isEmpty()) {
- stringBuilder.append(stack.pollLast()).append(" ");
- }
- return stringBuilder.substring(0, stringBuilder.length() - 1).toString();
- }
-
- public static void main(String... args) {
- /**This main program is to demo:
- * a string that contains consecutive empty spaces when splitting by delimiter " ",
- * it'll produce a an "" as an element.*/
- String s = "a b c";
- String[] strs = s.split(" ");
- CommonUtils.printArray_generic_type(strs);
+ }
+ StringBuilder stringBuilder = new StringBuilder();
+ while (!stack.isEmpty()) {
+ stringBuilder.append(stack.pollLast()).append(" ");
+ }
+ return stringBuilder.substring(0, stringBuilder.length() - 1).toString();
}
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_152.java b/src/main/java/com/fishercoder/solutions/_152.java
index 1ac94af9c8..ae5b1af255 100644
--- a/src/main/java/com/fishercoder/solutions/_152.java
+++ b/src/main/java/com/fishercoder/solutions/_152.java
@@ -1,24 +1,26 @@
package com.fishercoder.solutions;
/**
- * Find the contiguous subarray within an array (containing at least one number) which has the largest product.
+ * 152. Maximum Product Subarray
+
+ Find the contiguous subarray within an array (containing at least one number) which has the largest product.
For example, given the array [2,3,-2,4],
the contiguous subarray [2,3] has the largest product = 6.
*/
public class _152 {
-
+ public static class Solution1 {
public int maxProduct(int[] nums) {
- int pos = nums[0];
- int neg = nums[0];
- int max = nums[0];
- for (int i = 1; i < nums.length; i++) {
- int temp = pos;
- pos = Math.max(nums[i], nums[i] * ((nums[i] >= 0) ? pos : neg));
- neg = Math.min(nums[i], nums[i] * ((nums[i] >= 0) ? neg : temp));
- max = Math.max(max, pos);
- }
- return max;
+ int pos = nums[0];
+ int neg = nums[0];
+ int max = nums[0];
+ for (int i = 1; i < nums.length; i++) {
+ int temp = pos;
+ pos = Math.max(nums[i], nums[i] * ((nums[i] >= 0) ? pos : neg));
+ neg = Math.min(nums[i], nums[i] * ((nums[i] >= 0) ? neg : temp));
+ max = Math.max(max, pos);
+ }
+ return max;
}
-
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_153.java b/src/main/java/com/fishercoder/solutions/_153.java
index 054b985f64..9a3d43a02d 100644
--- a/src/main/java/com/fishercoder/solutions/_153.java
+++ b/src/main/java/com/fishercoder/solutions/_153.java
@@ -2,35 +2,45 @@
/**
* 153. Find Minimum in Rotated Sorted Array
- * Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
- (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).
+ Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
+
+ (i.e., [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2]).
Find the minimum element.
You may assume no duplicate exists in the array.
+
+ Example 1:
+ Input: [3,4,5,1,2]
+ Output: 1
+
+ Example 2:
+ Input: [4,5,6,7,0,1,2]
+ Output: 0
+
*/
public class _153 {
-
+ public static class Solution1 {
public int findMin(int[] nums) {
- int left = 0;
- int right = nums.length - 1;
- if (nums[left] < nums[right]) {
- return nums[left];
- }
- int min = nums[0];
- while (left + 1 < right) {
- int mid = left + (right - left) / 2;
- min = Math.min(min, nums[mid]);
- if (nums[mid] > nums[left]) {
- min = Math.min(nums[left], min);
- left = mid + 1;
- } else if (nums[mid] < nums[left]) {
- right = mid - 1;
- }
+ int left = 0;
+ int right = nums.length - 1;
+ if (nums[left] < nums[right]) {
+ return nums[left];
+ }
+ int min = nums[0];
+ while (left + 1 < right) {
+ int mid = left + (right - left) / 2;
+ min = Math.min(min, nums[mid]);
+ if (nums[mid] > nums[left]) {
+ min = Math.min(nums[left], min);
+ left = mid + 1;
+ } else if (nums[mid] < nums[left]) {
+ right = mid - 1;
}
- min = Math.min(min, Math.min(nums[left], nums[right]));
- return min;
+ }
+ min = Math.min(min, Math.min(nums[left], nums[right]));
+ return min;
}
-
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_154.java b/src/main/java/com/fishercoder/solutions/_154.java
index 45b1ef3f07..930f8b13c1 100644
--- a/src/main/java/com/fishercoder/solutions/_154.java
+++ b/src/main/java/com/fishercoder/solutions/_154.java
@@ -2,40 +2,51 @@
/**
* 154. Find Minimum in Rotated Sorted Array II
- *
- * Follow up for "Find Minimum in Rotated Sorted Array":
- What if duplicates are allowed?
- Would this affect the run-time complexity? How and why?
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
- (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).
+ (i.e., [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2]).
Find the minimum element.
The array may contain duplicates.
+
+ Example 1:
+ Input: [1,3,5]
+ Output: 1
+
+ Example 2:
+ Input: [2,2,2,0,1]
+ Output: 0
+
+ Note:
+ This is a follow up problem to Find Minimum in Rotated Sorted Array.
+ Would allow duplicates affect the run-time complexity? How and why?
+
*/
public class _154 {
+ public static class Solution1 {
public int findMin(int[] nums) {
- int left = 0;
- int right = nums.length - 1;
- if (nums[left] < nums[right]) {
- return nums[left];
- }
- int min = nums[0];
- while (left + 1 < right) {
- int mid = left + (right - left) / 2;
- min = Math.min(min, nums[mid]);
- if (nums[mid] > nums[left]) {
- min = Math.min(nums[left], min);
- left = mid + 1;
- } else if (nums[mid] < nums[left]) {
- right = mid - 1;
- } else {
- left++;
- }
+ int left = 0;
+ int right = nums.length - 1;
+ if (nums[left] < nums[right]) {
+ return nums[left];
+ }
+ int min = nums[0];
+ while (left + 1 < right) {
+ int mid = left + (right - left) / 2;
+ min = Math.min(min, nums[mid]);
+ if (nums[mid] > nums[left]) {
+ min = Math.min(nums[left], min);
+ left = mid + 1;
+ } else if (nums[mid] < nums[left]) {
+ right = mid - 1;
+ } else {
+ left++;
}
- min = Math.min(min, Math.min(nums[left], nums[right]));
- return min;
+ }
+ min = Math.min(min, Math.min(nums[left], nums[right]));
+ return min;
}
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_155.java b/src/main/java/com/fishercoder/solutions/_155.java
index a0be64367c..7029480b94 100644
--- a/src/main/java/com/fishercoder/solutions/_155.java
+++ b/src/main/java/com/fishercoder/solutions/_155.java
@@ -1,6 +1,5 @@
package com.fishercoder.solutions;
-
import java.util.Stack;
/**
@@ -25,47 +24,48 @@
public class _155 {
- public static class MinStack {
- private Stack stack;
- private int min;
-
- /**
- * initialize your data structure here.
- */
- public MinStack() {
- stack = new Stack();
- min = Integer.MAX_VALUE;
- }
+ public static class Solution1 {
+ class MinStack {
+ private Stack stack;
+ private int min;
- public void push(int x) {
- /**All the trick happens here, we push the second minimum number onto the stack before we push the newer one,
- * this way, when popping, we could always get the next minimum one in constant time.*/
- if (x <= min) {
- stack.push(min);
- min = x;
+ /**
+ * initialize your data structure here.
+ */
+ public MinStack() {
+ stack = new Stack();
+ min = Integer.MAX_VALUE;
}
- stack.push(x);
- }
- public void pop() {
- if (min == stack.peek()) {
- stack.pop();
- min = stack.pop();
- } else {
- stack.pop();
+ public void push(int x) {
+ /**All the trick happens here, we push the second minimum number onto the stack before we push the newer one,
+ * this way, when popping, we could always get the next minimum one in constant time.*/
+ if (x <= min) {
+ stack.push(min);
+ min = x;
+ }
+ stack.push(x);
}
- if (stack.isEmpty()) {
- min = Integer.MAX_VALUE;
+
+ public void pop() {
+ if (min == stack.peek()) {
+ stack.pop();
+ min = stack.pop();
+ } else {
+ stack.pop();
+ }
+ if (stack.isEmpty()) {
+ min = Integer.MAX_VALUE;
+ }
}
- }
- public int top() {
- return stack.peek();
- }
+ public int top() {
+ return stack.peek();
+ }
- public int getMin() {
- return min;
+ public int getMin() {
+ return min;
+ }
}
}
-
}
diff --git a/src/main/java/com/fishercoder/solutions/_156.java b/src/main/java/com/fishercoder/solutions/_156.java
index 0ad09f93ab..9a50d8f0b1 100644
--- a/src/main/java/com/fishercoder/solutions/_156.java
+++ b/src/main/java/com/fishercoder/solutions/_156.java
@@ -3,6 +3,8 @@
import com.fishercoder.common.classes.TreeNode;
/**
+ * 156. Binary Tree Upside Down
+ *
* Given a binary tree where all the right nodes are either leaf nodes with a sibling
* (a left node that shares the same parent node) or empty,
* flip it upside down and turn it into a tree where the original right nodes turned into left leaf nodes. Return the new root.
@@ -14,25 +16,29 @@
2 3
/ \
4 5
+
return the root of the binary tree [4,5,2,#,#,3,1].
4
/ \
5 2
/ \
3 1
+
confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ.
*/
public class _156 {
- public TreeNode upsideDownBinaryTree(TreeNode root) {
- if (root == null || root.left == null && root.right == null) {
- return root;
+ public static class Solution1 {
+ public TreeNode upsideDownBinaryTree(TreeNode root) {
+ if (root == null || root.left == null && root.right == null) {
+ return root;
+ }
+ TreeNode newRoot = upsideDownBinaryTree(root.left);
+ root.left.left = root.right;
+ root.left.right = root;
+ root.left = null;
+ root.right = null;
+ return newRoot;
}
- TreeNode newRoot = upsideDownBinaryTree(root.left);
- root.left.left = root.right;
- root.left.right = root;
- root.left = null;
- root.right = null;
- return newRoot;
}
}
diff --git a/src/main/java/com/fishercoder/solutions/_157.java b/src/main/java/com/fishercoder/solutions/_157.java
index 2730416ba4..cfc7117400 100644
--- a/src/main/java/com/fishercoder/solutions/_157.java
+++ b/src/main/java/com/fishercoder/solutions/_157.java
@@ -1,36 +1,46 @@
package com.fishercoder.solutions;
/**
+ * 157. Read N Characters Given Read4
+ *
* The API: int read4(char *buf) reads 4 characters at a time from a file.
- *
- * The return value is the actual number of characters read. For example, it returns 3 if there is
- * only 3 characters left in the file.
- *
- * By using the read4 API, implement the function int read(char *buf, int n) that reads n characters
- * from the file.
- *
- * Note: The read function will only be called once for each test case.
- */
-
-/**
- * The problem description is pretty ambiguous, actually the problem means to Keep reading until
- * either you have gotten n characters or there is no more characters to read.
+ *
+ * The return value is the actual number of characters read. For example, it returns 3 if there is only 3 characters left in the file.
+ *
+ * By using the read4 API, implement the function int read(char *buf, int n) that reads n characters from the file.
+ *
+ * Example 1:
+ *
+ * Input: buf = "abc", n = 4
+ * Output: "abc"
+ * Explanation: The actual number of characters read is 3, which is "abc".
+ *
+ * Example 2:
+ *
+ * Input: buf = "abcde", n = 5
+ * Output: "abcde"
+ *
+ * Note:
+ * The read function will only be called once for each test case.
+ *
*/
public class _157 {
- public int read(char[] buf, int n) {
- int index = 0;
- int next = 0;
- char[] buffer = new char[4];
- while (index < n && (next = read4(buffer)) != 0) {
- for (int i = 0; i < next && index < n; index++, i++) {
- buf[index] = buffer[i];
+ public static class Solution1 {
+ public int read(char[] buf, int n) {
+ int index = 0;
+ int next = 0;
+ char[] buffer = new char[4];
+ while (index < n && (next = read4(buffer)) != 0) {
+ for (int i = 0; i < next && index < n; index++, i++) {
+ buf[index] = buffer[i];
+ }
}
+ return index;
}
- return index;
- }
- private int read4(char[] buffer) {
- //this is a fake method to make Eclipse happy
- return 0;
+ private int read4(char[] buffer) {
+ //this is a fake method to make Eclipse happy
+ return 0;
+ }
}
}
diff --git a/src/main/java/com/fishercoder/solutions/_158.java b/src/main/java/com/fishercoder/solutions/_158.java
index ff6df434c7..3168731d21 100644
--- a/src/main/java/com/fishercoder/solutions/_158.java
+++ b/src/main/java/com/fishercoder/solutions/_158.java
@@ -1,7 +1,8 @@
package com.fishercoder.solutions;
/**
- * The API: int read4(char *buf) reads 4 characters at a time from a file.
+ 158. Read N Characters Given Read4 II - Call multiple times
+ The API: int read4(char *buf) reads 4 characters at a time from a file.
The return value is the actual number of characters read. For example, it returns 3 if there is only 3 characters left in the file.
@@ -9,40 +10,54 @@ By using the read4 API, implement the function int read(char *buf, int n) that r
Note:
The read function may be called multiple times.
+
+ Example 1:
+
+ Given buf = "abc"
+ read("abc", 1) // returns "a"
+ read("abc", 2); // returns "bc"
+ read("abc", 1); // returns ""
+
+ Example 2:
+
+ Given buf = "abc"
+ read("abc", 4) // returns "abc"
+ read("abc", 1); // returns ""
*/
public class _158 {
- /**
- * @param buf Destination buffer
- * @param n Maximum number of characters to read
- * @return The number of characters read
- */
- private int buffPtr = 0;
- private int buffCnt = 0;
- private char[] buff = new char[4];
-
- public int read(char[] buf, int n) {
- int ptr = 0;
- while (ptr < n) {
- if (buffPtr == 0) {
- buffCnt = read4(buff);
- }
- if (buffCnt == 0) {
- break;
- }
- while (ptr < n && buffPtr < buffCnt) {
- buf[ptr++] = buff[buffPtr++];
- }
- if (buffPtr >= buffCnt) {
- buffPtr = 0;
- }
- }
- return ptr;
- }
-
- //This is a fake method to make IDE happy.
- private int read4(char[] buff) {
- return 1;
- }
-
+ public static class Solution1 {
+ /**
+ * @param buf Destination buffer
+ * @param n Maximum number of characters to read
+ * @return The number of characters read
+ */
+ private int buffPtr = 0;
+ private int buffCnt = 0;
+ private char[] buff = new char[4];
+
+ public int read(char[] buf, int n) {
+ int ptr = 0;
+ while (ptr < n) {
+ if (buffPtr == 0) {
+ buffCnt = read4(buff);
+ }
+ if (buffCnt == 0) {
+ break;
+ }
+ while (ptr < n && buffPtr < buffCnt) {
+ buf[ptr++] = buff[buffPtr++];
+ }
+ if (buffPtr >= buffCnt) {
+ buffPtr = 0;
+ }
+ }
+ return ptr;
+ }
+
+ //This is a fake method to make IDE happy.
+ private int read4(char[] buff) {
+ return 1;
+ }
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_159.java b/src/main/java/com/fishercoder/solutions/_159.java
index 9a991483f4..a1661a00f5 100644
--- a/src/main/java/com/fishercoder/solutions/_159.java
+++ b/src/main/java/com/fishercoder/solutions/_159.java
@@ -1,42 +1,53 @@
package com.fishercoder.solutions;
import java.util.HashMap;
+import java.util.Map;
/**
- * Given a string, find the length of the longest substring T that contains at most 2 distinct characters.
+ * 159. Longest Substring with At Most Two Distinct Characters
- For example, Given s = “eceba”,
+ Given a string s , find the length of the longest substring t that contains at most 2 distinct characters.
- T is "ece" which its length is 3.
+ Example 1:
+
+ Input: "eceba"
+ Output: 3
+ Explanation: t is "ece" which its length is 3.
+
+ Example 2:
+
+ Input: "ccaabbb"
+ Output: 5
+ Explanation: t is "aabbb" which its length is 5.
*/
public class _159 {
-
+ public static class Solution1 {
public int lengthOfLongestSubstringTwoDistinct(String s) {
- if (s.length() < 1) {
- return 0;
+ if (s.length() < 1) {
+ return 0;
+ }
+ Map index = new HashMap<>();
+ int lo = 0;
+ int hi = 0;
+ int maxLength = 0;
+ while (hi < s.length()) {
+ if (index.size() <= 2) {
+ char c = s.charAt(hi);
+ index.put(c, hi);
+ hi++;
}
- HashMap index = new HashMap();
- int lo = 0;
- int hi = 0;
- int maxLength = 0;
- while (hi < s.length()) {
- if (index.size() <= 2) {
- char c = s.charAt(hi);
- index.put(c, hi);
- hi++;
- }
- if (index.size() > 2) {
- int leftMost = s.length();
- for (int i : index.values()) {
- leftMost = Math.min(leftMost, i);
- }
- char c = s.charAt(leftMost);
- index.remove(c);
- lo = leftMost + 1;
- }
- maxLength = Math.max(maxLength, hi - lo);
+ if (index.size() > 2) {
+ int leftMost = s.length();
+ for (int i : index.values()) {
+ leftMost = Math.min(leftMost, i);
+ }
+ char c = s.charAt(leftMost);
+ index.remove(c);
+ lo = leftMost + 1;
}
- return maxLength;
+ maxLength = Math.max(maxLength, hi - lo);
+ }
+ return maxLength;
}
-
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_16.java b/src/main/java/com/fishercoder/solutions/_16.java
index 10bdeca62e..899ba5e403 100644
--- a/src/main/java/com/fishercoder/solutions/_16.java
+++ b/src/main/java/com/fishercoder/solutions/_16.java
@@ -3,45 +3,47 @@
import java.util.Arrays;
/**
- * Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution.
+ * 16. 3Sum Closest
+ *
+ * Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target.
+ * Return the sum of the three integers. You may assume that each input would have exactly one solution.
* For example, given array S = {-1 2 1 -4}, and target = 1.
* The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
*/
public class _16 {
- public int threeSumClosest(int[] nums, int target) {
- if (nums == null || nums.length == 0) {
- return 0;
- }
- Arrays.sort(nums);
- int len = nums.length;
- if (len < 3) {
- int sum = 0;
- for (int i : nums) {
- sum += i;
+ public static class Solution1 {
+ public int threeSumClosest(int[] nums, int target) {
+ Arrays.sort(nums);
+ int len = nums.length;
+ if (len < 3) {
+ int sum = 0;
+ for (int i : nums) {
+ sum += i;
+ }
+ return sum;
}
- return sum;
- }
- int sum = nums[0] + nums[1] + nums[2];
- for (int i = 0; i < nums.length - 2; i++) {
- int left = i + 1;
- int right = nums.length - 1;
- while (left < right) {
- int thisSum = nums[i] + nums[left] + nums[right];
- if (Math.abs(target - thisSum) < Math.abs(target - sum)) {
- sum = thisSum;
- if (sum == target) {
- return sum;
+ int sum = nums[0] + nums[1] + nums[2];
+ for (int i = 0; i < len - 2; i++) {
+ int left = i + 1;
+ int right = len - 1;
+ while (left < right) {
+ int thisSum = nums[i] + nums[left] + nums[right];
+ if (Math.abs(target - thisSum) < Math.abs(target - sum)) {
+ sum = thisSum;
+ if (sum == target) {
+ return sum;
+ }
+ } else if (target > thisSum) {
+ left++;
+ } else {
+ right--;
}
- } else if (target > thisSum) {
- left++;
- } else {
- right--;
}
}
+ return sum;
}
- return sum;
}
}
diff --git a/src/main/java/com/fishercoder/solutions/_160.java b/src/main/java/com/fishercoder/solutions/_160.java
index dfd7d37d60..f9b525167c 100644
--- a/src/main/java/com/fishercoder/solutions/_160.java
+++ b/src/main/java/com/fishercoder/solutions/_160.java
@@ -5,9 +5,9 @@
import java.util.HashSet;
import java.util.Set;
-/**160. Intersection of Two Linked Lists
- *
- * Write a program to find the node at which the intersection of two singly linked lists begins.
+/**
+ * 160. Intersection of Two Linked Lists
+ Write a program to find the node at which the intersection of two singly linked lists begins.
For example, the following two linked lists:
diff --git a/src/main/java/com/fishercoder/solutions/_161.java b/src/main/java/com/fishercoder/solutions/_161.java
index a7ad30512c..e442968415 100644
--- a/src/main/java/com/fishercoder/solutions/_161.java
+++ b/src/main/java/com/fishercoder/solutions/_161.java
@@ -1,48 +1,71 @@
package com.fishercoder.solutions;
-/**Given two strings S and T, determine if they are both one edit distance apart.*/
+/**
+ * 161. One Edit Distance
+ *
+ * Given two strings s and t, determine if they are both one edit distance apart.
+ *
+ * Note:
+ *
+ * There are 3 possiblities to satisify one edit distance apart:
+ *
+ * Insert a character into s to get t
+ * Delete a character from s to get t
+ * Replace a character of s to get t
+ *
+ * Example 1:
+ * Input: s = "ab", t = "acb"
+ * Output: true
+ * Explanation: We can insert 'c' into s to get t.
+ *
+ * Example 2:
+ * Input: s = "cab", t = "ad"
+ * Output: false
+ * Explanation: We cannot get t from s by only one step.
+ *
+ * Example 3:
+ * Input: s = "1203", t = "1213"
+ * Output: true
+ * Explanation: We can replace '0' with '1' to get t.
+ */
public class _161 {
+ public static class Solution1 {
+ public boolean isOneEditDistance(String s, String t) {
+ char[] schar = s.toCharArray();
+ char[] tchar = t.toCharArray();
- public static boolean isOneEditDistance(String s, String t) {
- char[] schar = s.toCharArray();
- char[] tchar = t.toCharArray();
+ if (Math.abs(s.length() - t.length()) == 1) {
+ char[] longer = (s.length() > t.length()) ? schar : tchar;
+ char[] shorter = (longer == schar) ? tchar : schar;
- if (Math.abs(s.length() - t.length()) == 1) {
- char[] longer = (s.length() > t.length()) ? schar : tchar;
- char[] shorter = (longer == schar) ? tchar : schar;
-
- int diffCnt = 0;
- int i = 0;
- int j = 0;
- for (; i < shorter.length && j < longer.length; ) {
- if (longer[j] != shorter[i]) {
- diffCnt++;
- j++;
- } else {
- i++;
- j++;
- }
- }
- return diffCnt == 1 || diffCnt == 0;//it could be the last char of the longer is the different one, in that case, diffCnt remains to be zero
- } else if (s.length() == t.length()) {
- int diffCnt = 0;
- for (int i = 0; i < s.length(); i++) {
- if (schar[i] != tchar[i]) {
- diffCnt++;
- }
- if (diffCnt > 1) {
- return false;
- }
- }
- return diffCnt == 1;
+ int diffCnt = 0;
+ int i = 0;
+ int j = 0;
+ for (; i < shorter.length && j < longer.length; ) {
+ if (longer[j] != shorter[i]) {
+ diffCnt++;
+ j++;
+ } else {
+ i++;
+ j++;
+ }
}
- return false;
- }
-
- public static void main(String... strings) {
- String s = "a";
- String t = "ac";
- System.out.println(isOneEditDistance(s, t));
+ return diffCnt == 1
+ || diffCnt
+ == 0;//it could be the last char of the longer is the different one, in that case, diffCnt remains to be zero
+ } else if (s.length() == t.length()) {
+ int diffCnt = 0;
+ for (int i = 0; i < s.length(); i++) {
+ if (schar[i] != tchar[i]) {
+ diffCnt++;
+ }
+ if (diffCnt > 1) {
+ return false;
+ }
+ }
+ return diffCnt == 1;
+ }
+ return false;
}
-
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_162.java b/src/main/java/com/fishercoder/solutions/_162.java
index 3c6d67e2eb..9327114d41 100644
--- a/src/main/java/com/fishercoder/solutions/_162.java
+++ b/src/main/java/com/fishercoder/solutions/_162.java
@@ -2,71 +2,83 @@
/**
* 162. Find Peak Element
- *
- * A peak element is an element that is greater than its neighbors.
- Given an input array where num[i] ≠ num[i+1], find a peak element and return its index.
+
+ A peak element is an element that is greater than its neighbors.
+
+ Given an input array nums, where nums[i] ≠ nums[i+1], find a peak element and return its index.
+
The array may contain multiple peaks, in that case return the index to any one of the peaks is fine.
- You may imagine that num[-1] = num[n] = -∞.
- For example, in array [1, 2, 3, 1], 3 is a peak element and your function should return the index number 2.*/
+
+ You may imagine that nums[-1] = nums[n] = -∞.
+
+ Example 1:
+ Input: nums = [1,2,3,1]
+ Output: 2
+ Explanation: 3 is a peak element and your function should return the index number 2.
+
+ Example 2:
+ Input: nums = [1,2,1,3,5,6,4]
+ Output: 1 or 5
+ Explanation: Your function can return either index number 1 where the peak element is 2,
+ or index number 5 where the peak element is 6.
+
+ Note:
+ Your solution should be in logarithmic complexity.
+ */
public class _162 {
+ public static class Solution1 {
/**
- * On discuss, this post has very good explanation about an O(logn) solution:
- * https://discuss.leetcode.com/topic/29329/java-solution-and-explanation-using-invariants
- *
+ * credit: https://discuss.leetcode.com/topic/29329/java-solution-and-explanation-using-invariants
+ *
* Basically, we need to keep this invariant:
* nums[left] > nums[left-1], then we could return left as the result
* or nums[right] > nums[right+1], then we could return right as the result
+ *
+ * Time: O(Ologn)
*/
- public static int findPeakElement_Ologn(int[] nums) {
-
- if (nums == null || nums.length == 0) {
- return 0;
- }
- int left = 0;
- int right = nums.length - 1;
- while (left + 1 < right) {
- int mid = left + (right - left) / 2;
- if (nums[mid] < nums[mid + 1]) {
- left = mid;
- } else {
- right = mid;
- }
+ public int findPeakElement(int[] nums) {
+ if (nums == null || nums.length == 0) {
+ return 0;
+ }
+ int left = 0;
+ int right = nums.length - 1;
+ while (left + 1 < right) {
+ int mid = left + (right - left) / 2;
+ if (nums[mid] < nums[mid + 1]) {
+ left = mid;
+ } else {
+ right = mid;
}
- return (left == nums.length - 1 || nums[left] > nums[left + 1]) ? left : right;
-
- }
-
- public static void main(String... strings) {
-// int[] nums = new int[]{1,2};
-// int[] nums = new int[]{1};
- int[] nums = new int[]{1, 2, 3, 1};
-// System.out.println(findPeakElement(nums));
- System.out.println(findPeakElement_Ologn(nums));
+ }
+ return (left == nums.length - 1 || nums[left] > nums[left + 1]) ? left : right;
}
+ }
+ public static class Solution2 {
/**
* My original O(n) solution.
*/
- public static int findPeakElement(int[] nums) {
- if (nums == null || nums.length == 0) {
- return 0;
- }
- int n = nums.length;
- int result = 0;
- for (int i = 0; i < n; i++) {
- if (i == 0 && n > 1 && nums[i] > nums[i + 1]) {
- result = i;
- break;
- } else if (i == n - 1 && i > 0 && nums[i] > nums[i - 1]) {
- result = i;
- break;
- } else if (i > 0 && i < n - 1 && nums[i] > nums[i - 1] && nums[i] > nums[i + 1]) {
- result = i;
- break;
- }
+ public int findPeakElement(int[] nums) {
+ if (nums == null || nums.length == 0) {
+ return 0;
+ }
+ int n = nums.length;
+ int result = 0;
+ for (int i = 0; i < n; i++) {
+ if (i == 0 && n > 1 && nums[i] > nums[i + 1]) {
+ result = i;
+ break;
+ } else if (i == n - 1 && i > 0 && nums[i] > nums[i - 1]) {
+ result = i;
+ break;
+ } else if (i > 0 && i < n - 1 && nums[i] > nums[i - 1] && nums[i] > nums[i + 1]) {
+ result = i;
+ break;
}
- return result;
+ }
+ return result;
}
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_163.java b/src/main/java/com/fishercoder/solutions/_163.java
index de91144c78..78603dc409 100644
--- a/src/main/java/com/fishercoder/solutions/_163.java
+++ b/src/main/java/com/fishercoder/solutions/_163.java
@@ -5,28 +5,30 @@
/**
* 163. Missing Ranges
+ *
* Given a sorted integer array where the range of elements are in the inclusive range [lower, upper], return its missing ranges.
* For example, given [0, 1, 3, 50, 75], lower = 0 and upper = 99, return ["2", "4->49", "51->74", "76->99"].
*/
public class _163 {
-
- public List findMissingRanges(int[] nums, int lower, int upper) {
- List result = new ArrayList<>();
- long low = (long) lower - 1;
- long up = 0;
- for (int i = 0; i <= nums.length; i++) {
- if (i == nums.length) {
- up = (long) upper + 1;
- } else {
- up = nums[i];
- }
- if (up == low + 2) {
- result.add(low + 1 + "");
- } else if (up > low + 2) {
- result.add((low + 1) + "->" + (up - 1));
+ public static class Solution1 {
+ public List findMissingRanges(int[] nums, int lower, int upper) {
+ List result = new ArrayList<>();
+ long low = (long) lower - 1;
+ long up = 0;
+ for (int i = 0; i <= nums.length; i++) {
+ if (i == nums.length) {
+ up = (long) upper + 1;
+ } else {
+ up = nums[i];
+ }
+ if (up == low + 2) {
+ result.add(low + 1 + "");
+ } else if (up > low + 2) {
+ result.add((low + 1) + "->" + (up - 1));
+ }
+ low = up;
}
- low = up;
+ return result;
}
- return result;
}
}
diff --git a/src/main/java/com/fishercoder/solutions/_164.java b/src/main/java/com/fishercoder/solutions/_164.java
index 5eec5cde5c..8336ae84da 100644
--- a/src/main/java/com/fishercoder/solutions/_164.java
+++ b/src/main/java/com/fishercoder/solutions/_164.java
@@ -3,137 +3,52 @@
import java.util.Arrays;
/**
+ * 164. Maximum Gap
+ *
* Given an unsorted array, find the maximum difference between the successive elements in its sorted form.
- * Try to solve it in linear time/space.
* Return 0 if the array contains less than 2 elements.
- * You may assume all elements in the array are non-negative integers and fit in the 32-bit signed integer range.
+ *
+ * Example 1:
+ * Input: [3,6,9,1]
+ * Output: 3
+ * Explanation: The sorted form of the array is [1,3,6,9], either
+ * (3,6) or (6,9) has the maximum difference 3.
+ *
+ * Example 2:
+ * Input: [10]
+ * Output: 0
+ * Explanation: The array contains less than 2 elements, therefore return 0.
+ *
+ * Note:
+ * You may assume all elements in the array are non-negative integers and fit in the 32-bit signed integer range.
+ * Try to solve it in linear time/space.
*/
public class _164 {
- //brute force
+ public static class Solution1 {
+ /** brute force solution */
public int maximumGap(int[] nums) {
- if (nums.length < 2) {
- return 0;
- }
-
- Arrays.sort(nums);
- int max = Integer.MIN_VALUE;
- for (int i = 1; i < nums.length; ) {
- while (i < nums.length && nums[i] == nums[i - 1]) {
- i++;
- }
- if (i == nums.length) {
- i--;
- max = (nums[i] - nums[i - 1] > max) ? nums[i] - nums[i - 1] : max;
- break;
- } else {
- max = (nums[i] - nums[i - 1] > max) ? nums[i] - nums[i - 1] : max;
- }
- if (nums[i] != nums[i - 1]) {
- i++;
- }
- }
- return max;
- }
-
-
- //http://www.programcreek.com/2014/03/leetcode-maximum-gap-java/
- class Bucket {
- int min = -1;
- int max = -1;
-
- public Bucket() {
- this.min = -1;
- this.max = -1;
- }
- }
-
- //compute interval and multiply by interval to get the index
- public int maximumGap_from_programcreek_1(int[] nums) {
- if (nums == null || nums.length < 2) {
- return 0;
- }
-
- int maxNum = nums[0];
- int minNum = nums[0];
- for (int i = 0; i < nums.length; i++) {
- maxNum = Math.max(maxNum, nums[i]);
- minNum = Math.min(minNum, nums[i]);
- }
-
- //initialize bucket array
- Bucket[] buckets = new Bucket[nums.length + 1];
- for (int i = 0; i < buckets.length; i++) {
- buckets[i] = new Bucket();
- }
-
- double interval = (double) nums.length / (maxNum - minNum);
- //distribute the array to different buckets
- for (int i = 0; i < nums.length; i++) {
- int index = (int) ((nums[i] - minNum) * interval);
- if (buckets[index].min == -1) {
- buckets[index].min = nums[i];
- buckets[index].max = nums[i];
- } else {
- buckets[index].min = Math.min(nums[i], buckets[index].min);
- buckets[index].max = Math.max(nums[i], buckets[index].max);
- }
- }
-
- //scan through the bucket array to find the maximal gap
- int result = 0;
- int prev = buckets[0].max;
- for (int i = 1; i < buckets.length; i++) {
- if (buckets[i].min != -1) {
- result = Math.max(result, buckets[i].min - prev);
- prev = buckets[i].max;
- }
- }
-
- return result;
- }
-
- //compute gap and divide by gap to get the index
- public int maximumGap_from_programcreek_2(int[] nums) {
- if (nums == null || nums.length < 2) {
- return 0;
- }
-
- int maxNum = nums[0];
- int minNum = nums[0];
- for (int i = 0; i < nums.length; i++) {
- maxNum = Math.max(maxNum, nums[i]);
- minNum = Math.min(minNum, nums[i]);
- }
-
- //initialize bucket array
- Bucket[] buckets = new Bucket[nums.length + 1];
- for (int i = 0; i < buckets.length; i++) {
- buckets[i] = new Bucket();
- }
-
- double gap = (double) (maxNum - minNum) / (nums.length - 1);
- //distribute the array to different buckets
- for (int i = 0; i < nums.length; i++) {
- int index = (int) ((nums[i] - minNum) / gap);
- if (buckets[index].min == -1) {
- buckets[index].min = nums[i];
- buckets[index].max = nums[i];
- } else {
- buckets[index].min = Math.min(nums[i], buckets[index].min);
- buckets[index].max = Math.max(nums[i], buckets[index].max);
- }
- }
-
- //scan through the bucket array to find the maximal gap
- int result = 0;
- int prev = buckets[0].max;
- for (int i = 1; i < buckets.length; i++) {
- if (buckets[i].min != -1) {
- result = Math.max(result, buckets[i].min - prev);
- prev = buckets[i].max;
- }
- }
-
- return result;
+ if (nums.length < 2) {
+ return 0;
+ }
+
+ Arrays.sort(nums);
+ int max = Integer.MIN_VALUE;
+ for (int i = 1; i < nums.length; ) {
+ while (i < nums.length && nums[i] == nums[i - 1]) {
+ i++;
+ }
+ if (i == nums.length) {
+ i--;
+ max = (nums[i] - nums[i - 1] > max) ? nums[i] - nums[i - 1] : max;
+ break;
+ } else {
+ max = (nums[i] - nums[i - 1] > max) ? nums[i] - nums[i - 1] : max;
+ }
+ if (nums[i] != nums[i - 1]) {
+ i++;
+ }
+ }
+ return max;
}
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_165.java b/src/main/java/com/fishercoder/solutions/_165.java
index 8987ba4637..c37248f175 100644
--- a/src/main/java/com/fishercoder/solutions/_165.java
+++ b/src/main/java/com/fishercoder/solutions/_165.java
@@ -1,5 +1,8 @@
package com.fishercoder.solutions;
-/**Compare two version numbers version1 and version2.
+/**
+ * 165. Compare Version Numbers
+
+ Compare two version numbers version1 and version2.
If version1 > version2 return 1, if version1 < version2 return -1, otherwise return 0.
You may assume that the version strings are non-empty and contain only digits and the . character.
@@ -8,52 +11,40 @@
Here is an example of version numbers ordering:
- 0.1 < 1.1 < 1.2 < 13.37*/
+ 0.1 < 1.1 < 1.2 < 13.37
+ */
public class _165 {
-
- public static int compareVersion(String version1, String version2) {
- String[] v1s = version1.split("\\.");//escaping it is very important! Otherwise, it's not going to work as expected!
- String[] v2s = version2.split("\\.");
- int len = (v1s.length < v2s.length) ? v2s.length : v1s.length;
- for (int i = 0; i < len; i++) {
- if (v1s.length == i) {
- while (i < len) {
- if (Integer.parseInt(v2s[i]) > 0) {
- return -1;
- }
- i++;
- }
- } else if (v2s.length == i) {
- while (i < len) {
- if (Integer.parseInt(v1s[i]) > 0) {
- return 1;
- }
- i++;
- }
- } else {
- if (Integer.parseInt(v1s[i]) > Integer.parseInt(v2s[i])) {
- return 1;
- } else if (Integer.parseInt(v2s[i]) > Integer.parseInt(v1s[i])) {
- return -1;
- }
+ public static class Solution1 {
+ public int compareVersion(String version1, String version2) {
+ String[] v1s = version1.split(
+ "\\.");//escaping it is very important! Otherwise, it's not going to work as expected!
+ String[] v2s = version2.split("\\.");
+ int len = (v1s.length < v2s.length) ? v2s.length : v1s.length;
+ for (int i = 0; i < len; i++) {
+ if (v1s.length == i) {
+ while (i < len) {
+ if (Integer.parseInt(v2s[i]) > 0) {
+ return -1;
+ }
+ i++;
+ }
+ } else if (v2s.length == i) {
+ while (i < len) {
+ if (Integer.parseInt(v1s[i]) > 0) {
+ return 1;
}
+ i++;
+ }
+ } else {
+ if (Integer.parseInt(v1s[i]) > Integer.parseInt(v2s[i])) {
+ return 1;
+ } else if (Integer.parseInt(v2s[i]) > Integer.parseInt(v1s[i])) {
+ return -1;
+ }
}
- return 0;
+ }
+ return 0;
}
-
- public static void main(String... args) {
-// String version1 = "1.1";
-// String version2 = "1.2";//should return -1
-
-// String version1 = "1.0.1";
-// String version2 = "1";//should return 1
-
- String version1 = "1.0";
- String version2 = "1";//should return 0
-
- /**"1.0.1", "1"*/
- System.out.println(compareVersion(version1, version2));
- }
-
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_166.java b/src/main/java/com/fishercoder/solutions/_166.java
index 91929a0da7..d64bc20f35 100644
--- a/src/main/java/com/fishercoder/solutions/_166.java
+++ b/src/main/java/com/fishercoder/solutions/_166.java
@@ -18,39 +18,41 @@
*/
public class _166 {
- /**credit: https://discuss.leetcode.com/topic/33311/simple-and-short-solution-in-java*/
+ public static class Solution1 {
+ /** credit: https://discuss.leetcode.com/topic/33311/simple-and-short-solution-in-java */
public String fractionToDecimal(int numerator, int denominator) {
- String sign = (numerator >= 0 && denominator >= 0) || (numerator < 0 && denominator < 0) ? "" : "-";
- if (numerator == 0) {
- return "0";
- }
- long num = Math.abs((long) numerator);
- long deno = Math.abs((long) denominator);
- StringBuilder stringBuilder = new StringBuilder();
- stringBuilder.append(sign);
- long integral = Math.abs(num / deno);
- stringBuilder.append(integral);
- if (numerator % denominator == 0) {
- return stringBuilder.toString();
- } else {
- stringBuilder.append(".");
- }
- long remainder = num % deno;
-
- Map map = new HashMap<>();
- while (!map.containsKey(remainder)) {
- map.put(remainder, stringBuilder.length());
- long n = remainder * 10 / deno;
- remainder = remainder * 10 % deno;
- if (remainder != 0 || (remainder == 0 && !map.containsKey(remainder))) {
- stringBuilder.append(n);
- }
- }
- if (remainder != 0) {
- stringBuilder.insert(map.get(remainder), "(");
- stringBuilder.append(")");
- }
+ String sign =
+ (numerator >= 0 && denominator >= 0) || (numerator < 0 && denominator < 0) ? "" : "-";
+ if (numerator == 0) {
+ return "0";
+ }
+ long num = Math.abs((long) numerator);
+ long deno = Math.abs((long) denominator);
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.append(sign);
+ long integral = Math.abs(num / deno);
+ stringBuilder.append(integral);
+ if (numerator % denominator == 0) {
return stringBuilder.toString();
+ } else {
+ stringBuilder.append(".");
+ }
+ long remainder = num % deno;
+
+ Map map = new HashMap<>();
+ while (!map.containsKey(remainder)) {
+ map.put(remainder, stringBuilder.length());
+ long n = remainder * 10 / deno;
+ remainder = remainder * 10 % deno;
+ if (remainder != 0 || (remainder == 0 && !map.containsKey(remainder))) {
+ stringBuilder.append(n);
+ }
+ }
+ if (remainder != 0) {
+ stringBuilder.insert(map.get(remainder), "(");
+ stringBuilder.append(")");
+ }
+ return stringBuilder.toString();
}
-
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_167.java b/src/main/java/com/fishercoder/solutions/_167.java
index b3d2fbab9b..ccb36c690c 100644
--- a/src/main/java/com/fishercoder/solutions/_167.java
+++ b/src/main/java/com/fishercoder/solutions/_167.java
@@ -2,43 +2,43 @@
/**
* 167. Two Sum II - Input array is sorted
- *
- * Given an array of integers that is already sorted in ascending order,
- * find two numbers such that they add up to a specific target number.
- * The function twoSum should return indices of the two numbers such that they add up to the target,
- * where index1 must be less than index2.
- * Please note that your returned answers (both index1 and index2) are not zero-based.
- * You may assume that each input would have exactly one solution.
-
- Input: numbers={2, 7, 11, 15}, target=9
- Output: index1=1, index2=2
+
+ Given an array of integers that is already sorted in ascending order, find two numbers such that they add up to a specific target number.
+
+ The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2.
+
+ Note:
+
+ Your returned answers (both index1 and index2) are not zero-based.
+ You may assume that each input would have exactly one solution and you may not use the same element twice.
+
+ Example:
+
+ Input: numbers = [2,7,11,15], target = 9
+ Output: [1,2]
+ Explanation: The sum of 2 and 7 is 9. Therefore index1 = 1, index2 = 2.
+
*/
public class _167 {
-
- public int[] twoSum(int[] numbers, int target) {
- int left = 0;
- int right = numbers.length - 1;
- int[] result = new int[2];
- while (numbers[right] > target) {
- right--;
- }
- if (right < numbers.length - 1) {
- right++;
- }
- while (left <= right) {
- int sum = numbers[left] + numbers[right];
- if (sum > target) {
- right--;
- } else if (sum < target) {
- left++;
- } else if (sum == target) {
- result[0] = left + 1;
- result[1] = right + 1;
- break;
+ public static class Solution1 {
+ public int[] twoSum(int[] numbers, int target) {
+ int left = 0;
+ int right = numbers.length - 1;
+ while (left < right) {
+ long sum = numbers[left] + numbers[right];
+ if (sum > target) {
+ right--;
+ } else if (sum < target) {
+ left++;
+ } else {
+ int[] res = new int[2];
+ res[0] = left + 1;
+ res[1] = right + 1;
+ return res;
+ }
}
+ return new int[] {-1, -1};
}
- return result;
}
-
}
diff --git a/src/main/java/com/fishercoder/solutions/_168.java b/src/main/java/com/fishercoder/solutions/_168.java
index 4edaf59d71..f0150c0a9b 100644
--- a/src/main/java/com/fishercoder/solutions/_168.java
+++ b/src/main/java/com/fishercoder/solutions/_168.java
@@ -1,66 +1,48 @@
package com.fishercoder.solutions;
-/**168. Excel Sheet Column Title
+/**
*
-Given a positive integer, return its corresponding column title as appear in an Excel sheet.
+ * 168. Excel Sheet Column Title
-For example:
+ Given a positive integer, return its corresponding column title as appear in an Excel sheet.
- 1 -> A
- 2 -> B
- 3 -> C
- ...
- 26 -> Z
- 27 -> AA
- 28 -> AB */
-public class _168 {
+ For example:
- public String convertToTitle_accepted_more_beautiful(int n) {
- /**Get the right most digit first, move to the left, e.g. when n = 28, we get 'B' first, then we get 'A'.*/
- StringBuilder sb = new StringBuilder();
- while (n != 0) {
- int temp = (n - 1) % 26;
- sb.append((char) (temp + 65));
- n = (n - 1) / 26;
- }
- return sb.reverse().toString();
+ 1 -> A
+ 2 -> B
+ 3 -> C
+ ...
+ 26 -> Z
+ 27 -> AA
+ 28 -> AB
+ ...
- }
+ Example 1:
- public static void main(String... strings) {
- _168 test = new _168();
-// int n = 28899;
-// int n = 1;
-// int n = 1000000001;
-// int n = 26;
-// int n = 27;
- int n = 28;
-// int n = 52;
-// int n = 53;
-// System.out.println((int) 'A');
-// System.out.println(1000000001/26);
-// System.out.println(25*26);
-// System.out.println(26*26);
-// System.out.println(27*26);
-// System.out.println(702%26);
-// System.out.println(702/26);
- System.out.println(Integer.parseInt(String.valueOf(26), 10));
- System.out.println(test.convertToTitle_accepted_more_beautiful(n));
- }
+ Input: 1
+ Output: "A"
- public String convertToTitle_accepted(int n) {
- /**'Z' is the corner case, so we'll have to special case handling specially, also, we'll have to do (n-1)/26,
- * only when this is not equal to 1, we'll continue.*/
- StringBuilder sb = new StringBuilder();
- while (n != 0) {
- int temp = n % 26;
- if (temp == 0) {
- sb.append("Z");
- } else {
- sb.append((char) (temp + 64));
- }
- n = (n - 1) / 26;
- }
- return sb.reverse().toString();
- }
+ Example 2:
+
+ Input: 28
+ Output: "AB"
-}
\ No newline at end of file
+ Example 3:
+
+ Input: 701
+ Output: "ZY"
+
+ */
+public class _168 {
+ public static class Solution1 {
+ public String convertToTitle(int n) {
+ /**Get the right most digit first, move to the left, e.g. when n = 28, we get 'B' first, then we get 'A'.*/
+ StringBuilder sb = new StringBuilder();
+ while (n != 0) {
+ int temp = (n - 1) % 26;
+ sb.append((char) (temp + 65));
+ n = (n - 1) / 26;
+ }
+ return sb.reverse().toString();
+ }
+ }
+}
diff --git a/src/main/java/com/fishercoder/solutions/_169.java b/src/main/java/com/fishercoder/solutions/_169.java
index eb22509d0e..6403bf6444 100644
--- a/src/main/java/com/fishercoder/solutions/_169.java
+++ b/src/main/java/com/fishercoder/solutions/_169.java
@@ -4,74 +4,83 @@
import java.util.HashMap;
import java.util.Map;
-/**169. Majority Element
- *
-Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.
+/**
+ * 169. Majority Element
-You may assume that the array is non-empty and the majority element always exist in the array.
+ Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.
-*/
-public class _169 {
+ You may assume that the array is non-empty and the majority element always exist in the array.
- public int majorityElement_bit_manipulation(int[] nums) {
- int[] bit = new int[32];//because an integer is 32 bits, so we use an array of 32 long
- for (int num : nums) {
- for (int i = 0; i < 32; i++) {
- if ((num >> (31 - i) & 1) == 1) {
- bit[i]++;//this is to compute each number's ones frequency
- }
- }
- }
- int res = 0;
- //this below for loop is to construct the majority element: since every bit of this element would have appeared more than n/2 times
- for (int i = 0; i < 32; i++) {
- bit[i] = bit[i] > nums.length / 2 ? 1 : 0;//we get rid of those that bits that are not part of the majority number
- res += bit[i] * (1 << (31 - i));
+ Example 1:
+
+ Input: [3,2,3]
+ Output: 3
+
+ Example 2:
+
+ Input: [2,2,1,1,1,2,2]
+ Output: 2
+ */
+public class _169 {
+ public static class Solution1 {
+ /**Moore Voting Algorithm*/
+ public int majorityElement(int[] nums) {
+ int count = 1;
+ int majority = nums[0];
+ for (int i = 1; i < nums.length; i++) {
+ if (count == 0) {
+ count++;
+ majority = nums[i];
+ } else if (nums[i] == majority) {
+ count++;
+ } else {
+ count--;
}
- return res;
+ }
+ return majority;
}
+ }
- //saw a really clever solution on Discuss, though it didn't use bit manipulatoin
- //this is actually applying a famous algorithm called Moore Voting algorithm: http://www.cs.utexas.edu/~moore/best-ideas/mjrty/example.html
- public int majorityElement_moore_voting_algorithm(int[] nums) {
- int count = 1;
- int majority = nums[0];
- for (int i = 1; i < nums.length; i++) {
- if (count == 0) {
- count++;
- majority = nums[i];
- } else if (nums[i] == majority) {
- count++;
- } else {
- count--;
- }
+ public static class Solution2 {
+ public int majorityElement(int[] nums) {
+ Map map = new HashMap();
+ for (int i : nums) {
+ map.put(i, map.getOrDefault(i, 0) + 1);
+ if (map.get(i) > nums.length / 2) {
+ return i;
}
- return majority;
+ }
+ return -1;
}
+ }
- public static void main(String... strings) {
- int[] nums = new int[]{1, 2, 3, 4, 2, 3, 2, 2, 4, 2};
- _169 test = new _169();
- System.out.println(test.majorityElement_bit_manipulation(nums));
+ public static class Solution3 {
+ //This is O(nlogn) time.
+ public int majorityElement(int[] nums) {
+ Arrays.sort(nums);
+ return nums[nums.length / 2];
}
+ }
- //my natural idea is to either compute the frequency of each unique number or sort it and return the median, I can hardly think of
- //how bit manipulation could come into play for this question
- //this is O(n) time.
- public int majorityElement_compute_frequency(int[] nums) {
- Map map = new HashMap();
- for (int i : nums) {
- map.put(i, map.getOrDefault(i, 0) + 1);
- if (map.get(i) > nums.length / 2) {
- return i;
- }
+ public static class Solution4 {
+ //bit manipulation
+ public int majorityElement(int[] nums) {
+ int[] bit = new int[32];//because an integer is 32 bits, so we use an array of 32 long
+ for (int num : nums) {
+ for (int i = 0; i < 32; i++) {
+ if ((num >> (31 - i) & 1) == 1) {
+ bit[i]++;//this is to compute each number's ones frequency
+ }
}
- return -1;
- }
-
- //This is O(nlogn) time.
- public int majorityElement_sort(int[] nums) {
- Arrays.sort(nums);
- return nums[nums.length / 2];
+ }
+ int res = 0;
+ //this below for loop is to construct the majority element: since every bit of this element would have appeared more than n/2 times
+ for (int i = 0; i < 32; i++) {
+ bit[i] = bit[i] > nums.length / 2 ? 1
+ : 0;//we get rid of those that bits that are not part of the majority number
+ res += bit[i] * (1 << (31 - i));
+ }
+ return res;
}
+ }
}
diff --git a/src/main/java/com/fishercoder/solutions/_17.java b/src/main/java/com/fishercoder/solutions/_17.java
index b6c70b3932..b126c36e6d 100644
--- a/src/main/java/com/fishercoder/solutions/_17.java
+++ b/src/main/java/com/fishercoder/solutions/_17.java
@@ -1,6 +1,5 @@
package com.fishercoder.solutions;
-
import java.util.ArrayList;
import java.util.List;
@@ -19,31 +18,33 @@
public class _17 {
- public List letterCombinations(String digits) {
- List result = new ArrayList();
- if (digits.length() == 0) {
- return result;
- }
+ public static class Solution1 {
+ public List letterCombinations(String digits) {
+ List result = new ArrayList();
+ if (digits.length() == 0) {
+ return result;
+ }
- String[] digits2Letters = new String[]{"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
+ String[] digits2Letters = new String[]{"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
- result.add("");//this line is important, otherwise result is empty and Java will default it to an empty String
- for (int i = 0; i < digits.length(); i++) {
- result = combine(digits2Letters[digits.charAt(i) - '0'], result);
- }
+ result.add("");//this line is important, otherwise result is empty and Java will default it to an empty String
+ for (int i = 0; i < digits.length(); i++) {
+ result = combine(digits2Letters[digits.charAt(i) - '0'], result);
+ }
- return result;
- }
+ return result;
+ }
- List combine(String letters, List result) {
- List newResult = new ArrayList();
+ List combine(String letters, List result) {
+ List newResult = new ArrayList();
- for (int i = 0; i < letters.length(); i++) {
- //the order of the two for loops doesn't matter, you could swap them and it still works.
- for (String str : result) {
- newResult.add(str + letters.charAt(i));
+ for (int i = 0; i < letters.length(); i++) {
+ //the order of the two for loops doesn't matter, you could swap them and it still works.
+ for (String str : result) {
+ newResult.add(str + letters.charAt(i));
+ }
}
+ return newResult;
}
- return newResult;
}
}
diff --git a/src/main/java/com/fishercoder/solutions/_170.java b/src/main/java/com/fishercoder/solutions/_170.java
index f5f5bcb8d6..743115ae5b 100644
--- a/src/main/java/com/fishercoder/solutions/_170.java
+++ b/src/main/java/com/fishercoder/solutions/_170.java
@@ -5,50 +5,52 @@
import java.util.List;
import java.util.Map;
-
/**
* 170. Two Sum III - Data structure design
- *