From c903b26a590ef412346e97cea0fc44ca2be53d7b Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Thu, 21 Feb 2019 22:13:31 +0000 Subject: [PATCH 001/164] Successor done --- .../com/ctci/treesandgraphs/Successor.java | 88 ++++++++++++++++++- 1 file changed, 87 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/ctci/treesandgraphs/Successor.java b/src/main/java/com/ctci/treesandgraphs/Successor.java index 743a2be5..4e6455b1 100644 --- a/src/main/java/com/ctci/treesandgraphs/Successor.java +++ b/src/main/java/com/ctci/treesandgraphs/Successor.java @@ -1,12 +1,98 @@ package com.ctci.treesandgraphs; /** + * Write an algorithm to find the "next" node (i.e., in-order successor) of a given node + * in a binary search tree. You may assume that each node has a link to its parent. + * * @author rampatra * @since 2019-02-17 */ public class Successor { + /** + * To get the inorder successor what this method does is that it checks if the right child of the input node + * is null and if not, gets the leftmost child of the right child. And, if the right child of the input + * node is null, it checks all the parents until it finds the next successor. + * + * @param node + * @return + */ + private static TreeNode getInOrderSuccessor(TreeNode node) { + if (node == null) return null; + + if (node.right != null) { + return getLeftmostNode(node.right); + } else { + TreeNode curr = node; + + while (curr != null) { + if (curr.parent != null && curr.parent.left == curr) { + return curr.parent; + } + curr = curr.parent; + } + } + return null; + } + + private static TreeNode getLeftmostNode(TreeNode node) { + TreeNode curr = node; + while (curr != null && curr.left != null) { + curr = curr.left; + } + return curr; + } + public static void main(String[] args) { + /* + The binary search tree looks like: + 4 + / \ + 2 8 + / \ / \ + 1 3 6 9 + / \ + 0 7 + + */ + TreeNode treeRoot = new TreeNode(4); + treeRoot.left = new TreeNode(2); + treeRoot.left.parent = treeRoot; + treeRoot.right = new TreeNode(8); + treeRoot.right.parent = treeRoot; + treeRoot.left.left = new TreeNode(1); + treeRoot.left.left.parent = treeRoot.left; + treeRoot.left.right = new TreeNode(3); + treeRoot.left.right.parent = treeRoot.left; + treeRoot.left.left.left = new TreeNode(0); + treeRoot.left.left.left.parent = treeRoot.left.left; + treeRoot.right.left = new TreeNode(6); + treeRoot.right.left.parent = treeRoot.right; + treeRoot.right.right = new TreeNode(9); + treeRoot.right.right.parent = treeRoot.right; + treeRoot.right.left.right = new TreeNode(7); + treeRoot.right.left.right.parent = treeRoot.right.left; + + System.out.println("InOrder successor of 0 is: " + getInOrderSuccessor(treeRoot.left.left.left).val); + System.out.println("InOrder successor of 1 is: " + getInOrderSuccessor(treeRoot.left.left).val); + System.out.println("InOrder successor of 2 is: " + getInOrderSuccessor(treeRoot.left).val); + System.out.println("InOrder successor of 3 is: " + getInOrderSuccessor(treeRoot.left.right).val); + System.out.println("InOrder successor of 4 is: " + getInOrderSuccessor(treeRoot).val); + System.out.println("InOrder successor of 6 is: " + getInOrderSuccessor(treeRoot.right.left).val); + System.out.println("InOrder successor of 7 is: " + getInOrderSuccessor(treeRoot.right.left.right).val); + System.out.println("InOrder successor of 8 is: " + getInOrderSuccessor(treeRoot.right).val); + System.out.println("InOrder successor of 9 is: " + getInOrderSuccessor(treeRoot.right.right)); + } + + private static class TreeNode { + int val; + TreeNode parent; + TreeNode left; + TreeNode right; + + TreeNode(int val) { + this.val = val; + } } -} +} \ No newline at end of file From 0e3392de27b7a254a8dbdb3e39b10b2fa6efc4d0 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sat, 23 Feb 2019 22:02:56 +0000 Subject: [PATCH 002/164] LCA with access to parent node: done --- .../com/ctci/treesandgraphs/BuildOrder.java | 14 +++ .../LeastCommonAncestorWithParentAccess.java | 114 ++++++++++++++++++ .../com/ctci/treesandgraphs/Successor.java | 22 ++-- 3 files changed, 139 insertions(+), 11 deletions(-) create mode 100644 src/main/java/com/ctci/treesandgraphs/BuildOrder.java create mode 100644 src/main/java/com/ctci/treesandgraphs/LeastCommonAncestorWithParentAccess.java diff --git a/src/main/java/com/ctci/treesandgraphs/BuildOrder.java b/src/main/java/com/ctci/treesandgraphs/BuildOrder.java new file mode 100644 index 00000000..3e98eb58 --- /dev/null +++ b/src/main/java/com/ctci/treesandgraphs/BuildOrder.java @@ -0,0 +1,14 @@ +package com.ctci.treesandgraphs; + +/** + * @author rampatra + * @since 2019-02-21 + */ +public class BuildOrder { + + + + public static void main(String[] args) { + + } +} diff --git a/src/main/java/com/ctci/treesandgraphs/LeastCommonAncestorWithParentAccess.java b/src/main/java/com/ctci/treesandgraphs/LeastCommonAncestorWithParentAccess.java new file mode 100644 index 00000000..9085f7cb --- /dev/null +++ b/src/main/java/com/ctci/treesandgraphs/LeastCommonAncestorWithParentAccess.java @@ -0,0 +1,114 @@ +package com.ctci.treesandgraphs; + +/** + * Design an algorithm and write code to find the first common ancestor of two nodes in a binary + * tree. Avoid storing additional nodes in a data structure. Also, for this question, the tree node + * has access to its parent node. NOTE: This is not necessarily a binary search tree. + * + * @author rampatra + * @since 2019-02-23 + */ +public class LeastCommonAncestorWithParentAccess { + + /** + * This is a simple approach where we start with two references, one pointing to {@code node a} and another + * pointing to {@code node b}. We move the reference pointing to the deeper node upwards, if required, so that + * both the references are at the same depth from root. After both the references are at same depth, we simply + * move both the references upwards until they merge. The node at which they merge is our LCA. + * + * @param a + * @param b + * @return the least common ancestor node + */ + private static TreeNode findLCA(TreeNode a, TreeNode b) { + if (a == null || b == null) { + return null; + } + + int depthA = depth(a); + int depthB = depth(b); + // be little careful when both nodes are at same depth + TreeNode shallowNode = depthA < depthB ? a : b; + TreeNode deeperNode = depthB > depthA ? b : a; + + // move deeper node reference upwards so that both the references are at same depth + deeperNode = goUpBy(deeperNode, Math.abs(depthA - depthB)); + + while (shallowNode != deeperNode && shallowNode != null && deeperNode != null) { + shallowNode = shallowNode.parent; + deeperNode = deeperNode.parent; + } + + return shallowNode; + } + + private static int depth(TreeNode node) { + int d = 0; + while (node != null && node.parent != null) { + d++; + node = node.parent; + } + return d; + } + + private static TreeNode goUpBy(TreeNode node, int levelsUp) { + int c = 0; + while (node != null && c < levelsUp) { + node = node.parent; + c++; + } + return node; + } + + private static class TreeNode { + int val; + TreeNode parent; + TreeNode left; + TreeNode right; + + TreeNode(int val) { + this.val = val; + } + } + + public static void main(String[] args) { + /* + The binary tree looks like: + + 4 + / \ + 5 8 + / \ / \ + 1 3 2 9 + / \ + 0 7 + + */ + TreeNode treeRoot = new TreeNode(4); + treeRoot.left = new TreeNode(5); + treeRoot.left.parent = treeRoot; + treeRoot.right = new TreeNode(8); + treeRoot.right.parent = treeRoot; + treeRoot.left.left = new TreeNode(1); + treeRoot.left.left.parent = treeRoot.left; + treeRoot.left.right = new TreeNode(3); + treeRoot.left.right.parent = treeRoot.left; + treeRoot.left.left.left = new TreeNode(0); + treeRoot.left.left.left.parent = treeRoot.left.left; + treeRoot.right.left = new TreeNode(2); + treeRoot.right.left.parent = treeRoot.right; + treeRoot.right.right = new TreeNode(9); + treeRoot.right.right.parent = treeRoot.right; + treeRoot.right.left.right = new TreeNode(7); + treeRoot.right.left.right.parent = treeRoot.right.left; + + System.out.println("LCA of 0 and 7 is: " + findLCA(treeRoot.left.left.left, treeRoot.right.left.right).val); + System.out.println("LCA of 0 and 9 is: " + findLCA(treeRoot.left.left.left, treeRoot.right.right).val); + System.out.println("LCA of 0 and 1 is: " + findLCA(treeRoot.left.left.left, treeRoot.left.left).val); + System.out.println("LCA of 1 and 2 is: " + findLCA(treeRoot.left.left, treeRoot.right.left).val); + System.out.println("LCA of 1 and 7 is: " + findLCA(treeRoot.left.left, treeRoot.right.left.right).val); + System.out.println("LCA of 4 and 7 is: " + findLCA(treeRoot, treeRoot.right.left.right).val); + System.out.println("LCA of 5 and 2 is: " + findLCA(treeRoot.left, treeRoot.right.left).val); + System.out.println("LCA of 7 and 9 is: " + findLCA(treeRoot.right.left.right, treeRoot.right.right).val); + } +} \ No newline at end of file diff --git a/src/main/java/com/ctci/treesandgraphs/Successor.java b/src/main/java/com/ctci/treesandgraphs/Successor.java index 4e6455b1..d37488bd 100644 --- a/src/main/java/com/ctci/treesandgraphs/Successor.java +++ b/src/main/java/com/ctci/treesandgraphs/Successor.java @@ -43,6 +43,17 @@ private static TreeNode getLeftmostNode(TreeNode node) { return curr; } + private static class TreeNode { + int val; + TreeNode parent; + TreeNode left; + TreeNode right; + + TreeNode(int val) { + this.val = val; + } + } + public static void main(String[] args) { /* The binary search tree looks like: @@ -84,15 +95,4 @@ public static void main(String[] args) { System.out.println("InOrder successor of 8 is: " + getInOrderSuccessor(treeRoot.right).val); System.out.println("InOrder successor of 9 is: " + getInOrderSuccessor(treeRoot.right.right)); } - - private static class TreeNode { - int val; - TreeNode parent; - TreeNode left; - TreeNode right; - - TreeNode(int val) { - this.val = val; - } - } } \ No newline at end of file From 45ed43765cc9cafb8a0a83e3db03152f4e8f9370 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sun, 24 Feb 2019 22:08:20 +0000 Subject: [PATCH 003/164] LCA with no parent access: done --- .../com/ctci/treesandgraphs/BuildOrder.java | 2 +- .../treesandgraphs/LeastCommonAncestor.java | 98 +++++++++++++++++++ .../LeastCommonAncestorWithParentAccess.java | 3 +- 3 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/ctci/treesandgraphs/LeastCommonAncestor.java diff --git a/src/main/java/com/ctci/treesandgraphs/BuildOrder.java b/src/main/java/com/ctci/treesandgraphs/BuildOrder.java index 3e98eb58..4afab552 100644 --- a/src/main/java/com/ctci/treesandgraphs/BuildOrder.java +++ b/src/main/java/com/ctci/treesandgraphs/BuildOrder.java @@ -6,7 +6,7 @@ */ public class BuildOrder { - + // todo public static void main(String[] args) { diff --git a/src/main/java/com/ctci/treesandgraphs/LeastCommonAncestor.java b/src/main/java/com/ctci/treesandgraphs/LeastCommonAncestor.java new file mode 100644 index 00000000..5d4964df --- /dev/null +++ b/src/main/java/com/ctci/treesandgraphs/LeastCommonAncestor.java @@ -0,0 +1,98 @@ +package com.ctci.treesandgraphs; + +/** + * Design an algorithm and write code to find the first common ancestor of two nodes in a binary + * tree. Avoid storing additional nodes in a data structure. Also, for this question, the tree node + * does NOT have access to its parent node. NOTE: This is not necessarily a binary search tree. + * + * @author rampatra + * @since 2019-02-24 + */ +public class LeastCommonAncestor { + + /** + * We recurse through the entire tree with a function called findLCA(TreeNode root, TreeNode TreeNode a, TreeNode b). + * This function returns values as follows: + * - Returns p,if root's subtree includes p (and not q). + * - Returns q, if root's subtree includes q (and not p). + * - Returns null, if neither p nor q are in root's subtree. + * - Else, returns the common ancestor of p and q. + * + * @param root + * @param a + * @param b + * @return the least common ancestor node + */ + private static TreeNode findLCA(TreeNode root, TreeNode a, TreeNode b) { + if (root == null) { // validation + return null; + } + if (root == a && root == b) { // optimization + return root; + } + + TreeNode left = findLCA(root.left, a, b); + if (left != null && left != a && left != b) { + return left; + } + + TreeNode right = findLCA(root.right, a, b); + if (right != null && right != a && right != b) { + return right; + } + + /* One node is found on the left subtree and other on the + right one. This means current node is the ancestor. */ + if (left != null && right != null) { + return root; + } else if (root == a || root == b) { + return root; + } else { + return left == null ? right : left; + } + } + + private static class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int val) { + this.val = val; + } + } + + public static void main(String[] args) { + /* + The binary tree looks like: + + 4 + / \ + 5 8 + / \ / \ + 1 3 2 9 + / \ + 0 7 + + */ + TreeNode treeRoot = new TreeNode(4); + treeRoot.left = new TreeNode(5); + treeRoot.right = new TreeNode(8); + treeRoot.left.left = new TreeNode(1); + treeRoot.left.right = new TreeNode(3); + treeRoot.left.left.left = new TreeNode(0); + treeRoot.right.left = new TreeNode(2); + treeRoot.right.right = new TreeNode(9); + treeRoot.right.left.right = new TreeNode(7); + + System.out.println("LCA of 0 and 7 is: " + findLCA(treeRoot, treeRoot.left.left.left, treeRoot.right.left.right).val); + System.out.println("LCA of 0 and 9 is: " + findLCA(treeRoot, treeRoot.left.left.left, treeRoot.right.right).val); + System.out.println("LCA of 0 and 1 is: " + findLCA(treeRoot, treeRoot.left.left.left, treeRoot.left.left).val); + System.out.println("LCA of 1 and 2 is: " + findLCA(treeRoot, treeRoot.left.left, treeRoot.right.left).val); + System.out.println("LCA of 1 and 7 is: " + findLCA(treeRoot, treeRoot.left.left, treeRoot.right.left.right).val); + System.out.println("LCA of 4 and 7 is: " + findLCA(treeRoot, treeRoot, treeRoot.right.left.right).val); + System.out.println("LCA of 5 and 2 is: " + findLCA(treeRoot, treeRoot.left, treeRoot.right.left).val); + System.out.println("LCA of 7 and 9 is: " + findLCA(treeRoot, treeRoot.right.left.right, treeRoot.right.right).val); + System.out.println("LCA of 7 and 10 is: " + findLCA(treeRoot, treeRoot.right.left.right, new TreeNode(10)).val); // this use case does not work with the above algorithm + } +} \ No newline at end of file diff --git a/src/main/java/com/ctci/treesandgraphs/LeastCommonAncestorWithParentAccess.java b/src/main/java/com/ctci/treesandgraphs/LeastCommonAncestorWithParentAccess.java index 9085f7cb..0de2cf3a 100644 --- a/src/main/java/com/ctci/treesandgraphs/LeastCommonAncestorWithParentAccess.java +++ b/src/main/java/com/ctci/treesandgraphs/LeastCommonAncestorWithParentAccess.java @@ -27,7 +27,8 @@ private static TreeNode findLCA(TreeNode a, TreeNode b) { int depthA = depth(a); int depthB = depth(b); - // be little careful when both nodes are at same depth + /* be little careful when both nodes are at same depth, have the checks such that + shallow and deeper references point to different nodes */ TreeNode shallowNode = depthA < depthB ? a : b; TreeNode deeperNode = depthB > depthA ? b : a; From fe3ac34b417014e25a2635c31366239317e5679b Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Tue, 26 Feb 2019 09:54:48 +0000 Subject: [PATCH 004/164] Renamed common package to base --- .../com/ctci/treesandgraphs/CheckSubtree.java | 18 ++++++++++++++++++ src/main/java/com/rampatra/Main.java | 16 ++++++++-------- .../com/rampatra/arrays/CelebrityProblem.java | 4 ++-- .../com/rampatra/arrays/KLargestElements.java | 2 +- .../com/rampatra/arrays/KthLargestElement.java | 2 +- .../com/rampatra/arrays/MaxInAllSubArrays.java | 2 +- .../com/rampatra/arrays/MedianOfStream.java | 4 ++-- .../rampatra/arrays/NextGreaterElement.java | 4 ++-- .../com/rampatra/{common => base}/AVLTree.java | 2 +- .../rampatra/{common => base}/BinaryNode.java | 2 +- .../{common => base}/BinarySearchTree.java | 2 +- .../rampatra/{common => base}/BinaryTree.java | 2 +- .../CircularSingleLinkedList.java | 2 +- .../{common => base}/DoubleLinkedList.java | 2 +- .../{common => base}/DoubleLinkedNode.java | 2 +- .../com/rampatra/{common => base}/Graph.java | 2 +- .../rampatra/{common => base}/GraphNode.java | 2 +- .../rampatra/{common => base}/LinkedList.java | 2 +- .../rampatra/{common => base}/LinkedQueue.java | 2 +- .../rampatra/{common => base}/LinkedStack.java | 2 +- .../com/rampatra/{common => base}/MaxHeap.java | 2 +- .../com/rampatra/{common => base}/MinHeap.java | 2 +- .../com/rampatra/{common => base}/Queue.java | 2 +- .../{common => base}/SingleLinkedList.java | 2 +- .../{common => base}/SingleLinkedNode.java | 2 +- .../com/rampatra/{common => base}/Stack.java | 2 +- .../com/rampatra/{common => base}/Tree.java | 2 +- .../com/rampatra/{common => base}/Trie.java | 2 +- .../{common => base}/UndirectedGraph.java | 2 +- .../linkedlists/AddNumbersInTwoLists.java | 4 ++-- .../linkedlists/CloneWithRandPointers.java | 4 ++-- .../linkedlists/DeleteAlternateNodes.java | 4 ++-- .../linkedlists/DeleteLesserNodes.java | 4 ++-- .../linkedlists/DeleteMnodesAfterNnodes.java | 4 ++-- .../com/rampatra/linkedlists/DeleteNode.java | 4 ++-- .../linkedlists/DetectAndRemoveLoop.java | 4 ++-- .../com/rampatra/linkedlists/DetectLoop.java | 4 ++-- .../linkedlists/DivideCircularListIntoTwo.java | 4 ++-- .../FlattenMultiLevelLinkedList.java | 2 +- .../com/rampatra/linkedlists/Identical.java | 4 ++-- .../InsertInSortedCircularLinkedList.java | 4 ++-- .../linkedlists/InsertInSortedList.java | 4 ++-- .../IntersectionAndUnionOf2Lists.java | 4 ++-- .../IntersectionOf2SortedLists.java | 4 ++-- .../IntersectionPointOfTwoLists.java | 4 ++-- .../linkedlists/MaximumSumLinkedList.java | 4 ++-- .../com/rampatra/linkedlists/MergeSort.java | 4 ++-- .../linkedlists/MergeSortDoubleLinkedList.java | 4 ++-- .../MergeTwoLinkedListAlternatively.java | 4 ++-- .../linkedlists/MergeTwoSortedLists.java | 4 ++-- .../com/rampatra/linkedlists/MiddleNode.java | 4 ++-- .../linkedlists/MoveLastNodeToFirst.java | 4 ++-- .../rampatra/linkedlists/NthNodeFromLast.java | 4 ++-- .../com/rampatra/linkedlists/PairWiseSwap.java | 4 ++-- .../com/rampatra/linkedlists/Palindrome.java | 8 ++++---- .../com/rampatra/linkedlists/QuickSort.java | 4 ++-- .../com/rampatra/linkedlists/RandomNode.java | 4 ++-- .../rampatra/linkedlists/RemoveDuplicates.java | 4 ++-- .../RemoveMiddlePointsFromLineSegments.java | 4 ++-- .../ReverseAlternateNodesAndAppendAtEnd.java | 4 ++-- .../linkedlists/ReverseDoubleLinkedList.java | 4 ++-- .../ReverseLinkedListInAlternateGroups.java | 4 ++-- .../linkedlists/ReverseLinkedListInGroups.java | 4 ++-- .../linkedlists/ReverseSingleLinkedList.java | 4 ++-- .../rampatra/linkedlists/RotateLinkedList.java | 4 ++-- .../linkedlists/SegregateEvenOddNumbers.java | 4 ++-- .../SortAlternativelySortedLinkedList.java | 4 ++-- .../linkedlists/SortLinkedListOf0s1s2s.java | 4 ++-- .../rampatra/linkedlists/SortedDLLToBBST.java | 4 ++-- .../StackWithOperationOnMiddleElement.java | 2 +- .../com/rampatra/linkedlists/SwapKthNode.java | 4 ++-- .../com/rampatra/linkedlists/SwapNodes.java | 4 ++-- .../TripletFromThreeLinkedLists.java | 4 ++-- .../java/com/rampatra/sorting/HeapSort.java | 2 +- .../{misc => stacks}/BalancingParenthesis.java | 2 +- .../java/com/rampatra/trees/BFSUsingQueue.java | 9 ++++----- .../java/com/rampatra/trees/CheckForBST.java | 6 +++--- .../java/com/rampatra/trees/ChildrenSum.java | 4 ++-- .../ConstructTreeFromInOrderAndPreOrder.java | 2 +- .../java/com/rampatra/trees/DoubleTree.java | 4 ++-- .../com/rampatra/trees/HeightBalanced.java | 4 ++-- .../com/rampatra/trees/IdenticalTrees.java | 4 ++-- .../com/rampatra/trees/InOrderUsingStack.java | 8 ++++---- .../trees/InOrderWithoutStackAndRecursion.java | 4 ++-- .../java/com/rampatra/trees/LeafNodes.java | 4 ++-- .../rampatra/trees/LeastCommonAncestor.java | 4 ++-- .../java/com/rampatra/trees/MirrorTree.java | 4 ++-- .../com/rampatra/trees/RootToLeafPaths.java | 4 ++-- .../com/rampatra/trees/SpiralTraversal.java | 8 ++++---- .../java/com/rampatra/trees/TreeToList.java | 4 ++-- 90 files changed, 182 insertions(+), 165 deletions(-) create mode 100644 src/main/java/com/ctci/treesandgraphs/CheckSubtree.java rename src/main/java/com/rampatra/{common => base}/AVLTree.java (85%) rename src/main/java/com/rampatra/{common => base}/BinaryNode.java (95%) rename src/main/java/com/rampatra/{common => base}/BinarySearchTree.java (98%) rename src/main/java/com/rampatra/{common => base}/BinaryTree.java (99%) rename src/main/java/com/rampatra/{common => base}/CircularSingleLinkedList.java (99%) rename src/main/java/com/rampatra/{common => base}/DoubleLinkedList.java (99%) rename src/main/java/com/rampatra/{common => base}/DoubleLinkedNode.java (94%) rename src/main/java/com/rampatra/{common => base}/Graph.java (84%) rename src/main/java/com/rampatra/{common => base}/GraphNode.java (97%) rename src/main/java/com/rampatra/{common => base}/LinkedList.java (98%) rename src/main/java/com/rampatra/{common => base}/LinkedQueue.java (98%) rename src/main/java/com/rampatra/{common => base}/LinkedStack.java (98%) rename src/main/java/com/rampatra/{common => base}/MaxHeap.java (99%) rename src/main/java/com/rampatra/{common => base}/MinHeap.java (99%) rename src/main/java/com/rampatra/{common => base}/Queue.java (96%) rename src/main/java/com/rampatra/{common => base}/SingleLinkedList.java (99%) rename src/main/java/com/rampatra/{common => base}/SingleLinkedNode.java (93%) rename src/main/java/com/rampatra/{common => base}/Stack.java (97%) rename src/main/java/com/rampatra/{common => base}/Tree.java (88%) rename src/main/java/com/rampatra/{common => base}/Trie.java (99%) rename src/main/java/com/rampatra/{common => base}/UndirectedGraph.java (99%) rename src/main/java/com/rampatra/{misc => stacks}/BalancingParenthesis.java (99%) diff --git a/src/main/java/com/ctci/treesandgraphs/CheckSubtree.java b/src/main/java/com/ctci/treesandgraphs/CheckSubtree.java new file mode 100644 index 00000000..79e2e58e --- /dev/null +++ b/src/main/java/com/ctci/treesandgraphs/CheckSubtree.java @@ -0,0 +1,18 @@ +package com.ctci.treesandgraphs; + +/** + * @author rampatra + * @since 2019-02-24 + */ +public class CheckSubtree { + + /*private static boolean isT2SubtreeofT1(TreeNode t1, TreeNode t2) { + + } + + private static boolean matchTree(TreeNode a, TreeNode b) { + }*/ + + public static void main(String[] args) { + } +} diff --git a/src/main/java/com/rampatra/Main.java b/src/main/java/com/rampatra/Main.java index 8702669f..9306b1a2 100644 --- a/src/main/java/com/rampatra/Main.java +++ b/src/main/java/com/rampatra/Main.java @@ -1,13 +1,13 @@ package com.rampatra; -import com.rampatra.common.CircularSingleLinkedList; -import com.rampatra.common.DoubleLinkedList; -import com.rampatra.common.LinkedList; -import com.rampatra.common.LinkedQueue; -import com.rampatra.common.LinkedStack; -import com.rampatra.common.Queue; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.Stack; +import com.rampatra.base.CircularSingleLinkedList; +import com.rampatra.base.DoubleLinkedList; +import com.rampatra.base.LinkedList; +import com.rampatra.base.LinkedQueue; +import com.rampatra.base.LinkedStack; +import com.rampatra.base.Queue; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.Stack; import java.util.Scanner; diff --git a/src/main/java/com/rampatra/arrays/CelebrityProblem.java b/src/main/java/com/rampatra/arrays/CelebrityProblem.java index 9aab7a15..2c66050c 100644 --- a/src/main/java/com/rampatra/arrays/CelebrityProblem.java +++ b/src/main/java/com/rampatra/arrays/CelebrityProblem.java @@ -1,7 +1,7 @@ package com.rampatra.arrays; -import com.rampatra.common.LinkedStack; -import com.rampatra.common.Stack; +import com.rampatra.base.LinkedStack; +import com.rampatra.base.Stack; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/arrays/KLargestElements.java b/src/main/java/com/rampatra/arrays/KLargestElements.java index 029b319c..ce1e217f 100644 --- a/src/main/java/com/rampatra/arrays/KLargestElements.java +++ b/src/main/java/com/rampatra/arrays/KLargestElements.java @@ -1,6 +1,6 @@ package com.rampatra.arrays; -import com.rampatra.common.MinHeap; +import com.rampatra.base.MinHeap; import java.util.Arrays; diff --git a/src/main/java/com/rampatra/arrays/KthLargestElement.java b/src/main/java/com/rampatra/arrays/KthLargestElement.java index b2d39a02..4b119519 100644 --- a/src/main/java/com/rampatra/arrays/KthLargestElement.java +++ b/src/main/java/com/rampatra/arrays/KthLargestElement.java @@ -1,7 +1,7 @@ package com.rampatra.arrays; import com.rampatra.sorting.MergeSort; -import com.rampatra.common.MaxHeap; +import com.rampatra.base.MaxHeap; import java.util.Arrays; diff --git a/src/main/java/com/rampatra/arrays/MaxInAllSubArrays.java b/src/main/java/com/rampatra/arrays/MaxInAllSubArrays.java index 8d2ea88f..5f27a660 100644 --- a/src/main/java/com/rampatra/arrays/MaxInAllSubArrays.java +++ b/src/main/java/com/rampatra/arrays/MaxInAllSubArrays.java @@ -1,6 +1,6 @@ package com.rampatra.arrays; -import com.rampatra.common.MaxHeap; +import com.rampatra.base.MaxHeap; import java.util.ArrayDeque; import java.util.Arrays; diff --git a/src/main/java/com/rampatra/arrays/MedianOfStream.java b/src/main/java/com/rampatra/arrays/MedianOfStream.java index bb066655..84829ccf 100644 --- a/src/main/java/com/rampatra/arrays/MedianOfStream.java +++ b/src/main/java/com/rampatra/arrays/MedianOfStream.java @@ -1,7 +1,7 @@ package com.rampatra.arrays; -import com.rampatra.common.MaxHeap; -import com.rampatra.common.MinHeap; +import com.rampatra.base.MaxHeap; +import com.rampatra.base.MinHeap; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/arrays/NextGreaterElement.java b/src/main/java/com/rampatra/arrays/NextGreaterElement.java index 13ee8924..03f02209 100644 --- a/src/main/java/com/rampatra/arrays/NextGreaterElement.java +++ b/src/main/java/com/rampatra/arrays/NextGreaterElement.java @@ -1,7 +1,7 @@ package com.rampatra.arrays; -import com.rampatra.common.LinkedStack; -import com.rampatra.common.Stack; +import com.rampatra.base.LinkedStack; +import com.rampatra.base.Stack; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/common/AVLTree.java b/src/main/java/com/rampatra/base/AVLTree.java similarity index 85% rename from src/main/java/com/rampatra/common/AVLTree.java rename to src/main/java/com/rampatra/base/AVLTree.java index 246df319..61999cd0 100644 --- a/src/main/java/com/rampatra/common/AVLTree.java +++ b/src/main/java/com/rampatra/base/AVLTree.java @@ -1,4 +1,4 @@ -package com.rampatra.common; +package com.rampatra.base; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/common/BinaryNode.java b/src/main/java/com/rampatra/base/BinaryNode.java similarity index 95% rename from src/main/java/com/rampatra/common/BinaryNode.java rename to src/main/java/com/rampatra/base/BinaryNode.java index 6a7de266..6e57530e 100644 --- a/src/main/java/com/rampatra/common/BinaryNode.java +++ b/src/main/java/com/rampatra/base/BinaryNode.java @@ -1,4 +1,4 @@ -package com.rampatra.common; +package com.rampatra.base; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/common/BinarySearchTree.java b/src/main/java/com/rampatra/base/BinarySearchTree.java similarity index 98% rename from src/main/java/com/rampatra/common/BinarySearchTree.java rename to src/main/java/com/rampatra/base/BinarySearchTree.java index f6a00a2e..9766a1e3 100644 --- a/src/main/java/com/rampatra/common/BinarySearchTree.java +++ b/src/main/java/com/rampatra/base/BinarySearchTree.java @@ -1,4 +1,4 @@ -package com.rampatra.common; +package com.rampatra.base; import java.util.NoSuchElementException; diff --git a/src/main/java/com/rampatra/common/BinaryTree.java b/src/main/java/com/rampatra/base/BinaryTree.java similarity index 99% rename from src/main/java/com/rampatra/common/BinaryTree.java rename to src/main/java/com/rampatra/base/BinaryTree.java index 1d9367c5..1b7c790f 100644 --- a/src/main/java/com/rampatra/common/BinaryTree.java +++ b/src/main/java/com/rampatra/base/BinaryTree.java @@ -1,4 +1,4 @@ -package com.rampatra.common; +package com.rampatra.base; import com.rampatra.trees.BFSUsingQueue; diff --git a/src/main/java/com/rampatra/common/CircularSingleLinkedList.java b/src/main/java/com/rampatra/base/CircularSingleLinkedList.java similarity index 99% rename from src/main/java/com/rampatra/common/CircularSingleLinkedList.java rename to src/main/java/com/rampatra/base/CircularSingleLinkedList.java index 5416bfa6..cdf37470 100644 --- a/src/main/java/com/rampatra/common/CircularSingleLinkedList.java +++ b/src/main/java/com/rampatra/base/CircularSingleLinkedList.java @@ -1,4 +1,4 @@ -package com.rampatra.common; +package com.rampatra.base; import java.util.NoSuchElementException; diff --git a/src/main/java/com/rampatra/common/DoubleLinkedList.java b/src/main/java/com/rampatra/base/DoubleLinkedList.java similarity index 99% rename from src/main/java/com/rampatra/common/DoubleLinkedList.java rename to src/main/java/com/rampatra/base/DoubleLinkedList.java index b5acba2b..e905725c 100644 --- a/src/main/java/com/rampatra/common/DoubleLinkedList.java +++ b/src/main/java/com/rampatra/base/DoubleLinkedList.java @@ -1,4 +1,4 @@ -package com.rampatra.common; +package com.rampatra.base; import java.util.NoSuchElementException; diff --git a/src/main/java/com/rampatra/common/DoubleLinkedNode.java b/src/main/java/com/rampatra/base/DoubleLinkedNode.java similarity index 94% rename from src/main/java/com/rampatra/common/DoubleLinkedNode.java rename to src/main/java/com/rampatra/base/DoubleLinkedNode.java index 38795f1f..7da01c20 100644 --- a/src/main/java/com/rampatra/common/DoubleLinkedNode.java +++ b/src/main/java/com/rampatra/base/DoubleLinkedNode.java @@ -1,4 +1,4 @@ -package com.rampatra.common; +package com.rampatra.base; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/common/Graph.java b/src/main/java/com/rampatra/base/Graph.java similarity index 84% rename from src/main/java/com/rampatra/common/Graph.java rename to src/main/java/com/rampatra/base/Graph.java index 85be0f96..0de77ba1 100644 --- a/src/main/java/com/rampatra/common/Graph.java +++ b/src/main/java/com/rampatra/base/Graph.java @@ -1,4 +1,4 @@ -package com.rampatra.common; +package com.rampatra.base; /** * A rudimentary Graph having all the basic methods. diff --git a/src/main/java/com/rampatra/common/GraphNode.java b/src/main/java/com/rampatra/base/GraphNode.java similarity index 97% rename from src/main/java/com/rampatra/common/GraphNode.java rename to src/main/java/com/rampatra/base/GraphNode.java index 0899e9bf..90f98478 100644 --- a/src/main/java/com/rampatra/common/GraphNode.java +++ b/src/main/java/com/rampatra/base/GraphNode.java @@ -1,4 +1,4 @@ -package com.rampatra.common; +package com.rampatra.base; import java.util.HashSet; import java.util.Set; diff --git a/src/main/java/com/rampatra/common/LinkedList.java b/src/main/java/com/rampatra/base/LinkedList.java similarity index 98% rename from src/main/java/com/rampatra/common/LinkedList.java rename to src/main/java/com/rampatra/base/LinkedList.java index be0b1c9d..cd45a2d5 100644 --- a/src/main/java/com/rampatra/common/LinkedList.java +++ b/src/main/java/com/rampatra/base/LinkedList.java @@ -1,4 +1,4 @@ -package com.rampatra.common; +package com.rampatra.base; /** * A generic interface for LinkedList. diff --git a/src/main/java/com/rampatra/common/LinkedQueue.java b/src/main/java/com/rampatra/base/LinkedQueue.java similarity index 98% rename from src/main/java/com/rampatra/common/LinkedQueue.java rename to src/main/java/com/rampatra/base/LinkedQueue.java index d993b998..3e4c472d 100644 --- a/src/main/java/com/rampatra/common/LinkedQueue.java +++ b/src/main/java/com/rampatra/base/LinkedQueue.java @@ -1,4 +1,4 @@ -package com.rampatra.common; +package com.rampatra.base; import java.util.NoSuchElementException; diff --git a/src/main/java/com/rampatra/common/LinkedStack.java b/src/main/java/com/rampatra/base/LinkedStack.java similarity index 98% rename from src/main/java/com/rampatra/common/LinkedStack.java rename to src/main/java/com/rampatra/base/LinkedStack.java index 95adaf08..d41c8945 100644 --- a/src/main/java/com/rampatra/common/LinkedStack.java +++ b/src/main/java/com/rampatra/base/LinkedStack.java @@ -1,4 +1,4 @@ -package com.rampatra.common; +package com.rampatra.base; import java.util.EmptyStackException; diff --git a/src/main/java/com/rampatra/common/MaxHeap.java b/src/main/java/com/rampatra/base/MaxHeap.java similarity index 99% rename from src/main/java/com/rampatra/common/MaxHeap.java rename to src/main/java/com/rampatra/base/MaxHeap.java index 3265f221..22b36cfa 100644 --- a/src/main/java/com/rampatra/common/MaxHeap.java +++ b/src/main/java/com/rampatra/base/MaxHeap.java @@ -1,4 +1,4 @@ -package com.rampatra.common; +package com.rampatra.base; import com.rampatra.sorting.HeapSort; diff --git a/src/main/java/com/rampatra/common/MinHeap.java b/src/main/java/com/rampatra/base/MinHeap.java similarity index 99% rename from src/main/java/com/rampatra/common/MinHeap.java rename to src/main/java/com/rampatra/base/MinHeap.java index 60378d60..6e7b7df1 100644 --- a/src/main/java/com/rampatra/common/MinHeap.java +++ b/src/main/java/com/rampatra/base/MinHeap.java @@ -1,4 +1,4 @@ -package com.rampatra.common; +package com.rampatra.base; import java.util.Arrays; diff --git a/src/main/java/com/rampatra/common/Queue.java b/src/main/java/com/rampatra/base/Queue.java similarity index 96% rename from src/main/java/com/rampatra/common/Queue.java rename to src/main/java/com/rampatra/base/Queue.java index 2fa0bafa..660fcb90 100644 --- a/src/main/java/com/rampatra/common/Queue.java +++ b/src/main/java/com/rampatra/base/Queue.java @@ -1,4 +1,4 @@ -package com.rampatra.common; +package com.rampatra.base; /** * A generic interface for a queue. diff --git a/src/main/java/com/rampatra/common/SingleLinkedList.java b/src/main/java/com/rampatra/base/SingleLinkedList.java similarity index 99% rename from src/main/java/com/rampatra/common/SingleLinkedList.java rename to src/main/java/com/rampatra/base/SingleLinkedList.java index ba4ff895..d52484cb 100644 --- a/src/main/java/com/rampatra/common/SingleLinkedList.java +++ b/src/main/java/com/rampatra/base/SingleLinkedList.java @@ -1,4 +1,4 @@ -package com.rampatra.common; +package com.rampatra.base; import java.util.NoSuchElementException; diff --git a/src/main/java/com/rampatra/common/SingleLinkedNode.java b/src/main/java/com/rampatra/base/SingleLinkedNode.java similarity index 93% rename from src/main/java/com/rampatra/common/SingleLinkedNode.java rename to src/main/java/com/rampatra/base/SingleLinkedNode.java index 4a152067..97cd9a05 100644 --- a/src/main/java/com/rampatra/common/SingleLinkedNode.java +++ b/src/main/java/com/rampatra/base/SingleLinkedNode.java @@ -1,4 +1,4 @@ -package com.rampatra.common; +package com.rampatra.base; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/common/Stack.java b/src/main/java/com/rampatra/base/Stack.java similarity index 97% rename from src/main/java/com/rampatra/common/Stack.java rename to src/main/java/com/rampatra/base/Stack.java index d1b3326c..3761052a 100644 --- a/src/main/java/com/rampatra/common/Stack.java +++ b/src/main/java/com/rampatra/base/Stack.java @@ -1,4 +1,4 @@ -package com.rampatra.common; +package com.rampatra.base; /** * A generic interface for a stack. diff --git a/src/main/java/com/rampatra/common/Tree.java b/src/main/java/com/rampatra/base/Tree.java similarity index 88% rename from src/main/java/com/rampatra/common/Tree.java rename to src/main/java/com/rampatra/base/Tree.java index 7b643947..56c8b338 100644 --- a/src/main/java/com/rampatra/common/Tree.java +++ b/src/main/java/com/rampatra/base/Tree.java @@ -1,4 +1,4 @@ -package com.rampatra.common; +package com.rampatra.base; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/common/Trie.java b/src/main/java/com/rampatra/base/Trie.java similarity index 99% rename from src/main/java/com/rampatra/common/Trie.java rename to src/main/java/com/rampatra/base/Trie.java index 6996f26f..c5c72278 100644 --- a/src/main/java/com/rampatra/common/Trie.java +++ b/src/main/java/com/rampatra/base/Trie.java @@ -1,4 +1,4 @@ -package com.rampatra.common; +package com.rampatra.base; import java.util.HashMap; diff --git a/src/main/java/com/rampatra/common/UndirectedGraph.java b/src/main/java/com/rampatra/base/UndirectedGraph.java similarity index 99% rename from src/main/java/com/rampatra/common/UndirectedGraph.java rename to src/main/java/com/rampatra/base/UndirectedGraph.java index 40a4da79..88ed8231 100644 --- a/src/main/java/com/rampatra/common/UndirectedGraph.java +++ b/src/main/java/com/rampatra/base/UndirectedGraph.java @@ -1,4 +1,4 @@ -package com.rampatra.common; +package com.rampatra.base; import java.util.ArrayDeque; import java.util.HashMap; diff --git a/src/main/java/com/rampatra/linkedlists/AddNumbersInTwoLists.java b/src/main/java/com/rampatra/linkedlists/AddNumbersInTwoLists.java index 6657c520..d3ed31ab 100644 --- a/src/main/java/com/rampatra/linkedlists/AddNumbersInTwoLists.java +++ b/src/main/java/com/rampatra/linkedlists/AddNumbersInTwoLists.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/CloneWithRandPointers.java b/src/main/java/com/rampatra/linkedlists/CloneWithRandPointers.java index 7883454b..ecdb2849 100644 --- a/src/main/java/com/rampatra/linkedlists/CloneWithRandPointers.java +++ b/src/main/java/com/rampatra/linkedlists/CloneWithRandPointers.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.DoubleLinkedList; -import com.rampatra.common.DoubleLinkedNode; +import com.rampatra.base.DoubleLinkedList; +import com.rampatra.base.DoubleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/DeleteAlternateNodes.java b/src/main/java/com/rampatra/linkedlists/DeleteAlternateNodes.java index e640e2bf..d6bf4e8f 100644 --- a/src/main/java/com/rampatra/linkedlists/DeleteAlternateNodes.java +++ b/src/main/java/com/rampatra/linkedlists/DeleteAlternateNodes.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/DeleteLesserNodes.java b/src/main/java/com/rampatra/linkedlists/DeleteLesserNodes.java index 523e80c6..dae9ed02 100644 --- a/src/main/java/com/rampatra/linkedlists/DeleteLesserNodes.java +++ b/src/main/java/com/rampatra/linkedlists/DeleteLesserNodes.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/DeleteMnodesAfterNnodes.java b/src/main/java/com/rampatra/linkedlists/DeleteMnodesAfterNnodes.java index de68f56f..74b23927 100644 --- a/src/main/java/com/rampatra/linkedlists/DeleteMnodesAfterNnodes.java +++ b/src/main/java/com/rampatra/linkedlists/DeleteMnodesAfterNnodes.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/DeleteNode.java b/src/main/java/com/rampatra/linkedlists/DeleteNode.java index ea8b6ac9..d9b0bc78 100644 --- a/src/main/java/com/rampatra/linkedlists/DeleteNode.java +++ b/src/main/java/com/rampatra/linkedlists/DeleteNode.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/DetectAndRemoveLoop.java b/src/main/java/com/rampatra/linkedlists/DetectAndRemoveLoop.java index 6eb4e704..3be3c3c5 100644 --- a/src/main/java/com/rampatra/linkedlists/DetectAndRemoveLoop.java +++ b/src/main/java/com/rampatra/linkedlists/DetectAndRemoveLoop.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/DetectLoop.java b/src/main/java/com/rampatra/linkedlists/DetectLoop.java index dad12376..d6696e23 100644 --- a/src/main/java/com/rampatra/linkedlists/DetectLoop.java +++ b/src/main/java/com/rampatra/linkedlists/DetectLoop.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; import java.util.HashMap; diff --git a/src/main/java/com/rampatra/linkedlists/DivideCircularListIntoTwo.java b/src/main/java/com/rampatra/linkedlists/DivideCircularListIntoTwo.java index 0e1fee8b..f955c18a 100644 --- a/src/main/java/com/rampatra/linkedlists/DivideCircularListIntoTwo.java +++ b/src/main/java/com/rampatra/linkedlists/DivideCircularListIntoTwo.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.CircularSingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.CircularSingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/FlattenMultiLevelLinkedList.java b/src/main/java/com/rampatra/linkedlists/FlattenMultiLevelLinkedList.java index 1a5fa5fe..480c999d 100644 --- a/src/main/java/com/rampatra/linkedlists/FlattenMultiLevelLinkedList.java +++ b/src/main/java/com/rampatra/linkedlists/FlattenMultiLevelLinkedList.java @@ -1,6 +1,6 @@ package com.rampatra.linkedlists; -import com.rampatra.common.DoubleLinkedNode; +import com.rampatra.base.DoubleLinkedNode; import static java.lang.System.out; diff --git a/src/main/java/com/rampatra/linkedlists/Identical.java b/src/main/java/com/rampatra/linkedlists/Identical.java index 3a846d0c..aa760b47 100644 --- a/src/main/java/com/rampatra/linkedlists/Identical.java +++ b/src/main/java/com/rampatra/linkedlists/Identical.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/InsertInSortedCircularLinkedList.java b/src/main/java/com/rampatra/linkedlists/InsertInSortedCircularLinkedList.java index ec009b5b..f5b07d9f 100644 --- a/src/main/java/com/rampatra/linkedlists/InsertInSortedCircularLinkedList.java +++ b/src/main/java/com/rampatra/linkedlists/InsertInSortedCircularLinkedList.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.CircularSingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.CircularSingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/InsertInSortedList.java b/src/main/java/com/rampatra/linkedlists/InsertInSortedList.java index 3e659683..77488a2c 100644 --- a/src/main/java/com/rampatra/linkedlists/InsertInSortedList.java +++ b/src/main/java/com/rampatra/linkedlists/InsertInSortedList.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/IntersectionAndUnionOf2Lists.java b/src/main/java/com/rampatra/linkedlists/IntersectionAndUnionOf2Lists.java index 5c645588..42301f2d 100644 --- a/src/main/java/com/rampatra/linkedlists/IntersectionAndUnionOf2Lists.java +++ b/src/main/java/com/rampatra/linkedlists/IntersectionAndUnionOf2Lists.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/IntersectionOf2SortedLists.java b/src/main/java/com/rampatra/linkedlists/IntersectionOf2SortedLists.java index 5f271d0f..bc7575ce 100644 --- a/src/main/java/com/rampatra/linkedlists/IntersectionOf2SortedLists.java +++ b/src/main/java/com/rampatra/linkedlists/IntersectionOf2SortedLists.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/IntersectionPointOfTwoLists.java b/src/main/java/com/rampatra/linkedlists/IntersectionPointOfTwoLists.java index 3b8894b9..d55e5336 100644 --- a/src/main/java/com/rampatra/linkedlists/IntersectionPointOfTwoLists.java +++ b/src/main/java/com/rampatra/linkedlists/IntersectionPointOfTwoLists.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/MaximumSumLinkedList.java b/src/main/java/com/rampatra/linkedlists/MaximumSumLinkedList.java index 7761e591..fe5db9cd 100644 --- a/src/main/java/com/rampatra/linkedlists/MaximumSumLinkedList.java +++ b/src/main/java/com/rampatra/linkedlists/MaximumSumLinkedList.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/MergeSort.java b/src/main/java/com/rampatra/linkedlists/MergeSort.java index 4b79e43c..daaa4663 100644 --- a/src/main/java/com/rampatra/linkedlists/MergeSort.java +++ b/src/main/java/com/rampatra/linkedlists/MergeSort.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/MergeSortDoubleLinkedList.java b/src/main/java/com/rampatra/linkedlists/MergeSortDoubleLinkedList.java index 5bc38809..9637430a 100644 --- a/src/main/java/com/rampatra/linkedlists/MergeSortDoubleLinkedList.java +++ b/src/main/java/com/rampatra/linkedlists/MergeSortDoubleLinkedList.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.DoubleLinkedList; -import com.rampatra.common.DoubleLinkedNode; +import com.rampatra.base.DoubleLinkedList; +import com.rampatra.base.DoubleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/MergeTwoLinkedListAlternatively.java b/src/main/java/com/rampatra/linkedlists/MergeTwoLinkedListAlternatively.java index 5f95fc37..14777e7e 100644 --- a/src/main/java/com/rampatra/linkedlists/MergeTwoLinkedListAlternatively.java +++ b/src/main/java/com/rampatra/linkedlists/MergeTwoLinkedListAlternatively.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/MergeTwoSortedLists.java b/src/main/java/com/rampatra/linkedlists/MergeTwoSortedLists.java index a926b143..23f646f2 100644 --- a/src/main/java/com/rampatra/linkedlists/MergeTwoSortedLists.java +++ b/src/main/java/com/rampatra/linkedlists/MergeTwoSortedLists.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/MiddleNode.java b/src/main/java/com/rampatra/linkedlists/MiddleNode.java index 22a81872..706d1415 100644 --- a/src/main/java/com/rampatra/linkedlists/MiddleNode.java +++ b/src/main/java/com/rampatra/linkedlists/MiddleNode.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/MoveLastNodeToFirst.java b/src/main/java/com/rampatra/linkedlists/MoveLastNodeToFirst.java index 6637b372..dfca9643 100644 --- a/src/main/java/com/rampatra/linkedlists/MoveLastNodeToFirst.java +++ b/src/main/java/com/rampatra/linkedlists/MoveLastNodeToFirst.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/NthNodeFromLast.java b/src/main/java/com/rampatra/linkedlists/NthNodeFromLast.java index a81b219d..e4e5a09f 100644 --- a/src/main/java/com/rampatra/linkedlists/NthNodeFromLast.java +++ b/src/main/java/com/rampatra/linkedlists/NthNodeFromLast.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/PairWiseSwap.java b/src/main/java/com/rampatra/linkedlists/PairWiseSwap.java index 0663b617..991a97ae 100644 --- a/src/main/java/com/rampatra/linkedlists/PairWiseSwap.java +++ b/src/main/java/com/rampatra/linkedlists/PairWiseSwap.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/Palindrome.java b/src/main/java/com/rampatra/linkedlists/Palindrome.java index 1718a17d..0f38cefe 100644 --- a/src/main/java/com/rampatra/linkedlists/Palindrome.java +++ b/src/main/java/com/rampatra/linkedlists/Palindrome.java @@ -1,9 +1,9 @@ package com.rampatra.linkedlists; -import com.rampatra.common.LinkedStack; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; -import com.rampatra.common.Stack; +import com.rampatra.base.LinkedStack; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; +import com.rampatra.base.Stack; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/QuickSort.java b/src/main/java/com/rampatra/linkedlists/QuickSort.java index 5d6f2352..c358ec9a 100644 --- a/src/main/java/com/rampatra/linkedlists/QuickSort.java +++ b/src/main/java/com/rampatra/linkedlists/QuickSort.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/RandomNode.java b/src/main/java/com/rampatra/linkedlists/RandomNode.java index ca0c22c7..5f7b9b64 100644 --- a/src/main/java/com/rampatra/linkedlists/RandomNode.java +++ b/src/main/java/com/rampatra/linkedlists/RandomNode.java @@ -1,8 +1,8 @@ package com.rampatra.linkedlists; import com.rampatra.arrays.ReservoirSampling; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; import java.util.Random; diff --git a/src/main/java/com/rampatra/linkedlists/RemoveDuplicates.java b/src/main/java/com/rampatra/linkedlists/RemoveDuplicates.java index 0bc33542..f87b0f55 100644 --- a/src/main/java/com/rampatra/linkedlists/RemoveDuplicates.java +++ b/src/main/java/com/rampatra/linkedlists/RemoveDuplicates.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; import java.util.HashSet; import java.util.Set; diff --git a/src/main/java/com/rampatra/linkedlists/RemoveMiddlePointsFromLineSegments.java b/src/main/java/com/rampatra/linkedlists/RemoveMiddlePointsFromLineSegments.java index cd250c0c..b77a6a53 100644 --- a/src/main/java/com/rampatra/linkedlists/RemoveMiddlePointsFromLineSegments.java +++ b/src/main/java/com/rampatra/linkedlists/RemoveMiddlePointsFromLineSegments.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/ReverseAlternateNodesAndAppendAtEnd.java b/src/main/java/com/rampatra/linkedlists/ReverseAlternateNodesAndAppendAtEnd.java index 44d01877..d0b7685a 100644 --- a/src/main/java/com/rampatra/linkedlists/ReverseAlternateNodesAndAppendAtEnd.java +++ b/src/main/java/com/rampatra/linkedlists/ReverseAlternateNodesAndAppendAtEnd.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/ReverseDoubleLinkedList.java b/src/main/java/com/rampatra/linkedlists/ReverseDoubleLinkedList.java index fc78b4a2..3d86969a 100644 --- a/src/main/java/com/rampatra/linkedlists/ReverseDoubleLinkedList.java +++ b/src/main/java/com/rampatra/linkedlists/ReverseDoubleLinkedList.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.DoubleLinkedList; -import com.rampatra.common.DoubleLinkedNode; +import com.rampatra.base.DoubleLinkedList; +import com.rampatra.base.DoubleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/ReverseLinkedListInAlternateGroups.java b/src/main/java/com/rampatra/linkedlists/ReverseLinkedListInAlternateGroups.java index fddd2afb..f759840c 100644 --- a/src/main/java/com/rampatra/linkedlists/ReverseLinkedListInAlternateGroups.java +++ b/src/main/java/com/rampatra/linkedlists/ReverseLinkedListInAlternateGroups.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/ReverseLinkedListInGroups.java b/src/main/java/com/rampatra/linkedlists/ReverseLinkedListInGroups.java index a5326687..7ac36e9d 100644 --- a/src/main/java/com/rampatra/linkedlists/ReverseLinkedListInGroups.java +++ b/src/main/java/com/rampatra/linkedlists/ReverseLinkedListInGroups.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/ReverseSingleLinkedList.java b/src/main/java/com/rampatra/linkedlists/ReverseSingleLinkedList.java index 0260a419..e30f1879 100644 --- a/src/main/java/com/rampatra/linkedlists/ReverseSingleLinkedList.java +++ b/src/main/java/com/rampatra/linkedlists/ReverseSingleLinkedList.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * This is for reversing a linked list, both iteratively and recursively. If you diff --git a/src/main/java/com/rampatra/linkedlists/RotateLinkedList.java b/src/main/java/com/rampatra/linkedlists/RotateLinkedList.java index 66eb43ba..b4cab9bf 100644 --- a/src/main/java/com/rampatra/linkedlists/RotateLinkedList.java +++ b/src/main/java/com/rampatra/linkedlists/RotateLinkedList.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/SegregateEvenOddNumbers.java b/src/main/java/com/rampatra/linkedlists/SegregateEvenOddNumbers.java index 3a66a72d..05c9de62 100644 --- a/src/main/java/com/rampatra/linkedlists/SegregateEvenOddNumbers.java +++ b/src/main/java/com/rampatra/linkedlists/SegregateEvenOddNumbers.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/SortAlternativelySortedLinkedList.java b/src/main/java/com/rampatra/linkedlists/SortAlternativelySortedLinkedList.java index 18290245..3f76388e 100644 --- a/src/main/java/com/rampatra/linkedlists/SortAlternativelySortedLinkedList.java +++ b/src/main/java/com/rampatra/linkedlists/SortAlternativelySortedLinkedList.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/SortLinkedListOf0s1s2s.java b/src/main/java/com/rampatra/linkedlists/SortLinkedListOf0s1s2s.java index 45c33104..ba4ec323 100644 --- a/src/main/java/com/rampatra/linkedlists/SortLinkedListOf0s1s2s.java +++ b/src/main/java/com/rampatra/linkedlists/SortLinkedListOf0s1s2s.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/SortedDLLToBBST.java b/src/main/java/com/rampatra/linkedlists/SortedDLLToBBST.java index 78c88c68..6332bc18 100644 --- a/src/main/java/com/rampatra/linkedlists/SortedDLLToBBST.java +++ b/src/main/java/com/rampatra/linkedlists/SortedDLLToBBST.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.DoubleLinkedList; -import com.rampatra.common.DoubleLinkedNode; +import com.rampatra.base.DoubleLinkedList; +import com.rampatra.base.DoubleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/StackWithOperationOnMiddleElement.java b/src/main/java/com/rampatra/linkedlists/StackWithOperationOnMiddleElement.java index cc0b01dc..111e0465 100644 --- a/src/main/java/com/rampatra/linkedlists/StackWithOperationOnMiddleElement.java +++ b/src/main/java/com/rampatra/linkedlists/StackWithOperationOnMiddleElement.java @@ -1,6 +1,6 @@ package com.rampatra.linkedlists; -import com.rampatra.common.DoubleLinkedNode; +import com.rampatra.base.DoubleLinkedNode; import java.util.EmptyStackException; diff --git a/src/main/java/com/rampatra/linkedlists/SwapKthNode.java b/src/main/java/com/rampatra/linkedlists/SwapKthNode.java index dfcfc48a..75bf8f35 100644 --- a/src/main/java/com/rampatra/linkedlists/SwapKthNode.java +++ b/src/main/java/com/rampatra/linkedlists/SwapKthNode.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/SwapNodes.java b/src/main/java/com/rampatra/linkedlists/SwapNodes.java index c2598f60..446aa3b1 100644 --- a/src/main/java/com/rampatra/linkedlists/SwapNodes.java +++ b/src/main/java/com/rampatra/linkedlists/SwapNodes.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/linkedlists/TripletFromThreeLinkedLists.java b/src/main/java/com/rampatra/linkedlists/TripletFromThreeLinkedLists.java index ae10516d..1cf5da2e 100644 --- a/src/main/java/com/rampatra/linkedlists/TripletFromThreeLinkedLists.java +++ b/src/main/java/com/rampatra/linkedlists/TripletFromThreeLinkedLists.java @@ -1,7 +1,7 @@ package com.rampatra.linkedlists; -import com.rampatra.common.SingleLinkedList; -import com.rampatra.common.SingleLinkedNode; +import com.rampatra.base.SingleLinkedList; +import com.rampatra.base.SingleLinkedNode; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/sorting/HeapSort.java b/src/main/java/com/rampatra/sorting/HeapSort.java index 7d2c8172..92473dd9 100644 --- a/src/main/java/com/rampatra/sorting/HeapSort.java +++ b/src/main/java/com/rampatra/sorting/HeapSort.java @@ -1,6 +1,6 @@ package com.rampatra.sorting; -import com.rampatra.common.MaxHeap; +import com.rampatra.base.MaxHeap; import java.util.Arrays; diff --git a/src/main/java/com/rampatra/misc/BalancingParenthesis.java b/src/main/java/com/rampatra/stacks/BalancingParenthesis.java similarity index 99% rename from src/main/java/com/rampatra/misc/BalancingParenthesis.java rename to src/main/java/com/rampatra/stacks/BalancingParenthesis.java index 7c4e3a15..9b497db4 100644 --- a/src/main/java/com/rampatra/misc/BalancingParenthesis.java +++ b/src/main/java/com/rampatra/stacks/BalancingParenthesis.java @@ -1,4 +1,4 @@ -package com.rampatra.misc; +package com.rampatra.stacks; import java.io.BufferedReader; import java.io.FileReader; diff --git a/src/main/java/com/rampatra/trees/BFSUsingQueue.java b/src/main/java/com/rampatra/trees/BFSUsingQueue.java index 89cd7246..7d1df283 100644 --- a/src/main/java/com/rampatra/trees/BFSUsingQueue.java +++ b/src/main/java/com/rampatra/trees/BFSUsingQueue.java @@ -1,11 +1,10 @@ package com.rampatra.trees; -import com.rampatra.common.BinaryNode; -import com.rampatra.common.BinaryTree; -import com.rampatra.common.LinkedQueue; -import com.rampatra.common.Queue; +import com.rampatra.base.BinaryNode; +import com.rampatra.base.BinaryTree; +import com.rampatra.base.LinkedQueue; +import com.rampatra.base.Queue; -import java.util.LinkedList; import java.util.NoSuchElementException; import static java.lang.System.out; diff --git a/src/main/java/com/rampatra/trees/CheckForBST.java b/src/main/java/com/rampatra/trees/CheckForBST.java index 856253eb..ed0b6317 100644 --- a/src/main/java/com/rampatra/trees/CheckForBST.java +++ b/src/main/java/com/rampatra/trees/CheckForBST.java @@ -1,8 +1,8 @@ package com.rampatra.trees; -import com.rampatra.common.BinaryNode; -import com.rampatra.common.BinarySearchTree; -import com.rampatra.common.BinaryTree; +import com.rampatra.base.BinaryNode; +import com.rampatra.base.BinarySearchTree; +import com.rampatra.base.BinaryTree; import java.util.List; diff --git a/src/main/java/com/rampatra/trees/ChildrenSum.java b/src/main/java/com/rampatra/trees/ChildrenSum.java index c8c6ccb6..a5ad7f3a 100644 --- a/src/main/java/com/rampatra/trees/ChildrenSum.java +++ b/src/main/java/com/rampatra/trees/ChildrenSum.java @@ -1,7 +1,7 @@ package com.rampatra.trees; -import com.rampatra.common.BinaryNode; -import com.rampatra.common.BinaryTree; +import com.rampatra.base.BinaryNode; +import com.rampatra.base.BinaryTree; import static java.lang.System.out; diff --git a/src/main/java/com/rampatra/trees/ConstructTreeFromInOrderAndPreOrder.java b/src/main/java/com/rampatra/trees/ConstructTreeFromInOrderAndPreOrder.java index dbecda30..4ccbe61b 100644 --- a/src/main/java/com/rampatra/trees/ConstructTreeFromInOrderAndPreOrder.java +++ b/src/main/java/com/rampatra/trees/ConstructTreeFromInOrderAndPreOrder.java @@ -1,6 +1,6 @@ package com.rampatra.trees; -import com.rampatra.common.BinaryNode; +import com.rampatra.base.BinaryNode; import java.util.List; diff --git a/src/main/java/com/rampatra/trees/DoubleTree.java b/src/main/java/com/rampatra/trees/DoubleTree.java index 5e6dc27d..8a3af0b1 100644 --- a/src/main/java/com/rampatra/trees/DoubleTree.java +++ b/src/main/java/com/rampatra/trees/DoubleTree.java @@ -1,7 +1,7 @@ package com.rampatra.trees; -import com.rampatra.common.BinaryNode; -import com.rampatra.common.BinaryTree; +import com.rampatra.base.BinaryNode; +import com.rampatra.base.BinaryTree; import static java.lang.System.out; diff --git a/src/main/java/com/rampatra/trees/HeightBalanced.java b/src/main/java/com/rampatra/trees/HeightBalanced.java index d253b7f2..394dff5b 100644 --- a/src/main/java/com/rampatra/trees/HeightBalanced.java +++ b/src/main/java/com/rampatra/trees/HeightBalanced.java @@ -1,7 +1,7 @@ package com.rampatra.trees; -import com.rampatra.common.BinaryNode; -import com.rampatra.common.BinarySearchTree; +import com.rampatra.base.BinaryNode; +import com.rampatra.base.BinarySearchTree; import static java.lang.System.out; diff --git a/src/main/java/com/rampatra/trees/IdenticalTrees.java b/src/main/java/com/rampatra/trees/IdenticalTrees.java index 935cddbc..e9d278c6 100644 --- a/src/main/java/com/rampatra/trees/IdenticalTrees.java +++ b/src/main/java/com/rampatra/trees/IdenticalTrees.java @@ -1,7 +1,7 @@ package com.rampatra.trees; -import com.rampatra.common.BinaryNode; -import com.rampatra.common.BinarySearchTree; +import com.rampatra.base.BinaryNode; +import com.rampatra.base.BinarySearchTree; import static java.lang.System.out; diff --git a/src/main/java/com/rampatra/trees/InOrderUsingStack.java b/src/main/java/com/rampatra/trees/InOrderUsingStack.java index 0e402d78..20d14d48 100644 --- a/src/main/java/com/rampatra/trees/InOrderUsingStack.java +++ b/src/main/java/com/rampatra/trees/InOrderUsingStack.java @@ -1,9 +1,9 @@ package com.rampatra.trees; -import com.rampatra.common.BinaryNode; -import com.rampatra.common.BinarySearchTree; -import com.rampatra.common.LinkedStack; -import com.rampatra.common.Stack; +import com.rampatra.base.BinaryNode; +import com.rampatra.base.BinarySearchTree; +import com.rampatra.base.LinkedStack; +import com.rampatra.base.Stack; import static java.lang.System.out; diff --git a/src/main/java/com/rampatra/trees/InOrderWithoutStackAndRecursion.java b/src/main/java/com/rampatra/trees/InOrderWithoutStackAndRecursion.java index 7320bf8f..8ae701bf 100644 --- a/src/main/java/com/rampatra/trees/InOrderWithoutStackAndRecursion.java +++ b/src/main/java/com/rampatra/trees/InOrderWithoutStackAndRecursion.java @@ -1,7 +1,7 @@ package com.rampatra.trees; -import com.rampatra.common.BinaryNode; -import com.rampatra.common.BinarySearchTree; +import com.rampatra.base.BinaryNode; +import com.rampatra.base.BinarySearchTree; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/trees/LeafNodes.java b/src/main/java/com/rampatra/trees/LeafNodes.java index 462addef..a8c95e3a 100644 --- a/src/main/java/com/rampatra/trees/LeafNodes.java +++ b/src/main/java/com/rampatra/trees/LeafNodes.java @@ -1,7 +1,7 @@ package com.rampatra.trees; -import com.rampatra.common.BinaryNode; -import com.rampatra.common.BinaryTree; +import com.rampatra.base.BinaryNode; +import com.rampatra.base.BinaryTree; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/trees/LeastCommonAncestor.java b/src/main/java/com/rampatra/trees/LeastCommonAncestor.java index e3d71dc5..789acf2d 100644 --- a/src/main/java/com/rampatra/trees/LeastCommonAncestor.java +++ b/src/main/java/com/rampatra/trees/LeastCommonAncestor.java @@ -1,7 +1,7 @@ package com.rampatra.trees; -import com.rampatra.common.BinaryNode; -import com.rampatra.common.BinarySearchTree; +import com.rampatra.base.BinaryNode; +import com.rampatra.base.BinarySearchTree; import java.util.NoSuchElementException; diff --git a/src/main/java/com/rampatra/trees/MirrorTree.java b/src/main/java/com/rampatra/trees/MirrorTree.java index a92cd4fa..575d6e2e 100644 --- a/src/main/java/com/rampatra/trees/MirrorTree.java +++ b/src/main/java/com/rampatra/trees/MirrorTree.java @@ -1,7 +1,7 @@ package com.rampatra.trees; -import com.rampatra.common.BinaryNode; -import com.rampatra.common.BinaryTree; +import com.rampatra.base.BinaryNode; +import com.rampatra.base.BinaryTree; /** * Created by IntelliJ IDEA. diff --git a/src/main/java/com/rampatra/trees/RootToLeafPaths.java b/src/main/java/com/rampatra/trees/RootToLeafPaths.java index aba3bdb8..38688199 100644 --- a/src/main/java/com/rampatra/trees/RootToLeafPaths.java +++ b/src/main/java/com/rampatra/trees/RootToLeafPaths.java @@ -1,7 +1,7 @@ package com.rampatra.trees; -import com.rampatra.common.BinaryNode; -import com.rampatra.common.BinaryTree; +import com.rampatra.base.BinaryNode; +import com.rampatra.base.BinaryTree; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/com/rampatra/trees/SpiralTraversal.java b/src/main/java/com/rampatra/trees/SpiralTraversal.java index cd8a193e..0f4cb62b 100644 --- a/src/main/java/com/rampatra/trees/SpiralTraversal.java +++ b/src/main/java/com/rampatra/trees/SpiralTraversal.java @@ -1,9 +1,9 @@ package com.rampatra.trees; -import com.rampatra.common.BinaryNode; -import com.rampatra.common.BinaryTree; -import com.rampatra.common.LinkedStack; -import com.rampatra.common.Stack; +import com.rampatra.base.BinaryNode; +import com.rampatra.base.BinaryTree; +import com.rampatra.base.LinkedStack; +import com.rampatra.base.Stack; import java.util.EmptyStackException; diff --git a/src/main/java/com/rampatra/trees/TreeToList.java b/src/main/java/com/rampatra/trees/TreeToList.java index 151b036c..8a169c6c 100644 --- a/src/main/java/com/rampatra/trees/TreeToList.java +++ b/src/main/java/com/rampatra/trees/TreeToList.java @@ -1,7 +1,7 @@ package com.rampatra.trees; -import com.rampatra.common.BinaryNode; -import com.rampatra.common.BinarySearchTree; +import com.rampatra.base.BinaryNode; +import com.rampatra.base.BinarySearchTree; /** * Created by IntelliJ IDEA. From 8503b1a27e1b8cb4bc5adfa6673da499318c880f Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Tue, 26 Feb 2019 11:48:14 +0000 Subject: [PATCH 005/164] Added a rudimentary Map/Reduce example --- .../java/com/rampatra/misc/MapReduce.java | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 src/main/java/com/rampatra/misc/MapReduce.java diff --git a/src/main/java/com/rampatra/misc/MapReduce.java b/src/main/java/com/rampatra/misc/MapReduce.java new file mode 100644 index 00000000..a69df528 --- /dev/null +++ b/src/main/java/com/rampatra/misc/MapReduce.java @@ -0,0 +1,74 @@ +package com.rampatra.misc; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * A rudimentary example explaining the concept of Map/Reduce paradigm. The question is, provided a list of Person + * objects from various countries, compute the total population in each country. + * + * @author rampatra + * @since 2019-02-26 + */ +public class MapReduce { + + private static class Person { + String name; + int age; + String country; + + Person(String country) { + this.country = country; + } + } + + /** + * The mapper function will take all the data and output only the information which we need, and in this + * case, it is just the country name to which a person belongs. + * + * @param personList a list of all persons + * @return a list of country names + */ + private static List mapper(List personList) { + return personList.stream().map(person -> person.country).collect(Collectors.toList()); + } + + /** + * The reducer function will take all the useful information from the mapper function and then compute the result + * we need. In this case, it is to count the number of persons in each country. + * + * @param countryNamesOfAllPersons a list of country names taken out of all {@code Person} objects + * @return a map containing country names as the keys and their resp. population as values + */ + private static Map reducer(List countryNamesOfAllPersons) { + Map countryToPopulationMap = new HashMap<>(); + + countryNamesOfAllPersons.forEach(countryName -> { + countryToPopulationMap.computeIfPresent(countryName, (country, population) -> population + 1); + countryToPopulationMap.computeIfAbsent(countryName, country -> countryToPopulationMap.put(country, 1)); + }); + + return countryToPopulationMap; + } + + /** + * Just to print the output. + * + * @param countryToPopulationMap a map containing country names as the keys and their resp. population as values + */ + private static void printPopulation(Map countryToPopulationMap) { + countryToPopulationMap.forEach((k, v) -> System.out.println(k + ": " + v)); + } + + public static void main(String[] args) { + + Person[] persons = new Person[]{new Person("India"), new Person("Ireland"), + new Person("Sweden"), new Person("United States"), new Person("India"), + new Person("Ireland"), new Person("India")}; + + printPopulation(reducer(mapper(Arrays.asList(persons)))); + } +} \ No newline at end of file From 66952870cb5aebdcae51623a02e528fe5e76a5c3 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Mon, 4 Mar 2019 22:37:30 +0000 Subject: [PATCH 006/164] Added different approaches to Fibonacci Numbers --- .../ctci/recursionanddp/FibonacciNumber.java | 64 +++++++++++++++++++ .../dynamicprogramming/FibonacciNumbers.java | 7 +- .../java/com/rampatra/misc/DivideByZero.java | 4 +- 3 files changed, 69 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/ctci/recursionanddp/FibonacciNumber.java diff --git a/src/main/java/com/ctci/recursionanddp/FibonacciNumber.java b/src/main/java/com/ctci/recursionanddp/FibonacciNumber.java new file mode 100644 index 00000000..caa4d095 --- /dev/null +++ b/src/main/java/com/ctci/recursionanddp/FibonacciNumber.java @@ -0,0 +1,64 @@ +package com.ctci.recursionanddp; + +/** + * The fabled fibonacci numbers problem with three different solutions. + * The {@link FibonacciNumber#fibonacciBottomUpOptimized(int)} version is the most optimized among all w.r.t space + * and time. See {@link com.rampatra.dynamicprogramming.FibonacciNumbers} for Fibonacci series. + * + * @author rampatra + * @since 2019-02-26 + */ +public class FibonacciNumber { + + private static int fibonacciTopDown(int n, int[] memo) { + if (n == 0 || n == 1) return n; + + if (memo[n] != 0) { + return memo[n]; + } else { + memo[n] = fibonacciTopDown(n - 1, memo) + fibonacciTopDown(n - 2, memo); + return memo[n]; + } + } + + private static int fibonacciBottomUp(int n) { + if (n == 0 || n == 1) return n; + + int[] memo = new int[n + 1]; + memo[1] = 1; + for (int i = 2; i <= n; i++) { + memo[i] = memo[i - 1] + memo[i - 2]; + } + return memo[n]; + } + + private static int fibonacciBottomUpOptimized(int n) { + if (n == 0 || n == 1) return n; + + int a = 0; + int b = 1; + int res = a + b; + + for (int i = 2; i <= n; i++) { + res = a + b; + a = b; + b = res; + } + + return res; + } + + public static void main(String[] args) { + System.out.println(fibonacciTopDown(4, new int[5])); + System.out.println(fibonacciBottomUp(4)); + System.out.println(fibonacciBottomUpOptimized(4)); + System.out.println("---"); + System.out.println(fibonacciTopDown(5, new int[6])); + System.out.println(fibonacciBottomUp(5)); + System.out.println(fibonacciBottomUpOptimized(5)); + System.out.println("---"); + System.out.println(fibonacciTopDown(10, new int[11])); + System.out.println(fibonacciBottomUp(10)); + System.out.println(fibonacciBottomUpOptimized(10)); + } +} \ No newline at end of file diff --git a/src/main/java/com/rampatra/dynamicprogramming/FibonacciNumbers.java b/src/main/java/com/rampatra/dynamicprogramming/FibonacciNumbers.java index a1b1d448..c17a315c 100644 --- a/src/main/java/com/rampatra/dynamicprogramming/FibonacciNumbers.java +++ b/src/main/java/com/rampatra/dynamicprogramming/FibonacciNumbers.java @@ -9,7 +9,6 @@ * * @author rampatra * @since 9/10/15 - * @time: 3:57 PM */ public class FibonacciNumbers { @@ -22,9 +21,9 @@ public class FibonacciNumbers { * @param k */ public static int[] getFirstKFibonacciNumbers(int k) { - int[] fib = new int[k + 1]; + int[] fib = new int[k]; int i = 1; - while (i <= k) { + while (i < k) { if (i == 1 || i == 2) { fib[i] = 1; } else { @@ -35,7 +34,7 @@ public static int[] getFirstKFibonacciNumbers(int k) { return fib; } - public static void main(String a[]) { + public static void main(String[] a) { out.println(Arrays.toString(getFirstKFibonacciNumbers(0))); out.println(Arrays.toString(getFirstKFibonacciNumbers(10))); out.println(Arrays.toString(getFirstKFibonacciNumbers(46))); diff --git a/src/main/java/com/rampatra/misc/DivideByZero.java b/src/main/java/com/rampatra/misc/DivideByZero.java index ebc9f218..9aa167ae 100644 --- a/src/main/java/com/rampatra/misc/DivideByZero.java +++ b/src/main/java/com/rampatra/misc/DivideByZero.java @@ -10,6 +10,6 @@ public class DivideByZero { public static void main(String[] a) { System.out.println(5.0 / 0); // doesn't throw any exception - System.out.println(5 / 0); // throws runtime exception (arithmetic exception) + System.out.println(5 / 0); // throws runtime exception or unchecked exception (does NOT need explicit handling). To be specific, throws an arithmetic exception. } -} +} \ No newline at end of file From e92db11cacad23b24ccdf215165b8173db8d6c62 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Tue, 5 Mar 2019 23:19:15 +0000 Subject: [PATCH 007/164] Blockchain in Java: WIP --- .../java/com/rampatra/blockchain/Block.java | 85 ++++++++++++++++ .../com/rampatra/blockchain/Blockchain.java | 96 +++++++++++++++++++ 2 files changed, 181 insertions(+) create mode 100644 src/main/java/com/rampatra/blockchain/Block.java create mode 100644 src/main/java/com/rampatra/blockchain/Blockchain.java diff --git a/src/main/java/com/rampatra/blockchain/Block.java b/src/main/java/com/rampatra/blockchain/Block.java new file mode 100644 index 00000000..43cca2d7 --- /dev/null +++ b/src/main/java/com/rampatra/blockchain/Block.java @@ -0,0 +1,85 @@ +package com.rampatra.blockchain; + +/** + * @author rampatra + * @since 2019-03-05 + */ +public class Block { + + private int index; + private String previousHash; + private long timestamp; + private String data; + private String hash; + private int nonce; + + public Block(int index, String previousHash, long timestamp, String data, String hash, int nonce) { + this.index = index; + this.previousHash = previousHash; + this.timestamp = timestamp; + this.data = data; + this.hash = hash; + this.nonce = nonce; + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } + + public String getPreviousHash() { + return previousHash; + } + + public void setPreviousHash(String previousHash) { + this.previousHash = previousHash; + } + + public long getTimestamp() { + return timestamp; + } + + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + + public String getData() { + return data; + } + + public void setData(String data) { + this.data = data; + } + + public String getHash() { + return hash; + } + + public void setHash(String hash) { + this.hash = hash; + } + + public int getNonce() { + return nonce; + } + + public void setNonce(int nonce) { + this.nonce = nonce; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("Block{"); + sb.append("index=").append(index); + sb.append(", previousHash='").append(previousHash).append('\''); + sb.append(", timestamp=").append(timestamp); + sb.append(", data='").append(data).append('\''); + sb.append(", hash='").append(hash).append('\''); + sb.append(", nonce=").append(nonce); + sb.append('}'); + return sb.toString(); + } +} \ No newline at end of file diff --git a/src/main/java/com/rampatra/blockchain/Blockchain.java b/src/main/java/com/rampatra/blockchain/Blockchain.java new file mode 100644 index 00000000..7c9737a9 --- /dev/null +++ b/src/main/java/com/rampatra/blockchain/Blockchain.java @@ -0,0 +1,96 @@ +package com.rampatra.blockchain; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Date; +import java.util.List; + +/** + * @author rampatra + * @since 2019-03-05 + */ +public class Blockchain { + + private List blockchain; + private int difficulty; + + public Blockchain(List blockchain, int difficulty) { + this.blockchain = blockchain; + this.difficulty = difficulty; + } + + public void mine(String data) { + if (blockchain.size() == 0) { + blockchain.add(getGenesisBlock(data)); + } else { + Block previousBlock = blockchain.get(blockchain.size() - 1); + blockchain.add(getNextBlock(previousBlock, data)); + } + } + + private boolean isValidNextBlock(Block previousBlock, Block nextBlock) { + + String nextBlockHash = calculateHashForBlock(nextBlock.getIndex(), previousBlock.getHash(), + nextBlock.getTimestamp(), nextBlock.getData(), nextBlock.getNonce()); + + if (previousBlock.getIndex() + 1 != nextBlock.getIndex()) { + return false; + } else if (!previousBlock.getHash().equals(nextBlock.getPreviousHash())) { + return false; + } else if (!this.isValidHashDifficulty(nextBlockHash)) { + return false; + } else if (!nextBlockHash.equals(nextBlock.getHash())) { + return false; + } else { + return true; + } + } + + private Block getGenesisBlock(String data) { + final long timestamp = new Date().getTime(); + String hash = calculateHashForBlock(0, "0", timestamp, data, 0); + + return new Block(0, "0", timestamp, data, hash, 0); + } + + private Block getNextBlock(Block previousBlock, String data) { + final int index = previousBlock.getIndex() + 1; + final long timestamp = new Date().getTime(); + + final String hash = calculateHashForBlock(index, previousBlock.getHash(), timestamp, data, 0); + return new Block(index, previousBlock.getHash(), timestamp, data, hash, 0); + } + + private boolean isValidHashDifficulty(String hash) { + for (int i = 0; i < difficulty; i++) { + if (hash.charAt(i) != '0') { + return false; + } + } + return true; + } + + private String calculateHashForBlock(final int index, final String previousHash, final long timestamp, + final String data, final int nonce) { + try { + MessageDigest digest = MessageDigest.getInstance("SHA-256"); + byte[] encodedhash = digest.digest( + (index + previousHash + timestamp + data + nonce).getBytes(StandardCharsets.UTF_8)); + return bytesToHex(encodedhash); + } catch (NoSuchAlgorithmException e) { + // do nothing for now + } + return ""; + } + + private static String bytesToHex(byte[] hash) { + StringBuilder hexString = new StringBuilder(); + for (int i = 0; i < hash.length; i++) { + String hex = Integer.toHexString(0xff & hash[i]); + if (hex.length() == 1) hexString.append('0'); + hexString.append(hex); + } + return hexString.toString(); + } +} From eb73332e86ce389ff066690f58f65d18e7e97dfa Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Tue, 5 Mar 2019 23:19:47 +0000 Subject: [PATCH 008/164] Blockchain in Java: WIP --- src/main/java/com/rampatra/blockchain/Blockchain.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/rampatra/blockchain/Blockchain.java b/src/main/java/com/rampatra/blockchain/Blockchain.java index 7c9737a9..e6786168 100644 --- a/src/main/java/com/rampatra/blockchain/Blockchain.java +++ b/src/main/java/com/rampatra/blockchain/Blockchain.java @@ -10,7 +10,7 @@ * @author rampatra * @since 2019-03-05 */ -public class Blockchain { +public class Blockchain { // TODO: WIP private List blockchain; private int difficulty; From fcc14919794a90b4682179e39836b233ec3a66d3 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Wed, 6 Mar 2019 23:57:24 +0000 Subject: [PATCH 009/164] Very basic blockchain implementation in Java --- .../com/rampatra/blockchain/Blockchain.java | 70 ++++++++++++------- 1 file changed, 46 insertions(+), 24 deletions(-) diff --git a/src/main/java/com/rampatra/blockchain/Blockchain.java b/src/main/java/com/rampatra/blockchain/Blockchain.java index e6786168..c90085ba 100644 --- a/src/main/java/com/rampatra/blockchain/Blockchain.java +++ b/src/main/java/com/rampatra/blockchain/Blockchain.java @@ -3,6 +3,7 @@ import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -10,7 +11,7 @@ * @author rampatra * @since 2019-03-05 */ -public class Blockchain { // TODO: WIP +public class Blockchain { // TODO: P2P private List blockchain; private int difficulty; @@ -18,20 +19,50 @@ public class Blockchain { // TODO: WIP public Blockchain(List blockchain, int difficulty) { this.blockchain = blockchain; this.difficulty = difficulty; + this.blockchain.add(getGenesisBlock("Blockchain in Java")); + } + + public List getBlockchain() { + return blockchain; } public void mine(String data) { - if (blockchain.size() == 0) { - blockchain.add(getGenesisBlock(data)); + Block previousBlock = blockchain.get(blockchain.size() - 1); + Block nextBlock = getNextBlock(previousBlock, data); + + if (isValidNextBlock(previousBlock, nextBlock)) { + blockchain.add(nextBlock); } else { - Block previousBlock = blockchain.get(blockchain.size() - 1); - blockchain.add(getNextBlock(previousBlock, data)); + throw new RuntimeException("Invalid block"); + } + } + + private Block getGenesisBlock(String data) { + final long timestamp = new Date().getTime(); + int nonce = 0; + String hash; + while (!isValidHashDifficulty(hash = calculateHashForBlock(0, "0", timestamp, data, nonce))) { + nonce++; + } + + return new Block(0, "0", timestamp, data, hash, nonce); + } + + private Block getNextBlock(Block previousBlock, String data) { + final int index = previousBlock.getIndex() + 1; + final long timestamp = new Date().getTime(); + int nonce = 0; + String hash; + while (!isValidHashDifficulty( + hash = calculateHashForBlock(index, previousBlock.getHash(), timestamp, data, nonce))) { + nonce++; } + return new Block(index, previousBlock.getHash(), timestamp, data, hash, nonce); } private boolean isValidNextBlock(Block previousBlock, Block nextBlock) { - - String nextBlockHash = calculateHashForBlock(nextBlock.getIndex(), previousBlock.getHash(), + + String nextBlockHash = calculateHashForBlock(nextBlock.getIndex(), previousBlock.getHash(), nextBlock.getTimestamp(), nextBlock.getData(), nextBlock.getNonce()); if (previousBlock.getIndex() + 1 != nextBlock.getIndex()) { @@ -47,21 +78,6 @@ private boolean isValidNextBlock(Block previousBlock, Block nextBlock) { } } - private Block getGenesisBlock(String data) { - final long timestamp = new Date().getTime(); - String hash = calculateHashForBlock(0, "0", timestamp, data, 0); - - return new Block(0, "0", timestamp, data, hash, 0); - } - - private Block getNextBlock(Block previousBlock, String data) { - final int index = previousBlock.getIndex() + 1; - final long timestamp = new Date().getTime(); - - final String hash = calculateHashForBlock(index, previousBlock.getHash(), timestamp, data, 0); - return new Block(index, previousBlock.getHash(), timestamp, data, hash, 0); - } - private boolean isValidHashDifficulty(String hash) { for (int i = 0; i < difficulty; i++) { if (hash.charAt(i) != '0') { @@ -79,9 +95,8 @@ private String calculateHashForBlock(final int index, final String previousHash, (index + previousHash + timestamp + data + nonce).getBytes(StandardCharsets.UTF_8)); return bytesToHex(encodedhash); } catch (NoSuchAlgorithmException e) { - // do nothing for now + throw new RuntimeException("Encryption Error: {}", e); } - return ""; } private static String bytesToHex(byte[] hash) { @@ -93,4 +108,11 @@ private static String bytesToHex(byte[] hash) { } return hexString.toString(); } + + public static void main(String[] args) { + Blockchain blockchain = new Blockchain(new ArrayList<>(), 3); + blockchain.mine("12"); + blockchain.mine("26"); + System.out.println("Blockchain: " + blockchain.getBlockchain()); + } } From 9726d60b94553d205208c8a297bb0ddee5851a89 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sun, 10 Mar 2019 18:42:56 +0000 Subject: [PATCH 010/164] Blockchain implementation in Java 90% complete --- .../java/com/rampatra/blockchain/Block.java | 4 +- .../com/rampatra/blockchain/Blockchain.java | 60 ++++++--- .../java/com/rampatra/blockchain/Message.java | 70 +++++++++++ .../rampatra/blockchain/MessageHandler.java | 96 ++++++++++++++ .../java/com/rampatra/blockchain/P2P.java | 36 ++++++ .../java/com/rampatra/blockchain/Peer.java | 117 ++++++++++++++++++ 6 files changed, 362 insertions(+), 21 deletions(-) create mode 100644 src/main/java/com/rampatra/blockchain/Message.java create mode 100644 src/main/java/com/rampatra/blockchain/MessageHandler.java create mode 100644 src/main/java/com/rampatra/blockchain/P2P.java create mode 100644 src/main/java/com/rampatra/blockchain/Peer.java diff --git a/src/main/java/com/rampatra/blockchain/Block.java b/src/main/java/com/rampatra/blockchain/Block.java index 43cca2d7..8ba8eab5 100644 --- a/src/main/java/com/rampatra/blockchain/Block.java +++ b/src/main/java/com/rampatra/blockchain/Block.java @@ -1,10 +1,12 @@ package com.rampatra.blockchain; +import java.io.Serializable; + /** * @author rampatra * @since 2019-03-05 */ -public class Block { +public class Block implements Serializable { private int index; private String previousHash; diff --git a/src/main/java/com/rampatra/blockchain/Blockchain.java b/src/main/java/com/rampatra/blockchain/Blockchain.java index c90085ba..5af0f9a8 100644 --- a/src/main/java/com/rampatra/blockchain/Blockchain.java +++ b/src/main/java/com/rampatra/blockchain/Blockchain.java @@ -3,43 +3,70 @@ import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.ListIterator; /** * @author rampatra * @since 2019-03-05 */ -public class Blockchain { // TODO: P2P +public class Blockchain { - private List blockchain; + private List blocks; private int difficulty; - public Blockchain(List blockchain, int difficulty) { - this.blockchain = blockchain; + public Blockchain(List blocks, int difficulty) { + this.blocks = blocks; this.difficulty = difficulty; - this.blockchain.add(getGenesisBlock("Blockchain in Java")); + this.blocks.add(getGenesisBlock()); } - public List getBlockchain() { - return blockchain; + public List getBlocks() { + return blocks; } - public void mine(String data) { - Block previousBlock = blockchain.get(blockchain.size() - 1); + public int getSize() { + return blocks.size(); + } + + public Block getLatestBlock() { + if (blocks.isEmpty()) return null; + + return blocks.get(blocks.size() - 1); + } + + public void addBlock(Block block) { + blocks.add(block); + } + + public Block mine(String data) { + Block previousBlock = getLatestBlock(); Block nextBlock = getNextBlock(previousBlock, data); - + if (isValidNextBlock(previousBlock, nextBlock)) { - blockchain.add(nextBlock); + blocks.add(nextBlock); + return nextBlock; } else { throw new RuntimeException("Invalid block"); } } - private Block getGenesisBlock(String data) { + public boolean isValidChain() { + ListIterator listIterator = blocks.listIterator(); + listIterator.next(); + while (listIterator.hasPrevious() && listIterator.hasNext()) { + if (!isValidNextBlock(listIterator.previous(), listIterator.next())) { + return false; + } + } + return true; + } + + private Block getGenesisBlock() { final long timestamp = new Date().getTime(); int nonce = 0; + String data = "Blockchain in Java"; String hash; while (!isValidHashDifficulty(hash = calculateHashForBlock(0, "0", timestamp, data, nonce))) { nonce++; @@ -108,11 +135,4 @@ private static String bytesToHex(byte[] hash) { } return hexString.toString(); } - - public static void main(String[] args) { - Blockchain blockchain = new Blockchain(new ArrayList<>(), 3); - blockchain.mine("12"); - blockchain.mine("26"); - System.out.println("Blockchain: " + blockchain.getBlockchain()); - } } diff --git a/src/main/java/com/rampatra/blockchain/Message.java b/src/main/java/com/rampatra/blockchain/Message.java new file mode 100644 index 00000000..9bebbae5 --- /dev/null +++ b/src/main/java/com/rampatra/blockchain/Message.java @@ -0,0 +1,70 @@ +package com.rampatra.blockchain; + +import java.io.Serializable; + +/** + * @author rampatra + * @since 2019-03-10 + */ +public class Message implements Serializable { + + enum MessageType { + REQUEST_LATEST_BLOCK, + RECEIVE_LATEST_BLOCK, + REQUEST_BLOCKCHAIN, + RECEIVE_BLOCKCHAIN + } + + private MessageType messageType; + private Block latestBlock; + private Blockchain blockchain; + + + public MessageType getMessageType() { + return messageType; + } + + public Block getLatestBlock() { + return latestBlock; + } + + public Blockchain getBlockchain() { + return blockchain; + } + + public static final class MessageBuilder { + private MessageType messageType; + private Block latestBlock; + private Blockchain blockchain; + + private MessageBuilder() { + } + + public static MessageBuilder aMessage() { + return new MessageBuilder(); + } + + public MessageBuilder withMessageType(MessageType messageType) { + this.messageType = messageType; + return this; + } + + public MessageBuilder withLatestBlock(Block latestBlock) { + this.latestBlock = latestBlock; + return this; + } + + public MessageBuilder withBlockchain(Blockchain blockchain) { + this.blockchain = blockchain; + return this; + } + + public Message build() { + Message message = new Message(); + message.latestBlock = this.latestBlock; + message.blockchain = this.blockchain; + message.messageType = this.messageType; + return message; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/rampatra/blockchain/MessageHandler.java b/src/main/java/com/rampatra/blockchain/MessageHandler.java new file mode 100644 index 00000000..40b923e3 --- /dev/null +++ b/src/main/java/com/rampatra/blockchain/MessageHandler.java @@ -0,0 +1,96 @@ +package com.rampatra.blockchain; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.net.Socket; + +/** + * @author rampatra + * @since 2019-03-10 + */ +public class MessageHandler implements Runnable { + + ObjectInputStream in; + ObjectOutputStream out; + Peer peer; + + MessageHandler(Socket client, Peer peer) { + try { + in = new ObjectInputStream(client.getInputStream()); + out = new ObjectOutputStream(client.getOutputStream()); + this.peer = peer; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public void run() { + Message message; + try { + while ((message = (Message) in.readObject()) != null) { + handleMessage(message); + } + in.close(); + out.close(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private void handleMessage(Message message) { + Message.MessageType type = message.getMessageType(); + switch (type) { + case REQUEST_LATEST_BLOCK: + sendMessage(Message.MessageBuilder + .aMessage() + .withMessageType(Message.MessageType.RECEIVE_LATEST_BLOCK) + .withLatestBlock(peer.getBlockchain().getLatestBlock()) + .build()); + break; + case RECEIVE_LATEST_BLOCK: + handleLatestBlock(message.getLatestBlock()); + break; + case REQUEST_BLOCKCHAIN: + sendMessage(Message.MessageBuilder + .aMessage() + .withMessageType(Message.MessageType.RECEIVE_BLOCKCHAIN) + .withBlockchain(peer.getBlockchain()) + .build()); + break; + case RECEIVE_BLOCKCHAIN: + handleBlockchain(message.getBlockchain()); + break; + default: + throw new RuntimeException("Unknown message type"); + } + } + + private void sendMessage(Message message) { + try { + out.writeObject(message); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private void handleLatestBlock(Block latestBlock) { + Block latestBlockWithCurrentPeer = peer.getBlockchain().getLatestBlock(); + + if (latestBlock.getPreviousHash().equals(latestBlockWithCurrentPeer.getHash())) { + peer.getBlockchain().addBlock(latestBlock); + } else if (latestBlock.getIndex() > latestBlockWithCurrentPeer.getIndex()) { + sendMessage(Message.MessageBuilder + .aMessage() + .withMessageType(Message.MessageType.REQUEST_BLOCKCHAIN) + .build()); + } + } + + private void handleBlockchain(Blockchain blockchain) { + if (blockchain.isValidChain() && blockchain.getSize() > peer.getBlockchain().getSize()) { + peer.setBlockchain(blockchain); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/rampatra/blockchain/P2P.java b/src/main/java/com/rampatra/blockchain/P2P.java new file mode 100644 index 00000000..79308249 --- /dev/null +++ b/src/main/java/com/rampatra/blockchain/P2P.java @@ -0,0 +1,36 @@ +package com.rampatra.blockchain; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * @author rampatra + * @since 2019-03-09 + */ +public class P2P { + + private static List peers = new ArrayList<>(); + private static int lastUsedPort = 4000; + + public static Peer addPeer(Blockchain blockchain) { + Peer peer = new Peer(blockchain, lastUsedPort++); + peers.add(peer); + return peer; + } + + public static void removePeer(Peer peer) { + Iterator iterator = peers.iterator(); + while (iterator.hasNext()) { + if (iterator.next().equals(peer)) { + peer.stopServer(); + iterator.remove(); + break; + } + } + } + + public static List getPeers() { + return peers; + } +} \ No newline at end of file diff --git a/src/main/java/com/rampatra/blockchain/Peer.java b/src/main/java/com/rampatra/blockchain/Peer.java new file mode 100644 index 00000000..2f5fef8f --- /dev/null +++ b/src/main/java/com/rampatra/blockchain/Peer.java @@ -0,0 +1,117 @@ +package com.rampatra.blockchain; + +import java.io.ObjectOutputStream; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.stream.Collectors; + +/** + * @author rampatra + * @since 2019-03-09 + */ +public class Peer { + + private Blockchain blockchain; + private int port; + private ServerSocket server; + private ExecutorService executor = Executors.newSingleThreadExecutor(); + + Peer(Blockchain blockchain, int port) { + this.blockchain = blockchain; + this.port = port; + startServer(); + getLatestBlockFromPeers(); + } + + private void startServer() { + try { + executor.submit(() -> { + server = new ServerSocket(port); + while (true) { + new Thread(new MessageHandler(server.accept(), this)).start(); + } + }); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public void stopServer() { + try { + if (!server.isClosed()) { + server.close(); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private void getLatestBlockFromPeers() { + sendMessageToPeers(Message.MessageBuilder + .aMessage() + .withMessageType(Message.MessageType.REQUEST_LATEST_BLOCK) + .build()); + } + + private void sendMessageToPeers(Message message) { + try { + List peers = P2P.getPeers() + .stream() + .filter(peer -> !(peer.port == this.port)) + .collect(Collectors.toList()); + for (Peer peer : peers) { + Socket client = new Socket("127.0.0.1", peer.port); + ObjectOutputStream out = new ObjectOutputStream(client.getOutputStream()); + out.writeObject(message); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public void mine(String data) { + Block latestBlock = this.blockchain.mine(data); + sendMessageToPeers(Message.MessageBuilder + .aMessage().withMessageType(Message.MessageType.RECEIVE_LATEST_BLOCK) + .withLatestBlock(latestBlock) + .build()); + } + + public Blockchain getBlockchain() { + return blockchain; + } + + public void setBlockchain(Blockchain blockchain) { + this.blockchain = blockchain; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("Peer{"); + sb.append("port=").append(port); + sb.append('}'); + return sb.toString(); + } + + public static void main(String[] args) { + Blockchain blockchain = new Blockchain(new ArrayList<>(), 3); + Peer peer1 = P2P.addPeer(blockchain); + System.out.println("Peers:" + P2P.getPeers()); + peer1.mine("1st block by p1"); + System.out.println("Blockchain with p1: " + peer1.getBlockchain().getBlocks()); + Peer peer2 = P2P.addPeer(blockchain); + System.out.println("Peers: " + P2P.getPeers()); + System.out.println("Blockchain with p1: " + peer1.getBlockchain().getBlocks()); + System.out.println("Blockchain with p2: " + peer2.getBlockchain().getBlocks()); + peer2.mine("2nd block by p2"); + System.out.println("Blockchain with p1: " + peer1.getBlockchain().getBlocks()); + System.out.println("Blockchain with p2: " + peer2.getBlockchain().getBlocks()); + peer1.mine("3rd block by p1"); + System.out.println("Blockchain with p1: " + peer1.getBlockchain().getBlocks()); + System.out.println("Blockchain with p2: " + peer2.getBlockchain().getBlocks()); + } +} \ No newline at end of file From bcad339cf5839890c7769dec10ad012beb3384ab Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sun, 10 Mar 2019 19:59:45 +0000 Subject: [PATCH 011/164] Blockchain in java done (comments pending) --- .../com/rampatra/blockchain/Blockchain.java | 8 ++ .../java/com/rampatra/blockchain/P2P.java | 31 +++++++ .../java/com/rampatra/blockchain/Peer.java | 82 +++++++++++++++---- 3 files changed, 104 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/rampatra/blockchain/Blockchain.java b/src/main/java/com/rampatra/blockchain/Blockchain.java index 5af0f9a8..8f6896a4 100644 --- a/src/main/java/com/rampatra/blockchain/Blockchain.java +++ b/src/main/java/com/rampatra/blockchain/Blockchain.java @@ -135,4 +135,12 @@ private static String bytesToHex(byte[] hash) { } return hexString.toString(); } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("Blockchain{"); + sb.append("blocks=").append(blocks); + sb.append('}'); + return sb.toString(); + } } diff --git a/src/main/java/com/rampatra/blockchain/P2P.java b/src/main/java/com/rampatra/blockchain/P2P.java index 79308249..4f1f5e43 100644 --- a/src/main/java/com/rampatra/blockchain/P2P.java +++ b/src/main/java/com/rampatra/blockchain/P2P.java @@ -18,6 +18,12 @@ public static Peer addPeer(Blockchain blockchain) { peers.add(peer); return peer; } + + public static void removePeer(int index) { + Peer peer = peers.get(index); + peer.stopServer(); + peers.remove(index); + } public static void removePeer(Peer peer) { Iterator iterator = peers.iterator(); @@ -29,8 +35,33 @@ public static void removePeer(Peer peer) { } } } + + public static void removeAllPeers() { + Iterator iterator = peers.iterator(); + while (iterator.hasNext()) { + Peer peer = iterator.next(); + peer.stopServer(); + iterator.remove(); + } + } + + public static Peer getPeer(int index) { + return peers.get(index); + } public static List getPeers() { return peers; } + + public static void showPeers() { + for (int i = 0; i < peers.size(); i++) { + System.out.println("Peer " + (i + 1) + ": " + peers.get(i).getPort()); + } + } + + public static void showPeersWithBlockchain() { + for (int i = 0; i < peers.size(); i++) { + System.out.println("Peer " + (i + 1) + ": " + peers.get(i).getBlockchain()); + } + } } \ No newline at end of file diff --git a/src/main/java/com/rampatra/blockchain/Peer.java b/src/main/java/com/rampatra/blockchain/Peer.java index 2f5fef8f..97ab5863 100644 --- a/src/main/java/com/rampatra/blockchain/Peer.java +++ b/src/main/java/com/rampatra/blockchain/Peer.java @@ -5,6 +5,7 @@ import java.net.Socket; import java.util.ArrayList; import java.util.List; +import java.util.Scanner; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.stream.Collectors; @@ -39,7 +40,7 @@ private void startServer() { throw new RuntimeException(e); } } - + public void stopServer() { try { if (!server.isClosed()) { @@ -89,29 +90,76 @@ public void setBlockchain(Blockchain blockchain) { this.blockchain = blockchain; } + public int getPort() { + return port; + } + @Override public String toString() { final StringBuilder sb = new StringBuilder("Peer{"); - sb.append("port=").append(port); + sb.append("blockchain=").append(blockchain); + sb.append(", port=").append(port); sb.append('}'); return sb.toString(); } public static void main(String[] args) { - Blockchain blockchain = new Blockchain(new ArrayList<>(), 3); - Peer peer1 = P2P.addPeer(blockchain); - System.out.println("Peers:" + P2P.getPeers()); - peer1.mine("1st block by p1"); - System.out.println("Blockchain with p1: " + peer1.getBlockchain().getBlocks()); - Peer peer2 = P2P.addPeer(blockchain); - System.out.println("Peers: " + P2P.getPeers()); - System.out.println("Blockchain with p1: " + peer1.getBlockchain().getBlocks()); - System.out.println("Blockchain with p2: " + peer2.getBlockchain().getBlocks()); - peer2.mine("2nd block by p2"); - System.out.println("Blockchain with p1: " + peer1.getBlockchain().getBlocks()); - System.out.println("Blockchain with p2: " + peer2.getBlockchain().getBlocks()); - peer1.mine("3rd block by p1"); - System.out.println("Blockchain with p1: " + peer1.getBlockchain().getBlocks()); - System.out.println("Blockchain with p2: " + peer2.getBlockchain().getBlocks()); + try { + int menuChoice; + int peerIndex; + String data; + Scanner s = new Scanner(System.in); + Blockchain blockchain = new Blockchain(new ArrayList<>(), 3); + + while (true) { + + System.out.println("\n======= Welcome to Blockchain in Java ======="); + System.out.println("1. Add Peer"); + System.out.println("2. Mine data in peer"); + System.out.println("3. Remove peer"); + System.out.println("4. Show peers"); + System.out.println("5. Exit"); + + menuChoice = s.nextInt(); + + switch (menuChoice) { + case 1: + P2P.addPeer(blockchain); + System.out.println("New peer added!"); + P2P.showPeersWithBlockchain(); + break; + case 2: + System.out.println("Choose peer: (ex. 1, 2, etc.)"); + P2P.showPeers(); + peerIndex = s.nextInt(); + Peer p = P2P.getPeer(peerIndex - 1); + System.out.println("Enter data: "); + data = s.next(); + p.mine(data); + System.out.println("Data mined!"); + P2P.showPeersWithBlockchain(); + break; + case 3: + System.out.println("Choose peer: (ex. 1, 2, etc.)"); + P2P.showPeers(); + peerIndex = s.nextInt(); + P2P.removePeer(peerIndex - 1); + System.out.println("Peer " + peerIndex + " removed!"); + P2P.showPeersWithBlockchain(); + break; + case 4: + P2P.showPeersWithBlockchain(); + break; + case 5: + P2P.removeAllPeers(); + System.out.println("Bye, see you soon!"); + System.exit(0); + default: + System.out.println("Wrong choice!"); + } + } + } catch (Exception e) { + throw new RuntimeException(e); + } } } \ No newline at end of file From a4073789b5b6d92806efd89f072c903680d9a85e Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sun, 10 Mar 2019 20:29:50 +0000 Subject: [PATCH 012/164] Minor improvements --- src/main/java/com/rampatra/blockchain/MessageHandler.java | 7 ++++++- src/main/java/com/rampatra/blockchain/P2P.java | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/rampatra/blockchain/MessageHandler.java b/src/main/java/com/rampatra/blockchain/MessageHandler.java index 40b923e3..71ec749c 100644 --- a/src/main/java/com/rampatra/blockchain/MessageHandler.java +++ b/src/main/java/com/rampatra/blockchain/MessageHandler.java @@ -1,9 +1,12 @@ package com.rampatra.blockchain; +import sun.net.ConnectionResetException; + import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.Socket; +import java.net.SocketException; /** * @author rampatra @@ -35,7 +38,9 @@ public void run() { in.close(); out.close(); } catch (Exception e) { - throw new RuntimeException(e); + if (!(e instanceof SocketException)) { + throw new RuntimeException(e); + } } } diff --git a/src/main/java/com/rampatra/blockchain/P2P.java b/src/main/java/com/rampatra/blockchain/P2P.java index 4f1f5e43..c18072ff 100644 --- a/src/main/java/com/rampatra/blockchain/P2P.java +++ b/src/main/java/com/rampatra/blockchain/P2P.java @@ -61,7 +61,7 @@ public static void showPeers() { public static void showPeersWithBlockchain() { for (int i = 0; i < peers.size(); i++) { - System.out.println("Peer " + (i + 1) + ": " + peers.get(i).getBlockchain()); + System.out.println("Peer " + (i + 1) + " (" + peers.get(i).getPort() + "): " + peers.get(i).getBlockchain()); } } } \ No newline at end of file From 2e9e2b28c96dbd2c9127f9d83f81d25a0583d45e Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sun, 10 Mar 2019 20:30:43 +0000 Subject: [PATCH 013/164] Removed unused imports --- src/main/java/com/rampatra/blockchain/MessageHandler.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/com/rampatra/blockchain/MessageHandler.java b/src/main/java/com/rampatra/blockchain/MessageHandler.java index 71ec749c..c72932f0 100644 --- a/src/main/java/com/rampatra/blockchain/MessageHandler.java +++ b/src/main/java/com/rampatra/blockchain/MessageHandler.java @@ -1,7 +1,5 @@ package com.rampatra.blockchain; -import sun.net.ConnectionResetException; - import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; From ee0b3e0cf96dac8978812a0db25aafce1f7fa464 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sun, 10 Mar 2019 21:10:00 +0000 Subject: [PATCH 014/164] Added comments and some minor improvements --- .../com/rampatra/blockchain/Blockchain.java | 36 +++++++++++++++++++ .../rampatra/blockchain/MessageHandler.java | 25 +++++++++++-- .../java/com/rampatra/blockchain/Peer.java | 30 ++++++++++++++-- 3 files changed, 85 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/rampatra/blockchain/Blockchain.java b/src/main/java/com/rampatra/blockchain/Blockchain.java index 8f6896a4..58fe7813 100644 --- a/src/main/java/com/rampatra/blockchain/Blockchain.java +++ b/src/main/java/com/rampatra/blockchain/Blockchain.java @@ -40,6 +40,15 @@ public void addBlock(Block block) { blocks.add(block); } + /** + * Mine, create a new block with the {@code data}, and finally, add it to the blockchain. + *

+ * Mining is nothing but the process of calculating a hash of a {@link Block} with {@code data} such + * that the hash starts with a specific number of zeros equal to the difficulty of the blockchain. + * + * @param data + * @return + */ public Block mine(String data) { Block previousBlock = getLatestBlock(); Block nextBlock = getNextBlock(previousBlock, data); @@ -52,6 +61,11 @@ public Block mine(String data) { } } + /** + * Executes the {@link Blockchain#isValidNextBlock(Block, Block)} on the entire blockchain. + * + * @return {@code false} if at least one block in the blockchain is invalid, {@code true} otherwise. + */ public boolean isValidChain() { ListIterator listIterator = blocks.listIterator(); listIterator.next(); @@ -63,6 +77,11 @@ public boolean isValidChain() { return true; } + /** + * Creates the Genesis Block for the blockchain. The Genesis Block is the first block in the blockchain. + * + * @return the genesis block + */ private Block getGenesisBlock() { final long timestamp = new Date().getTime(); int nonce = 0; @@ -105,6 +124,13 @@ private boolean isValidNextBlock(Block previousBlock, Block nextBlock) { } } + /** + * Checks if the hash respects the difficulty of the blockchain, i.e, if the hash + * begins with a number of zeros equal to the difficulty of the blockchain. + * + * @param hash the SHA256 hash of the block. + * @return {@code true} if hash obeys difficulty, {@code false} otherwise. + */ private boolean isValidHashDifficulty(String hash) { for (int i = 0; i < difficulty; i++) { if (hash.charAt(i) != '0') { @@ -114,6 +140,16 @@ private boolean isValidHashDifficulty(String hash) { return true; } + /** + * Calculates the SHA256 hash of the block. + * + * @param index + * @param previousHash + * @param timestamp + * @param data + * @param nonce + * @return the SHA256 hash of the block. + */ private String calculateHashForBlock(final int index, final String previousHash, final long timestamp, final String data, final int nonce) { try { diff --git a/src/main/java/com/rampatra/blockchain/MessageHandler.java b/src/main/java/com/rampatra/blockchain/MessageHandler.java index c72932f0..cfd51310 100644 --- a/src/main/java/com/rampatra/blockchain/MessageHandler.java +++ b/src/main/java/com/rampatra/blockchain/MessageHandler.java @@ -12,9 +12,9 @@ */ public class MessageHandler implements Runnable { - ObjectInputStream in; - ObjectOutputStream out; - Peer peer; + private ObjectInputStream in; + private ObjectOutputStream out; + private Peer peer; MessageHandler(Socket client, Peer peer) { try { @@ -42,6 +42,11 @@ public void run() { } } + /** + * Handle messages accordingly. + * + * @param message is the message object from the peer. + */ private void handleMessage(Message message) { Message.MessageType type = message.getMessageType(); switch (type) { @@ -78,6 +83,14 @@ private void sendMessage(Message message) { } } + /** + * If the latest block received from the peer has {@code previousHash} equal to the hash of the + * latest block in the current user's blockchain then add the latest block received to the + * current user's blockchain, or else, if the latest block received has a larger index then + * request the entire blockchain from the peer. + * + * @param latestBlock the block received from the peer + */ private void handleLatestBlock(Block latestBlock) { Block latestBlockWithCurrentPeer = peer.getBlockchain().getLatestBlock(); @@ -91,6 +104,12 @@ private void handleLatestBlock(Block latestBlock) { } } + /** + * If the blockchain received from the peer is valid and longer then replace current user's + * blockchain with the received blockchain. + * + * @param blockchain the entire blockchain received from the peer + */ private void handleBlockchain(Blockchain blockchain) { if (blockchain.isValidChain() && blockchain.getSize() > peer.getBlockchain().getSize()) { peer.setBlockchain(blockchain); diff --git a/src/main/java/com/rampatra/blockchain/Peer.java b/src/main/java/com/rampatra/blockchain/Peer.java index 97ab5863..9d0e553d 100644 --- a/src/main/java/com/rampatra/blockchain/Peer.java +++ b/src/main/java/com/rampatra/blockchain/Peer.java @@ -28,11 +28,15 @@ public class Peer { getLatestBlockFromPeers(); } + /** + * Once a new peer is created, we start the socket server to receive messages from the peers. + */ private void startServer() { try { executor.submit(() -> { server = new ServerSocket(port); while (true) { + // we create a new thread for each new client thereby supporting multiple client simultaneously new Thread(new MessageHandler(server.accept(), this)).start(); } }); @@ -41,6 +45,9 @@ private void startServer() { } } + /** + * Stop the server once a peer is removed from the network. + */ public void stopServer() { try { if (!server.isClosed()) { @@ -51,6 +58,10 @@ public void stopServer() { } } + /** + * Once a new peer is created and added to the network, it requests the latest block from + * all the peers and updates its blockchain if it is outdated. + */ private void getLatestBlockFromPeers() { sendMessageToPeers(Message.MessageBuilder .aMessage() @@ -60,6 +71,7 @@ private void getLatestBlockFromPeers() { private void sendMessageToPeers(Message message) { try { + // send to all peers except itself List peers = P2P.getPeers() .stream() .filter(peer -> !(peer.port == this.port)) @@ -74,6 +86,11 @@ private void sendMessageToPeers(Message message) { } } + /** + * Mine, create a new block with the {@code data}, and finally, add it to the blockchain. + * + * @param data + */ public void mine(String data) { Block latestBlock = this.blockchain.mine(data); sendMessageToPeers(Message.MessageBuilder @@ -103,6 +120,13 @@ public String toString() { return sb.toString(); } + /** + * The main starting point of the blockchain demo. At first, add some peers (option 1) and mine some data + * by choosing a particular peer (option 2). You would soon see that the newly mined block is broadcast to + * all the peers. + * + * @param args + */ public static void main(String[] args) { try { int menuChoice; @@ -129,18 +153,18 @@ public static void main(String[] args) { P2P.showPeersWithBlockchain(); break; case 2: - System.out.println("Choose peer: (ex. 1, 2, etc.)"); + System.out.println("Choose peer: (a number for ex. 1, 2, etc.)"); P2P.showPeers(); peerIndex = s.nextInt(); Peer p = P2P.getPeer(peerIndex - 1); - System.out.println("Enter data: "); + System.out.println("Enter data: (a string with no spaces)"); data = s.next(); p.mine(data); System.out.println("Data mined!"); P2P.showPeersWithBlockchain(); break; case 3: - System.out.println("Choose peer: (ex. 1, 2, etc.)"); + System.out.println("Choose peer: (a number for ex. 1, 2, etc.)"); P2P.showPeers(); peerIndex = s.nextInt(); P2P.removePeer(peerIndex - 1); From cb904cc613a7dc97e04bcd075e3fb3d8b07950da Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sun, 10 Mar 2019 21:21:11 +0000 Subject: [PATCH 015/164] Added contents --- README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/README.md b/README.md index b836dccc..7c1b7ff7 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,28 @@ The repo consists of solutions to numerous problems using different data structu You can also refer to my [Java Notes](http://java.ramswaroop.me) for a quick refresh on the Java concepts. +## Contents + +1. Cracking the coding interview. +2. HackerRank. +3. Basic Practice: + 1. [Arrays](/src/main/java/com/rampatra/arrays) + 2. [Backtracking](/src/main/java/com/rampatra/backtracking) + 3. [Bits](/src/main/java/com/rampatra/bits) + 4. [Blockchain Demo](/src/main/java/com/rampatra/blockchain) + 5. Dynamic Programming + 6. Graphs + 7. Java 8 + 8. Linked Lists + 9. Miscellaneous + 10. Permutations + 11. Searching + 12. Sorting + 13. Stacks + 14. Strings + 15. Threads + 16. Trees + ## Environment ### Java Version From c112c0f325ec97ff4ec797f994d688b13c960587 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sun, 10 Mar 2019 21:28:23 +0000 Subject: [PATCH 016/164] Added full contents --- README.md | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 7c1b7ff7..ed5ec67b 100644 --- a/README.md +++ b/README.md @@ -6,25 +6,31 @@ You can also refer to my [Java Notes](http://java.ramswaroop.me) for a quick ref ## Contents -1. Cracking the coding interview. -2. HackerRank. -3. Basic Practice: +1. [Basic Practice](/src/main/java/com/rampatra/): 1. [Arrays](/src/main/java/com/rampatra/arrays) 2. [Backtracking](/src/main/java/com/rampatra/backtracking) 3. [Bits](/src/main/java/com/rampatra/bits) 4. [Blockchain Demo](/src/main/java/com/rampatra/blockchain) - 5. Dynamic Programming - 6. Graphs - 7. Java 8 - 8. Linked Lists - 9. Miscellaneous - 10. Permutations - 11. Searching - 12. Sorting - 13. Stacks - 14. Strings - 15. Threads - 16. Trees + 5. [Dynamic Programming](/src/main/java/com/rampatra/dynamicprogramming) + 6. [Graphs](/src/main/java/com/rampatra/graphs) + 7. [Java 8](/src/main/java/com/rampatra/java8) + 8. [Linked Lists](/src/main/java/com/rampatra/linkedlists) + 9. [Miscellaneous](/src/main/java/com/rampatra/misc) + 10. [Permutations](/src/main/java/com/rampatra/permutations) + 11. [Searching](/src/main/java/com/rampatra/searching) + 12. [Sorting](/src/main/java/com/rampatra/sorting) + 13. [Stacks](/src/main/java/com/rampatra/stacks) + 14. [Strings](/src/main/java/com/rampatra/strings) + 15. [Threads](/src/main/java/com/rampatra/threads) + 16. [Trees](/src/main/java/com/rampatra/trees) +2. [Cracking the coding interview](/src/main/java/com/ctci): + 1. [Arrays and Strings](/src/main/java/com/ctci/arraysandstrings) + 2. [Linked Lists](/src/main/java/com/ctci/linkedlists) + 3. [Recursion and DP](/src/main/java/com/ctci/recursionanddp) + 4. [Stacks and Queues](/src/main/java/com/ctci/stacksandqueues) + 5. [Trees and Graphs](/src/main/java/com/ctci/treesandgraphs) +3. [HackerRank](/src/main/java/com/hackerrank). + ## Environment From 27bad3d2389c9a97a4e268bc41cd4441b198e48f Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Wed, 13 Mar 2019 21:56:13 +0000 Subject: [PATCH 017/164] A simple deadlock in java with 2 threads --- .../com/rampatra/threads/SimpleDeadlock.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/main/java/com/rampatra/threads/SimpleDeadlock.java diff --git a/src/main/java/com/rampatra/threads/SimpleDeadlock.java b/src/main/java/com/rampatra/threads/SimpleDeadlock.java new file mode 100644 index 00000000..53c2c23e --- /dev/null +++ b/src/main/java/com/rampatra/threads/SimpleDeadlock.java @@ -0,0 +1,56 @@ +package com.rampatra.threads; + + +import java.lang.management.ManagementFactory; +import java.lang.management.ThreadMXBean; + +/** + * @author rampatra + * @since 2019-03-13 + */ +public class SimpleDeadlock implements Runnable { + + private final Object obj1; + private final Object obj2; + + private SimpleDeadlock(Object obj1, Object obj2) { + this.obj1 = obj1; + this.obj2 = obj2; + } + + public void run() { + try { + synchronized (obj1) { + // sleep for some time so that the next thread starts and acquires the other lock in the mean time + Thread.sleep(5000); + synchronized (obj2) { + System.out.println("No deadlock!"); + } + } + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + public static void main(String[] args) { + + Object obj1 = new Object(); + Object obj2 = new Object(); + + Thread thread1 = new Thread(new SimpleDeadlock(obj1, obj2)); + Thread thread2 = new Thread(new SimpleDeadlock(obj2, obj1)); + + thread1.start(); + thread2.start(); + + // a way to detect deadlocks, although an expensive one + ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); + while (true) { + long[] deadlock = threadMXBean.findDeadlockedThreads(); + if (deadlock != null && deadlock.length > 0) { + System.out.println("Deadlock detected, exiting now..."); + System.exit(1); + } + } + } +} \ No newline at end of file From 1db94ed723ae1d60c8dfd7b4cf9e23cf4797c25e Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Fri, 15 Mar 2019 22:28:31 +0000 Subject: [PATCH 018/164] Bit insert done --- .../com/ctci/bitmanipulation/Insertion.java | 49 +++++++++++++++++++ ...Ancestor.java => FirstCommonAncestor.java} | 28 +++++------ ... FirstCommonAncestorWithParentAccess.java} | 18 +++---- .../com/rampatra/threads/SimpleDeadlock.java | 2 +- 4 files changed, 73 insertions(+), 24 deletions(-) create mode 100644 src/main/java/com/ctci/bitmanipulation/Insertion.java rename src/main/java/com/ctci/treesandgraphs/{LeastCommonAncestor.java => FirstCommonAncestor.java} (78%) rename src/main/java/com/ctci/treesandgraphs/{LeastCommonAncestorWithParentAccess.java => FirstCommonAncestorWithParentAccess.java} (87%) diff --git a/src/main/java/com/ctci/bitmanipulation/Insertion.java b/src/main/java/com/ctci/bitmanipulation/Insertion.java new file mode 100644 index 00000000..3230d86f --- /dev/null +++ b/src/main/java/com/ctci/bitmanipulation/Insertion.java @@ -0,0 +1,49 @@ +package com.ctci.bitmanipulation; + +/** + * @author rampatra + * @since 2019-03-14 + */ +public class Insertion { + + /** + * You are given two 32-bit numbers, N and M, and two bit positions, startIndex and endIndex. Write a method to + * insert M into N such that M starts at bit startIndex and ends at bit endIndex. You can assume that the bits + * startIndex through endIndex have enough space to fit all of M. That is, if M = 10011, you can assume that there + * are at least 5 bits between j and i. You would not, for example, have startIndex = 3 and endIndex = 2, because + * M could not fully fit between bit 3 and bit 2. + *

+ * EXAMPLE + * Input: N = 10000000000, M = 10011, startIndex = 6, endIndex = 2 + * Output: 10001001100 + * + * @param n + * @param m + * @param startIndex + * @param endIndex + * @return + */ + private static int insertMIntoN(int n, int m, int startIndex, int endIndex) { + // create a mask with only one bit set + int mask = 1; + // shift the set bit so that it starts with endIndex + mask <<= endIndex; + + // unset the bits in 'n' from endIndex to startIndex + for (int i = endIndex; i <= startIndex; i++) { + n = n & ~mask; // ~mask will make the bit at ith index 0 but the rest of the bits will be 1 + mask <<= 1; + } + + // shift 'm' so that it lines up with bits from startIndex to endIndex + m <<= endIndex; + + // finally, return the xor of both as we know that 0 ^ a = a + return n ^ m; + } + + public static void main(String[] args) { + System.out.println(Integer.toBinaryString(insertMIntoN(Integer.parseInt("10000000000", 2), Integer.parseInt("10011", 2), 6, 2))); + System.out.println(Integer.toBinaryString(insertMIntoN(Integer.parseInt("10110110111", 2), Integer.parseInt("11101", 2), 7, 3))); + } +} \ No newline at end of file diff --git a/src/main/java/com/ctci/treesandgraphs/LeastCommonAncestor.java b/src/main/java/com/ctci/treesandgraphs/FirstCommonAncestor.java similarity index 78% rename from src/main/java/com/ctci/treesandgraphs/LeastCommonAncestor.java rename to src/main/java/com/ctci/treesandgraphs/FirstCommonAncestor.java index 5d4964df..988d9442 100644 --- a/src/main/java/com/ctci/treesandgraphs/LeastCommonAncestor.java +++ b/src/main/java/com/ctci/treesandgraphs/FirstCommonAncestor.java @@ -8,10 +8,10 @@ * @author rampatra * @since 2019-02-24 */ -public class LeastCommonAncestor { +public class FirstCommonAncestor { /** - * We recurse through the entire tree with a function called findLCA(TreeNode root, TreeNode TreeNode a, TreeNode b). + * We recurse through the entire tree with a function called findFCA(TreeNode root, TreeNode TreeNode a, TreeNode b). * This function returns values as follows: * - Returns p,if root's subtree includes p (and not q). * - Returns q, if root's subtree includes q (and not p). @@ -23,7 +23,7 @@ public class LeastCommonAncestor { * @param b * @return the least common ancestor node */ - private static TreeNode findLCA(TreeNode root, TreeNode a, TreeNode b) { + private static TreeNode findFCA(TreeNode root, TreeNode a, TreeNode b) { if (root == null) { // validation return null; } @@ -31,12 +31,12 @@ private static TreeNode findLCA(TreeNode root, TreeNode a, TreeNode b) { return root; } - TreeNode left = findLCA(root.left, a, b); + TreeNode left = findFCA(root.left, a, b); if (left != null && left != a && left != b) { return left; } - TreeNode right = findLCA(root.right, a, b); + TreeNode right = findFCA(root.right, a, b); if (right != null && right != a && right != b) { return right; } @@ -85,14 +85,14 @@ public static void main(String[] args) { treeRoot.right.right = new TreeNode(9); treeRoot.right.left.right = new TreeNode(7); - System.out.println("LCA of 0 and 7 is: " + findLCA(treeRoot, treeRoot.left.left.left, treeRoot.right.left.right).val); - System.out.println("LCA of 0 and 9 is: " + findLCA(treeRoot, treeRoot.left.left.left, treeRoot.right.right).val); - System.out.println("LCA of 0 and 1 is: " + findLCA(treeRoot, treeRoot.left.left.left, treeRoot.left.left).val); - System.out.println("LCA of 1 and 2 is: " + findLCA(treeRoot, treeRoot.left.left, treeRoot.right.left).val); - System.out.println("LCA of 1 and 7 is: " + findLCA(treeRoot, treeRoot.left.left, treeRoot.right.left.right).val); - System.out.println("LCA of 4 and 7 is: " + findLCA(treeRoot, treeRoot, treeRoot.right.left.right).val); - System.out.println("LCA of 5 and 2 is: " + findLCA(treeRoot, treeRoot.left, treeRoot.right.left).val); - System.out.println("LCA of 7 and 9 is: " + findLCA(treeRoot, treeRoot.right.left.right, treeRoot.right.right).val); - System.out.println("LCA of 7 and 10 is: " + findLCA(treeRoot, treeRoot.right.left.right, new TreeNode(10)).val); // this use case does not work with the above algorithm + System.out.println("FCA of 0 and 7 is: " + findFCA(treeRoot, treeRoot.left.left.left, treeRoot.right.left.right).val); + System.out.println("FCA of 0 and 9 is: " + findFCA(treeRoot, treeRoot.left.left.left, treeRoot.right.right).val); + System.out.println("FCA of 0 and 1 is: " + findFCA(treeRoot, treeRoot.left.left.left, treeRoot.left.left).val); + System.out.println("FCA of 1 and 2 is: " + findFCA(treeRoot, treeRoot.left.left, treeRoot.right.left).val); + System.out.println("FCA of 1 and 7 is: " + findFCA(treeRoot, treeRoot.left.left, treeRoot.right.left.right).val); + System.out.println("FCA of 4 and 7 is: " + findFCA(treeRoot, treeRoot, treeRoot.right.left.right).val); + System.out.println("FCA of 5 and 2 is: " + findFCA(treeRoot, treeRoot.left, treeRoot.right.left).val); + System.out.println("FCA of 7 and 9 is: " + findFCA(treeRoot, treeRoot.right.left.right, treeRoot.right.right).val); + System.out.println("FCA of 7 and 10 is: " + findFCA(treeRoot, treeRoot.right.left.right, new TreeNode(10)).val); // this use case does not work with the above algorithm } } \ No newline at end of file diff --git a/src/main/java/com/ctci/treesandgraphs/LeastCommonAncestorWithParentAccess.java b/src/main/java/com/ctci/treesandgraphs/FirstCommonAncestorWithParentAccess.java similarity index 87% rename from src/main/java/com/ctci/treesandgraphs/LeastCommonAncestorWithParentAccess.java rename to src/main/java/com/ctci/treesandgraphs/FirstCommonAncestorWithParentAccess.java index 0de2cf3a..5aa453cf 100644 --- a/src/main/java/com/ctci/treesandgraphs/LeastCommonAncestorWithParentAccess.java +++ b/src/main/java/com/ctci/treesandgraphs/FirstCommonAncestorWithParentAccess.java @@ -8,7 +8,7 @@ * @author rampatra * @since 2019-02-23 */ -public class LeastCommonAncestorWithParentAccess { +public class FirstCommonAncestorWithParentAccess { /** * This is a simple approach where we start with two references, one pointing to {@code node a} and another @@ -103,13 +103,13 @@ public static void main(String[] args) { treeRoot.right.left.right = new TreeNode(7); treeRoot.right.left.right.parent = treeRoot.right.left; - System.out.println("LCA of 0 and 7 is: " + findLCA(treeRoot.left.left.left, treeRoot.right.left.right).val); - System.out.println("LCA of 0 and 9 is: " + findLCA(treeRoot.left.left.left, treeRoot.right.right).val); - System.out.println("LCA of 0 and 1 is: " + findLCA(treeRoot.left.left.left, treeRoot.left.left).val); - System.out.println("LCA of 1 and 2 is: " + findLCA(treeRoot.left.left, treeRoot.right.left).val); - System.out.println("LCA of 1 and 7 is: " + findLCA(treeRoot.left.left, treeRoot.right.left.right).val); - System.out.println("LCA of 4 and 7 is: " + findLCA(treeRoot, treeRoot.right.left.right).val); - System.out.println("LCA of 5 and 2 is: " + findLCA(treeRoot.left, treeRoot.right.left).val); - System.out.println("LCA of 7 and 9 is: " + findLCA(treeRoot.right.left.right, treeRoot.right.right).val); + System.out.println("FCA of 0 and 7 is: " + findLCA(treeRoot.left.left.left, treeRoot.right.left.right).val); + System.out.println("FCA of 0 and 9 is: " + findLCA(treeRoot.left.left.left, treeRoot.right.right).val); + System.out.println("FCA of 0 and 1 is: " + findLCA(treeRoot.left.left.left, treeRoot.left.left).val); + System.out.println("FCA of 1 and 2 is: " + findLCA(treeRoot.left.left, treeRoot.right.left).val); + System.out.println("FCA of 1 and 7 is: " + findLCA(treeRoot.left.left, treeRoot.right.left.right).val); + System.out.println("FCA of 4 and 7 is: " + findLCA(treeRoot, treeRoot.right.left.right).val); + System.out.println("FCA of 5 and 2 is: " + findLCA(treeRoot.left, treeRoot.right.left).val); + System.out.println("FCA of 7 and 9 is: " + findLCA(treeRoot.right.left.right, treeRoot.right.right).val); } } \ No newline at end of file diff --git a/src/main/java/com/rampatra/threads/SimpleDeadlock.java b/src/main/java/com/rampatra/threads/SimpleDeadlock.java index 53c2c23e..a9e41491 100644 --- a/src/main/java/com/rampatra/threads/SimpleDeadlock.java +++ b/src/main/java/com/rampatra/threads/SimpleDeadlock.java @@ -38,7 +38,7 @@ public static void main(String[] args) { Object obj2 = new Object(); Thread thread1 = new Thread(new SimpleDeadlock(obj1, obj2)); - Thread thread2 = new Thread(new SimpleDeadlock(obj2, obj1)); + Thread thread2 = new Thread(new SimpleDeadlock(obj2, obj1)); // note here that the object order is different thread1.start(); thread2.start(); From b72d3aeef53ffe92254d8f528ee6b10c795edc4c Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Fri, 15 Mar 2019 22:30:58 +0000 Subject: [PATCH 019/164] Updated Readme --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ed5ec67b..c970712f 100644 --- a/README.md +++ b/README.md @@ -23,12 +23,13 @@ You can also refer to my [Java Notes](http://java.ramswaroop.me) for a quick ref 14. [Strings](/src/main/java/com/rampatra/strings) 15. [Threads](/src/main/java/com/rampatra/threads) 16. [Trees](/src/main/java/com/rampatra/trees) -2. [Cracking the coding interview](/src/main/java/com/ctci): +2. [Cracking the Coding Interview](/src/main/java/com/ctci): 1. [Arrays and Strings](/src/main/java/com/ctci/arraysandstrings) 2. [Linked Lists](/src/main/java/com/ctci/linkedlists) 3. [Recursion and DP](/src/main/java/com/ctci/recursionanddp) 4. [Stacks and Queues](/src/main/java/com/ctci/stacksandqueues) 5. [Trees and Graphs](/src/main/java/com/ctci/treesandgraphs) + 6. [Bit Manipulation](/src/main/java/com/ctci/bitmanipulation) 3. [HackerRank](/src/main/java/com/hackerrank). From 81b720bea2a12932f39ba384a702f9da05a7a10d Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sat, 16 Mar 2019 16:38:22 +0000 Subject: [PATCH 020/164] Binary to string done --- README.md | 8 ++-- .../ctci/bitmanipulation/BinaryToString.java | 46 +++++++++++++++++++ 2 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/ctci/bitmanipulation/BinaryToString.java diff --git a/README.md b/README.md index c970712f..581730da 100644 --- a/README.md +++ b/README.md @@ -26,10 +26,10 @@ You can also refer to my [Java Notes](http://java.ramswaroop.me) for a quick ref 2. [Cracking the Coding Interview](/src/main/java/com/ctci): 1. [Arrays and Strings](/src/main/java/com/ctci/arraysandstrings) 2. [Linked Lists](/src/main/java/com/ctci/linkedlists) - 3. [Recursion and DP](/src/main/java/com/ctci/recursionanddp) - 4. [Stacks and Queues](/src/main/java/com/ctci/stacksandqueues) - 5. [Trees and Graphs](/src/main/java/com/ctci/treesandgraphs) - 6. [Bit Manipulation](/src/main/java/com/ctci/bitmanipulation) + 3. [Stacks and Queues](/src/main/java/com/ctci/stacksandqueues) + 4. [Trees and Graphs](/src/main/java/com/ctci/treesandgraphs) + 5. [Bit Manipulation](/src/main/java/com/ctci/bitmanipulation) + 6. [Recursion and DP](/src/main/java/com/ctci/recursionanddp) 3. [HackerRank](/src/main/java/com/hackerrank). diff --git a/src/main/java/com/ctci/bitmanipulation/BinaryToString.java b/src/main/java/com/ctci/bitmanipulation/BinaryToString.java new file mode 100644 index 00000000..c6d50c41 --- /dev/null +++ b/src/main/java/com/ctci/bitmanipulation/BinaryToString.java @@ -0,0 +1,46 @@ +package com.ctci.bitmanipulation; + +/** + * @author rampatra + * @since 2019-03-16 + */ +public class BinaryToString { + + /** + * Given a real number between 0 and 1 (e.g., 0.72) that is passed in as a double, print the binary representation. + * If the number cannot be represented accurately in binary with at most 32 characters, print "ERROR." + * + * @param realNum a real number between 0 and 1 (for ex. 0.75) + * @return binary string of the real number + * @see how to convert decimal fraction to binary + */ + private static String decimalFractionToBinaryString(double realNum) { + if (realNum <= 0 || realNum >= 1) { + return "ERROR"; + } + + int binaryBit; + StringBuilder sb = new StringBuilder(); + sb.append("0."); + + while (realNum > 0) { + if (sb.length() == 32) { + return "ERROR"; + } + realNum = realNum * 2; + binaryBit = (int) realNum; + if (binaryBit == 1) { + realNum -= 1; + } + sb.append(binaryBit); + } + return sb.toString(); + } + + public static void main(String[] args) { + System.out.println(decimalFractionToBinaryString(0.625)); + System.out.println(decimalFractionToBinaryString(0.75)); + System.out.println(decimalFractionToBinaryString(0.72)); + System.out.println(decimalFractionToBinaryString(0.10)); + } +} From f23ca72c15f7652689ae44eac7f4723ff0940a0d Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sat, 16 Mar 2019 17:21:22 +0000 Subject: [PATCH 021/164] Changed c style array in some places to java style --- README.md | 4 +++- .../hackerrank/algorithms/arraysandsorting/IntroTutorial.java | 2 +- .../com/hackerrank/algorithms/strings/MakingAnagrams.java | 2 +- .../com/hackerrank/algorithms/strings/PalindromeIndex.java | 2 +- .../java/com/hackerrank/algorithms/strings/TwoStrings.java | 2 +- .../com/hackerrank/algorithms/warmup/LoveLetterMystery.java | 2 +- .../java/com/hackerrank/algorithms/warmup/UtopianTree.java | 2 +- src/main/java/com/hackerrank/bitmanipulation/CounterGame.java | 2 +- .../java/com/hackerrank/bitmanipulation/TwosCompliment.java | 2 +- src/main/java/com/hackerrank/java/oops/JavaInheritance.java | 2 +- .../java/com/hackerrank/projecteuler/MultiplesOf3and5.java | 2 +- .../java/com/rampatra/arrays/ArrangeNosToFormBiggestNo.java | 2 +- src/main/java/com/rampatra/arrays/BooleanMatrix.java | 2 +- src/main/java/com/rampatra/arrays/CelebrityProblem.java | 2 +- src/main/java/com/rampatra/arrays/ConsecutiveElements.java | 2 +- src/main/java/com/rampatra/arrays/CountDivisors.java | 2 +- .../java/com/rampatra/arrays/CountSmallerElementsOnRHS.java | 2 +- src/main/java/com/rampatra/arrays/DuplicatesInArray.java | 2 +- .../com/rampatra/arrays/DuplicatesInArrayWithinKDistance.java | 2 +- .../rampatra/arrays/EqualProbabilityRandomNoGenerator.java | 2 +- src/main/java/com/rampatra/arrays/EquilibriumIndex.java | 2 +- src/main/java/com/rampatra/arrays/FixedPoint.java | 2 +- .../rampatra/arrays/IntersectionAndUnionOf2SortedArrays.java | 2 +- src/main/java/com/rampatra/arrays/InversionsInArray.java | 2 +- src/main/java/com/rampatra/arrays/KLargestElements.java | 2 +- src/main/java/com/rampatra/arrays/KthLargestElement.java | 2 +- .../com/rampatra/arrays/LargestProductContiguousSubArray.java | 2 +- .../com/rampatra/arrays/LargestSumContiguousSubArray.java | 2 +- src/main/java/com/rampatra/arrays/LeadersInArray.java | 2 +- src/main/java/com/rampatra/arrays/LongestBitonicSubArray.java | 2 +- src/main/java/com/rampatra/arrays/MajorityElement.java | 2 +- .../com/rampatra/arrays/MajorityElementInSortedArray.java | 2 +- src/main/java/com/rampatra/arrays/MatrixInSpiral.java | 2 +- .../arrays/MaxDiffWithLargerElementAfterSmallerElement.java | 2 +- src/main/java/com/rampatra/arrays/MaxInAllSubArrays.java | 2 +- src/main/java/com/rampatra/arrays/MaxIndexDiff.java | 2 +- .../java/com/rampatra/arrays/MaxMinWithMinComparisons.java | 2 +- .../java/com/rampatra/arrays/MaximumSizeSquareSubMatrix.java | 2 +- .../com/rampatra/arrays/MaximumSumNonAdjacentSubSequence.java | 2 +- src/main/java/com/rampatra/arrays/MedianOfStream.java | 2 +- .../java/com/rampatra/arrays/MedianOfTwoSortedArrays.java | 2 +- .../com/rampatra/arrays/MergeArrayOfNIntoArrayOfMPlusN.java | 2 +- .../com/rampatra/arrays/MinimumDistanceBetweenTwoNos.java | 2 +- .../java/com/rampatra/arrays/MissingAndRepeatingElements.java | 2 +- src/main/java/com/rampatra/arrays/MissingNumber.java | 2 +- src/main/java/com/rampatra/arrays/NextGreaterElement.java | 2 +- src/main/java/com/rampatra/arrays/NextLargerNumber.java | 2 +- .../java/com/rampatra/arrays/NumberOccurringOddTimes.java | 2 +- .../java/com/rampatra/arrays/OccurrencesInSortedArray.java | 2 +- src/main/java/com/rampatra/arrays/PairDiff.java | 2 +- src/main/java/com/rampatra/arrays/PairSum.java | 2 +- src/main/java/com/rampatra/arrays/PivotedBinarySearch.java | 2 +- src/main/java/com/rampatra/arrays/ProductArrayPuzzle.java | 2 +- src/main/java/com/rampatra/arrays/ReservoirSampling.java | 2 +- src/main/java/com/rampatra/arrays/ReverseArray.java | 2 +- src/main/java/com/rampatra/arrays/RotateArray.java | 2 +- .../java/com/rampatra/arrays/RotateMatrixBy90Degrees.java | 2 +- src/main/java/com/rampatra/arrays/SearchInSorted2DArray.java | 2 +- src/main/java/com/rampatra/arrays/Segregate0s1sAnd2s.java | 2 +- src/main/java/com/rampatra/arrays/Segregate0sAnd1s.java | 2 +- src/main/java/com/rampatra/arrays/SegregateEvenAndOddNos.java | 2 +- .../java/com/rampatra/arrays/SmallestAndSecondSmallest.java | 2 +- src/main/java/com/rampatra/arrays/SmallestMissingNumber.java | 2 +- src/main/java/com/rampatra/arrays/SortedSubSequence.java | 2 +- src/main/java/com/rampatra/arrays/SubArrayOfSum.java | 2 +- src/main/java/com/rampatra/arrays/SubsetOfArray.java | 2 +- src/main/java/com/rampatra/arrays/SymmetricDifference.java | 2 +- src/main/java/com/rampatra/arrays/TripletOfSum.java | 2 +- .../java/com/rampatra/arrays/TwoElementsSumClosestToZero.java | 2 +- src/main/java/com/rampatra/arrays/TwoRepeatingElements.java | 2 +- src/main/java/com/rampatra/arrays/TwoStacksInOneArray.java | 2 +- src/main/java/com/rampatra/arrays/UnsortedSubArray.java | 2 +- src/main/java/com/rampatra/backtracking/KnightTour.java | 2 +- src/main/java/com/rampatra/backtracking/RatInAMaze.java | 2 +- src/main/java/com/rampatra/base/BinaryTree.java | 2 +- src/main/java/com/rampatra/base/Trie.java | 2 +- src/main/java/com/rampatra/bits/AbsWithoutBranching.java | 2 +- src/main/java/com/rampatra/bits/Addition.java | 2 +- src/main/java/com/rampatra/bits/BooleanArrayPuzzle.java | 2 +- src/main/java/com/rampatra/bits/ConvertAToB.java | 2 +- src/main/java/com/rampatra/bits/CountSetBits.java | 2 +- .../java/com/rampatra/bits/CountSetBitsFromMinusNtoN.java | 2 +- src/main/java/com/rampatra/bits/ElementOccurringOnce.java | 2 +- src/main/java/com/rampatra/bits/FlippingBits.java | 2 +- src/main/java/com/rampatra/bits/IntegerOverflow.java | 2 +- src/main/java/com/rampatra/bits/LittleAndBigEndian.java | 2 +- src/main/java/com/rampatra/bits/MaxWithoutBranching.java | 2 +- src/main/java/com/rampatra/bits/Modulo.java | 2 +- src/main/java/com/rampatra/bits/MultipleOf3.java | 2 +- src/main/java/com/rampatra/bits/Multiply.java | 2 +- src/main/java/com/rampatra/bits/NextHigherNumber.java | 2 +- src/main/java/com/rampatra/bits/NextPowerOf2.java | 2 +- src/main/java/com/rampatra/bits/OppositeSign.java | 2 +- src/main/java/com/rampatra/bits/Parity.java | 2 +- src/main/java/com/rampatra/bits/PowerOf2.java | 2 +- src/main/java/com/rampatra/bits/PowerOf4.java | 2 +- src/main/java/com/rampatra/bits/ReverseBits.java | 2 +- src/main/java/com/rampatra/bits/RightShiftOperator.java | 4 ++-- src/main/java/com/rampatra/bits/RightmostSetBit.java | 2 +- src/main/java/com/rampatra/bits/RotateBits.java | 2 +- src/main/java/com/rampatra/bits/SmallestOf3Integers.java | 2 +- src/main/java/com/rampatra/bits/StrCmp.java | 2 +- src/main/java/com/rampatra/bits/SubBit.java | 2 +- src/main/java/com/rampatra/bits/SwapBits.java | 2 +- src/main/java/com/rampatra/bits/TwoNonRepeatingElements.java | 2 +- .../com/rampatra/dynamicprogramming/FibonacciNumbers.java | 2 +- .../dynamicprogramming/LongestIncreasingSubSequence.java | 2 +- .../rampatra/dynamicprogramming/MinimumJumpsToReachEnd.java | 2 +- src/main/java/com/rampatra/java8/FlatMapInStreams.java | 2 +- src/main/java/com/rampatra/java8/Lambdas.java | 2 +- src/main/java/com/rampatra/java8/Streams.java | 2 +- .../java/com/rampatra/linkedlists/AddNumbersInTwoLists.java | 2 +- .../java/com/rampatra/linkedlists/CloneWithRandPointers.java | 2 +- .../java/com/rampatra/linkedlists/DeleteAlternateNodes.java | 2 +- src/main/java/com/rampatra/linkedlists/DeleteLesserNodes.java | 2 +- .../com/rampatra/linkedlists/DeleteMnodesAfterNnodes.java | 2 +- src/main/java/com/rampatra/linkedlists/DeleteNode.java | 2 +- .../java/com/rampatra/linkedlists/DetectAndRemoveLoop.java | 2 +- src/main/java/com/rampatra/linkedlists/DetectLoop.java | 2 +- .../com/rampatra/linkedlists/DivideCircularListIntoTwo.java | 2 +- .../com/rampatra/linkedlists/FlattenMultiLevelLinkedList.java | 2 +- src/main/java/com/rampatra/linkedlists/Identical.java | 2 +- .../linkedlists/InsertInSortedCircularLinkedList.java | 2 +- .../java/com/rampatra/linkedlists/InsertInSortedList.java | 2 +- .../rampatra/linkedlists/IntersectionAndUnionOf2Lists.java | 2 +- .../com/rampatra/linkedlists/IntersectionOf2SortedLists.java | 2 +- .../com/rampatra/linkedlists/IntersectionPointOfTwoLists.java | 2 +- src/main/java/com/rampatra/linkedlists/LRUCache.java | 2 +- .../java/com/rampatra/linkedlists/MaximumSumLinkedList.java | 2 +- src/main/java/com/rampatra/linkedlists/MergeSort.java | 2 +- .../com/rampatra/linkedlists/MergeSortDoubleLinkedList.java | 2 +- .../rampatra/linkedlists/MergeTwoLinkedListAlternatively.java | 2 +- .../java/com/rampatra/linkedlists/MergeTwoSortedLists.java | 2 +- src/main/java/com/rampatra/linkedlists/MiddleNode.java | 2 +- .../java/com/rampatra/linkedlists/MoveLastNodeToFirst.java | 2 +- src/main/java/com/rampatra/linkedlists/NthNodeFromLast.java | 2 +- src/main/java/com/rampatra/linkedlists/PairWiseSwap.java | 2 +- src/main/java/com/rampatra/linkedlists/Palindrome.java | 2 +- src/main/java/com/rampatra/linkedlists/QuickSort.java | 2 +- src/main/java/com/rampatra/linkedlists/RandomNode.java | 2 +- src/main/java/com/rampatra/linkedlists/RemoveDuplicates.java | 2 +- .../linkedlists/RemoveMiddlePointsFromLineSegments.java | 2 +- .../linkedlists/ReverseAlternateNodesAndAppendAtEnd.java | 2 +- .../com/rampatra/linkedlists/ReverseDoubleLinkedList.java | 2 +- .../linkedlists/ReverseLinkedListInAlternateGroups.java | 2 +- .../com/rampatra/linkedlists/ReverseLinkedListInGroups.java | 2 +- .../com/rampatra/linkedlists/ReverseSingleLinkedList.java | 2 +- src/main/java/com/rampatra/linkedlists/RotateLinkedList.java | 2 +- .../com/rampatra/linkedlists/SegregateEvenOddNumbers.java | 2 +- .../linkedlists/SortAlternativelySortedLinkedList.java | 2 +- .../java/com/rampatra/linkedlists/SortLinkedListOf0s1s2s.java | 2 +- src/main/java/com/rampatra/linkedlists/SortedDLLToBBST.java | 2 +- .../linkedlists/StackWithOperationOnMiddleElement.java | 2 +- src/main/java/com/rampatra/linkedlists/SwapKthNode.java | 2 +- src/main/java/com/rampatra/linkedlists/SwapNodes.java | 2 +- .../com/rampatra/linkedlists/TripletFromThreeLinkedLists.java | 2 +- src/main/java/com/rampatra/misc/CollectionIteration.java | 2 +- src/main/java/com/rampatra/misc/DivideByZero.java | 2 +- src/main/java/com/rampatra/misc/Equals.java | 2 +- src/main/java/com/rampatra/misc/GenericNonGenericMix.java | 2 +- src/main/java/com/rampatra/misc/HitCount.java | 2 +- src/main/java/com/rampatra/misc/RecursiveWarmup.java | 2 +- src/main/java/com/rampatra/misc/Regex.java | 2 +- src/main/java/com/rampatra/misc/ReplaceAll.java | 2 +- src/main/java/com/rampatra/misc/ReverseAndAdd.java | 2 +- .../java/com/rampatra/permutations/StringPermutations.java | 2 +- .../com/rampatra/permutations/StringPermutationsCount.java | 2 +- .../rampatra/permutations/UppercaseLowercasePermutations.java | 2 +- src/main/java/com/rampatra/searching/BinarySearch.java | 2 +- src/main/java/com/rampatra/searching/InterpolationSearch.java | 2 +- src/main/java/com/rampatra/sorting/CheckSorted.java | 2 +- src/main/java/com/rampatra/sorting/HeapSort.java | 2 +- src/main/java/com/rampatra/sorting/MergeSort.java | 2 +- src/main/java/com/rampatra/sorting/PancakeSort.java | 2 +- src/main/java/com/rampatra/sorting/QuickSort.java | 2 +- src/main/java/com/rampatra/sorting/SelectionSort.java | 2 +- src/main/java/com/rampatra/sorting/WiggleSort.java | 2 +- src/main/java/com/rampatra/stacks/BalancingParenthesis.java | 2 +- src/main/java/com/rampatra/strings/AnagramsTogether.java | 2 +- .../rampatra/strings/AnagramsTogetherLexicographically.java | 2 +- src/main/java/com/rampatra/strings/RemoveExtraSpaces.java | 2 +- src/main/java/com/rampatra/strings/StringRotation.java | 2 +- src/main/java/com/rampatra/strings/SubStringCheck.java | 2 +- src/main/java/com/rampatra/strings/SubStrings.java | 2 +- src/main/java/com/rampatra/threads/Basics.java | 2 +- src/main/java/com/rampatra/threads/NamePrint.java | 2 +- src/main/java/com/rampatra/trees/BFSUsingQueue.java | 2 +- src/main/java/com/rampatra/trees/CheckForBST.java | 2 +- src/main/java/com/rampatra/trees/ChildrenSum.java | 2 +- .../rampatra/trees/ConstructTreeFromInOrderAndPreOrder.java | 2 +- src/main/java/com/rampatra/trees/DoubleTree.java | 2 +- src/main/java/com/rampatra/trees/HeightBalanced.java | 2 +- src/main/java/com/rampatra/trees/IdenticalTrees.java | 2 +- src/main/java/com/rampatra/trees/InOrderUsingStack.java | 2 +- .../com/rampatra/trees/InOrderWithoutStackAndRecursion.java | 2 +- src/main/java/com/rampatra/trees/LeafNodes.java | 2 +- src/main/java/com/rampatra/trees/LeastCommonAncestor.java | 2 +- src/main/java/com/rampatra/trees/MirrorTree.java | 2 +- src/main/java/com/rampatra/trees/RootToLeafPaths.java | 2 +- src/main/java/com/rampatra/trees/SpiralTraversal.java | 2 +- src/main/java/com/rampatra/trees/TreeToList.java | 2 +- 201 files changed, 204 insertions(+), 202 deletions(-) diff --git a/README.md b/README.md index 581730da..79c62a96 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # Algorithms and Data Structures in Java -The repo consists of solutions to numerous problems using different data structures and algorithms, all coded in Java. It also contains solutions to HackerRank problems which I have solved so far and also questions from Cracking the Coding Interview Book _(6th Edition)_. +The repo consists of solutions to numerous problems using different data structures and algorithms, all coded in Java. It also +contains solutions to HackerRank problems which I have solved so far and questions from Cracking the Coding Interview +Book _(6th Edition)_. You can also refer to my [Java Notes](http://java.ramswaroop.me) for a quick refresh on the Java concepts. diff --git a/src/main/java/com/hackerrank/algorithms/arraysandsorting/IntroTutorial.java b/src/main/java/com/hackerrank/algorithms/arraysandsorting/IntroTutorial.java index 990beb9f..aeb8ea5f 100644 --- a/src/main/java/com/hackerrank/algorithms/arraysandsorting/IntroTutorial.java +++ b/src/main/java/com/hackerrank/algorithms/arraysandsorting/IntroTutorial.java @@ -15,7 +15,7 @@ static int search(int searchVal, int[] arr) { return Arrays.binarySearch(arr, searchVal); } - public static void main(String[] a) { + public static void main(String[] args) { Scanner in = new Scanner(System.in); int searchVal = in.nextInt(); diff --git a/src/main/java/com/hackerrank/algorithms/strings/MakingAnagrams.java b/src/main/java/com/hackerrank/algorithms/strings/MakingAnagrams.java index 16a3a531..b218c04e 100644 --- a/src/main/java/com/hackerrank/algorithms/strings/MakingAnagrams.java +++ b/src/main/java/com/hackerrank/algorithms/strings/MakingAnagrams.java @@ -47,7 +47,7 @@ public static int makeAnagrams(String a, String b) { return c; } - public static void main(String[] a) { + public static void main(String[] args) { System.out.println(makeAnagrams("abc", "cde")); } } diff --git a/src/main/java/com/hackerrank/algorithms/strings/PalindromeIndex.java b/src/main/java/com/hackerrank/algorithms/strings/PalindromeIndex.java index 2460c3f7..294c4dd2 100644 --- a/src/main/java/com/hackerrank/algorithms/strings/PalindromeIndex.java +++ b/src/main/java/com/hackerrank/algorithms/strings/PalindromeIndex.java @@ -37,7 +37,7 @@ static boolean isPalindrome(String s) { return true; } - public static void main(String[] a) { + public static void main(String[] args) { Scanner in = new Scanner(System.in); int t = in.nextInt(); diff --git a/src/main/java/com/hackerrank/algorithms/strings/TwoStrings.java b/src/main/java/com/hackerrank/algorithms/strings/TwoStrings.java index 114f68ad..779a148b 100644 --- a/src/main/java/com/hackerrank/algorithms/strings/TwoStrings.java +++ b/src/main/java/com/hackerrank/algorithms/strings/TwoStrings.java @@ -22,7 +22,7 @@ public static String isSubstringInBoth(String[] a) { return "NO"; } - public static void main(String a[]) { + public static void main(String[] args) { Scanner in = new Scanner(System.in); int t = Integer.parseInt(in.nextLine()); diff --git a/src/main/java/com/hackerrank/algorithms/warmup/LoveLetterMystery.java b/src/main/java/com/hackerrank/algorithms/warmup/LoveLetterMystery.java index de74f43a..8855498c 100644 --- a/src/main/java/com/hackerrank/algorithms/warmup/LoveLetterMystery.java +++ b/src/main/java/com/hackerrank/algorithms/warmup/LoveLetterMystery.java @@ -20,7 +20,7 @@ static int calcPalindromeSteps(String s) { return steps; } - public static void main(String[] a) { + public static void main(String[] args) { Scanner in = new Scanner(System.in); int t = in.nextInt(); diff --git a/src/main/java/com/hackerrank/algorithms/warmup/UtopianTree.java b/src/main/java/com/hackerrank/algorithms/warmup/UtopianTree.java index 6b074c5a..43e455c2 100644 --- a/src/main/java/com/hackerrank/algorithms/warmup/UtopianTree.java +++ b/src/main/java/com/hackerrank/algorithms/warmup/UtopianTree.java @@ -23,7 +23,7 @@ static int calcHeight(int growthCycles) { return h; } - public static void main(String[] a) { + public static void main(String[] args) { Scanner in = new Scanner(System.in); int t = in.nextInt(); diff --git a/src/main/java/com/hackerrank/bitmanipulation/CounterGame.java b/src/main/java/com/hackerrank/bitmanipulation/CounterGame.java index 289b11a5..b2a03e21 100644 --- a/src/main/java/com/hackerrank/bitmanipulation/CounterGame.java +++ b/src/main/java/com/hackerrank/bitmanipulation/CounterGame.java @@ -37,7 +37,7 @@ public static String computeWinner(BigInteger n) { return (louiseTurn) ? "Richard" : "Louise"; } - public static void main(String a[]) { + public static void main(String[] args) { Scanner in = new Scanner(System.in); int t = Integer.parseInt(in.nextLine()); diff --git a/src/main/java/com/hackerrank/bitmanipulation/TwosCompliment.java b/src/main/java/com/hackerrank/bitmanipulation/TwosCompliment.java index ab32330a..0bfdc29f 100644 --- a/src/main/java/com/hackerrank/bitmanipulation/TwosCompliment.java +++ b/src/main/java/com/hackerrank/bitmanipulation/TwosCompliment.java @@ -19,7 +19,7 @@ public static long countSetBitsInRange(int start, int end) { return count; } - public static void main(String a[]) { + public static void main(String[] args) { Scanner in = new Scanner(System.in); int t = Integer.parseInt(in.nextLine()); diff --git a/src/main/java/com/hackerrank/java/oops/JavaInheritance.java b/src/main/java/com/hackerrank/java/oops/JavaInheritance.java index 913251a9..b8d0d9e4 100644 --- a/src/main/java/com/hackerrank/java/oops/JavaInheritance.java +++ b/src/main/java/com/hackerrank/java/oops/JavaInheritance.java @@ -13,7 +13,7 @@ public void JavaInheritance() { } - public static void main(String a[]) { + public static void main(String[] args) { } } diff --git a/src/main/java/com/hackerrank/projecteuler/MultiplesOf3and5.java b/src/main/java/com/hackerrank/projecteuler/MultiplesOf3and5.java index ab06da74..f56da78e 100644 --- a/src/main/java/com/hackerrank/projecteuler/MultiplesOf3and5.java +++ b/src/main/java/com/hackerrank/projecteuler/MultiplesOf3and5.java @@ -11,7 +11,7 @@ */ public class MultiplesOf3and5 { - public static void main(String a[]) { + public static void main(String[] args) { Scanner in = new Scanner(System.in); int t = Integer.parseInt(in.nextLine()); diff --git a/src/main/java/com/rampatra/arrays/ArrangeNosToFormBiggestNo.java b/src/main/java/com/rampatra/arrays/ArrangeNosToFormBiggestNo.java index 3b130d8d..8d6adcdd 100644 --- a/src/main/java/com/rampatra/arrays/ArrangeNosToFormBiggestNo.java +++ b/src/main/java/com/rampatra/arrays/ArrangeNosToFormBiggestNo.java @@ -39,7 +39,7 @@ public int compare(Integer o1, Integer o2) { return a; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(Arrays.toString(arrangeArrayOfNosToFormBiggestNo(new Integer[]{45, 567, 12, 1}))); System.out.println(Arrays.toString(arrangeArrayOfNosToFormBiggestNo(new Integer[]{54, 546, 548, 60}))); System.out.println(Arrays.toString(arrangeArrayOfNosToFormBiggestNo(new Integer[]{1, 34, 3, 98, 9, 76, 45, 4}))); diff --git a/src/main/java/com/rampatra/arrays/BooleanMatrix.java b/src/main/java/com/rampatra/arrays/BooleanMatrix.java index 9f3c16ec..04ee2d88 100644 --- a/src/main/java/com/rampatra/arrays/BooleanMatrix.java +++ b/src/main/java/com/rampatra/arrays/BooleanMatrix.java @@ -67,7 +67,7 @@ private static void print2DMatrix(int[][] a) { } } - public static void main(String a[]) { + public static void main(String[] args) { int[][] ar = new int[][]{{1, 0, 0, 1}, {0, 0, 1, 0}, {0, 0, 0, 0}}; print2DMatrix(ar); modifyBooleanMatrix(ar); diff --git a/src/main/java/com/rampatra/arrays/CelebrityProblem.java b/src/main/java/com/rampatra/arrays/CelebrityProblem.java index 2c66050c..8b7278ea 100644 --- a/src/main/java/com/rampatra/arrays/CelebrityProblem.java +++ b/src/main/java/com/rampatra/arrays/CelebrityProblem.java @@ -78,7 +78,7 @@ public static int findCelebrity(int[][] peoples) { return firstPerson; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(findCelebrity(new int[][]{{0, 0, 1, 0}, {0, 0, 1, 0}, {0, 0, 0, 0}, {0, 0, 1, 0}})); System.out.println(findCelebrity(new int[][]{{0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}})); } diff --git a/src/main/java/com/rampatra/arrays/ConsecutiveElements.java b/src/main/java/com/rampatra/arrays/ConsecutiveElements.java index c6e1ac8f..f8dc151e 100644 --- a/src/main/java/com/rampatra/arrays/ConsecutiveElements.java +++ b/src/main/java/com/rampatra/arrays/ConsecutiveElements.java @@ -99,7 +99,7 @@ public static boolean areConsecutiveElementsInO1Space(int[] a) { return true; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(areConsecutiveElements(new int[]{5, 4, 3, 2, 1})); System.out.println(areConsecutiveElements(new int[]{67, 68, 69, 72, 70, 71})); System.out.println(areConsecutiveElements(new int[]{67, 68, 69, 72, 70, 71, 70})); diff --git a/src/main/java/com/rampatra/arrays/CountDivisors.java b/src/main/java/com/rampatra/arrays/CountDivisors.java index 71c46f1e..af1c5a43 100644 --- a/src/main/java/com/rampatra/arrays/CountDivisors.java +++ b/src/main/java/com/rampatra/arrays/CountDivisors.java @@ -24,7 +24,7 @@ public static int countDivisorsInRange(int begin, int end, int n) { return b - a; // return integers in range } - public static void main(String[] a) { + public static void main(String[] args) { countDivisorsInRange(0, 2000000000, 5); } } diff --git a/src/main/java/com/rampatra/arrays/CountSmallerElementsOnRHS.java b/src/main/java/com/rampatra/arrays/CountSmallerElementsOnRHS.java index 4c08fe0d..413234ec 100644 --- a/src/main/java/com/rampatra/arrays/CountSmallerElementsOnRHS.java +++ b/src/main/java/com/rampatra/arrays/CountSmallerElementsOnRHS.java @@ -16,7 +16,7 @@ public static int[] getSmallerElementsCountOnRHSNaive(int[] a) { return null; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(Arrays.toString(getSmallerElementsCountOnRHSNaive(new int[]{12, 1, 2, 3, 0, 11, 4}))); System.out.println(Arrays.toString(getSmallerElementsCountOnRHSNaive(new int[]{5, 4, 3, 2, 1}))); System.out.println(Arrays.toString(getSmallerElementsCountOnRHSNaive(new int[]{1, 2, 3, 4, 5}))); diff --git a/src/main/java/com/rampatra/arrays/DuplicatesInArray.java b/src/main/java/com/rampatra/arrays/DuplicatesInArray.java index b4e39d46..a101aa7f 100644 --- a/src/main/java/com/rampatra/arrays/DuplicatesInArray.java +++ b/src/main/java/com/rampatra/arrays/DuplicatesInArray.java @@ -43,7 +43,7 @@ public static int[] findDuplicatesInArray(int[] a) { return duplicates; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(Arrays.toString(findDuplicatesInArray(new int[]{1, 1, 2, 3, 1, 3, 6, 6}))); // doesn't work if 0 is present in array (as -0 makes no sense but we can modify the algorithm to handle 0) System.out.println(Arrays.toString(findDuplicatesInArray(new int[]{1, 0, 1, 2, 3, 1, 3, 6, 6}))); diff --git a/src/main/java/com/rampatra/arrays/DuplicatesInArrayWithinKDistance.java b/src/main/java/com/rampatra/arrays/DuplicatesInArrayWithinKDistance.java index 6cf8daaf..1cf4cbb7 100644 --- a/src/main/java/com/rampatra/arrays/DuplicatesInArrayWithinKDistance.java +++ b/src/main/java/com/rampatra/arrays/DuplicatesInArrayWithinKDistance.java @@ -41,7 +41,7 @@ public static int[] findDuplicatesInArrayWithinKDistance(int[] a, int k) { return Arrays.copyOf(duplicates, index); } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(Arrays.toString(findDuplicatesInArrayWithinKDistance(new int[]{1, 2, 8, 1, 3, 4, 5, 6, 6, 7}, 3))); } } diff --git a/src/main/java/com/rampatra/arrays/EqualProbabilityRandomNoGenerator.java b/src/main/java/com/rampatra/arrays/EqualProbabilityRandomNoGenerator.java index 94449b70..c26d8694 100644 --- a/src/main/java/com/rampatra/arrays/EqualProbabilityRandomNoGenerator.java +++ b/src/main/java/com/rampatra/arrays/EqualProbabilityRandomNoGenerator.java @@ -35,7 +35,7 @@ public static int f(int n) { return new Random().nextInt(n); } - public static void main(String a[]) { + public static void main(String[] args) { Scanner in = new Scanner(System.in); System.out.println("How many random numbers you would like to generate?"); diff --git a/src/main/java/com/rampatra/arrays/EquilibriumIndex.java b/src/main/java/com/rampatra/arrays/EquilibriumIndex.java index 8bbad988..c943c603 100644 --- a/src/main/java/com/rampatra/arrays/EquilibriumIndex.java +++ b/src/main/java/com/rampatra/arrays/EquilibriumIndex.java @@ -44,7 +44,7 @@ public static int getEquilibriumIndex(int[] a) { return -1; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(getEquilibriumIndex(new int[]{-7, 1, 5, 2, -4, 3, 0})); System.out.println(getEquilibriumIndex(new int[]{-7, 1, 5, 0, 0, 0, 0, 1, 2, -4, 1, 3, 0})); System.out.println(getEquilibriumIndex(new int[]{4, 5, 2, 1, 6, 7, 8, 0, 1})); diff --git a/src/main/java/com/rampatra/arrays/FixedPoint.java b/src/main/java/com/rampatra/arrays/FixedPoint.java index 3b3d0363..99e8a333 100644 --- a/src/main/java/com/rampatra/arrays/FixedPoint.java +++ b/src/main/java/com/rampatra/arrays/FixedPoint.java @@ -33,7 +33,7 @@ public static int findFixedPoint(int[] a) { return -1; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(findFixedPoint(new int[]{-10, -5, 0, 3, 7})); System.out.println(findFixedPoint(new int[]{0, 2, 5, 8, 17})); System.out.println(findFixedPoint(new int[]{-10, -5, 3, 4, 7, 9})); diff --git a/src/main/java/com/rampatra/arrays/IntersectionAndUnionOf2SortedArrays.java b/src/main/java/com/rampatra/arrays/IntersectionAndUnionOf2SortedArrays.java index 933372aa..595e85a5 100644 --- a/src/main/java/com/rampatra/arrays/IntersectionAndUnionOf2SortedArrays.java +++ b/src/main/java/com/rampatra/arrays/IntersectionAndUnionOf2SortedArrays.java @@ -50,7 +50,7 @@ public static int[][] getIntersectionAndUnionOf2SortedArrays(int[] a, int[] b) { return new int[][]{intersection, union}; } - public static void main(String a[]) { + public static void main(String[] args) { int[] a1 = new int[]{2, 3, 4, 5, 6, 7, 8}; int[] a2 = new int[]{6, 7, 8, 10, 12, 14, 16}; int[][] result = getIntersectionAndUnionOf2SortedArrays(a1, a2); diff --git a/src/main/java/com/rampatra/arrays/InversionsInArray.java b/src/main/java/com/rampatra/arrays/InversionsInArray.java index c86bdacc..1677764d 100644 --- a/src/main/java/com/rampatra/arrays/InversionsInArray.java +++ b/src/main/java/com/rampatra/arrays/InversionsInArray.java @@ -95,7 +95,7 @@ public static int[] merge(int[] a, int[] b) { return sortedArray; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(getInversionCountNaiveApproach(new int[]{2, 4, 1, 3, 5})); System.out.println(getInversionCount(new int[]{2, 4, 1, 3, 5})); } diff --git a/src/main/java/com/rampatra/arrays/KLargestElements.java b/src/main/java/com/rampatra/arrays/KLargestElements.java index ce1e217f..87546e7d 100644 --- a/src/main/java/com/rampatra/arrays/KLargestElements.java +++ b/src/main/java/com/rampatra/arrays/KLargestElements.java @@ -49,7 +49,7 @@ public static int[] getKLargestElements(int[] a, int k) { return minHeap.getHeap(); } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(Arrays.toString(getKLargestElements(new int[]{2, 3, 4, 1, 5, 7, 9}, 3))); } } diff --git a/src/main/java/com/rampatra/arrays/KthLargestElement.java b/src/main/java/com/rampatra/arrays/KthLargestElement.java index 4b119519..65ca77c7 100644 --- a/src/main/java/com/rampatra/arrays/KthLargestElement.java +++ b/src/main/java/com/rampatra/arrays/KthLargestElement.java @@ -52,7 +52,7 @@ public static int getKthLargestElement(int[] a, int k) { return maxHeap.findMax(); } - public static void main(String a[]) { + public static void main(String[] args) { int[] ar = new int[]{2, 4, 5, 7, 1, 8, 9}; System.out.println(Arrays.toString(ar)); System.out.println(getKthLargestElementNaive(ar, 3)); diff --git a/src/main/java/com/rampatra/arrays/LargestProductContiguousSubArray.java b/src/main/java/com/rampatra/arrays/LargestProductContiguousSubArray.java index 8488c7c6..c7afb19b 100644 --- a/src/main/java/com/rampatra/arrays/LargestProductContiguousSubArray.java +++ b/src/main/java/com/rampatra/arrays/LargestProductContiguousSubArray.java @@ -17,7 +17,7 @@ public static int getLargestProductContiguousSubArray(int[] a) { return 0; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(getLargestProductContiguousSubArray(new int[]{-2, 1, -3, 4, 5, -1, 4})); System.out.println(getLargestProductContiguousSubArray(new int[]{6, -3, -10, 0, 2})); } diff --git a/src/main/java/com/rampatra/arrays/LargestSumContiguousSubArray.java b/src/main/java/com/rampatra/arrays/LargestSumContiguousSubArray.java index 3e9d1409..8b34d9ef 100644 --- a/src/main/java/com/rampatra/arrays/LargestSumContiguousSubArray.java +++ b/src/main/java/com/rampatra/arrays/LargestSumContiguousSubArray.java @@ -47,7 +47,7 @@ public static int getLargestSumOfContiguousSubArrayWhenAllNosNegative(int[] a) { return maxSum; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(getLargestSumOfContiguousSubArray(new int[]{-2, 1, -3, 4, 5, -1, 4})); System.out.println(getLargestSumOfContiguousSubArray(new int[]{2, -1, -3, 4, -5, 1, 4})); // kadane's algorithm doesn't work if all no.s are -ve diff --git a/src/main/java/com/rampatra/arrays/LeadersInArray.java b/src/main/java/com/rampatra/arrays/LeadersInArray.java index f67f30ca..c2075751 100644 --- a/src/main/java/com/rampatra/arrays/LeadersInArray.java +++ b/src/main/java/com/rampatra/arrays/LeadersInArray.java @@ -37,7 +37,7 @@ public static int[] getAllLeaders(int[] a) { return Arrays.copyOfRange(leaders, 0, j + 1); } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(Arrays.toString(getAllLeaders(new int[]{16, 17, 4, 3, 5, 2}))); System.out.println(Arrays.toString(getAllLeaders(new int[]{16, 1, 4, 3, 5, 12}))); System.out.println(Arrays.toString(getAllLeaders(new int[]{16, 15, 14, 13, 12, 10}))); diff --git a/src/main/java/com/rampatra/arrays/LongestBitonicSubArray.java b/src/main/java/com/rampatra/arrays/LongestBitonicSubArray.java index 131fb50f..dc3caafb 100644 --- a/src/main/java/com/rampatra/arrays/LongestBitonicSubArray.java +++ b/src/main/java/com/rampatra/arrays/LongestBitonicSubArray.java @@ -54,7 +54,7 @@ public static int getLongestBitonicSubArrayLength(int[] a) { return bitonicLength; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(getLongestBitonicSubArrayLength(new int[]{1, 2, 5, 4, 3})); System.out.println(getLongestBitonicSubArrayLength(new int[]{12, 4, 78, 90, 45, 23})); System.out.println(getLongestBitonicSubArrayLength(new int[]{10, 20, 30, 40})); diff --git a/src/main/java/com/rampatra/arrays/MajorityElement.java b/src/main/java/com/rampatra/arrays/MajorityElement.java index c5632951..e7785f90 100644 --- a/src/main/java/com/rampatra/arrays/MajorityElement.java +++ b/src/main/java/com/rampatra/arrays/MajorityElement.java @@ -62,7 +62,7 @@ public static void majorityElement(int a[]) { } } - public static void main(String a[]) { + public static void main(String[] args) { majorityElement(new int[]{1, 6, 2, 2, 2, 1, 2, 2, 7, 2}); } } diff --git a/src/main/java/com/rampatra/arrays/MajorityElementInSortedArray.java b/src/main/java/com/rampatra/arrays/MajorityElementInSortedArray.java index cf89101c..56e5ff21 100644 --- a/src/main/java/com/rampatra/arrays/MajorityElementInSortedArray.java +++ b/src/main/java/com/rampatra/arrays/MajorityElementInSortedArray.java @@ -64,7 +64,7 @@ public static int getFirstIndexOf(int[] a, int n, int low, int high) { return -1; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(isMajorityElement(new int[]{2, 2}, 2)); System.out.println(isMajorityElement(new int[]{1, 2}, 2)); System.out.println(isMajorityElement(new int[]{1, 2, 2, 2, 2, 2, 3, 3}, 2)); diff --git a/src/main/java/com/rampatra/arrays/MatrixInSpiral.java b/src/main/java/com/rampatra/arrays/MatrixInSpiral.java index 97847f51..a498f39a 100644 --- a/src/main/java/com/rampatra/arrays/MatrixInSpiral.java +++ b/src/main/java/com/rampatra/arrays/MatrixInSpiral.java @@ -43,7 +43,7 @@ public static void printMatrixInSpiral(int[][] a) { } } - public static void main(String a[]) { + public static void main(String[] args) { printMatrixInSpiral(new int[][]{{1}, {2}}); out.println(); printMatrixInSpiral(new int[][]{{1, 2}, {3, 4}}); diff --git a/src/main/java/com/rampatra/arrays/MaxDiffWithLargerElementAfterSmallerElement.java b/src/main/java/com/rampatra/arrays/MaxDiffWithLargerElementAfterSmallerElement.java index 11189802..04d7a9f8 100644 --- a/src/main/java/com/rampatra/arrays/MaxDiffWithLargerElementAfterSmallerElement.java +++ b/src/main/java/com/rampatra/arrays/MaxDiffWithLargerElementAfterSmallerElement.java @@ -35,7 +35,7 @@ public static int getMaxDiffWithLargerElementAfterSmallerElement(int[] a) { return maxDiff; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(getMaxDiffWithLargerElementAfterSmallerElement(new int[]{2, 1, 4, 5, 10, 0})); System.out.println(getMaxDiffWithLargerElementAfterSmallerElement(new int[]{2, -6, 4, 5, 10, 1})); System.out.println(getMaxDiffWithLargerElementAfterSmallerElement(new int[]{-2, -6, -4, -5, -10, -1})); diff --git a/src/main/java/com/rampatra/arrays/MaxInAllSubArrays.java b/src/main/java/com/rampatra/arrays/MaxInAllSubArrays.java index 5f27a660..8061d44d 100644 --- a/src/main/java/com/rampatra/arrays/MaxInAllSubArrays.java +++ b/src/main/java/com/rampatra/arrays/MaxInAllSubArrays.java @@ -93,7 +93,7 @@ public static int[] maxInAllSubArraysOfSizeK(int[] a, int k) { return result; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(Arrays.toString(maxInAllSubArraysOfSizeKNaive(new int[]{1, 2, 3, 1, 4, 5, 2, 3, 6}, 3))); System.out.println(Arrays.toString(maxInAllSubArraysOfSizeKNaive(new int[]{8, 5, 10, 7, 9, 4, 15, 12, 90, 13}, 4))); System.out.println(Arrays.toString(maxInAllSubArraysOfSizeK(new int[]{1, 2, 3, 1, 4, 5, 2, 3, 6}, 3))); diff --git a/src/main/java/com/rampatra/arrays/MaxIndexDiff.java b/src/main/java/com/rampatra/arrays/MaxIndexDiff.java index f71ae192..9eb982c4 100644 --- a/src/main/java/com/rampatra/arrays/MaxIndexDiff.java +++ b/src/main/java/com/rampatra/arrays/MaxIndexDiff.java @@ -49,7 +49,7 @@ public static int maxDiff(int[] a) { return maxDiff; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(maxDiff(new int[]{34, 8, 10, 3, 2, 80, 30, 33, 1})); System.out.println(maxDiff(new int[]{9, 2, 3, 4, 5, 6, 7, 8, 18, 0})); System.out.println(maxDiff(new int[]{1, 2, 3, 4, 5, 6})); diff --git a/src/main/java/com/rampatra/arrays/MaxMinWithMinComparisons.java b/src/main/java/com/rampatra/arrays/MaxMinWithMinComparisons.java index 402bad67..23e3e99d 100644 --- a/src/main/java/com/rampatra/arrays/MaxMinWithMinComparisons.java +++ b/src/main/java/com/rampatra/arrays/MaxMinWithMinComparisons.java @@ -53,7 +53,7 @@ public static int[] getMaxMinWithMinComparisons(int[] a) { return new int[]{min, max}; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(Arrays.toString(getMaxMinWithMinComparisons(new int[]{2, 5, 1, 6, 7, 9, 0, 8, 10}))); } } diff --git a/src/main/java/com/rampatra/arrays/MaximumSizeSquareSubMatrix.java b/src/main/java/com/rampatra/arrays/MaximumSizeSquareSubMatrix.java index 9669cd34..0c9c4419 100644 --- a/src/main/java/com/rampatra/arrays/MaximumSizeSquareSubMatrix.java +++ b/src/main/java/com/rampatra/arrays/MaximumSizeSquareSubMatrix.java @@ -64,7 +64,7 @@ public static void printMaximumSizeSquareSubMatrix(int[][] a) { } } - public static void main(String a[]) { + public static void main(String[] args) { int[][] ar = new int[][]{{0, 1, 1, 1}, {1, 1, 0, 1}, {1, 0, 0, 1}, diff --git a/src/main/java/com/rampatra/arrays/MaximumSumNonAdjacentSubSequence.java b/src/main/java/com/rampatra/arrays/MaximumSumNonAdjacentSubSequence.java index 2dd02ab4..9734aa29 100644 --- a/src/main/java/com/rampatra/arrays/MaximumSumNonAdjacentSubSequence.java +++ b/src/main/java/com/rampatra/arrays/MaximumSumNonAdjacentSubSequence.java @@ -35,7 +35,7 @@ public static int maximumSumNonAdjacentSubSequence(int[] a) { return Math.max(incl, excl); } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(maximumSumNonAdjacentSubSequence(new int[]{3, 2, 7, 10})); System.out.println(maximumSumNonAdjacentSubSequence(new int[]{3, 2, 5, 10, 7})); } diff --git a/src/main/java/com/rampatra/arrays/MedianOfStream.java b/src/main/java/com/rampatra/arrays/MedianOfStream.java index 84829ccf..47781bc0 100644 --- a/src/main/java/com/rampatra/arrays/MedianOfStream.java +++ b/src/main/java/com/rampatra/arrays/MedianOfStream.java @@ -73,7 +73,7 @@ static int compare(int a, int b) { } } - public static void main(String a[]) { + public static void main(String[] args) { printMedianOfStream(new int[]{5, 15, 1, 3, 2, 8, 7, 9, 10, 6, 11, 4}); printMedianOfStream(new int[]{5, 15, 1}); printMedianOfStream(new int[]{5, 15, 10, 20}); diff --git a/src/main/java/com/rampatra/arrays/MedianOfTwoSortedArrays.java b/src/main/java/com/rampatra/arrays/MedianOfTwoSortedArrays.java index 7cfb13bf..d64ec757 100644 --- a/src/main/java/com/rampatra/arrays/MedianOfTwoSortedArrays.java +++ b/src/main/java/com/rampatra/arrays/MedianOfTwoSortedArrays.java @@ -94,7 +94,7 @@ public static int median(int[] a1, int[] a2) { } } - public static void main(String a[]) { + public static void main(String[] args) { // test cases System.out.println(median(new int[]{1, 2, 3, 6}, new int[]{4, 6, 8, 9})); System.out.println(median(new int[]{4, 6, 8, 9}, new int[]{1, 2, 3, 6})); diff --git a/src/main/java/com/rampatra/arrays/MergeArrayOfNIntoArrayOfMPlusN.java b/src/main/java/com/rampatra/arrays/MergeArrayOfNIntoArrayOfMPlusN.java index 15d66042..e95c653a 100644 --- a/src/main/java/com/rampatra/arrays/MergeArrayOfNIntoArrayOfMPlusN.java +++ b/src/main/java/com/rampatra/arrays/MergeArrayOfNIntoArrayOfMPlusN.java @@ -57,7 +57,7 @@ public static void merge(int[] mPlusN, int[] n) { } } - public static void main(String a[]) { + public static void main(String[] args) { int[] mPlusN = {2, NA, 12, NA, NA, 14, NA}; int[] n = {5, 7, 8, 10}; merge(mPlusN, n); diff --git a/src/main/java/com/rampatra/arrays/MinimumDistanceBetweenTwoNos.java b/src/main/java/com/rampatra/arrays/MinimumDistanceBetweenTwoNos.java index 1f29472e..48edc1a9 100644 --- a/src/main/java/com/rampatra/arrays/MinimumDistanceBetweenTwoNos.java +++ b/src/main/java/com/rampatra/arrays/MinimumDistanceBetweenTwoNos.java @@ -45,7 +45,7 @@ public static int getMinimumDistanceBetweenTwoNos(int[] a, int x, int y) { return minDiff; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(getMinimumDistanceBetweenTwoNos(new int[]{1, 2}, 1, 2)); System.out.println(getMinimumDistanceBetweenTwoNos(new int[]{3, 4, 5}, 3, 5)); System.out.println(getMinimumDistanceBetweenTwoNos(new int[]{3, 5, 4, 2, 6, 5, 6, 6, 5, 4, 8, 3}, 3, 6)); diff --git a/src/main/java/com/rampatra/arrays/MissingAndRepeatingElements.java b/src/main/java/com/rampatra/arrays/MissingAndRepeatingElements.java index 8df64f03..5fe08bf2 100644 --- a/src/main/java/com/rampatra/arrays/MissingAndRepeatingElements.java +++ b/src/main/java/com/rampatra/arrays/MissingAndRepeatingElements.java @@ -38,7 +38,7 @@ public static int[] findMissingAndRepeatingElements(int[] a) { return result; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(Arrays.toString(findMissingAndRepeatingElements(new int[]{3, 1, 3}))); System.out.println(Arrays.toString(findMissingAndRepeatingElements(new int[]{4, 3, 6, 2, 1, 1}))); System.out.println(Arrays.toString(findMissingAndRepeatingElements(new int[]{4, 4, 6, 2, 5, 1}))); diff --git a/src/main/java/com/rampatra/arrays/MissingNumber.java b/src/main/java/com/rampatra/arrays/MissingNumber.java index 9ca15df8..6691f6db 100644 --- a/src/main/java/com/rampatra/arrays/MissingNumber.java +++ b/src/main/java/com/rampatra/arrays/MissingNumber.java @@ -48,7 +48,7 @@ public static int missingNumberUsingXOR(int a[], int n) { return nXOR ^ arrayXOR; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println("Missing No: " + missingNumber(new int[]{2, 3, 1, 4, 6, 7, 8}, 8)); System.out.println("Missing No using XOR: " + missingNumberUsingXOR(new int[]{2, 3, 1, 4, 6, 7, 8}, 8)); } diff --git a/src/main/java/com/rampatra/arrays/NextGreaterElement.java b/src/main/java/com/rampatra/arrays/NextGreaterElement.java index 03f02209..96c568f1 100644 --- a/src/main/java/com/rampatra/arrays/NextGreaterElement.java +++ b/src/main/java/com/rampatra/arrays/NextGreaterElement.java @@ -47,7 +47,7 @@ public static void nextGreaterElements(int[] a) { System.out.println(a[i] + "->" + -1); } - public static void main(String a[]) { + public static void main(String[] args) { int[] ar = new int[]{4, 5, 2, 25}; nextGreaterElements(ar); System.out.println("========="); diff --git a/src/main/java/com/rampatra/arrays/NextLargerNumber.java b/src/main/java/com/rampatra/arrays/NextLargerNumber.java index 7582afeb..00e00b78 100644 --- a/src/main/java/com/rampatra/arrays/NextLargerNumber.java +++ b/src/main/java/com/rampatra/arrays/NextLargerNumber.java @@ -84,7 +84,7 @@ private static void swap(int[] a, int index1, int index2) { a[index2] = temp; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(findNextLargerNumber(56)); System.out.println(findNextLargerNumber(65)); System.out.println(findNextLargerNumber(3451)); diff --git a/src/main/java/com/rampatra/arrays/NumberOccurringOddTimes.java b/src/main/java/com/rampatra/arrays/NumberOccurringOddTimes.java index e2e7b966..81656dd1 100644 --- a/src/main/java/com/rampatra/arrays/NumberOccurringOddTimes.java +++ b/src/main/java/com/rampatra/arrays/NumberOccurringOddTimes.java @@ -28,7 +28,7 @@ public static int numberOccurringOddTimes(int a[]) { return res; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.print(numberOccurringOddTimes(new int[]{2, 3, 3, 3, 1, 2, 1})); } } diff --git a/src/main/java/com/rampatra/arrays/OccurrencesInSortedArray.java b/src/main/java/com/rampatra/arrays/OccurrencesInSortedArray.java index f0044d83..fea37847 100644 --- a/src/main/java/com/rampatra/arrays/OccurrencesInSortedArray.java +++ b/src/main/java/com/rampatra/arrays/OccurrencesInSortedArray.java @@ -74,7 +74,7 @@ public static int getLastIndexOf(int[] a, int n, int low, int high) { } } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(getOccurrencesInSortedArray(new int[]{1, 1, 2, 2, 2, 2, 3}, 1)); System.out.println(getOccurrencesInSortedArray(new int[]{1, 1, 1, 2, 2, 2, 2, 3}, 1)); System.out.println(getOccurrencesInSortedArray(new int[]{1, 1, 2, 2, 2, 2, 3}, 2)); diff --git a/src/main/java/com/rampatra/arrays/PairDiff.java b/src/main/java/com/rampatra/arrays/PairDiff.java index 47184e31..8fce2367 100644 --- a/src/main/java/com/rampatra/arrays/PairDiff.java +++ b/src/main/java/com/rampatra/arrays/PairDiff.java @@ -63,7 +63,7 @@ static boolean pairDiff(int ar[], int x, Map map) { return false; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(pairDiff(new int[]{-3, 4, -6, 1, 1}, -4)); System.out.println(pairDiff(new int[]{3, 1}, 2)); System.out.println(pairDiff(new int[]{-3, 4, -6, 1, 1}, -4, new HashMap())); diff --git a/src/main/java/com/rampatra/arrays/PairSum.java b/src/main/java/com/rampatra/arrays/PairSum.java index 17c518f4..75ce7d63 100644 --- a/src/main/java/com/rampatra/arrays/PairSum.java +++ b/src/main/java/com/rampatra/arrays/PairSum.java @@ -58,7 +58,7 @@ static boolean pairSum(int[] ar, int sum, Set numSet) { return false; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(pairSum(new int[]{-3, 4, -6, 1, 1}, -2)); System.out.println(pairSum(new int[]{-3, 4, -6, 1, 1}, 5)); System.out.println(pairSum(new int[]{-3, 4, -6, 1, 1}, 0)); diff --git a/src/main/java/com/rampatra/arrays/PivotedBinarySearch.java b/src/main/java/com/rampatra/arrays/PivotedBinarySearch.java index 292856aa..a87875b5 100644 --- a/src/main/java/com/rampatra/arrays/PivotedBinarySearch.java +++ b/src/main/java/com/rampatra/arrays/PivotedBinarySearch.java @@ -58,7 +58,7 @@ public static int findPivot(int a[], int low, int high) { } } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println("Pivot: " + findPivot(new int[]{1, 2, 3, 4, 5}, 0, 3)); System.out.println("Index: " + pivotedBinarySearch(new int[]{1, 2, 3, 4, 5}, 4)); diff --git a/src/main/java/com/rampatra/arrays/ProductArrayPuzzle.java b/src/main/java/com/rampatra/arrays/ProductArrayPuzzle.java index 08441951..23de1acc 100644 --- a/src/main/java/com/rampatra/arrays/ProductArrayPuzzle.java +++ b/src/main/java/com/rampatra/arrays/ProductArrayPuzzle.java @@ -63,7 +63,7 @@ public static int[] getProductArray(int[] a) { return prod; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(Arrays.toString(getProductArray(new int[]{10, 3, 5, 6, 2}))); System.out.println(Arrays.toString(getProductArray(new int[]{0, 0}))); System.out.println(Arrays.toString(getProductArray(new int[]{1}))); diff --git a/src/main/java/com/rampatra/arrays/ReservoirSampling.java b/src/main/java/com/rampatra/arrays/ReservoirSampling.java index cc956f56..050fb17f 100644 --- a/src/main/java/com/rampatra/arrays/ReservoirSampling.java +++ b/src/main/java/com/rampatra/arrays/ReservoirSampling.java @@ -58,7 +58,7 @@ public static int[] getKRandomNumbers(int[] stream, int k) { } - public static void main(String a[]) { + public static void main(String[] args) { int[] stream = {1, 2, 3, 4, 5, 6, 7, 8, 9}; System.out.println(Arrays.toString(getKRandomNumbers(stream, 4))); } diff --git a/src/main/java/com/rampatra/arrays/ReverseArray.java b/src/main/java/com/rampatra/arrays/ReverseArray.java index 97f556b3..64550c58 100644 --- a/src/main/java/com/rampatra/arrays/ReverseArray.java +++ b/src/main/java/com/rampatra/arrays/ReverseArray.java @@ -43,7 +43,7 @@ public static void reverseRecursive(int[] a, int i, int j) { reverseRecursive(a, ++i, --j); } - public static void main(String a[]) { + public static void main(String[] args) { int[] ar = new int[]{1, 2, 3, 4, 5}; System.out.println(Arrays.toString(ar)); reverse(ar); diff --git a/src/main/java/com/rampatra/arrays/RotateArray.java b/src/main/java/com/rampatra/arrays/RotateArray.java index 3f8e0b6f..f720dcf6 100644 --- a/src/main/java/com/rampatra/arrays/RotateArray.java +++ b/src/main/java/com/rampatra/arrays/RotateArray.java @@ -91,7 +91,7 @@ public static int gcd(int a, int b) { } } - public static void main(String a[]) { + public static void main(String[] args) { int[] ar = {1, 2, 3, 4, 5, 6, 7}; System.out.println(Arrays.toString(ar)); rotateNaiveApproach(ar, 2); diff --git a/src/main/java/com/rampatra/arrays/RotateMatrixBy90Degrees.java b/src/main/java/com/rampatra/arrays/RotateMatrixBy90Degrees.java index 59288a39..ccff75ca 100644 --- a/src/main/java/com/rampatra/arrays/RotateMatrixBy90Degrees.java +++ b/src/main/java/com/rampatra/arrays/RotateMatrixBy90Degrees.java @@ -42,7 +42,7 @@ private static void print2DMatrix(int[][] a) { } } - public static void main(String a[]) { + public static void main(String[] args) { int[][] ar = new int[][]{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; print2DMatrix(ar); System.out.println("--------"); diff --git a/src/main/java/com/rampatra/arrays/SearchInSorted2DArray.java b/src/main/java/com/rampatra/arrays/SearchInSorted2DArray.java index 914bbad5..8ab14269 100644 --- a/src/main/java/com/rampatra/arrays/SearchInSorted2DArray.java +++ b/src/main/java/com/rampatra/arrays/SearchInSorted2DArray.java @@ -86,7 +86,7 @@ private static void print2DMatrix(int[][] a) { } } - public static void main(String a[]) { + public static void main(String[] args) { int[][] ar = new int[][]{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; print2DMatrix(ar); System.out.println(Arrays.toString(linearSearchNaive(ar, 0, 0, 1))); diff --git a/src/main/java/com/rampatra/arrays/Segregate0s1sAnd2s.java b/src/main/java/com/rampatra/arrays/Segregate0s1sAnd2s.java index 93fcefc4..e64929f8 100644 --- a/src/main/java/com/rampatra/arrays/Segregate0s1sAnd2s.java +++ b/src/main/java/com/rampatra/arrays/Segregate0s1sAnd2s.java @@ -45,7 +45,7 @@ private static void swap(int[] a, int index1, int index2) { a[index2] = temp; } - public static void main(String a[]) { + public static void main(String[] args) { int[] ar = new int[]{0, 1, 2, 0, 1, 2}; segregate0s1sAnd2s(ar); System.out.println(Arrays.toString(ar)); diff --git a/src/main/java/com/rampatra/arrays/Segregate0sAnd1s.java b/src/main/java/com/rampatra/arrays/Segregate0sAnd1s.java index 5fe9fe8e..e5f9634a 100644 --- a/src/main/java/com/rampatra/arrays/Segregate0sAnd1s.java +++ b/src/main/java/com/rampatra/arrays/Segregate0sAnd1s.java @@ -27,7 +27,7 @@ public static void segregate0sAnd1s(int[] a) { } } - public static void main(String a[]) { + public static void main(String[] args) { int[] ar = new int[]{0, 1, 1, 1, 0, 0, 1}; segregate0sAnd1s(ar); System.out.println(Arrays.toString(ar)); diff --git a/src/main/java/com/rampatra/arrays/SegregateEvenAndOddNos.java b/src/main/java/com/rampatra/arrays/SegregateEvenAndOddNos.java index 9652af57..8cdaf6b6 100644 --- a/src/main/java/com/rampatra/arrays/SegregateEvenAndOddNos.java +++ b/src/main/java/com/rampatra/arrays/SegregateEvenAndOddNos.java @@ -39,7 +39,7 @@ public static void segregateEvenAndOddNos(int[] a) { } } - public static void main(String a[]) { + public static void main(String[] args) { int[] ar = new int[]{12, 34, 45, 9, 8, 90, 3}; segregateEvenAndOddNos(ar); System.out.println(Arrays.toString(ar)); diff --git a/src/main/java/com/rampatra/arrays/SmallestAndSecondSmallest.java b/src/main/java/com/rampatra/arrays/SmallestAndSecondSmallest.java index f200aaba..9e683caf 100644 --- a/src/main/java/com/rampatra/arrays/SmallestAndSecondSmallest.java +++ b/src/main/java/com/rampatra/arrays/SmallestAndSecondSmallest.java @@ -25,7 +25,7 @@ private static int[] getSmallestAndSecondSmallest(int[] a) { return new int[]{smallest, secondSmallest}; } - public static void main(String[] a) { + public static void main(String[] args) { System.out.println(Arrays.toString(getSmallestAndSecondSmallest(new int[]{100, 1, 60, -10, -80, 85, 70, -80}))); System.out.println(Arrays.toString(getSmallestAndSecondSmallest(new int[]{100, 1, 60, 10, 80, 85, 70, 0}))); } diff --git a/src/main/java/com/rampatra/arrays/SmallestMissingNumber.java b/src/main/java/com/rampatra/arrays/SmallestMissingNumber.java index 334929f8..7b63a415 100644 --- a/src/main/java/com/rampatra/arrays/SmallestMissingNumber.java +++ b/src/main/java/com/rampatra/arrays/SmallestMissingNumber.java @@ -45,7 +45,7 @@ public static int smallestMissingNumber(int[] a, int low, int high) { } } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(smallestMissingNumber(new int[]{0, 1}, 0, 1)); System.out.println(smallestMissingNumber(new int[]{0, 1, 2, 6, 9}, 0, 4)); System.out.println(smallestMissingNumber(new int[]{4, 5, 10, 11}, 0, 3)); diff --git a/src/main/java/com/rampatra/arrays/SortedSubSequence.java b/src/main/java/com/rampatra/arrays/SortedSubSequence.java index 7c82474f..7e689389 100644 --- a/src/main/java/com/rampatra/arrays/SortedSubSequence.java +++ b/src/main/java/com/rampatra/arrays/SortedSubSequence.java @@ -55,7 +55,7 @@ public static void printSortedSubSequenceOfSize3(int[] a) { } - public static void main(String a[]) { + public static void main(String[] args) { printSortedSubSequenceOfSize3(new int[]{12, 11, 10, 5, 6, 2, 30}); printSortedSubSequenceOfSize3(new int[]{1, 2, 3, 4}); printSortedSubSequenceOfSize3(new int[]{4, 3, 2, 1}); diff --git a/src/main/java/com/rampatra/arrays/SubArrayOfSum.java b/src/main/java/com/rampatra/arrays/SubArrayOfSum.java index 90cbcb29..4e4f5c2e 100644 --- a/src/main/java/com/rampatra/arrays/SubArrayOfSum.java +++ b/src/main/java/com/rampatra/arrays/SubArrayOfSum.java @@ -37,7 +37,7 @@ public static void printSubArrayOfSum(int[] a, int sum) { System.out.println("Sub-array with sum " + sum + " not found!"); } - public static void main(String a[]) { + public static void main(String[] args) { printSubArrayOfSum(new int[]{1, 4, 20, 3, 10, 5}, 33); printSubArrayOfSum(new int[]{1, 4, 20, 3, 10, 5}, 38); printSubArrayOfSum(new int[]{1, 4, 20, 3, 10, 5}, 13); diff --git a/src/main/java/com/rampatra/arrays/SubsetOfArray.java b/src/main/java/com/rampatra/arrays/SubsetOfArray.java index 6e6509fa..21d5ff2c 100644 --- a/src/main/java/com/rampatra/arrays/SubsetOfArray.java +++ b/src/main/java/com/rampatra/arrays/SubsetOfArray.java @@ -48,7 +48,7 @@ public static boolean isSubsetOfArray(int[] a, int[] b) { } } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(isSubsetOfArray(new int[]{11, 1, 13, 21, 3, 7}, new int[]{11, 3, 7, 1})); System.out.println(isSubsetOfArray(new int[]{1, 2, 2, 3, 4, 5, 6}, new int[]{1, 2, 4})); System.out.println(isSubsetOfArray(new int[]{1, 2, 2, 3, 4, 5, 6}, new int[]{1, 2, 2, 4})); diff --git a/src/main/java/com/rampatra/arrays/SymmetricDifference.java b/src/main/java/com/rampatra/arrays/SymmetricDifference.java index 4088489d..9ae00478 100644 --- a/src/main/java/com/rampatra/arrays/SymmetricDifference.java +++ b/src/main/java/com/rampatra/arrays/SymmetricDifference.java @@ -51,7 +51,7 @@ public static int[] getSymmetricDifference(int[] a1, int[] a2) { return Arrays.copyOf(res, index); } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(Arrays.toString(getSymmetricDifference(new int[]{1, 2, 3, 4}, new int[]{2, 4, 5}))); System.out.println(Arrays.toString(getSymmetricDifference(new int[]{1, 2, 3, 4}, new int[]{5, 6, 7}))); System.out.println(Arrays.toString(getSymmetricDifference(new int[]{1, 2, 3, 4}, new int[]{5, 6, 7, 8}))); diff --git a/src/main/java/com/rampatra/arrays/TripletOfSum.java b/src/main/java/com/rampatra/arrays/TripletOfSum.java index 81da24ed..91d47649 100644 --- a/src/main/java/com/rampatra/arrays/TripletOfSum.java +++ b/src/main/java/com/rampatra/arrays/TripletOfSum.java @@ -42,7 +42,7 @@ public static int[] getTripletOfSum(int[] a, int sum) { return new int[]{-1}; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(Arrays.toString(getTripletOfSum(new int[]{12, 3, 4, 5, 1, 6, 9}, 24))); System.out.println(Arrays.toString(getTripletOfSum(new int[]{12, 3, 4, 5, 1, 6, 9}, 19))); System.out.println(Arrays.toString(getTripletOfSum(new int[]{1, 2, 3}, 6))); diff --git a/src/main/java/com/rampatra/arrays/TwoElementsSumClosestToZero.java b/src/main/java/com/rampatra/arrays/TwoElementsSumClosestToZero.java index 7007218f..e41a0f92 100644 --- a/src/main/java/com/rampatra/arrays/TwoElementsSumClosestToZero.java +++ b/src/main/java/com/rampatra/arrays/TwoElementsSumClosestToZero.java @@ -39,7 +39,7 @@ public static int[] getTwoElementsWhoseSumIsClosestToZero(int[] a) { return new int[]{n1, n2}; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(Arrays.toString(getTwoElementsWhoseSumIsClosestToZero(new int[]{1, 60, -10, -80, 85, 70}))); System.out.println(Arrays.toString(getTwoElementsWhoseSumIsClosestToZero(new int[]{-3, -100, -10, -80, 85, 70}))); } diff --git a/src/main/java/com/rampatra/arrays/TwoRepeatingElements.java b/src/main/java/com/rampatra/arrays/TwoRepeatingElements.java index 21de8122..a943a532 100644 --- a/src/main/java/com/rampatra/arrays/TwoRepeatingElements.java +++ b/src/main/java/com/rampatra/arrays/TwoRepeatingElements.java @@ -88,7 +88,7 @@ public static int[] findTwoRepeatingElements(int[] a) { return repeatingElements; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(Arrays.toString(getTwoRepeatingElements(new int[]{4, 2, 4, 5, 2, 3, 1}))); System.out.println(Arrays.toString(getTwoRepeatingElements(new int[]{2, 4, 5, 2, 3, 1, 6, 7, 7}))); System.out.println(Arrays.toString(getTwoRepeatingElements(new int[]{1, 2, 1, 2}))); diff --git a/src/main/java/com/rampatra/arrays/TwoStacksInOneArray.java b/src/main/java/com/rampatra/arrays/TwoStacksInOneArray.java index 7025072e..b4e83806 100644 --- a/src/main/java/com/rampatra/arrays/TwoStacksInOneArray.java +++ b/src/main/java/com/rampatra/arrays/TwoStacksInOneArray.java @@ -70,7 +70,7 @@ void printStack(int stack) { } } - public static void main(String a[]) { + public static void main(String[] args) { TwoStacksInOneArray twoStack = new TwoStacksInOneArray(5); twoStack.push(1, 3); twoStack.push(1, 4); diff --git a/src/main/java/com/rampatra/arrays/UnsortedSubArray.java b/src/main/java/com/rampatra/arrays/UnsortedSubArray.java index 7f0c4de9..36aa4e12 100644 --- a/src/main/java/com/rampatra/arrays/UnsortedSubArray.java +++ b/src/main/java/com/rampatra/arrays/UnsortedSubArray.java @@ -89,7 +89,7 @@ public static int[] getUnsortedSubArray(int[] a) { return unsortedArray; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(Arrays.toString(getUnsortedSubArray(new int[]{10, 12, 20, 30, 25, 40, 32, 31, 35, 50, 60}))); System.out.println(Arrays.toString(getUnsortedSubArray(new int[]{0, 1, 15, 25, 6, 7, 30, 40, 50}))); System.out.println(Arrays.toString(getUnsortedSubArray(new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8}))); // fully sorted already diff --git a/src/main/java/com/rampatra/backtracking/KnightTour.java b/src/main/java/com/rampatra/backtracking/KnightTour.java index 9bd98afa..64b58918 100644 --- a/src/main/java/com/rampatra/backtracking/KnightTour.java +++ b/src/main/java/com/rampatra/backtracking/KnightTour.java @@ -105,7 +105,7 @@ public static void print2DMatrix(int[][] array) { } } - public static void main(String a[]) { + public static void main(String[] args) { printKnightTour(0, 0, new int[]{8, 8}); } } diff --git a/src/main/java/com/rampatra/backtracking/RatInAMaze.java b/src/main/java/com/rampatra/backtracking/RatInAMaze.java index 75163c08..bb8ea749 100644 --- a/src/main/java/com/rampatra/backtracking/RatInAMaze.java +++ b/src/main/java/com/rampatra/backtracking/RatInAMaze.java @@ -86,7 +86,7 @@ public static void print2DMatrix(int[][] array) { } } - public static void main(String a[]) { + public static void main(String[] args) { printMazePath(0, 0, new int[][]{{1, 1, 1, 1}, {0, 0, 1, 1}}); } } diff --git a/src/main/java/com/rampatra/base/BinaryTree.java b/src/main/java/com/rampatra/base/BinaryTree.java index 1b7c790f..e420d7c0 100644 --- a/src/main/java/com/rampatra/base/BinaryTree.java +++ b/src/main/java/com/rampatra/base/BinaryTree.java @@ -272,7 +272,7 @@ public void printValue(BinaryNode node) { } // test cases - public static void main(String[] a) { + public static void main(String[] args) { BinaryTree bt = new BinaryTree<>(); bt.put(1); bt.put(2); diff --git a/src/main/java/com/rampatra/base/Trie.java b/src/main/java/com/rampatra/base/Trie.java index c5c72278..608bd081 100644 --- a/src/main/java/com/rampatra/base/Trie.java +++ b/src/main/java/com/rampatra/base/Trie.java @@ -90,7 +90,7 @@ private class TrieNode { } // unit testing - public static void main(String[] a) { + public static void main(String[] args) { Trie trie = new Trie<>(); trie.insert("ram"); trie.insert("r"); diff --git a/src/main/java/com/rampatra/bits/AbsWithoutBranching.java b/src/main/java/com/rampatra/bits/AbsWithoutBranching.java index 5a57f20f..53973b6a 100644 --- a/src/main/java/com/rampatra/bits/AbsWithoutBranching.java +++ b/src/main/java/com/rampatra/bits/AbsWithoutBranching.java @@ -28,7 +28,7 @@ public static int abs(int n) { return (mask + n) ^ mask; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(abs(-5)); System.out.println(abs(5)); System.out.println(abs(0)); diff --git a/src/main/java/com/rampatra/bits/Addition.java b/src/main/java/com/rampatra/bits/Addition.java index 16d9f121..c120ecaa 100644 --- a/src/main/java/com/rampatra/bits/Addition.java +++ b/src/main/java/com/rampatra/bits/Addition.java @@ -95,7 +95,7 @@ public static int addByFlip(int n) { return n ^ mask; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(add(0, 0)); //0 System.out.println(add(12, 12)); //24 System.out.println(add(12, 5)); //17 diff --git a/src/main/java/com/rampatra/bits/BooleanArrayPuzzle.java b/src/main/java/com/rampatra/bits/BooleanArrayPuzzle.java index 5ea254d1..d3d87feb 100644 --- a/src/main/java/com/rampatra/bits/BooleanArrayPuzzle.java +++ b/src/main/java/com/rampatra/bits/BooleanArrayPuzzle.java @@ -23,7 +23,7 @@ public static int[] change1To0InArray(int a[]) { return a; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(Arrays.toString(change1To0InArray(new int[]{0, 0}))); System.out.println(Arrays.toString(change1To0InArray(new int[]{0, 1}))); System.out.println(Arrays.toString(change1To0InArray(new int[]{1, 0}))); diff --git a/src/main/java/com/rampatra/bits/ConvertAToB.java b/src/main/java/com/rampatra/bits/ConvertAToB.java index 5d584a0d..07c162b8 100644 --- a/src/main/java/com/rampatra/bits/ConvertAToB.java +++ b/src/main/java/com/rampatra/bits/ConvertAToB.java @@ -21,7 +21,7 @@ public static int getBitsToConvertAToB(int a, int b) { return CountSetBits.countSetBits(a ^ b); } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(getBitsToConvertAToB(3, 4)); System.out.println(getBitsToConvertAToB(3, 5)); System.out.println(getBitsToConvertAToB(5, 3)); diff --git a/src/main/java/com/rampatra/bits/CountSetBits.java b/src/main/java/com/rampatra/bits/CountSetBits.java index 29b71006..a2296e6e 100644 --- a/src/main/java/com/rampatra/bits/CountSetBits.java +++ b/src/main/java/com/rampatra/bits/CountSetBits.java @@ -48,7 +48,7 @@ static int countSetBits(long n) { return count; } - public static void main(String[] a) { + public static void main(String[] args) { Scanner in = new Scanner(System.in); long n = Long.parseLong(in.nextLine()); diff --git a/src/main/java/com/rampatra/bits/CountSetBitsFromMinusNtoN.java b/src/main/java/com/rampatra/bits/CountSetBitsFromMinusNtoN.java index a4aea0ab..a0aeb5e0 100644 --- a/src/main/java/com/rampatra/bits/CountSetBitsFromMinusNtoN.java +++ b/src/main/java/com/rampatra/bits/CountSetBitsFromMinusNtoN.java @@ -30,7 +30,7 @@ public static int countSetBitsFromMinusNtoN(int n) { return n * 32 + CountSetBits.countSetBits((long) n); // 32 because int is of 32 bits in java } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(countSetBitsFromMinusNtoN(3)); System.out.println(countSetBitsFromMinusNtoN(0)); System.out.println(countSetBitsFromMinusNtoN(9)); diff --git a/src/main/java/com/rampatra/bits/ElementOccurringOnce.java b/src/main/java/com/rampatra/bits/ElementOccurringOnce.java index 10dbf390..4621209c 100644 --- a/src/main/java/com/rampatra/bits/ElementOccurringOnce.java +++ b/src/main/java/com/rampatra/bits/ElementOccurringOnce.java @@ -30,7 +30,7 @@ public static int getElementOccurringOnceInElementsRepeatedThreeTimes(int a[]) { return result; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(getElementOccurringOnceInElementsRepeatedThreeTimes(new int[]{12, 12, 6, 6, 2, 12, 6})); System.out.println(getElementOccurringOnceInElementsRepeatedThreeTimes(new int[]{5, 5, 45, 45, 456, 5, 45})); System.out.println(getElementOccurringOnceInElementsRepeatedThreeTimes(new int[]{12, 12, 34, 34, 6, 12, 34})); diff --git a/src/main/java/com/rampatra/bits/FlippingBits.java b/src/main/java/com/rampatra/bits/FlippingBits.java index 5a81b3be..48c891ad 100644 --- a/src/main/java/com/rampatra/bits/FlippingBits.java +++ b/src/main/java/com/rampatra/bits/FlippingBits.java @@ -31,7 +31,7 @@ public static int getNumberByFlippingBits_V1(int n) { return ~n; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(getNumberByFlippingBits(5)); System.out.println(getNumberByFlippingBits_V1(5)); } diff --git a/src/main/java/com/rampatra/bits/IntegerOverflow.java b/src/main/java/com/rampatra/bits/IntegerOverflow.java index 4c7478ba..6d214ac8 100644 --- a/src/main/java/com/rampatra/bits/IntegerOverflow.java +++ b/src/main/java/com/rampatra/bits/IntegerOverflow.java @@ -43,7 +43,7 @@ public static int add_V1(int a, int b) throws Exception { } } - public static void main(String a[]) { + public static void main(String[] args) { try { System.out.println(add(2, 3)); System.out.println(add(2147483647, 999999999)); diff --git a/src/main/java/com/rampatra/bits/LittleAndBigEndian.java b/src/main/java/com/rampatra/bits/LittleAndBigEndian.java index 2bef8259..86ca46e9 100644 --- a/src/main/java/com/rampatra/bits/LittleAndBigEndian.java +++ b/src/main/java/com/rampatra/bits/LittleAndBigEndian.java @@ -16,7 +16,7 @@ public static boolean isLittleEndian() { return ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN); } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(isLittleEndian()); } } diff --git a/src/main/java/com/rampatra/bits/MaxWithoutBranching.java b/src/main/java/com/rampatra/bits/MaxWithoutBranching.java index 12c77e4c..f2669829 100644 --- a/src/main/java/com/rampatra/bits/MaxWithoutBranching.java +++ b/src/main/java/com/rampatra/bits/MaxWithoutBranching.java @@ -18,7 +18,7 @@ public static int getMaxWithoutBranching(int a, int b) { return a ^ ((a ^ b) & -((a < b) ? 1 : 0)); } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(getMinWithoutBranching(5, 6)); System.out.println(getMinWithoutBranching(-5, -6)); System.out.println(getMinWithoutBranching(-5, 6)); diff --git a/src/main/java/com/rampatra/bits/Modulo.java b/src/main/java/com/rampatra/bits/Modulo.java index d7141751..d220f3a8 100644 --- a/src/main/java/com/rampatra/bits/Modulo.java +++ b/src/main/java/com/rampatra/bits/Modulo.java @@ -21,7 +21,7 @@ public static int getNmoduloD(int n, int d) { return n & (d - 1); } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(getNmoduloD(18, 8)); System.out.println(getNmoduloD(18, 4)); System.out.println(getNmoduloD(13, 4)); diff --git a/src/main/java/com/rampatra/bits/MultipleOf3.java b/src/main/java/com/rampatra/bits/MultipleOf3.java index 1909c5ee..87af5c1d 100644 --- a/src/main/java/com/rampatra/bits/MultipleOf3.java +++ b/src/main/java/com/rampatra/bits/MultipleOf3.java @@ -39,7 +39,7 @@ public static boolean isMultipleOf3(long n) { } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(isMultipleOf3(0)); System.out.println(isMultipleOf3(1)); System.out.println(isMultipleOf3(2)); diff --git a/src/main/java/com/rampatra/bits/Multiply.java b/src/main/java/com/rampatra/bits/Multiply.java index 22256cd0..edc2e421 100644 --- a/src/main/java/com/rampatra/bits/Multiply.java +++ b/src/main/java/com/rampatra/bits/Multiply.java @@ -60,7 +60,7 @@ public static long multiplyWith8(long n) { return (n << 3); } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(multiplyWith3point5(3)); System.out.println(multiplyWith3point5(4)); System.out.println(multiplyWith3point5(6)); diff --git a/src/main/java/com/rampatra/bits/NextHigherNumber.java b/src/main/java/com/rampatra/bits/NextHigherNumber.java index 45cf86e5..444dcf99 100644 --- a/src/main/java/com/rampatra/bits/NextHigherNumber.java +++ b/src/main/java/com/rampatra/bits/NextHigherNumber.java @@ -47,7 +47,7 @@ public static int getNextHigherNumberWithSameSetBits(int n) { return (n << count) | (leftPattern << count) | (rightPattern >> 1); } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(getNextHigherNumberWithSameSetBits(0));//doesn't work for 0 System.out.println(getNextHigherNumberWithSameSetBits(4));//8 System.out.println(getNextHigherNumberWithSameSetBits(5));//6 diff --git a/src/main/java/com/rampatra/bits/NextPowerOf2.java b/src/main/java/com/rampatra/bits/NextPowerOf2.java index d5a24977..44c04491 100644 --- a/src/main/java/com/rampatra/bits/NextPowerOf2.java +++ b/src/main/java/com/rampatra/bits/NextPowerOf2.java @@ -100,7 +100,7 @@ public static long nextLowerPowerOf2(long n) { return (n > 1) ? p >> 1 : n; // check for n = 0 or 1; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(nextHigherPowerOf2(2)); System.out.println(nextHigherPowerOf2(3)); diff --git a/src/main/java/com/rampatra/bits/OppositeSign.java b/src/main/java/com/rampatra/bits/OppositeSign.java index 1388567e..919d2137 100644 --- a/src/main/java/com/rampatra/bits/OppositeSign.java +++ b/src/main/java/com/rampatra/bits/OppositeSign.java @@ -13,7 +13,7 @@ public static int isOppositeSign(int a, int b) { return (a ^ b) >>> 31; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(isOppositeSign(-5, -3)); System.out.println(isOppositeSign(-5, 3)); System.out.println(isOppositeSign(5, -3)); diff --git a/src/main/java/com/rampatra/bits/Parity.java b/src/main/java/com/rampatra/bits/Parity.java index 2b0e0450..673ba5b3 100644 --- a/src/main/java/com/rampatra/bits/Parity.java +++ b/src/main/java/com/rampatra/bits/Parity.java @@ -54,7 +54,7 @@ public static boolean isEvenParityByCountingSetBits(long n) { return setBitsCount % 2 == 0; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(isEvenParity(0)); System.out.println(isEvenParity(1)); System.out.println(isEvenParity(5)); diff --git a/src/main/java/com/rampatra/bits/PowerOf2.java b/src/main/java/com/rampatra/bits/PowerOf2.java index 9bffe86f..04a1d9dd 100644 --- a/src/main/java/com/rampatra/bits/PowerOf2.java +++ b/src/main/java/com/rampatra/bits/PowerOf2.java @@ -40,7 +40,7 @@ public static boolean isPowerOf2FromRandomClass(long n) { return n != 0 && (n & -n) == n; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(isPowerOf2(18)); System.out.println(isPowerOf2UsingANDoperator(18)); System.out.println(isPowerOf2FromRandomClass(18)); diff --git a/src/main/java/com/rampatra/bits/PowerOf4.java b/src/main/java/com/rampatra/bits/PowerOf4.java index a51474c3..5b75c4a2 100644 --- a/src/main/java/com/rampatra/bits/PowerOf4.java +++ b/src/main/java/com/rampatra/bits/PowerOf4.java @@ -31,7 +31,7 @@ public static boolean isPowerOf4(int n) { return false; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(isPowerOf4(0)); System.out.println(isPowerOf4(1)); System.out.println(isPowerOf4(4)); diff --git a/src/main/java/com/rampatra/bits/ReverseBits.java b/src/main/java/com/rampatra/bits/ReverseBits.java index 4c172530..04f8cc3b 100644 --- a/src/main/java/com/rampatra/bits/ReverseBits.java +++ b/src/main/java/com/rampatra/bits/ReverseBits.java @@ -82,7 +82,7 @@ public static int getNumberByReversingBitsV2(int n) { return reverse; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(getNumberByReversingBits(79876)); System.out.println(getNumberByReversingBitsV1(79876)); System.out.println(getNumberByReversingBitsV2(79876)); diff --git a/src/main/java/com/rampatra/bits/RightShiftOperator.java b/src/main/java/com/rampatra/bits/RightShiftOperator.java index 74774e1b..3eafd7b6 100644 --- a/src/main/java/com/rampatra/bits/RightShiftOperator.java +++ b/src/main/java/com/rampatra/bits/RightShiftOperator.java @@ -11,7 +11,7 @@ */ public class RightShiftOperator { - public static void main(String a[]) { + public static void main(String[] args) { int n = -4; System.out.printf("n: %32d\n", n); System.out.printf("n: %32s\n", Integer.toBinaryString(n)); @@ -44,4 +44,4 @@ public static void main(String a[]) { System.out.printf("n>>2: %32s\n", Integer.toBinaryString(n >> 2)); System.out.printf("n>>>2: %32s\n", Integer.toBinaryString(n >>> 2)); } -} +} \ No newline at end of file diff --git a/src/main/java/com/rampatra/bits/RightmostSetBit.java b/src/main/java/com/rampatra/bits/RightmostSetBit.java index aeef4fb4..1916ed64 100644 --- a/src/main/java/com/rampatra/bits/RightmostSetBit.java +++ b/src/main/java/com/rampatra/bits/RightmostSetBit.java @@ -34,7 +34,7 @@ public static long unsetRightmostSetBit(long n) { return n & (n - 1); // brian kerningham's algorithm } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(getRightmostSetBitPosition(0)); System.out.println(getRightmostSetBitPosition(1)); System.out.println(getRightmostSetBitPosition(2)); diff --git a/src/main/java/com/rampatra/bits/RotateBits.java b/src/main/java/com/rampatra/bits/RotateBits.java index 626fba35..9712b028 100644 --- a/src/main/java/com/rampatra/bits/RotateBits.java +++ b/src/main/java/com/rampatra/bits/RotateBits.java @@ -25,7 +25,7 @@ public static int rightRotateBits(int n, int times) { return n >>> times | n << (32 - times); } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(leftRotateBits(5, 3)); System.out.println(leftRotateBits(234324, 3)); System.out.println(rightRotateBits(5, 3)); diff --git a/src/main/java/com/rampatra/bits/SmallestOf3Integers.java b/src/main/java/com/rampatra/bits/SmallestOf3Integers.java index 32851402..63e542a9 100644 --- a/src/main/java/com/rampatra/bits/SmallestOf3Integers.java +++ b/src/main/java/com/rampatra/bits/SmallestOf3Integers.java @@ -50,7 +50,7 @@ public static int getSmallest_V1(int a[]) { return c; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(getSmallest(new int[]{4, 5, 6})); System.out.println(getSmallest_V1(new int[]{4, 5, 6})); } diff --git a/src/main/java/com/rampatra/bits/StrCmp.java b/src/main/java/com/rampatra/bits/StrCmp.java index b0f9095c..4b1be36f 100644 --- a/src/main/java/com/rampatra/bits/StrCmp.java +++ b/src/main/java/com/rampatra/bits/StrCmp.java @@ -48,7 +48,7 @@ public static int compareStringIgnoreCase(String s1, String s2) { return n1 - n2; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(compareStringIgnoreCase("ram", "ram")); System.out.println(compareStringIgnoreCase("ram", "Ram")); System.out.println(compareStringIgnoreCase("", "")); diff --git a/src/main/java/com/rampatra/bits/SubBit.java b/src/main/java/com/rampatra/bits/SubBit.java index 8c324b36..f91a4dd8 100644 --- a/src/main/java/com/rampatra/bits/SubBit.java +++ b/src/main/java/com/rampatra/bits/SubBit.java @@ -22,7 +22,7 @@ public static int getNumberFromSubBits(int num, int start, int end) { return num << (32 - end) >>> (start - end + 31); // more intuitive (start - 1 + 32 - end) } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(getNumberFromSubBits(5, 1, 2)); } } diff --git a/src/main/java/com/rampatra/bits/SwapBits.java b/src/main/java/com/rampatra/bits/SwapBits.java index 3fbaa5a0..40fbb613 100644 --- a/src/main/java/com/rampatra/bits/SwapBits.java +++ b/src/main/java/com/rampatra/bits/SwapBits.java @@ -71,7 +71,7 @@ public static int swapBitRangeInNumber(int n, int pos1, int pos2, int length) { // (this logic is similar to swapping bits using XOR) } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(swapEvenOddBits(23)); System.out.println(swapEvenOddBits(0)); System.out.println(swapEvenOddBits(5)); diff --git a/src/main/java/com/rampatra/bits/TwoNonRepeatingElements.java b/src/main/java/com/rampatra/bits/TwoNonRepeatingElements.java index 2058a033..a3b47f08 100644 --- a/src/main/java/com/rampatra/bits/TwoNonRepeatingElements.java +++ b/src/main/java/com/rampatra/bits/TwoNonRepeatingElements.java @@ -36,7 +36,7 @@ public static int[] getTwoNonRepeatingElementsInArray(int a[]) { return new int[]{x, y}; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(Arrays.toString(getTwoNonRepeatingElementsInArray(new int[]{2, 3, 4, 2, 3, 4, 5, 6}))); } } diff --git a/src/main/java/com/rampatra/dynamicprogramming/FibonacciNumbers.java b/src/main/java/com/rampatra/dynamicprogramming/FibonacciNumbers.java index c17a315c..17483cbf 100644 --- a/src/main/java/com/rampatra/dynamicprogramming/FibonacciNumbers.java +++ b/src/main/java/com/rampatra/dynamicprogramming/FibonacciNumbers.java @@ -34,7 +34,7 @@ public static int[] getFirstKFibonacciNumbers(int k) { return fib; } - public static void main(String[] a) { + public static void main(String[] args) { out.println(Arrays.toString(getFirstKFibonacciNumbers(0))); out.println(Arrays.toString(getFirstKFibonacciNumbers(10))); out.println(Arrays.toString(getFirstKFibonacciNumbers(46))); diff --git a/src/main/java/com/rampatra/dynamicprogramming/LongestIncreasingSubSequence.java b/src/main/java/com/rampatra/dynamicprogramming/LongestIncreasingSubSequence.java index bc9a544e..4521b4fa 100644 --- a/src/main/java/com/rampatra/dynamicprogramming/LongestIncreasingSubSequence.java +++ b/src/main/java/com/rampatra/dynamicprogramming/LongestIncreasingSubSequence.java @@ -53,7 +53,7 @@ public static int getLongestIncreasingSubSequenceLength(int[] a) { return maxLisLength; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(getLongestIncreasingSubSequenceLength(new int[]{2, 3, 7, 8, 15})); System.out.println(getLongestIncreasingSubSequenceLength(new int[]{2, 20, 7, 8, 1})); System.out.println(getLongestIncreasingSubSequenceLength(new int[]{20, 10, 5})); diff --git a/src/main/java/com/rampatra/dynamicprogramming/MinimumJumpsToReachEnd.java b/src/main/java/com/rampatra/dynamicprogramming/MinimumJumpsToReachEnd.java index f4e8bea1..bbc6a40f 100644 --- a/src/main/java/com/rampatra/dynamicprogramming/MinimumJumpsToReachEnd.java +++ b/src/main/java/com/rampatra/dynamicprogramming/MinimumJumpsToReachEnd.java @@ -43,7 +43,7 @@ public static int getMinimumJumpsToReachEndNaive(int[] a, int l, int h) { // TODO dp approach - public static void main(String a[]) { + public static void main(String[] args) { int[] ar = new int[]{1, 3, 5, 8, 9, 2, 6, 7, 6, 8, 9}; System.out.println(getMinimumJumpsToReachEndNaive(ar, 0, ar.length - 1)); ar = new int[]{5, 4, 3, 2, 1}; diff --git a/src/main/java/com/rampatra/java8/FlatMapInStreams.java b/src/main/java/com/rampatra/java8/FlatMapInStreams.java index 193e7a4f..996830f5 100644 --- a/src/main/java/com/rampatra/java8/FlatMapInStreams.java +++ b/src/main/java/com/rampatra/java8/FlatMapInStreams.java @@ -14,7 +14,7 @@ public static long countTotalIngredientsInAllDishes(List dishes) { return dishes.stream().map(Dish::getIngredients).flatMap(List::stream).count(); } - public static void main(String[] a) { + public static void main(String[] args) { List ingredients = new ArrayList<>(); ingredients.add("rice"); ingredients.add("chicken"); diff --git a/src/main/java/com/rampatra/java8/Lambdas.java b/src/main/java/com/rampatra/java8/Lambdas.java index 1921beba..2450d80c 100644 --- a/src/main/java/com/rampatra/java8/Lambdas.java +++ b/src/main/java/com/rampatra/java8/Lambdas.java @@ -14,7 +14,7 @@ public void testScopeOfLambda(Consumer consumer) { consumer.accept("Lambda"); } - public static void main(String[] a) { + public static void main(String[] args) { Lambdas l = new Lambdas(); l.testScopeOfLambda(x -> System.out.println(x)); l.testScopeOfLambda(x -> System.out.println(x + l.a)); diff --git a/src/main/java/com/rampatra/java8/Streams.java b/src/main/java/com/rampatra/java8/Streams.java index ceb160f3..8376b503 100644 --- a/src/main/java/com/rampatra/java8/Streams.java +++ b/src/main/java/com/rampatra/java8/Streams.java @@ -135,7 +135,7 @@ public static Transaction getSmallestTransaction() { .get(); } - public static void main(String[] a) { + public static void main(String[] args) { System.out.println("1: " + getTransactionsIn2011SortedByValue()); System.out.println("2: " + findUniqueCities()); System.out.println("3: " + getAllTradersFromCambridgeAndSortByName()); diff --git a/src/main/java/com/rampatra/linkedlists/AddNumbersInTwoLists.java b/src/main/java/com/rampatra/linkedlists/AddNumbersInTwoLists.java index d3ed31ab..e32e3336 100644 --- a/src/main/java/com/rampatra/linkedlists/AddNumbersInTwoLists.java +++ b/src/main/java/com/rampatra/linkedlists/AddNumbersInTwoLists.java @@ -129,7 +129,7 @@ private static int convertToInt(SingleLinkedList list) { return num; } - public static void main(String a[]) { + public static void main(String[] args) { SingleLinkedList linkedList1 = new SingleLinkedList<>(); linkedList1.add(7); linkedList1.add(5); diff --git a/src/main/java/com/rampatra/linkedlists/CloneWithRandPointers.java b/src/main/java/com/rampatra/linkedlists/CloneWithRandPointers.java index ecdb2849..c6f69bbd 100644 --- a/src/main/java/com/rampatra/linkedlists/CloneWithRandPointers.java +++ b/src/main/java/com/rampatra/linkedlists/CloneWithRandPointers.java @@ -53,7 +53,7 @@ public static > DoubleLinkedList clone(DoubleLinkedLi return DoubleLinkedList.getLinkedList(cloneHead); } - public static void main(String a[]) { + public static void main(String[] args) { DoubleLinkedList linkedList = new DoubleLinkedList<>(); linkedList.add(00); linkedList.add(11); diff --git a/src/main/java/com/rampatra/linkedlists/DeleteAlternateNodes.java b/src/main/java/com/rampatra/linkedlists/DeleteAlternateNodes.java index d6bf4e8f..6a8c21d2 100644 --- a/src/main/java/com/rampatra/linkedlists/DeleteAlternateNodes.java +++ b/src/main/java/com/rampatra/linkedlists/DeleteAlternateNodes.java @@ -24,7 +24,7 @@ public static > void deleteAlternateNodes(SingleLinkedNo deleteAlternateNodes(node.next); } - public static void main(String a[]) { + public static void main(String[] args) { SingleLinkedList linkedList = new SingleLinkedList<>(); linkedList.add(00); linkedList.add(11); diff --git a/src/main/java/com/rampatra/linkedlists/DeleteLesserNodes.java b/src/main/java/com/rampatra/linkedlists/DeleteLesserNodes.java index dae9ed02..0dbc734a 100644 --- a/src/main/java/com/rampatra/linkedlists/DeleteLesserNodes.java +++ b/src/main/java/com/rampatra/linkedlists/DeleteLesserNodes.java @@ -76,7 +76,7 @@ public static > SingleLinkedNode deleteLesserNodes(Si } } - public static void main(String a[]) { + public static void main(String[] args) { SingleLinkedList linkedList = new SingleLinkedList<>(); linkedList.add(00); linkedList.add(11); diff --git a/src/main/java/com/rampatra/linkedlists/DeleteMnodesAfterNnodes.java b/src/main/java/com/rampatra/linkedlists/DeleteMnodesAfterNnodes.java index 74b23927..005aef06 100644 --- a/src/main/java/com/rampatra/linkedlists/DeleteMnodesAfterNnodes.java +++ b/src/main/java/com/rampatra/linkedlists/DeleteMnodesAfterNnodes.java @@ -44,7 +44,7 @@ public static > void deleteMnodesAfterNnodes(SingleLinke } } - public static void main(String a[]) { + public static void main(String[] args) { SingleLinkedList linkedList = new SingleLinkedList<>(); linkedList.add(7); linkedList.add(5); diff --git a/src/main/java/com/rampatra/linkedlists/DeleteNode.java b/src/main/java/com/rampatra/linkedlists/DeleteNode.java index d9b0bc78..82d8c3d7 100644 --- a/src/main/java/com/rampatra/linkedlists/DeleteNode.java +++ b/src/main/java/com/rampatra/linkedlists/DeleteNode.java @@ -24,7 +24,7 @@ public static > void deleteNode(SingleLinkedNode node node.next = node.next.next; } - public static void main(String[] a) { + public static void main(String[] args) { SingleLinkedList linkedList = new SingleLinkedList<>(); linkedList.add(0); linkedList.add(1); diff --git a/src/main/java/com/rampatra/linkedlists/DetectAndRemoveLoop.java b/src/main/java/com/rampatra/linkedlists/DetectAndRemoveLoop.java index 3be3c3c5..63faa3be 100644 --- a/src/main/java/com/rampatra/linkedlists/DetectAndRemoveLoop.java +++ b/src/main/java/com/rampatra/linkedlists/DetectAndRemoveLoop.java @@ -70,7 +70,7 @@ public static > boolean detectAndRemoveLoop(SingleLinked return isLoopPresent; } - public static void main(String a[]) { + public static void main(String[] args) { SingleLinkedList linkedList = new SingleLinkedList<>(); linkedList.add(00); linkedList.add(11); diff --git a/src/main/java/com/rampatra/linkedlists/DetectLoop.java b/src/main/java/com/rampatra/linkedlists/DetectLoop.java index d6696e23..ad9d13c0 100644 --- a/src/main/java/com/rampatra/linkedlists/DetectLoop.java +++ b/src/main/java/com/rampatra/linkedlists/DetectLoop.java @@ -64,7 +64,7 @@ public static > boolean isLoopPresentUsingHashMap(Single return false; } - public static void main(String a[]) { + public static void main(String[] args) { SingleLinkedList linkedList = new SingleLinkedList<>(); linkedList.add(0); linkedList.add(1); diff --git a/src/main/java/com/rampatra/linkedlists/DivideCircularListIntoTwo.java b/src/main/java/com/rampatra/linkedlists/DivideCircularListIntoTwo.java index f955c18a..b19af007 100644 --- a/src/main/java/com/rampatra/linkedlists/DivideCircularListIntoTwo.java +++ b/src/main/java/com/rampatra/linkedlists/DivideCircularListIntoTwo.java @@ -24,7 +24,7 @@ public static > CircularSingleLinkedList[] divideIntoTwo return new CircularSingleLinkedList[]{getLinkedList(list.head), getLinkedList(secondHead)}; } - public static void main(String a[]) { + public static void main(String[] args) { CircularSingleLinkedList linkedList = new CircularSingleLinkedList<>(); linkedList.add(00); linkedList.add(11); diff --git a/src/main/java/com/rampatra/linkedlists/FlattenMultiLevelLinkedList.java b/src/main/java/com/rampatra/linkedlists/FlattenMultiLevelLinkedList.java index 480c999d..5f9434ed 100644 --- a/src/main/java/com/rampatra/linkedlists/FlattenMultiLevelLinkedList.java +++ b/src/main/java/com/rampatra/linkedlists/FlattenMultiLevelLinkedList.java @@ -78,7 +78,7 @@ public static > void printList(DoubleLinkedNode node) out.println(curr.item.toString() + "]"); } - public static void main(String a[]) { + public static void main(String[] args) { // 1st level DoubleLinkedNode head = new DoubleLinkedNode<>(1); head.next = new DoubleLinkedNode<>(5); diff --git a/src/main/java/com/rampatra/linkedlists/Identical.java b/src/main/java/com/rampatra/linkedlists/Identical.java index aa760b47..a4aa0d1c 100644 --- a/src/main/java/com/rampatra/linkedlists/Identical.java +++ b/src/main/java/com/rampatra/linkedlists/Identical.java @@ -44,7 +44,7 @@ private static > boolean isIdentical(SingleLinkedList return true; } - public static void main(String[] a) { + public static void main(String[] args) { SingleLinkedList linkedList1 = new SingleLinkedList<>(); linkedList1.add(0); linkedList1.add(1); diff --git a/src/main/java/com/rampatra/linkedlists/InsertInSortedCircularLinkedList.java b/src/main/java/com/rampatra/linkedlists/InsertInSortedCircularLinkedList.java index f5b07d9f..a04b48bc 100644 --- a/src/main/java/com/rampatra/linkedlists/InsertInSortedCircularLinkedList.java +++ b/src/main/java/com/rampatra/linkedlists/InsertInSortedCircularLinkedList.java @@ -41,7 +41,7 @@ public void insert(E item) { } while (node != head); } - public static void main(String a[]) { + public static void main(String[] args) { InsertInSortedCircularLinkedList linkedList = new InsertInSortedCircularLinkedList<>(); linkedList.add(00); linkedList.add(11); diff --git a/src/main/java/com/rampatra/linkedlists/InsertInSortedList.java b/src/main/java/com/rampatra/linkedlists/InsertInSortedList.java index 77488a2c..fc0bd2b1 100644 --- a/src/main/java/com/rampatra/linkedlists/InsertInSortedList.java +++ b/src/main/java/com/rampatra/linkedlists/InsertInSortedList.java @@ -33,7 +33,7 @@ public void insert(E item) { } } - public static void main(String a[]) { + public static void main(String[] args) { InsertInSortedList linkedList = new InsertInSortedList<>(); linkedList.add(00); linkedList.add(11); diff --git a/src/main/java/com/rampatra/linkedlists/IntersectionAndUnionOf2Lists.java b/src/main/java/com/rampatra/linkedlists/IntersectionAndUnionOf2Lists.java index 42301f2d..f8fd3a79 100644 --- a/src/main/java/com/rampatra/linkedlists/IntersectionAndUnionOf2Lists.java +++ b/src/main/java/com/rampatra/linkedlists/IntersectionAndUnionOf2Lists.java @@ -53,7 +53,7 @@ public static > SingleLinkedList[] getIntersectionAnd return new SingleLinkedList[]{intersectionList, unionList}; } - public static void main(String a[]) { + public static void main(String[] args) { SingleLinkedList linkedList1 = new SingleLinkedList<>(); linkedList1.add(00); linkedList1.add(11); diff --git a/src/main/java/com/rampatra/linkedlists/IntersectionOf2SortedLists.java b/src/main/java/com/rampatra/linkedlists/IntersectionOf2SortedLists.java index bc7575ce..0213a3b9 100644 --- a/src/main/java/com/rampatra/linkedlists/IntersectionOf2SortedLists.java +++ b/src/main/java/com/rampatra/linkedlists/IntersectionOf2SortedLists.java @@ -42,7 +42,7 @@ public static > SingleLinkedList getIntersectionList( return intersectedList; } - public static void main(String a[]) { + public static void main(String[] args) { SingleLinkedList linkedList1 = new SingleLinkedList<>(); linkedList1.add(00); linkedList1.add(11); diff --git a/src/main/java/com/rampatra/linkedlists/IntersectionPointOfTwoLists.java b/src/main/java/com/rampatra/linkedlists/IntersectionPointOfTwoLists.java index d55e5336..705da489 100644 --- a/src/main/java/com/rampatra/linkedlists/IntersectionPointOfTwoLists.java +++ b/src/main/java/com/rampatra/linkedlists/IntersectionPointOfTwoLists.java @@ -50,7 +50,7 @@ public static > SingleLinkedNode getIntersectionNode( return null; } - public static void main(String[] a) { + public static void main(String[] args) { SingleLinkedList linkedList1 = new SingleLinkedList<>(); linkedList1.add(0); linkedList1.add(1); diff --git a/src/main/java/com/rampatra/linkedlists/LRUCache.java b/src/main/java/com/rampatra/linkedlists/LRUCache.java index 730c710e..5a8d12f1 100644 --- a/src/main/java/com/rampatra/linkedlists/LRUCache.java +++ b/src/main/java/com/rampatra/linkedlists/LRUCache.java @@ -47,7 +47,7 @@ private void print() { } } - public static void main(String[] a) { + public static void main(String[] args) { LRUCache cache = new LRUCache<>(3); cache.add(1, 1); cache.add(2, 2); diff --git a/src/main/java/com/rampatra/linkedlists/MaximumSumLinkedList.java b/src/main/java/com/rampatra/linkedlists/MaximumSumLinkedList.java index fe5db9cd..cb51fe73 100644 --- a/src/main/java/com/rampatra/linkedlists/MaximumSumLinkedList.java +++ b/src/main/java/com/rampatra/linkedlists/MaximumSumLinkedList.java @@ -75,7 +75,7 @@ public static > SingleLinkedNode maximumSumLinkedList return head; } - public static void main(String[] a) { + public static void main(String[] args) { SingleLinkedList linkedList1 = new SingleLinkedList<>(); linkedList1.add(00); linkedList1.add(11); diff --git a/src/main/java/com/rampatra/linkedlists/MergeSort.java b/src/main/java/com/rampatra/linkedlists/MergeSort.java index daaa4663..3ad4ad65 100644 --- a/src/main/java/com/rampatra/linkedlists/MergeSort.java +++ b/src/main/java/com/rampatra/linkedlists/MergeSort.java @@ -111,7 +111,7 @@ public static > SingleLinkedNode mergeTwoSortedLists( return head.next; } - public static void main(String[] a) { + public static void main(String[] args) { SingleLinkedList linkedList = new SingleLinkedList<>(); linkedList.add(21); linkedList.add(33); diff --git a/src/main/java/com/rampatra/linkedlists/MergeSortDoubleLinkedList.java b/src/main/java/com/rampatra/linkedlists/MergeSortDoubleLinkedList.java index 9637430a..1adab868 100644 --- a/src/main/java/com/rampatra/linkedlists/MergeSortDoubleLinkedList.java +++ b/src/main/java/com/rampatra/linkedlists/MergeSortDoubleLinkedList.java @@ -117,7 +117,7 @@ public static > DoubleLinkedNode mergeTwoSortedLists( return head.next; } - public static void main(String a[]) { + public static void main(String[] args) { DoubleLinkedList linkedList = new DoubleLinkedList<>(); linkedList.add(21); linkedList.add(33); diff --git a/src/main/java/com/rampatra/linkedlists/MergeTwoLinkedListAlternatively.java b/src/main/java/com/rampatra/linkedlists/MergeTwoLinkedListAlternatively.java index 14777e7e..e94c08e8 100644 --- a/src/main/java/com/rampatra/linkedlists/MergeTwoLinkedListAlternatively.java +++ b/src/main/java/com/rampatra/linkedlists/MergeTwoLinkedListAlternatively.java @@ -49,7 +49,7 @@ public static > SingleLinkedNode mergeTwoLinkedListAl } - public static void main(String a[]) { + public static void main(String[] args) { SingleLinkedList linkedList1 = new SingleLinkedList<>(); linkedList1.add(00); linkedList1.add(11); diff --git a/src/main/java/com/rampatra/linkedlists/MergeTwoSortedLists.java b/src/main/java/com/rampatra/linkedlists/MergeTwoSortedLists.java index 23f646f2..1c4eaf93 100644 --- a/src/main/java/com/rampatra/linkedlists/MergeTwoSortedLists.java +++ b/src/main/java/com/rampatra/linkedlists/MergeTwoSortedLists.java @@ -95,7 +95,7 @@ public static > SingleLinkedNode mergeTwoSortedLists( } } - public static void main(String a[]) { + public static void main(String[] args) { SingleLinkedList linkedList1 = new SingleLinkedList<>(); linkedList1.add(00); linkedList1.add(11); diff --git a/src/main/java/com/rampatra/linkedlists/MiddleNode.java b/src/main/java/com/rampatra/linkedlists/MiddleNode.java index 706d1415..72318998 100644 --- a/src/main/java/com/rampatra/linkedlists/MiddleNode.java +++ b/src/main/java/com/rampatra/linkedlists/MiddleNode.java @@ -20,7 +20,7 @@ public static > SingleLinkedNode getMiddleNode(Single return slow; } - public static void main(String a[]) { + public static void main(String[] args) { SingleLinkedList linkedList = new SingleLinkedList<>(); linkedList.add(00); linkedList.add(11); diff --git a/src/main/java/com/rampatra/linkedlists/MoveLastNodeToFirst.java b/src/main/java/com/rampatra/linkedlists/MoveLastNodeToFirst.java index dfca9643..5f79e936 100644 --- a/src/main/java/com/rampatra/linkedlists/MoveLastNodeToFirst.java +++ b/src/main/java/com/rampatra/linkedlists/MoveLastNodeToFirst.java @@ -25,7 +25,7 @@ public static > void moveLastNodeToFirst(SingleLinkedLis list.head = curr; } - public static void main(String a[]) { + public static void main(String[] args) { SingleLinkedList linkedList = new SingleLinkedList<>(); linkedList.add(00); linkedList.add(11); diff --git a/src/main/java/com/rampatra/linkedlists/NthNodeFromLast.java b/src/main/java/com/rampatra/linkedlists/NthNodeFromLast.java index e4e5a09f..871af6cf 100644 --- a/src/main/java/com/rampatra/linkedlists/NthNodeFromLast.java +++ b/src/main/java/com/rampatra/linkedlists/NthNodeFromLast.java @@ -32,7 +32,7 @@ public static > SingleLinkedNode getNthNodeFromLast(S return slow; } - public static void main(String a[]) { + public static void main(String[] args) { SingleLinkedList linkedList = new SingleLinkedList<>(); linkedList.add(0); linkedList.add(1); diff --git a/src/main/java/com/rampatra/linkedlists/PairWiseSwap.java b/src/main/java/com/rampatra/linkedlists/PairWiseSwap.java index 991a97ae..3adc98b5 100644 --- a/src/main/java/com/rampatra/linkedlists/PairWiseSwap.java +++ b/src/main/java/com/rampatra/linkedlists/PairWiseSwap.java @@ -33,7 +33,7 @@ public static > SingleLinkedNode pairWiseSwap(SingleL return nextNode; } - public static void main(String a[]) { + public static void main(String[] args) { SingleLinkedList linkedList = new SingleLinkedList<>(); linkedList.add(11); linkedList.add(22); diff --git a/src/main/java/com/rampatra/linkedlists/Palindrome.java b/src/main/java/com/rampatra/linkedlists/Palindrome.java index 0f38cefe..1f85b35d 100644 --- a/src/main/java/com/rampatra/linkedlists/Palindrome.java +++ b/src/main/java/com/rampatra/linkedlists/Palindrome.java @@ -64,7 +64,7 @@ private boolean isPalindromeRecursive(SingleLinkedNode node) { } } - public static void main(String[] a) { + public static void main(String[] args) { Palindrome linkedList = new Palindrome<>(); linkedList.add(0); linkedList.add(1); diff --git a/src/main/java/com/rampatra/linkedlists/QuickSort.java b/src/main/java/com/rampatra/linkedlists/QuickSort.java index c358ec9a..5808fdcb 100644 --- a/src/main/java/com/rampatra/linkedlists/QuickSort.java +++ b/src/main/java/com/rampatra/linkedlists/QuickSort.java @@ -75,7 +75,7 @@ public static > SingleLinkedNode getLastNode(SingleLi return curr; } - public static void main(String a[]) { + public static void main(String[] args) { SingleLinkedList linkedList = new SingleLinkedList<>(); linkedList.add(23); linkedList.add(4); diff --git a/src/main/java/com/rampatra/linkedlists/RandomNode.java b/src/main/java/com/rampatra/linkedlists/RandomNode.java index 5f7b9b64..97aafdec 100644 --- a/src/main/java/com/rampatra/linkedlists/RandomNode.java +++ b/src/main/java/com/rampatra/linkedlists/RandomNode.java @@ -39,7 +39,7 @@ public static > SingleLinkedNode getRandomNode(Single return result; } - public static void main(String a[]) { + public static void main(String[] args) { SingleLinkedList linkedList = new SingleLinkedList<>(); linkedList.add(00); linkedList.add(11); diff --git a/src/main/java/com/rampatra/linkedlists/RemoveDuplicates.java b/src/main/java/com/rampatra/linkedlists/RemoveDuplicates.java index f87b0f55..7471f231 100644 --- a/src/main/java/com/rampatra/linkedlists/RemoveDuplicates.java +++ b/src/main/java/com/rampatra/linkedlists/RemoveDuplicates.java @@ -58,7 +58,7 @@ public static > void removeDuplicatesFromUnsortedList(Si } } - public static void main(String[] a) { + public static void main(String[] args) { SingleLinkedList linkedList = new SingleLinkedList<>(); linkedList.add(0); linkedList.add(0); diff --git a/src/main/java/com/rampatra/linkedlists/RemoveMiddlePointsFromLineSegments.java b/src/main/java/com/rampatra/linkedlists/RemoveMiddlePointsFromLineSegments.java index b77a6a53..d4099eed 100644 --- a/src/main/java/com/rampatra/linkedlists/RemoveMiddlePointsFromLineSegments.java +++ b/src/main/java/com/rampatra/linkedlists/RemoveMiddlePointsFromLineSegments.java @@ -53,7 +53,7 @@ public static void removeMiddlePointsFromLineSegments(SingleLinkedNode no } } - public static void main(String[] a) { + public static void main(String[] args) { // test case 1 SingleLinkedList linkedList = new SingleLinkedList<>(); linkedList.add(new Point(0, 10)); diff --git a/src/main/java/com/rampatra/linkedlists/ReverseAlternateNodesAndAppendAtEnd.java b/src/main/java/com/rampatra/linkedlists/ReverseAlternateNodesAndAppendAtEnd.java index d0b7685a..70b005d2 100644 --- a/src/main/java/com/rampatra/linkedlists/ReverseAlternateNodesAndAppendAtEnd.java +++ b/src/main/java/com/rampatra/linkedlists/ReverseAlternateNodesAndAppendAtEnd.java @@ -49,7 +49,7 @@ public static > SingleLinkedNode reverseAlternateNode return node; } - public static void main(String a[]) { + public static void main(String[] args) { SingleLinkedList linkedList = new SingleLinkedList<>(); linkedList.add(11); linkedList.add(22); diff --git a/src/main/java/com/rampatra/linkedlists/ReverseDoubleLinkedList.java b/src/main/java/com/rampatra/linkedlists/ReverseDoubleLinkedList.java index 3d86969a..466c6ac4 100644 --- a/src/main/java/com/rampatra/linkedlists/ReverseDoubleLinkedList.java +++ b/src/main/java/com/rampatra/linkedlists/ReverseDoubleLinkedList.java @@ -35,7 +35,7 @@ public static > void reverseList(DoubleLinkedList lis } } - public static void main(String a[]) { + public static void main(String[] args) { DoubleLinkedList linkedList = new DoubleLinkedList<>(); linkedList.add(11); linkedList.add(22); diff --git a/src/main/java/com/rampatra/linkedlists/ReverseLinkedListInAlternateGroups.java b/src/main/java/com/rampatra/linkedlists/ReverseLinkedListInAlternateGroups.java index f759840c..68a3b81f 100644 --- a/src/main/java/com/rampatra/linkedlists/ReverseLinkedListInAlternateGroups.java +++ b/src/main/java/com/rampatra/linkedlists/ReverseLinkedListInAlternateGroups.java @@ -61,7 +61,7 @@ public SingleLinkedNode reverseLinkedListInAltGroups(SingleLinkedNode node return prev; } - public static void main(String a[]) { + public static void main(String[] args) { ReverseLinkedListInAlternateGroups linkedList = new ReverseLinkedListInAlternateGroups<>(); linkedList.add(00); linkedList.add(11); diff --git a/src/main/java/com/rampatra/linkedlists/ReverseLinkedListInGroups.java b/src/main/java/com/rampatra/linkedlists/ReverseLinkedListInGroups.java index 7ac36e9d..1935356e 100644 --- a/src/main/java/com/rampatra/linkedlists/ReverseLinkedListInGroups.java +++ b/src/main/java/com/rampatra/linkedlists/ReverseLinkedListInGroups.java @@ -49,7 +49,7 @@ public static > SingleLinkedNode reverseLinkedListInG return prev; } - public static void main(String a[]) { + public static void main(String[] args) { SingleLinkedList linkedList = new SingleLinkedList<>(); linkedList.add(0); linkedList.add(1); diff --git a/src/main/java/com/rampatra/linkedlists/ReverseSingleLinkedList.java b/src/main/java/com/rampatra/linkedlists/ReverseSingleLinkedList.java index e30f1879..de474417 100644 --- a/src/main/java/com/rampatra/linkedlists/ReverseSingleLinkedList.java +++ b/src/main/java/com/rampatra/linkedlists/ReverseSingleLinkedList.java @@ -66,7 +66,7 @@ public static > void printListInReverse(SingleLinkedNode System.out.print(node.item + ","); } - public static void main(String a[]) { + public static void main(String[] args) { SingleLinkedList linkedList = new SingleLinkedList<>(); linkedList.add(11); linkedList.add(22); diff --git a/src/main/java/com/rampatra/linkedlists/RotateLinkedList.java b/src/main/java/com/rampatra/linkedlists/RotateLinkedList.java index b4cab9bf..15d28211 100644 --- a/src/main/java/com/rampatra/linkedlists/RotateLinkedList.java +++ b/src/main/java/com/rampatra/linkedlists/RotateLinkedList.java @@ -60,7 +60,7 @@ public static > void rotateClockwise(SingleLinkedList } - public static void main(String a[]) { + public static void main(String[] args) { SingleLinkedList linkedList = new SingleLinkedList<>(); linkedList.add(00); linkedList.add(11); diff --git a/src/main/java/com/rampatra/linkedlists/SegregateEvenOddNumbers.java b/src/main/java/com/rampatra/linkedlists/SegregateEvenOddNumbers.java index 05c9de62..1bdcb4db 100644 --- a/src/main/java/com/rampatra/linkedlists/SegregateEvenOddNumbers.java +++ b/src/main/java/com/rampatra/linkedlists/SegregateEvenOddNumbers.java @@ -68,7 +68,7 @@ public static > void segregateEvenOddNumbers(SingleLinke } - public static void main(String a[]) { + public static void main(String[] args) { SingleLinkedList linkedList = new SingleLinkedList<>(); linkedList.add(00); linkedList.add(11); diff --git a/src/main/java/com/rampatra/linkedlists/SortAlternativelySortedLinkedList.java b/src/main/java/com/rampatra/linkedlists/SortAlternativelySortedLinkedList.java index 3f76388e..79842cc4 100644 --- a/src/main/java/com/rampatra/linkedlists/SortAlternativelySortedLinkedList.java +++ b/src/main/java/com/rampatra/linkedlists/SortAlternativelySortedLinkedList.java @@ -44,7 +44,7 @@ public static > SingleLinkedNode sort(SingleLinkedNod return MergeSort.mergeTwoSortedLists(node, secondList); } - public static void main(String a[]) { + public static void main(String[] args) { SingleLinkedList linkedList = new SingleLinkedList<>(); linkedList.add(21); linkedList.add(67); diff --git a/src/main/java/com/rampatra/linkedlists/SortLinkedListOf0s1s2s.java b/src/main/java/com/rampatra/linkedlists/SortLinkedListOf0s1s2s.java index ba4ec323..6b5c08c1 100644 --- a/src/main/java/com/rampatra/linkedlists/SortLinkedListOf0s1s2s.java +++ b/src/main/java/com/rampatra/linkedlists/SortLinkedListOf0s1s2s.java @@ -39,7 +39,7 @@ public static void sort(SingleLinkedList list) { } } - public static void main(String a[]) { + public static void main(String[] args) { SingleLinkedList linkedList = new SingleLinkedList<>(); linkedList.add(0); linkedList.add(1); diff --git a/src/main/java/com/rampatra/linkedlists/SortedDLLToBBST.java b/src/main/java/com/rampatra/linkedlists/SortedDLLToBBST.java index 6332bc18..6b050d0c 100644 --- a/src/main/java/com/rampatra/linkedlists/SortedDLLToBBST.java +++ b/src/main/java/com/rampatra/linkedlists/SortedDLLToBBST.java @@ -69,7 +69,7 @@ public static > DoubleLinkedNode sortedDLLToBBST(Doub return root; } - public static void main(String a[]) { + public static void main(String[] args) { DoubleLinkedList linkedList = new DoubleLinkedList<>(); linkedList.add(11); linkedList.add(22); diff --git a/src/main/java/com/rampatra/linkedlists/StackWithOperationOnMiddleElement.java b/src/main/java/com/rampatra/linkedlists/StackWithOperationOnMiddleElement.java index 111e0465..bbcc4193 100644 --- a/src/main/java/com/rampatra/linkedlists/StackWithOperationOnMiddleElement.java +++ b/src/main/java/com/rampatra/linkedlists/StackWithOperationOnMiddleElement.java @@ -94,7 +94,7 @@ public void print() { out.println(curr.item.toString() + "]"); } - public static void main(String a[]) { + public static void main(String[] args) { StackWithOperationOnMiddleElement stack = new StackWithOperationOnMiddleElement<>(); stack.push(2); stack.push(3); diff --git a/src/main/java/com/rampatra/linkedlists/SwapKthNode.java b/src/main/java/com/rampatra/linkedlists/SwapKthNode.java index 75bf8f35..44f12da7 100644 --- a/src/main/java/com/rampatra/linkedlists/SwapKthNode.java +++ b/src/main/java/com/rampatra/linkedlists/SwapKthNode.java @@ -60,7 +60,7 @@ public static > SingleLinkedNode swapKthNodeFromStart } - public static void main(String a[]) { + public static void main(String[] args) { SingleLinkedList linkedList = new SingleLinkedList<>(); linkedList.add(11); linkedList.add(22); diff --git a/src/main/java/com/rampatra/linkedlists/SwapNodes.java b/src/main/java/com/rampatra/linkedlists/SwapNodes.java index 446aa3b1..ffb50332 100644 --- a/src/main/java/com/rampatra/linkedlists/SwapNodes.java +++ b/src/main/java/com/rampatra/linkedlists/SwapNodes.java @@ -58,7 +58,7 @@ public static > SingleLinkedNode swap(SingleLinkedNod return head.next; } - public static void main(String a[]) { + public static void main(String[] args) { SingleLinkedList linkedList = new SingleLinkedList<>(); linkedList.add(11); linkedList.add(22); diff --git a/src/main/java/com/rampatra/linkedlists/TripletFromThreeLinkedLists.java b/src/main/java/com/rampatra/linkedlists/TripletFromThreeLinkedLists.java index 1cf5da2e..1addeb69 100644 --- a/src/main/java/com/rampatra/linkedlists/TripletFromThreeLinkedLists.java +++ b/src/main/java/com/rampatra/linkedlists/TripletFromThreeLinkedLists.java @@ -53,7 +53,7 @@ public static SingleLinkedNode findTripletWithSumEqualsTo(SingleLinkedN } - public static void main(String a[]) { + public static void main(String[] args) { SingleLinkedList linkedList1 = new SingleLinkedList<>(); linkedList1.add(2); SingleLinkedList linkedList2 = new SingleLinkedList<>(); diff --git a/src/main/java/com/rampatra/misc/CollectionIteration.java b/src/main/java/com/rampatra/misc/CollectionIteration.java index ea1ea0f8..54edc937 100644 --- a/src/main/java/com/rampatra/misc/CollectionIteration.java +++ b/src/main/java/com/rampatra/misc/CollectionIteration.java @@ -20,7 +20,7 @@ */ public class CollectionIteration { - public static void main(String a[]) { + public static void main(String[] args) { List list = new ArrayList<>(); list.add(1); list.add(2); diff --git a/src/main/java/com/rampatra/misc/DivideByZero.java b/src/main/java/com/rampatra/misc/DivideByZero.java index 9aa167ae..e879a783 100644 --- a/src/main/java/com/rampatra/misc/DivideByZero.java +++ b/src/main/java/com/rampatra/misc/DivideByZero.java @@ -8,7 +8,7 @@ * To change this template go to Preferences | IDE Settings | File and Code Templates */ public class DivideByZero { - public static void main(String[] a) { + public static void main(String[] args) { System.out.println(5.0 / 0); // doesn't throw any exception System.out.println(5 / 0); // throws runtime exception or unchecked exception (does NOT need explicit handling). To be specific, throws an arithmetic exception. } diff --git a/src/main/java/com/rampatra/misc/Equals.java b/src/main/java/com/rampatra/misc/Equals.java index 04437f62..9987a957 100644 --- a/src/main/java/com/rampatra/misc/Equals.java +++ b/src/main/java/com/rampatra/misc/Equals.java @@ -8,7 +8,7 @@ * To change this template go to Preferences | IDE Settings | File and Code Templates */ public class Equals { - public static void main(String[] a) { + public static void main(String[] args) { Short i = new Short((short) 12); Short j = new Short((short) 12); System.out.print(j == i); // prints false as compiler compares 2 references instead of their values diff --git a/src/main/java/com/rampatra/misc/GenericNonGenericMix.java b/src/main/java/com/rampatra/misc/GenericNonGenericMix.java index b5d9995b..b13b0392 100644 --- a/src/main/java/com/rampatra/misc/GenericNonGenericMix.java +++ b/src/main/java/com/rampatra/misc/GenericNonGenericMix.java @@ -17,7 +17,7 @@ static List add(ArrayList list) { return list; } - public static void main(String[] a) { + public static void main(String[] args) { ArrayList stringArrayList = new ArrayList<>(); stringArrayList.add("ram"); add(stringArrayList); diff --git a/src/main/java/com/rampatra/misc/HitCount.java b/src/main/java/com/rampatra/misc/HitCount.java index b38d998b..97f946ec 100644 --- a/src/main/java/com/rampatra/misc/HitCount.java +++ b/src/main/java/com/rampatra/misc/HitCount.java @@ -40,7 +40,7 @@ public int compare(Map.Entry o1, Map.Entry o2) return list.get(0).getKey(); } - public static void main(String a[]) { + public static void main(String[] args) { List inputList = new ArrayList<>(); inputList.add("10.1.2.23 http://we.sdfdsf.sdf"); inputList.add("10.1.2.24 http://we.sdfdsf.sdf"); diff --git a/src/main/java/com/rampatra/misc/RecursiveWarmup.java b/src/main/java/com/rampatra/misc/RecursiveWarmup.java index c31c31e4..ad99d0c3 100644 --- a/src/main/java/com/rampatra/misc/RecursiveWarmup.java +++ b/src/main/java/com/rampatra/misc/RecursiveWarmup.java @@ -87,7 +87,7 @@ public List reverseRecursive(List input) { * * @param a */ - public static void main(String a[]) { + public static void main(String[] args) { RecursiveWarmup RecursiveWarmup = new RecursiveWarmup(); List list1 = new ArrayList<>(); list1.add(1); diff --git a/src/main/java/com/rampatra/misc/Regex.java b/src/main/java/com/rampatra/misc/Regex.java index cdc15695..19fcdf11 100644 --- a/src/main/java/com/rampatra/misc/Regex.java +++ b/src/main/java/com/rampatra/misc/Regex.java @@ -29,7 +29,7 @@ public static String validateLatLong(String s) { return "Invalid"; } - public static void main(String a[]) { + public static void main(String[] args) { Scanner in = new Scanner(System.in); int t = Integer.parseInt(in.nextLine()); diff --git a/src/main/java/com/rampatra/misc/ReplaceAll.java b/src/main/java/com/rampatra/misc/ReplaceAll.java index ea54409e..cc17b70f 100644 --- a/src/main/java/com/rampatra/misc/ReplaceAll.java +++ b/src/main/java/com/rampatra/misc/ReplaceAll.java @@ -13,7 +13,7 @@ public static String replaceAll(String str, String regex, String replacement) { return str.replaceAll(regex, replacement); } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(replaceAll("ram s", "\\s+", "")); } } diff --git a/src/main/java/com/rampatra/misc/ReverseAndAdd.java b/src/main/java/com/rampatra/misc/ReverseAndAdd.java index cbe2ef0f..91c36963 100644 --- a/src/main/java/com/rampatra/misc/ReverseAndAdd.java +++ b/src/main/java/com/rampatra/misc/ReverseAndAdd.java @@ -98,7 +98,7 @@ public static void readFile(String filePath) { * * @param a */ - public static void main(String a[]) { + public static void main(String[] args) { readFile(a[0]); System.exit(0); } diff --git a/src/main/java/com/rampatra/permutations/StringPermutations.java b/src/main/java/com/rampatra/permutations/StringPermutations.java index 64dde648..302d14f9 100644 --- a/src/main/java/com/rampatra/permutations/StringPermutations.java +++ b/src/main/java/com/rampatra/permutations/StringPermutations.java @@ -30,7 +30,7 @@ public static void printAllPermutations(String prefix, String s) { } } - public static void main(String a[]) { + public static void main(String[] args) { printAllPermutations("", "a"); System.out.println("-------"); printAllPermutations("", "ab"); diff --git a/src/main/java/com/rampatra/permutations/StringPermutationsCount.java b/src/main/java/com/rampatra/permutations/StringPermutationsCount.java index e8eb786e..c5916a07 100644 --- a/src/main/java/com/rampatra/permutations/StringPermutationsCount.java +++ b/src/main/java/com/rampatra/permutations/StringPermutationsCount.java @@ -34,7 +34,7 @@ public static int getStringPermutationsCount(String prefix, String s1, String s2 return count; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(getStringPermutationsCount("", "abc", "abcba", 0)); System.out.println(getStringPermutationsCount("", "abc", "abcbacb", 0)); } diff --git a/src/main/java/com/rampatra/permutations/UppercaseLowercasePermutations.java b/src/main/java/com/rampatra/permutations/UppercaseLowercasePermutations.java index e344a079..fec104a6 100644 --- a/src/main/java/com/rampatra/permutations/UppercaseLowercasePermutations.java +++ b/src/main/java/com/rampatra/permutations/UppercaseLowercasePermutations.java @@ -43,7 +43,7 @@ public static boolean isNumber(char s) { return true; } - public static void main(String a[]) { + public static void main(String[] args) { printUppercaseLowercasePermutations("", "0ab"); System.out.println("========"); printUppercaseLowercasePermutations("", "01"); diff --git a/src/main/java/com/rampatra/searching/BinarySearch.java b/src/main/java/com/rampatra/searching/BinarySearch.java index bca430c0..26997658 100644 --- a/src/main/java/com/rampatra/searching/BinarySearch.java +++ b/src/main/java/com/rampatra/searching/BinarySearch.java @@ -65,7 +65,7 @@ private static int binarySearchNonRecursive(int[] a, int n) { * * @param a */ - public static void main(String[] a) { + public static void main(String[] args) { System.out.println(binarySearch(new int[]{0, 2}, 2)); System.out.println(binarySearch(new int[]{0, 1, 2, 3}, 2)); System.out.println(binarySearch(new int[]{0, 1, 2, 3}, 3)); diff --git a/src/main/java/com/rampatra/searching/InterpolationSearch.java b/src/main/java/com/rampatra/searching/InterpolationSearch.java index 2ac2dda2..20f76665 100644 --- a/src/main/java/com/rampatra/searching/InterpolationSearch.java +++ b/src/main/java/com/rampatra/searching/InterpolationSearch.java @@ -36,7 +36,7 @@ public static int search(int[] a, int k) { } } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(search(new int[]{0, 2}, 2)); System.out.println(search(new int[]{0, 1}, 2)); System.out.println(search(new int[]{0, 1, 2, 3}, 2)); diff --git a/src/main/java/com/rampatra/sorting/CheckSorted.java b/src/main/java/com/rampatra/sorting/CheckSorted.java index 56979f8c..0b9b6c3f 100644 --- a/src/main/java/com/rampatra/sorting/CheckSorted.java +++ b/src/main/java/com/rampatra/sorting/CheckSorted.java @@ -55,7 +55,7 @@ public static boolean isSorted(int[] a) { return true; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(isSorted(new int[]{1, 2, 3, 4, 5})); System.out.println(isSorted(new int[]{5, 4, 3, 2, 1})); System.out.println(isSorted(new int[]{})); diff --git a/src/main/java/com/rampatra/sorting/HeapSort.java b/src/main/java/com/rampatra/sorting/HeapSort.java index 92473dd9..61f03802 100644 --- a/src/main/java/com/rampatra/sorting/HeapSort.java +++ b/src/main/java/com/rampatra/sorting/HeapSort.java @@ -76,7 +76,7 @@ private static void swap(int[] a, int firstIndex, int secondIndex) { a[firstIndex] = a[firstIndex] - a[secondIndex]; } - public static void main(String[] a) { + public static void main(String[] args) { int[] ar = new int[]{2, 5, 1, 7, 9, 4}; System.out.println(Arrays.toString(ar)); heapSort(ar); diff --git a/src/main/java/com/rampatra/sorting/MergeSort.java b/src/main/java/com/rampatra/sorting/MergeSort.java index ee05deff..c5a890d5 100644 --- a/src/main/java/com/rampatra/sorting/MergeSort.java +++ b/src/main/java/com/rampatra/sorting/MergeSort.java @@ -53,7 +53,7 @@ public static int[] merge(int[] a, int[] b) { return sortedArray; } - public static void main(String a[]) { + public static void main(String[] args) { int[] ar = new int[]{3, 5, 1, 6, 9, 8}; System.out.println(Arrays.toString(ar)); System.out.println(Arrays.toString(mergeSort(ar))); diff --git a/src/main/java/com/rampatra/sorting/PancakeSort.java b/src/main/java/com/rampatra/sorting/PancakeSort.java index ecffd752..81cd9943 100644 --- a/src/main/java/com/rampatra/sorting/PancakeSort.java +++ b/src/main/java/com/rampatra/sorting/PancakeSort.java @@ -58,7 +58,7 @@ public static void reverse(int[] a, int end) { } } - public static void main(String a[]) { + public static void main(String[] args) { int[] ar = {1, 2, 3, 4, 5, 6}; System.out.println(Arrays.toString(ar)); sort(ar); diff --git a/src/main/java/com/rampatra/sorting/QuickSort.java b/src/main/java/com/rampatra/sorting/QuickSort.java index 62795f5b..48744ddc 100644 --- a/src/main/java/com/rampatra/sorting/QuickSort.java +++ b/src/main/java/com/rampatra/sorting/QuickSort.java @@ -74,7 +74,7 @@ public static void quickSort(int[] arr) { quickSort(arr, 0, arr.length - 1); } - public static void main(String[] a) { + public static void main(String[] args) { int[] ar = {3, 2, 1, 6, 4, 9, 7, 8}; System.out.println(Arrays.toString(ar)); quickSort(ar); diff --git a/src/main/java/com/rampatra/sorting/SelectionSort.java b/src/main/java/com/rampatra/sorting/SelectionSort.java index ee579941..fb1e2b0e 100644 --- a/src/main/java/com/rampatra/sorting/SelectionSort.java +++ b/src/main/java/com/rampatra/sorting/SelectionSort.java @@ -53,7 +53,7 @@ private static void swap(int[] a, int index1, int index2) { a[index2] = temp; } - public static void main(String a[]) { + public static void main(String[] args) { int[] ar = new int[]{3, 2, 1, 5, 6, 9, 7, 10}; selectionSort(ar); System.out.println(Arrays.toString(ar)); diff --git a/src/main/java/com/rampatra/sorting/WiggleSort.java b/src/main/java/com/rampatra/sorting/WiggleSort.java index 94e6d66b..51ef266a 100644 --- a/src/main/java/com/rampatra/sorting/WiggleSort.java +++ b/src/main/java/com/rampatra/sorting/WiggleSort.java @@ -32,7 +32,7 @@ private static void swap(int[] a, int index1, int index2) { a[index1] = a[index1] - a[index2]; } - public static void main(String[] a) { + public static void main(String[] args) { int[] ar = {3, 5, 6, 7, 8, 1, 2}; System.out.println(Arrays.toString(wiggleSortEasyWay(ar))); int[] ar1 = {3, 5, 6, 7, 2, 1}; diff --git a/src/main/java/com/rampatra/stacks/BalancingParenthesis.java b/src/main/java/com/rampatra/stacks/BalancingParenthesis.java index 9b497db4..a92f23a9 100644 --- a/src/main/java/com/rampatra/stacks/BalancingParenthesis.java +++ b/src/main/java/com/rampatra/stacks/BalancingParenthesis.java @@ -81,7 +81,7 @@ public static void readFile(String filePath) { * * @param a */ - public static void main(String a[]) { + public static void main(String[] args) { readFile(a[0]); } } diff --git a/src/main/java/com/rampatra/strings/AnagramsTogether.java b/src/main/java/com/rampatra/strings/AnagramsTogether.java index 775f9bb7..caf1dc26 100644 --- a/src/main/java/com/rampatra/strings/AnagramsTogether.java +++ b/src/main/java/com/rampatra/strings/AnagramsTogether.java @@ -49,7 +49,7 @@ public static void printAnagramsTogether(String[] s) { } } - public static void main(String a[]) { + public static void main(String[] args) { printAnagramsTogether(new String[]{"cat", "dog", "tac", "god", "act"}); printAnagramsTogether(new String[]{"cat", "tac", "act", "god", "dog"}); } diff --git a/src/main/java/com/rampatra/strings/AnagramsTogetherLexicographically.java b/src/main/java/com/rampatra/strings/AnagramsTogetherLexicographically.java index 86d69092..72bf3a28 100644 --- a/src/main/java/com/rampatra/strings/AnagramsTogetherLexicographically.java +++ b/src/main/java/com/rampatra/strings/AnagramsTogetherLexicographically.java @@ -68,7 +68,7 @@ public int compare(Object o1, Object o2) { * * @param a */ - public static void main(String a[]) { + public static void main(String[] args) { Scanner in = new Scanner(System.in); List strings = new ArrayList<>(); String s; diff --git a/src/main/java/com/rampatra/strings/RemoveExtraSpaces.java b/src/main/java/com/rampatra/strings/RemoveExtraSpaces.java index 1924f2a3..3c5b6954 100644 --- a/src/main/java/com/rampatra/strings/RemoveExtraSpaces.java +++ b/src/main/java/com/rampatra/strings/RemoveExtraSpaces.java @@ -52,7 +52,7 @@ public static String removeExtraSpaces(String s) { return String.valueOf(Arrays.copyOf(c, j)); } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(removeExtraSpaces("ram swaroop is a good boy.")); System.out.println(removeExtraSpaces("ram swaroop is a good boy.")); System.out.println(removeExtraSpaces(" ram swaroop is a good boy.")); diff --git a/src/main/java/com/rampatra/strings/StringRotation.java b/src/main/java/com/rampatra/strings/StringRotation.java index 35aa6139..0ab15138 100644 --- a/src/main/java/com/rampatra/strings/StringRotation.java +++ b/src/main/java/com/rampatra/strings/StringRotation.java @@ -41,7 +41,7 @@ public static boolean isStringRotation(String s1, String s2) { return false; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(isStringRotation("rampatra", "swaroopram")); System.out.println(isStringRotation("rampatra", "swaroopramramram")); System.out.println(isStringRotation("rampatra", "mswaroopra")); diff --git a/src/main/java/com/rampatra/strings/SubStringCheck.java b/src/main/java/com/rampatra/strings/SubStringCheck.java index 7564ab2e..63786967 100644 --- a/src/main/java/com/rampatra/strings/SubStringCheck.java +++ b/src/main/java/com/rampatra/strings/SubStringCheck.java @@ -36,7 +36,7 @@ public static boolean isSubString(String s1, String s2) { return false; } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println(isSubString("rampatra", "rampatra")); System.out.println(isSubString("rampatra", "")); System.out.println(isSubString("rampatra", "ram")); diff --git a/src/main/java/com/rampatra/strings/SubStrings.java b/src/main/java/com/rampatra/strings/SubStrings.java index 9e6223fa..792830c9 100644 --- a/src/main/java/com/rampatra/strings/SubStrings.java +++ b/src/main/java/com/rampatra/strings/SubStrings.java @@ -36,7 +36,7 @@ public static void printAllSubStringsRecursive(String s) { printAllSubStrings(s.substring(1)); } - public static void main(String a[]) { + public static void main(String[] args) { System.out.println("----Iterative----"); printAllSubStrings("ram"); System.out.println("--------"); diff --git a/src/main/java/com/rampatra/threads/Basics.java b/src/main/java/com/rampatra/threads/Basics.java index dfc39bdd..52d443da 100644 --- a/src/main/java/com/rampatra/threads/Basics.java +++ b/src/main/java/com/rampatra/threads/Basics.java @@ -8,7 +8,7 @@ * To change this template go to Preferences | IDE Settings | File and Code Templates */ public class Basics { - public static void main(String[] a) { + public static void main(String[] args) { Runnable r = new Runnable() { @Override public void run() { diff --git a/src/main/java/com/rampatra/threads/NamePrint.java b/src/main/java/com/rampatra/threads/NamePrint.java index 1dd4249a..b87f3e5a 100644 --- a/src/main/java/com/rampatra/threads/NamePrint.java +++ b/src/main/java/com/rampatra/threads/NamePrint.java @@ -63,7 +63,7 @@ public void printNameUsingMultipleThreads() { secondThread.start(); } - public static void main(String a[]) { + public static void main(String[] args) { NamePrint obj = new NamePrint(); obj.printNameUsingMultipleThreads(); } diff --git a/src/main/java/com/rampatra/trees/BFSUsingQueue.java b/src/main/java/com/rampatra/trees/BFSUsingQueue.java index 7d1df283..04166d8d 100644 --- a/src/main/java/com/rampatra/trees/BFSUsingQueue.java +++ b/src/main/java/com/rampatra/trees/BFSUsingQueue.java @@ -72,7 +72,7 @@ public static > void breadthFirstTraversalUsingQueueIter } } - public static void main(String a[]) { + public static void main(String[] args) { BinaryTree bt = new BinaryTree<>(); bt.put(6); bt.put(3); diff --git a/src/main/java/com/rampatra/trees/CheckForBST.java b/src/main/java/com/rampatra/trees/CheckForBST.java index ed0b6317..d0e323e0 100644 --- a/src/main/java/com/rampatra/trees/CheckForBST.java +++ b/src/main/java/com/rampatra/trees/CheckForBST.java @@ -95,7 +95,7 @@ public static > boolean isBST(BinaryNode node, E minV return isBST(node.left, minValue, node.value) && isBST(node.right, node.value, maxValue); } - public static void main(String a[]) { + public static void main(String[] args) { // in-order approach BinarySearchTree binarySearchTree = new BinarySearchTree<>(); binarySearchTree.put(6); diff --git a/src/main/java/com/rampatra/trees/ChildrenSum.java b/src/main/java/com/rampatra/trees/ChildrenSum.java index a5ad7f3a..232e1554 100644 --- a/src/main/java/com/rampatra/trees/ChildrenSum.java +++ b/src/main/java/com/rampatra/trees/ChildrenSum.java @@ -81,7 +81,7 @@ private static > void increment(BinaryNode node, int } } - public static void main(String a[]) { + public static void main(String[] args) { BinaryTree bt = new BinaryTree<>(); bt.put(6); bt.put(3); diff --git a/src/main/java/com/rampatra/trees/ConstructTreeFromInOrderAndPreOrder.java b/src/main/java/com/rampatra/trees/ConstructTreeFromInOrderAndPreOrder.java index 4ccbe61b..f9eddac0 100644 --- a/src/main/java/com/rampatra/trees/ConstructTreeFromInOrderAndPreOrder.java +++ b/src/main/java/com/rampatra/trees/ConstructTreeFromInOrderAndPreOrder.java @@ -20,7 +20,7 @@ public > void constructTreeWithInOrderAndPreOrder(List> void doubleTree(BinaryNode node) { doubleTree(node.right); } - public static void main(String a[]) { + public static void main(String[] args) { BinaryTree bt = new BinaryTree<>(); bt.put(6); bt.put(3); diff --git a/src/main/java/com/rampatra/trees/HeightBalanced.java b/src/main/java/com/rampatra/trees/HeightBalanced.java index 394dff5b..24dbed99 100644 --- a/src/main/java/com/rampatra/trees/HeightBalanced.java +++ b/src/main/java/com/rampatra/trees/HeightBalanced.java @@ -36,7 +36,7 @@ public boolean isHeightBalanced(BinaryNode node) { return isHeightBalanced(node.left) && isHeightBalanced(node.right); } - public static void main(String a[]) { + public static void main(String[] args) { HeightBalanced bst = new HeightBalanced<>(); bst.put(6); bst.put(3); diff --git a/src/main/java/com/rampatra/trees/IdenticalTrees.java b/src/main/java/com/rampatra/trees/IdenticalTrees.java index e9d278c6..221aeb24 100644 --- a/src/main/java/com/rampatra/trees/IdenticalTrees.java +++ b/src/main/java/com/rampatra/trees/IdenticalTrees.java @@ -34,7 +34,7 @@ public static > boolean isIdentical(BinaryNode node1, } } - public static void main(String a[]) { + public static void main(String[] args) { BinarySearchTree bst = new BinarySearchTree<>(); bst.put(6); bst.put(3); diff --git a/src/main/java/com/rampatra/trees/InOrderUsingStack.java b/src/main/java/com/rampatra/trees/InOrderUsingStack.java index 20d14d48..15ef82d0 100644 --- a/src/main/java/com/rampatra/trees/InOrderUsingStack.java +++ b/src/main/java/com/rampatra/trees/InOrderUsingStack.java @@ -43,7 +43,7 @@ public static > void inOrderUsingStack(BinaryNode nod } } - public static void main(String a[]) { + public static void main(String[] args) { BinarySearchTree bst = new BinarySearchTree<>(); bst.put(6); bst.put(3); diff --git a/src/main/java/com/rampatra/trees/InOrderWithoutStackAndRecursion.java b/src/main/java/com/rampatra/trees/InOrderWithoutStackAndRecursion.java index 8ae701bf..5663986e 100644 --- a/src/main/java/com/rampatra/trees/InOrderWithoutStackAndRecursion.java +++ b/src/main/java/com/rampatra/trees/InOrderWithoutStackAndRecursion.java @@ -67,7 +67,7 @@ public void inOrderWithoutStackAndRecursion(BinaryNode node) { } } - public static void main(String a[]) { + public static void main(String[] args) { InOrderWithoutStackAndRecursion bst = new InOrderWithoutStackAndRecursion<>(); bst.put(6); bst.put(3); diff --git a/src/main/java/com/rampatra/trees/LeafNodes.java b/src/main/java/com/rampatra/trees/LeafNodes.java index a8c95e3a..bc3d271e 100644 --- a/src/main/java/com/rampatra/trees/LeafNodes.java +++ b/src/main/java/com/rampatra/trees/LeafNodes.java @@ -27,7 +27,7 @@ public static > int countLeafNodes(BinaryNode node) { } } - public static void main(String a[]) { + public static void main(String[] args) { BinaryTree bt = new BinaryTree<>(); bt.put(6); bt.put(3); diff --git a/src/main/java/com/rampatra/trees/LeastCommonAncestor.java b/src/main/java/com/rampatra/trees/LeastCommonAncestor.java index 789acf2d..6ed648b6 100644 --- a/src/main/java/com/rampatra/trees/LeastCommonAncestor.java +++ b/src/main/java/com/rampatra/trees/LeastCommonAncestor.java @@ -53,7 +53,7 @@ public static > BinaryNode leastCommonAncestor(Binary } } - public static void main(String a[]) { + public static void main(String[] args) { BinarySearchTree bst = new BinarySearchTree<>(); bst.put(6); bst.put(3); diff --git a/src/main/java/com/rampatra/trees/MirrorTree.java b/src/main/java/com/rampatra/trees/MirrorTree.java index 575d6e2e..421e2241 100644 --- a/src/main/java/com/rampatra/trees/MirrorTree.java +++ b/src/main/java/com/rampatra/trees/MirrorTree.java @@ -35,7 +35,7 @@ public static > void mirror(BinaryNode node) { node.right = tempNode; } - public static void main(String a[]) { + public static void main(String[] args) { BinaryTree bt = new BinaryTree<>(); bt.put(6); bt.put(3); diff --git a/src/main/java/com/rampatra/trees/RootToLeafPaths.java b/src/main/java/com/rampatra/trees/RootToLeafPaths.java index 38688199..a42ca4b6 100644 --- a/src/main/java/com/rampatra/trees/RootToLeafPaths.java +++ b/src/main/java/com/rampatra/trees/RootToLeafPaths.java @@ -106,7 +106,7 @@ public boolean rootToLeafPathsSum(BinaryNode node, List pathList, int path } } - public static void main(String a[]) { + public static void main(String[] args) { RootToLeafPaths bt = new RootToLeafPaths<>(); bt.put(6); bt.put(3); diff --git a/src/main/java/com/rampatra/trees/SpiralTraversal.java b/src/main/java/com/rampatra/trees/SpiralTraversal.java index 0f4cb62b..fa313e1c 100644 --- a/src/main/java/com/rampatra/trees/SpiralTraversal.java +++ b/src/main/java/com/rampatra/trees/SpiralTraversal.java @@ -98,7 +98,7 @@ public void spiralTraversalUsingStacks(BinaryNode node) { } } - public static void main(String a[]) { + public static void main(String[] args) { SpiralTraversal bt = new SpiralTraversal<>(); bt.put(6); bt.put(3); diff --git a/src/main/java/com/rampatra/trees/TreeToList.java b/src/main/java/com/rampatra/trees/TreeToList.java index 8a169c6c..26256b30 100644 --- a/src/main/java/com/rampatra/trees/TreeToList.java +++ b/src/main/java/com/rampatra/trees/TreeToList.java @@ -59,7 +59,7 @@ private static > BinaryNode addToList(BinaryNode a return aList; } - public static void main(String a[]) { + public static void main(String[] args) { BinarySearchTree bst = new BinarySearchTree<>(); bst.put(6); bst.put(3); From 4d7348dbbc6f7a4168b8d3e04dd52a8189d797ea Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sat, 16 Mar 2019 17:24:12 +0000 Subject: [PATCH 022/164] Fix some minor issues after renaming variable --- src/main/java/com/rampatra/misc/ReverseAndAdd.java | 4 ++-- src/main/java/com/rampatra/stacks/BalancingParenthesis.java | 4 ++-- .../rampatra/strings/AnagramsTogetherLexicographically.java | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/rampatra/misc/ReverseAndAdd.java b/src/main/java/com/rampatra/misc/ReverseAndAdd.java index 91c36963..56713796 100644 --- a/src/main/java/com/rampatra/misc/ReverseAndAdd.java +++ b/src/main/java/com/rampatra/misc/ReverseAndAdd.java @@ -96,10 +96,10 @@ public static void readFile(String filePath) { /** * Starting point of the program. * - * @param a + * @param args */ public static void main(String[] args) { - readFile(a[0]); + readFile(args[0]); System.exit(0); } } diff --git a/src/main/java/com/rampatra/stacks/BalancingParenthesis.java b/src/main/java/com/rampatra/stacks/BalancingParenthesis.java index a92f23a9..c6e2851d 100644 --- a/src/main/java/com/rampatra/stacks/BalancingParenthesis.java +++ b/src/main/java/com/rampatra/stacks/BalancingParenthesis.java @@ -79,10 +79,10 @@ public static void readFile(String filePath) { /** * Starting point of the program. * - * @param a + * @param args */ public static void main(String[] args) { - readFile(a[0]); + readFile(args[0]); } } diff --git a/src/main/java/com/rampatra/strings/AnagramsTogetherLexicographically.java b/src/main/java/com/rampatra/strings/AnagramsTogetherLexicographically.java index 72bf3a28..afa6bc1a 100644 --- a/src/main/java/com/rampatra/strings/AnagramsTogetherLexicographically.java +++ b/src/main/java/com/rampatra/strings/AnagramsTogetherLexicographically.java @@ -66,7 +66,7 @@ public int compare(Object o1, Object o2) { /** * Take list of strings from console and print anagrams in groups. * - * @param a + * @param args */ public static void main(String[] args) { Scanner in = new Scanner(System.in); From 39ea03255fa1d144469e67fbba44fb69d331678d Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sat, 16 Mar 2019 21:16:33 +0000 Subject: [PATCH 023/164] Longest set bits done --- .../ctci/bitmanipulation/BinaryToString.java | 2 + .../ctci/bitmanipulation/FlipBitToWin.java | 52 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 src/main/java/com/ctci/bitmanipulation/FlipBitToWin.java diff --git a/src/main/java/com/ctci/bitmanipulation/BinaryToString.java b/src/main/java/com/ctci/bitmanipulation/BinaryToString.java index c6d50c41..895c354a 100644 --- a/src/main/java/com/ctci/bitmanipulation/BinaryToString.java +++ b/src/main/java/com/ctci/bitmanipulation/BinaryToString.java @@ -28,7 +28,9 @@ private static String decimalFractionToBinaryString(double realNum) { return "ERROR"; } realNum = realNum * 2; + // the binary bit is the whole number part (left to the decimal) binaryBit = (int) realNum; + // we only have to take the part after the decimal (right to the decimal) for the next iteration if (binaryBit == 1) { realNum -= 1; } diff --git a/src/main/java/com/ctci/bitmanipulation/FlipBitToWin.java b/src/main/java/com/ctci/bitmanipulation/FlipBitToWin.java new file mode 100644 index 00000000..0af95ad6 --- /dev/null +++ b/src/main/java/com/ctci/bitmanipulation/FlipBitToWin.java @@ -0,0 +1,52 @@ +package com.ctci.bitmanipulation; + +/** + * @author rampatra + * @since 2019-03-16 + */ +public class FlipBitToWin { + + /** + * You have an integer and you can flip exactly one bit from a O to a 1. Write code to find the length of the + * longest sequence of 1s you could create. + * Example: + * Input: 1775 (or: 11011101111) Output: 8 + *

+ * Approach: + * We just walk through the integer tracking the current 1s sequence length and the previous 1s sequence length. + * When we see a zero, update previous length as follows: + * - If the next bit is a 1, previous Length should be set to current Length. + * - If the next bit is a 0, then we can't merge these sequences together. So, set previous Length to 0. + * + * @param n an integer + * @return the longest sequence of set bits in {@code n} by flipping only one zero bit + */ + private static int findLongestSequence(int n) { + // if all bits are set, return the total number of bits in an integer + if (n == ~0) { + return Integer.BYTES * 8; + } + + int prevOnesLen = 0; + int currOnesLen = 0; + int maxOnesLen = 0; + + while (n > 0) { + // if the current bit is 0, reset the currOnesLen + if ((n & 1) == 0) { + prevOnesLen = (n & 2) == 0 ? 0 : currOnesLen; // if the next bit is also 0, set prevOnesLen to 0 + currOnesLen = 0; + } else { + currOnesLen++; + } + n >>>= 1; + maxOnesLen = Math.max(maxOnesLen, prevOnesLen + 1 + currOnesLen); + } + return maxOnesLen; + } + + public static void main(String[] args) { + System.out.println("Longest seq in " + Integer.toBinaryString(125) + " is " + findLongestSequence(125)); + System.out.println("Longest seq in " + Integer.toBinaryString(1275) + " is " + findLongestSequence(1275)); + } +} From 33d903c6c560ba83739a10503d49f37896362818 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sun, 17 Mar 2019 11:38:23 +0000 Subject: [PATCH 024/164] Flip bits done --- .../com/ctci/bitmanipulation/Conversion.java | 40 +++++++++++++++++++ .../ctci/bitmanipulation/FlipBitToWin.java | 3 +- 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/ctci/bitmanipulation/Conversion.java diff --git a/src/main/java/com/ctci/bitmanipulation/Conversion.java b/src/main/java/com/ctci/bitmanipulation/Conversion.java new file mode 100644 index 00000000..9218ef9d --- /dev/null +++ b/src/main/java/com/ctci/bitmanipulation/Conversion.java @@ -0,0 +1,40 @@ +package com.ctci.bitmanipulation; + +/** + * @author rampatra + * @since 2019-03-17 + */ +public class Conversion { + + /** + * Write a function to determine the number of bits you would need to flip to convert + * integer A to integer B. + * Example: + * Input: 29 (or: 11101), 15 (or: 01111) + * Output: 2 + * + * @param a + * @param b + * @return the number of bits to flip + */ + private static int getNoOfBitsToFlipToConvertAToB(int a, int b) { + return countSetBits(a ^ b); + } + + private static int countSetBits(int n) { + int count = 0; + while (n > 0) { + if ((n & 1) == 1) { + count++; + } + n >>>= 1; + } + return count; + } + + public static void main(String[] args) { + System.out.println(getNoOfBitsToFlipToConvertAToB(5, 7)); + System.out.println(getNoOfBitsToFlipToConvertAToB(5, 5)); + System.out.println(getNoOfBitsToFlipToConvertAToB(29, 15)); + } +} \ No newline at end of file diff --git a/src/main/java/com/ctci/bitmanipulation/FlipBitToWin.java b/src/main/java/com/ctci/bitmanipulation/FlipBitToWin.java index 0af95ad6..4424f7ab 100644 --- a/src/main/java/com/ctci/bitmanipulation/FlipBitToWin.java +++ b/src/main/java/com/ctci/bitmanipulation/FlipBitToWin.java @@ -10,7 +10,8 @@ public class FlipBitToWin { * You have an integer and you can flip exactly one bit from a O to a 1. Write code to find the length of the * longest sequence of 1s you could create. * Example: - * Input: 1775 (or: 11011101111) Output: 8 + * Input: 1775 (or: 11011101111) + * Output: 8 *

* Approach: * We just walk through the integer tracking the current 1s sequence length and the previous 1s sequence length. From 9d87a5332563a2f9f931a5546b1c9a8c7992c089 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sun, 17 Mar 2019 21:37:15 +0000 Subject: [PATCH 025/164] Un-set the least significant bit --- .../com/ctci/bitmanipulation/Conversion.java | 25 +++++++++++++++- .../com/ctci/bitmanipulation/Debugger.java | 30 +++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/ctci/bitmanipulation/Debugger.java diff --git a/src/main/java/com/ctci/bitmanipulation/Conversion.java b/src/main/java/com/ctci/bitmanipulation/Conversion.java index 9218ef9d..5a4c7575 100644 --- a/src/main/java/com/ctci/bitmanipulation/Conversion.java +++ b/src/main/java/com/ctci/bitmanipulation/Conversion.java @@ -12,7 +12,7 @@ public class Conversion { * Example: * Input: 29 (or: 11101), 15 (or: 01111) * Output: 2 - * + * * @param a * @param b * @return the number of bits to flip @@ -32,9 +32,32 @@ private static int countSetBits(int n) { return count; } + /** + * In this approach, we first take the xor of both the integers (which sets the bits at positions where the bits + * in a and b are different). We then unset the least significant bit in each iteration (c & (c - 1)) and count the + * number of iterations to find the bits to flip. + * + * @param a + * @param b + * @return the number of bits to flip + */ + private static int getNoOfBitsToFlipToConvertAToBWithoutRightShift(int a, int b) { + int count = 0; + for (int c = a ^ b; c != 0; c = c & (c - 1)) { + count++; + } + return count; + } + public static void main(String[] args) { System.out.println(getNoOfBitsToFlipToConvertAToB(5, 7)); System.out.println(getNoOfBitsToFlipToConvertAToB(5, 5)); System.out.println(getNoOfBitsToFlipToConvertAToB(29, 15)); + + System.out.println("---"); + + System.out.println(getNoOfBitsToFlipToConvertAToBWithoutRightShift(5, 7)); + System.out.println(getNoOfBitsToFlipToConvertAToBWithoutRightShift(5, 5)); + System.out.println(getNoOfBitsToFlipToConvertAToBWithoutRightShift(29, 15)); } } \ No newline at end of file diff --git a/src/main/java/com/ctci/bitmanipulation/Debugger.java b/src/main/java/com/ctci/bitmanipulation/Debugger.java new file mode 100644 index 00000000..6782036b --- /dev/null +++ b/src/main/java/com/ctci/bitmanipulation/Debugger.java @@ -0,0 +1,30 @@ +package com.ctci.bitmanipulation; + +/** + * @author rampatra + * @since 2019-03-17 + */ +public class Debugger { + + /** + * If after un-setting the least significant bit in n, it becomes 0 then it implies that it has only set bit. This + * can also imply that n is a power of 2. + * + * @param n input integer + * @return {@code true} if n has only set bit, {@code false} otherwise. + */ + private static boolean hasOneSetBit(int n) { + // edge case + if (n == 0) { + return false; + } + return (n & (n - 1)) == 0; // (n & (n - 1)) un-sets the least significant bit + } + + public static void main(String[] args) { + System.out.println(hasOneSetBit(0)); + System.out.println(hasOneSetBit(2)); + System.out.println(hasOneSetBit(16)); + System.out.println(hasOneSetBit(10)); + } +} From 445e1ee923fda086c03334f9daff1bde24ebac5a Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Mon, 18 Mar 2019 18:50:06 +0000 Subject: [PATCH 026/164] Next number done --- .../com/ctci/bitmanipulation/NextNumber.java | 135 ++++++++++++++++++ .../treesandgraphs/FirstCommonAncestor.java | 2 +- 2 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/ctci/bitmanipulation/NextNumber.java diff --git a/src/main/java/com/ctci/bitmanipulation/NextNumber.java b/src/main/java/com/ctci/bitmanipulation/NextNumber.java new file mode 100644 index 00000000..af016aa5 --- /dev/null +++ b/src/main/java/com/ctci/bitmanipulation/NextNumber.java @@ -0,0 +1,135 @@ +package com.ctci.bitmanipulation; + +/** + * @author rampatra + * @since 2019-03-17 + */ +public class NextNumber { + + private static class NextLargerAndSmallerNumber { + int nextLarger; + int nextSmaller; + } + + /** + * Given a positive integer, print the next smallest and the next largest number that have the same number of + * 1 bits in their binary representation. + * + * @param n a positive integer. + * @return an object containing the next larger and next smaller number containing the identical set bits. + */ + private static NextLargerAndSmallerNumber getNextLargerAndSmallerNumber(int n) { + NextLargerAndSmallerNumber result = new NextLargerAndSmallerNumber(); + result.nextLarger = getNextLarger(n); + result.nextSmaller = getNextSmaller(n); + return result; + } + + private static int getNextLarger(int n) { + int zeroPrecededByOneFromRight = 0; + int noOfOnes = 0; + int mask = 1; + + /* Find the position of the bit pattern '01' from the right and then make it '10'. + For example, see below: + + n = 10110110011110 + ^^ + n = 10110110101110 (after bit swap) + */ + for (int i = 0; i < Integer.BYTES * 8 - 1; i++) { + if ((n & mask) == mask) { + if ((n & mask << 1) == 0) { + n = (n & ~mask) | mask << 1; // swap the bits + break; + } + noOfOnes++; + } + zeroPrecededByOneFromRight++; + mask <<= 1; + } + + if (zeroPrecededByOneFromRight == Integer.BYTES * 8 - 1) { + return -1; + } + + /* Shift all the 1s to the right end and then fill with 0s until the bit pattern '01. + For example, consider the above number: + + n = 10110110101110 (after bit swap) + ^^ + next larger = 10110110100111 (the 1s are shifted to the right end) + */ + mask = 1; + for (int i = 0; i < zeroPrecededByOneFromRight; i++) { + if (i < noOfOnes) { + n = n | mask; // set the bits + } else { + n = n & ~mask; // unset the bits + } + mask <<= 1; + } + return n; + } + + private static int getNextSmaller(int n) { + int onePrecededByZeroFromRight = 0; + int noOfZeros = 0; + int mask = 1; + + // find the position of the bit pattern '10' from the right and then make it '01' + for (int i = 0; i < Integer.BYTES * 8 - 1; i++) { + if ((n & mask) == 0) { + if ((n & mask << 1) == mask << 1) { + n = (n | mask) & ~(mask << 1); // swap the bits + break; + } + noOfZeros++; + } + onePrecededByZeroFromRight++; + mask <<= 1; + } + + if (onePrecededByZeroFromRight == Integer.BYTES * 8 - 1) { + return -1; + } + + // shift all the 0s to the right end and then fill with 1s until the bit pattern '10' + mask = 1; + for (int i = 0; i < onePrecededByZeroFromRight; i++) { + if (i < noOfZeros) { + n = n & ~mask; // unset the bits + } else { + n = n | mask; // set the bits + } + mask <<= 1; + } + return n; + } + + public static void main(String[] args) { + NextLargerAndSmallerNumber of0 = getNextLargerAndSmallerNumber(0); + System.out.println("Next larger of 0: " + of0.nextLarger); + System.out.println("Next smaller of 0: " + of0.nextSmaller); + + NextLargerAndSmallerNumber of2 = getNextLargerAndSmallerNumber(2); + System.out.println("Next larger of 2: " + of2.nextLarger); + System.out.println("Next smaller of 2: " + of2.nextSmaller); + + NextLargerAndSmallerNumber of5 = getNextLargerAndSmallerNumber(5); + System.out.println("Next larger of 5: " + of5.nextLarger); + System.out.println("Next smaller of 5: " + of5.nextSmaller); + + NextLargerAndSmallerNumber of7 = getNextLargerAndSmallerNumber(7); + System.out.println("Next larger of 7: " + of7.nextLarger); + System.out.println("Next smaller of 7: " + of7.nextSmaller); + + NextLargerAndSmallerNumber of8 = getNextLargerAndSmallerNumber(8); + System.out.println("Next larger of 8: " + of8.nextLarger); + System.out.println("Next smaller of 8: " + of8.nextSmaller); + + NextLargerAndSmallerNumber of15 = getNextLargerAndSmallerNumber(15); + System.out.println("Next larger of 15: " + of15.nextLarger); + System.out.println("Next smaller of 15: " + of15.nextSmaller); + } +} \ No newline at end of file diff --git a/src/main/java/com/ctci/treesandgraphs/FirstCommonAncestor.java b/src/main/java/com/ctci/treesandgraphs/FirstCommonAncestor.java index 988d9442..7a6ebc97 100644 --- a/src/main/java/com/ctci/treesandgraphs/FirstCommonAncestor.java +++ b/src/main/java/com/ctci/treesandgraphs/FirstCommonAncestor.java @@ -13,7 +13,7 @@ public class FirstCommonAncestor { /** * We recurse through the entire tree with a function called findFCA(TreeNode root, TreeNode TreeNode a, TreeNode b). * This function returns values as follows: - * - Returns p,if root's subtree includes p (and not q). + * - Returns p, if root's subtree includes p (and not q). * - Returns q, if root's subtree includes q (and not p). * - Returns null, if neither p nor q are in root's subtree. * - Else, returns the common ancestor of p and q. From f4f0a17bc20cb5197129cf1f32b1befa7feb43e9 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Mon, 18 Mar 2019 19:59:13 +0000 Subject: [PATCH 027/164] Improved next higher and lower number --- .../com/ctci/bitmanipulation/NextNumber.java | 101 ++++++++---------- 1 file changed, 45 insertions(+), 56 deletions(-) diff --git a/src/main/java/com/ctci/bitmanipulation/NextNumber.java b/src/main/java/com/ctci/bitmanipulation/NextNumber.java index af016aa5..ec817c13 100644 --- a/src/main/java/com/ctci/bitmanipulation/NextNumber.java +++ b/src/main/java/com/ctci/bitmanipulation/NextNumber.java @@ -26,84 +26,73 @@ private static NextLargerAndSmallerNumber getNextLargerAndSmallerNumber(int n) { } private static int getNextLarger(int n) { - int zeroPrecededByOneFromRight = 0; + int rightmostNonTrailingZero = 0; + int noOfZeros = 0; int noOfOnes = 0; - int mask = 1; + int temp = n; - /* Find the position of the bit pattern '01' from the right and then make it '10'. - For example, see below: + /* Count the number of zeros and ones until the rightmost non-trailing zero + For example, see below: n = 10110110011110 - ^^ - n = 10110110101110 (after bit swap) + ^ */ - for (int i = 0; i < Integer.BYTES * 8 - 1; i++) { - if ((n & mask) == mask) { - if ((n & mask << 1) == 0) { - n = (n & ~mask) | mask << 1; // swap the bits - break; - } - noOfOnes++; - } - zeroPrecededByOneFromRight++; - mask <<= 1; + while ((temp & 1) == 0 && temp != 0) { + noOfZeros++; + temp >>>= 1; } - if (zeroPrecededByOneFromRight == Integer.BYTES * 8 - 1) { + while ((temp & 1) == 1 && temp != 0) { + noOfOnes++; + temp >>>= 1; + } + + if (noOfZeros + noOfOnes == 31 || noOfZeros + noOfOnes == 0) { return -1; } - /* Shift all the 1s to the right end and then fill with 0s until the bit pattern '01. + /* Flip the bit and then shift all the 1s to the right end and then fill with 0s until the bit pattern '01. For example, consider the above number: - - n = 10110110101110 (after bit swap) - ^^ - next larger = 10110110100111 (the 1s are shifted to the right end) + n = 10110110011110 (original) + ^ + n = 10110110111110 (after flip bit) + ^ + next larger = 10110110100111 (the 1s are shifted to the right end and 0s to the left but before the rightmostNonTrailingZero) + ^ */ - mask = 1; - for (int i = 0; i < zeroPrecededByOneFromRight; i++) { - if (i < noOfOnes) { - n = n | mask; // set the bits - } else { - n = n & ~mask; // unset the bits - } - mask <<= 1; - } + rightmostNonTrailingZero = noOfOnes + noOfZeros; + n |= 1 << rightmostNonTrailingZero; // set the rightmost non-trailing zero + n &= ~((1 << rightmostNonTrailingZero) - 1); // unset all bits until rightmost non-trailing zero + n |= (1 << noOfOnes - 1) - 1; // set (noOfOnes - 1) bits from the right + return n; } private static int getNextSmaller(int n) { - int onePrecededByZeroFromRight = 0; + int rightmostNonTrailingOne = 0; int noOfZeros = 0; - int mask = 1; - - // find the position of the bit pattern '10' from the right and then make it '01' - for (int i = 0; i < Integer.BYTES * 8 - 1; i++) { - if ((n & mask) == 0) { - if ((n & mask << 1) == mask << 1) { - n = (n | mask) & ~(mask << 1); // swap the bits - break; - } - noOfZeros++; - } - onePrecededByZeroFromRight++; - mask <<= 1; + int noOfOnes = 0; + int temp = n; + + while ((temp & 1) == 1 && temp != 0) { + noOfOnes++; + temp >>>= 1; } - - if (onePrecededByZeroFromRight == Integer.BYTES * 8 - 1) { + + if (temp == 0) { return -1; } - // shift all the 0s to the right end and then fill with 1s until the bit pattern '10' - mask = 1; - for (int i = 0; i < onePrecededByZeroFromRight; i++) { - if (i < noOfZeros) { - n = n & ~mask; // unset the bits - } else { - n = n | mask; // set the bits - } - mask <<= 1; + while ((temp & 1) == 0 && temp != 0) { + noOfZeros++; + temp >>>= 1; } + + rightmostNonTrailingOne = noOfZeros + noOfOnes; + n &= ~(1 << rightmostNonTrailingOne); // unset the rightmost non-trailing one + n |= (1 << rightmostNonTrailingOne - 1); // set all the bits until rightmost non-trailing one + n &= ~((1 << noOfZeros - 1) - 1); // unset (noOfZeros - 1) bits from the right + return n; } From 55d5bd9afa72208753798986bbe53ef131b30cf0 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Mon, 18 Mar 2019 23:11:26 +0000 Subject: [PATCH 028/164] Bit swap done --- .../ctci/bitmanipulation/PairwiseSwap.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/main/java/com/ctci/bitmanipulation/PairwiseSwap.java diff --git a/src/main/java/com/ctci/bitmanipulation/PairwiseSwap.java b/src/main/java/com/ctci/bitmanipulation/PairwiseSwap.java new file mode 100644 index 00000000..ba54bdd2 --- /dev/null +++ b/src/main/java/com/ctci/bitmanipulation/PairwiseSwap.java @@ -0,0 +1,40 @@ +package com.ctci.bitmanipulation; + +/** + * @author rampatra + * @since 2019-03-18 + */ +public class PairwiseSwap { + + /** + * Write a program to swap odd and even bits in an integer with as few instructions as + * possible (e.g., bit O and bit 1 are swapped, bit 2 and bit 3 are swapped, and so on). + * + * Approach: + * Shift the odd bits to the left, shift the even bits to the right, and finally, OR both the results. + * Note: You can operate on only odd bits or only even bits by using the appropriate masks, for e.g., + * 0x55555555 for odd bits and 0xaaaaaaaa for even bits. + * + * @param n an input integer. + * @return an integer with even and odd bits swapped. + */ + private static int swapBits(int n) { + return ((n & 0x55555555) << 1) | ((n & 0xaaaaaaaa) >>> 1); + } + + public static void main(String[] args) { + System.out.println("Input: " + Integer.toBinaryString(1569) + + "\nOutput: " + Integer.toBinaryString(swapBits(1569))); + + assert Integer.toBinaryString(swapBits(1569)).equals("100100010010"); + + System.out.println("Input: " + Integer.toBinaryString(2680) + + "\nOutput: " + Integer.toBinaryString(swapBits(2680))); + + assert Integer.toBinaryString(swapBits(2680)).equals("10110110100"); + + // fyi + System.out.println(Integer.toBinaryString(0xaaaaaaaa)); + System.out.println(Integer.toBinaryString(0x99999999)); + } +} \ No newline at end of file From a2e9429ea2ed4a96688288e048661069921e0a70 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Thu, 21 Mar 2019 22:03:45 +0000 Subject: [PATCH 029/164] drawline done --- .../com/ctci/bitmanipulation/DrawLine.java | 109 ++++++++++++++++++ .../java/com/rampatra/bits/BinaryString.java | 28 +++++ 2 files changed, 137 insertions(+) create mode 100644 src/main/java/com/ctci/bitmanipulation/DrawLine.java create mode 100644 src/main/java/com/rampatra/bits/BinaryString.java diff --git a/src/main/java/com/ctci/bitmanipulation/DrawLine.java b/src/main/java/com/ctci/bitmanipulation/DrawLine.java new file mode 100644 index 00000000..3eb2be0c --- /dev/null +++ b/src/main/java/com/ctci/bitmanipulation/DrawLine.java @@ -0,0 +1,109 @@ +package com.ctci.bitmanipulation; + +import java.util.Arrays; + +/** + * @author rampatra + * @since 2019-03-21 + */ +public class DrawLine { + + /** + * A monochrome screen is stored as a single array of bytes, allowing eight consecutive pixels to be stored + * in one byte. The screen has width w, where w is divisible by 8 (that is, no byte will be split across rows). + * The height of the screen, of course, can be derived from the length of the array and the width. Implement a + * function that draws a horizontal line from (xl, y) to ( x2, y). + *

+ * The method signature should look something like: + * {@code drawline(byte[] screen, int width, int xl, int x2, int y)} + *

+ * Approach: + * First, find the numbers in which all bits has to be set. Next, find the starting number and apply the mask + * created from the starting offset. Do the same with the ending number. + * + * @param screen + * @param width + * @param x1 + * @param x2 + * @param y + */ + private static void drawLine(byte[] screen, int width, int x1, int x2, int y) { + int startOffset = x1 % 8; + int startFullByte = x1 / 8; + if (startOffset != 0) { + startFullByte++; + } + int endOffset = x2 % 8; + int endFullByte = x2 / 8; + if (endOffset != 7) { + endFullByte--; + } + + // all bits have to be set in in-between numbers + for (int i = startFullByte; i <= endFullByte; i++) { + screen[width / 8 * y + i] |= (byte) 0xff; + } + + /* 0xff is an integer literal which is like 000...11111111 (32 bits) but when we + cast it to a byte, we get rid of the initial 24 bits */ + byte startByteMask = (byte) (0xff >> startOffset); + byte endByteMask = (byte) ~(0xff >> endOffset + 1); + + if (x1 / 8 == x2 / 8) { // if starting and ending both lie in the same byte + screen[width / 8 * y + (x1 / 8)] |= (startByteMask & endByteMask); + } else { + screen[width / 8 * y + (startFullByte - 1)] |= startByteMask; // only specific bits set in the starting number + screen[width / 8 * y + (endFullByte + 1)] |= endByteMask; // only specific bits set in the ending number + } + } + + public static void main(String[] args) { + /* + Consider the below screen with width 32 as an example: + + byte[] screen = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; + + This screen has a width of 32 so you can assume the screen would be looking like: + + 9 10 11 12 + 5 6 7 8 + 1 2 3 4 + + x-axis is 5-20 (5th position to 20th position) + y-axis is 1 + + which means our line would lie in numbers 5, 6, and 7 + + so if you visualize these numbers in bits, it would be like: + + 00000101 00000110 00000111 + ^ ^ + and after drawing the line, the bits would become: + + 00000111 11111111 11111111 + + and in the output we would see: + + 7, -1, -1 instead of 5, 6, 7 + */ + byte[] screen = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; + System.out.println("Input: " + Arrays.toString(screen)); + drawLine(screen, 32, 5, 20, 1); + System.out.println("Output: " + Arrays.toString(screen)); + System.out.println("---"); + screen = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; + System.out.println("Input: " + Arrays.toString(screen)); + drawLine(screen, 32, 0, 5, 1); + System.out.println("Output: " + Arrays.toString(screen)); + System.out.println("---"); + screen = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; + System.out.println("Input: " + Arrays.toString(screen)); + drawLine(screen, 32, 3, 7, 1); + System.out.println("Output: " + Arrays.toString(screen)); + System.out.println("---"); + screen = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; + System.out.println("Input: " + Arrays.toString(screen)); + drawLine(screen, 16, 0, 7, 0); + System.out.println("Output: " + Arrays.toString(screen)); + } +} \ No newline at end of file diff --git a/src/main/java/com/rampatra/bits/BinaryString.java b/src/main/java/com/rampatra/bits/BinaryString.java new file mode 100644 index 00000000..ad0ffb84 --- /dev/null +++ b/src/main/java/com/rampatra/bits/BinaryString.java @@ -0,0 +1,28 @@ +package com.rampatra.bits; + +/** + * @author rampatra + * @since 2019-03-21 + */ +public class BinaryString { + + /** + * Returns the binary representation of a {@code byte}. + * + * @param b a byte. + * @return the binary representation of the input byte. + */ + private static String toBinaryString(byte b) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < Byte.SIZE; i++) { + sb.append(b & (byte) 1); + b >>= 1; + } + return sb.reverse().toString(); + } + + public static void main(String[] args) { + System.out.println(toBinaryString((byte) 0xff)); + System.out.println(toBinaryString((byte) (0xff >> 3))); + } +} From 8d2180a909ca8426cc26c1446152c6b594f48b58 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Thu, 21 Mar 2019 22:35:03 +0000 Subject: [PATCH 030/164] Added bit readme --- src/main/java/com/rampatra/bits/README.md | 46 +++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/main/java/com/rampatra/bits/README.md diff --git a/src/main/java/com/rampatra/bits/README.md b/src/main/java/com/rampatra/bits/README.md new file mode 100644 index 00000000..fba7b3ba --- /dev/null +++ b/src/main/java/com/rampatra/bits/README.md @@ -0,0 +1,46 @@ +## Bits (Work In Progress) + +### Basic Operators + +AND: +| x | y | x & y | +----------------- +| 0 | 0 | 0 | +| 0 | 1 | 0 | +| 1 | 0 | 0 | +| 1 | 1 | 1 | + +OR: +| x | y | x | y | +----------------- +| 0 | 0 | 0 | +| 0 | 1 | 1 | +| 1 | 0 | 1 | +| 1 | 1 | 1 | + +XOR: +| x | y | x ^ y | +----------------- +| 0 | 0 | 0 | +| 0 | 1 | 1 | +| 1 | 0 | 1 | +| 1 | 1 | 0 | + + +### Shifts + +1. Left Shift (<<): + + 1 << 3 = 8 + + 00000001 << 3 = 00001000 (only showing 8 bits) + +2. Right Shift: + + Two types: + + a. Signed Right Shift (>>): + + b. Unsigned Right Shift (>>>): + + \ No newline at end of file From d727b3c3c9aff0730a0cf6131f0c3c31ab27bbf0 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Fri, 22 Mar 2019 13:32:43 +0000 Subject: [PATCH 031/164] Updated bits readme --- .../com/ctci/treesandgraphs/GraphNode.java | 8 ++ .../treesandgraphs/RouteBetweenNodes.java | 8 ++ src/main/java/com/rampatra/bits/README.md | 84 +++++++++++-------- 3 files changed, 67 insertions(+), 33 deletions(-) create mode 100644 src/main/java/com/ctci/treesandgraphs/GraphNode.java create mode 100644 src/main/java/com/ctci/treesandgraphs/RouteBetweenNodes.java diff --git a/src/main/java/com/ctci/treesandgraphs/GraphNode.java b/src/main/java/com/ctci/treesandgraphs/GraphNode.java new file mode 100644 index 00000000..f9b5712b --- /dev/null +++ b/src/main/java/com/ctci/treesandgraphs/GraphNode.java @@ -0,0 +1,8 @@ +package com.ctci.treesandgraphs; + +/** + * @author rampatra + * @since 2019-03-21 + */ +public class GraphNode { +} diff --git a/src/main/java/com/ctci/treesandgraphs/RouteBetweenNodes.java b/src/main/java/com/ctci/treesandgraphs/RouteBetweenNodes.java new file mode 100644 index 00000000..33bd4fa7 --- /dev/null +++ b/src/main/java/com/ctci/treesandgraphs/RouteBetweenNodes.java @@ -0,0 +1,8 @@ +package com.ctci.treesandgraphs; + +/** + * @author rampatra + * @since 2019-03-21 + */ +public class RouteBetweenNodes { +} diff --git a/src/main/java/com/rampatra/bits/README.md b/src/main/java/com/rampatra/bits/README.md index fba7b3ba..686cd48d 100644 --- a/src/main/java/com/rampatra/bits/README.md +++ b/src/main/java/com/rampatra/bits/README.md @@ -2,45 +2,63 @@ ### Basic Operators -AND: -| x | y | x & y | ------------------ -| 0 | 0 | 0 | -| 0 | 1 | 0 | -| 1 | 0 | 0 | -| 1 | 1 | 1 | - -OR: -| x | y | x | y | ------------------ -| 0 | 0 | 0 | -| 0 | 1 | 1 | -| 1 | 0 | 1 | -| 1 | 1 | 1 | - -XOR: -| x | y | x ^ y | ------------------ -| 0 | 0 | 0 | -| 0 | 1 | 1 | -| 1 | 0 | 1 | -| 1 | 1 | 0 | +**AND:** + +| x | y | x `&` y | +----|---|---------| +| 0 | 0 | 0 | +| 0 | 1 | 0 | +| 1 | 0 | 0 | +| 1 | 1 | 1 | + +**OR:** + +| x | y | x `|` y | +|---|---|---------| +| 0 | 0 | 0 | +| 0 | 1 | 1 | +| 1 | 0 | 1 | +| 1 | 1 | 1 | + +**XOR:** + +| x | y | x `^` y | +|---|---|---------| +| 0 | 0 | 0 | +| 0 | 1 | 1 | +| 1 | 0 | 1 | +| 1 | 1 | 0 | ### Shifts -1. Left Shift (<<): +#### 1. Left Shift (<<): + +1 << 3 = 8 + +> 00000001 << 3 = 00001000 (only showing 8 bits) + +### 2. Right Shift: + +**Two types:** + +**a. Signed Right Shift (>>):** + +64 >> 2 = 16 + +> 001000000 >> 2 = 00010000 + +-64 >> 2 = -16 + + 111000000 >> 2 = 11110000 + +**b. Unsigned Right Shift (>>>):** - 1 << 3 = 8 +64 >>> 2 = 16 - 00000001 << 3 = 00001000 (only showing 8 bits) + 001000000 >>> 2 = 00010000 -2. Right Shift: +-64 >>> 2 = - Two types: - - a. Signed Right Shift (>>): - - b. Unsigned Right Shift (>>>): - + 111000000 >>> 2 = 00010000 \ No newline at end of file From 861415ce3498d94262a2e7c33780fee4041e39fc Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Fri, 22 Mar 2019 13:34:46 +0000 Subject: [PATCH 032/164] Updated bits readme --- src/main/java/com/rampatra/bits/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/rampatra/bits/README.md b/src/main/java/com/rampatra/bits/README.md index 686cd48d..a783c841 100644 --- a/src/main/java/com/rampatra/bits/README.md +++ b/src/main/java/com/rampatra/bits/README.md @@ -9,7 +9,7 @@ | 0 | 0 | 0 | | 0 | 1 | 0 | | 1 | 0 | 0 | -| 1 | 1 | 1 | +| 1 | 1 | 1 | **OR:** @@ -38,7 +38,7 @@ > 00000001 << 3 = 00001000 (only showing 8 bits) -### 2. Right Shift: +#### 2. Right Shift: **Two types:** @@ -50,15 +50,15 @@ -64 >> 2 = -16 - 111000000 >> 2 = 11110000 +> 111000000 >> 2 = 11110000 **b. Unsigned Right Shift (>>>):** 64 >>> 2 = 16 - 001000000 >>> 2 = 00010000 +> 001000000 >>> 2 = 00010000 -64 >>> 2 = - 111000000 >>> 2 = 00010000 +> 111000000 >>> 2 = 00010000 \ No newline at end of file From 51cfe39219efb213493d20f4aa84af16461138e3 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Fri, 22 Mar 2019 13:36:00 +0000 Subject: [PATCH 033/164] Updated bits readme --- src/main/java/com/rampatra/bits/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/rampatra/bits/README.md b/src/main/java/com/rampatra/bits/README.md index a783c841..4e53f14b 100644 --- a/src/main/java/com/rampatra/bits/README.md +++ b/src/main/java/com/rampatra/bits/README.md @@ -5,16 +5,16 @@ **AND:** | x | y | x `&` y | -----|---|---------| +----|---|:-------:| | 0 | 0 | 0 | | 0 | 1 | 0 | | 1 | 0 | 0 | | 1 | 1 | 1 | **OR:** - + | x | y | x `|` y | -|---|---|---------| +|---|---|:-------:| | 0 | 0 | 0 | | 0 | 1 | 1 | | 1 | 0 | 1 | @@ -23,7 +23,7 @@ **XOR:** | x | y | x `^` y | -|---|---|---------| +|---|---|:-------:| | 0 | 0 | 0 | | 0 | 1 | 1 | | 1 | 0 | 1 | From 50211a7bf4d30886e02f307427917ea6f51ceb91 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Fri, 22 Mar 2019 13:42:17 +0000 Subject: [PATCH 034/164] Updated bits readme --- src/main/java/com/rampatra/bits/README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/rampatra/bits/README.md b/src/main/java/com/rampatra/bits/README.md index 4e53f14b..0c09a34d 100644 --- a/src/main/java/com/rampatra/bits/README.md +++ b/src/main/java/com/rampatra/bits/README.md @@ -32,11 +32,14 @@ ### Shifts +_Disclaimer: We are taking `byte` (8 bits) as our datatype to explain the + concepts instead of the usual integer._ + #### 1. Left Shift (<<): 1 << 3 = 8 -> 00000001 << 3 = 00001000 (only showing 8 bits) +> 00000001 << 3 = 00001000 #### 2. Right Shift: @@ -58,7 +61,6 @@ > 001000000 >>> 2 = 00010000 --64 >>> 2 = +-64 >>> 2 = 56 -> 111000000 >>> 2 = 00010000 - \ No newline at end of file +> 111000000 >>> 2 = 00111000 \ No newline at end of file From 66f1d52b92dcf476ad05065ae8a40600fa6f1d41 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Fri, 22 Mar 2019 13:43:45 +0000 Subject: [PATCH 035/164] Updated bits readme --- src/main/java/com/rampatra/bits/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/rampatra/bits/README.md b/src/main/java/com/rampatra/bits/README.md index 0c09a34d..bf13f528 100644 --- a/src/main/java/com/rampatra/bits/README.md +++ b/src/main/java/com/rampatra/bits/README.md @@ -2,7 +2,7 @@ ### Basic Operators -**AND:** +#### AND: | x | y | x `&` y | ----|---|:-------:| @@ -11,7 +11,7 @@ | 1 | 0 | 0 | | 1 | 1 | 1 | -**OR:** +#### OR: | x | y | x `|` y | |---|---|:-------:| @@ -20,7 +20,7 @@ | 1 | 0 | 1 | | 1 | 1 | 1 | -**XOR:** +#### XOR: | x | y | x `^` y | |---|---|:-------:| From 3ab3e7a92279898cf47b6ea9e11f661ce024b97d Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sat, 30 Mar 2019 11:11:22 +0000 Subject: [PATCH 036/164] BFS in graph: done --- .../com/ctci/treesandgraphs/GraphNode.java | 11 ++- .../treesandgraphs/RouteBetweenNodes.java | 79 +++++++++++++++++++ .../com/rampatra/base/UndirectedGraph.java | 7 +- src/main/java/com/rampatra/bits/README.md | 25 +++++- .../rampatra/blockchain/MessageHandler.java | 9 ++- 5 files changed, 123 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/ctci/treesandgraphs/GraphNode.java b/src/main/java/com/ctci/treesandgraphs/GraphNode.java index f9b5712b..573cccf3 100644 --- a/src/main/java/com/ctci/treesandgraphs/GraphNode.java +++ b/src/main/java/com/ctci/treesandgraphs/GraphNode.java @@ -1,8 +1,17 @@ package com.ctci.treesandgraphs; +import java.util.HashSet; +import java.util.Set; + /** * @author rampatra * @since 2019-03-21 */ public class GraphNode { -} + int value; + Set adjacent = new HashSet<>(); + + GraphNode(int value) { + this.value = value; + } +} \ No newline at end of file diff --git a/src/main/java/com/ctci/treesandgraphs/RouteBetweenNodes.java b/src/main/java/com/ctci/treesandgraphs/RouteBetweenNodes.java index 33bd4fa7..691d0d5b 100644 --- a/src/main/java/com/ctci/treesandgraphs/RouteBetweenNodes.java +++ b/src/main/java/com/ctci/treesandgraphs/RouteBetweenNodes.java @@ -1,8 +1,87 @@ package com.ctci.treesandgraphs; +import java.util.ArrayDeque; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Queue; +import java.util.Set; + /** * @author rampatra * @since 2019-03-21 */ public class RouteBetweenNodes { + + public static void main(String[] args) { + Graph g = new Graph(); + g.addEdge(1, 2); + g.addEdge(2, 3); + g.addEdge(4, 5); + g.addEdge(5, 6); + System.out.println("Route exists from 1 to 2: " + g.isRoutePresent(1, 2)); + System.out.println("Route exists from 2 to 5: " + g.isRoutePresent(2, 5)); + System.out.println("Route exists from 1 to 3: " + g.isRoutePresent(1, 3)); + System.out.println("Route exists from 4 to 6: " + g.isRoutePresent(4, 6)); + System.out.println("Route exists from 6 to 4: " + g.isRoutePresent(6, 4)); + System.out.println("Route exists from 6 to 5: " + g.isRoutePresent(6, 5)); + } +} + +class Graph { + + private static final Map nodes = new HashMap<>(); + + void addEdge(int v1, int v2) { + GraphNode n1 = nodes.get(v1); + GraphNode n2 = nodes.get(v2); + + if (n1 == null) { + n1 = new GraphNode(v1); + nodes.put(v1, n1); + } + if (n2 == null) { + n2 = new GraphNode(v2); + nodes.put(v2, n2); + } + + n1.adjacent.add(n2); // as it is a directed graph + } + + /** + * Checks for a path from a node with value {@code v1} to another node with value {@code v2} in a breadth-first + * manner. + * + * @param v1 the value of the first node or starting node. + * @param v2 the value of the ending node. + * @return {@code true} if path exists, {@code false} otherwise. + */ + boolean isRoutePresent(int v1, int v2) { + Queue queue = new ArrayDeque<>(); + Set visited = new HashSet<>(); + + GraphNode n1 = nodes.get(v1); + GraphNode n2 = nodes.get(v2); + + if (n1 == null || n2 == null) { + return false; + } + + queue.add(n1); + + while (!queue.isEmpty()) { + GraphNode n = queue.poll(); + + if (visited.contains(n)) { + continue; + } + if (n.adjacent.contains(n2)) { + return true; + } + queue.addAll(n.adjacent); + visited.add(n); + } + + return false; + } } diff --git a/src/main/java/com/rampatra/base/UndirectedGraph.java b/src/main/java/com/rampatra/base/UndirectedGraph.java index 88ed8231..661fa45a 100644 --- a/src/main/java/com/rampatra/base/UndirectedGraph.java +++ b/src/main/java/com/rampatra/base/UndirectedGraph.java @@ -18,8 +18,9 @@ public class UndirectedGraph> extends Graph { private Map> nodes = new HashMap<>(); /** - * Adds an edge between a node with value {@code value} and another node with value {@code adjacentValue}. - * If nodes with respective values are not present in the graph then this method creates them. + * Adds an edge between a node with value {@code value} and another node with value {@code adjacentValue}. As the + * graph is undirected, the edges are added in both the nodes. If nodes with respective values are not present in + * the graph then this method creates the nodes. * * @param value refers to the value for first node * @param adjacentValue refers to the value for the second node @@ -143,7 +144,7 @@ public static void main(String[] args) { graph.print(); System.out.println("----"); - + // has path DFS System.out.println(graph.hasPathDFS(1, 5)); System.out.println(graph.hasPathDFS(1, 6)); diff --git a/src/main/java/com/rampatra/bits/README.md b/src/main/java/com/rampatra/bits/README.md index bf13f528..ca236161 100644 --- a/src/main/java/com/rampatra/bits/README.md +++ b/src/main/java/com/rampatra/bits/README.md @@ -2,7 +2,7 @@ ### Basic Operators -#### AND: +#### AND: | x | y | x `&` y | ----|---|:-------:| @@ -63,4 +63,25 @@ _Disclaimer: We are taking `byte` (8 bits) as our datatype to explain the -64 >>> 2 = 56 -> 111000000 >>> 2 = 00111000 \ No newline at end of file +> 111000000 >>> 2 = 00111000 + +### Helpful Masks + +#### 1. Set the 4th bit from right: + +```java +int mask = 1 << 3; +``` + +For example, + +``` +00100000 | mask = 00101000 +``` + +#### 2. Set the first 3 bits from right: + +```java +int mask = (1 << 4) - 1; +``` + diff --git a/src/main/java/com/rampatra/blockchain/MessageHandler.java b/src/main/java/com/rampatra/blockchain/MessageHandler.java index cfd51310..52aaf328 100644 --- a/src/main/java/com/rampatra/blockchain/MessageHandler.java +++ b/src/main/java/com/rampatra/blockchain/MessageHandler.java @@ -33,12 +33,17 @@ public void run() { while ((message = (Message) in.readObject()) != null) { handleMessage(message); } - in.close(); - out.close(); } catch (Exception e) { if (!(e instanceof SocketException)) { throw new RuntimeException(e); } + } finally { + try { + in.close(); + out.close(); + } catch (Exception e) { + // do nothing + } } } From 932f210c0d21f7842cde857a3e57e9521b2bc0c3 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sat, 30 Mar 2019 11:14:51 +0000 Subject: [PATCH 037/164] Minor refactorings --- .../java/com/rampatra/blockchain/P2P.java | 68 ++++++++++++++++++ .../java/com/rampatra/blockchain/Peer.java | 71 +------------------ 2 files changed, 69 insertions(+), 70 deletions(-) diff --git a/src/main/java/com/rampatra/blockchain/P2P.java b/src/main/java/com/rampatra/blockchain/P2P.java index c18072ff..c8c65ac6 100644 --- a/src/main/java/com/rampatra/blockchain/P2P.java +++ b/src/main/java/com/rampatra/blockchain/P2P.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Scanner; /** * @author rampatra @@ -64,4 +65,71 @@ public static void showPeersWithBlockchain() { System.out.println("Peer " + (i + 1) + " (" + peers.get(i).getPort() + "): " + peers.get(i).getBlockchain()); } } + + /** + * The main starting point of the blockchain demo. At first, add some peers (option 1) and mine some data + * by choosing a particular peer (option 2). You would soon see that the newly mined block is broadcast to + * all the peers. + * + * @param args + */ + public static void main(String[] args) { + try { + int menuChoice; + int peerIndex; + String data; + Scanner s = new Scanner(System.in); + Blockchain blockchain = new Blockchain(new ArrayList<>(), 3); + + while (true) { + + System.out.println("\n======= Welcome to Blockchain in Java ======="); + System.out.println("1. Add Peer"); + System.out.println("2. Mine data in peer"); + System.out.println("3. Remove peer"); + System.out.println("4. Show peers"); + System.out.println("5. Exit"); + + menuChoice = s.nextInt(); + + switch (menuChoice) { + case 1: + P2P.addPeer(blockchain); + System.out.println("New peer added!"); + P2P.showPeersWithBlockchain(); + break; + case 2: + System.out.println("Choose peer: (a number for ex. 1, 2, etc.)"); + P2P.showPeers(); + peerIndex = s.nextInt(); + Peer p = P2P.getPeer(peerIndex - 1); + System.out.println("Enter data: (a string with no spaces)"); + data = s.next(); + p.mine(data); + System.out.println("Data mined!"); + P2P.showPeersWithBlockchain(); + break; + case 3: + System.out.println("Choose peer: (a number for ex. 1, 2, etc.)"); + P2P.showPeers(); + peerIndex = s.nextInt(); + P2P.removePeer(peerIndex - 1); + System.out.println("Peer " + peerIndex + " removed!"); + P2P.showPeersWithBlockchain(); + break; + case 4: + P2P.showPeersWithBlockchain(); + break; + case 5: + P2P.removeAllPeers(); + System.out.println("Bye, see you soon!"); + System.exit(0); + default: + System.out.println("Wrong choice!"); + } + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } } \ No newline at end of file diff --git a/src/main/java/com/rampatra/blockchain/Peer.java b/src/main/java/com/rampatra/blockchain/Peer.java index 9d0e553d..fcb34632 100644 --- a/src/main/java/com/rampatra/blockchain/Peer.java +++ b/src/main/java/com/rampatra/blockchain/Peer.java @@ -3,9 +3,7 @@ import java.io.ObjectOutputStream; import java.net.ServerSocket; import java.net.Socket; -import java.util.ArrayList; import java.util.List; -import java.util.Scanner; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.stream.Collectors; @@ -59,7 +57,7 @@ public void stopServer() { } /** - * Once a new peer is created and added to the network, it requests the latest block from + * Once a new peer is created and added to the network, it requests the latest block from * all the peers and updates its blockchain if it is outdated. */ private void getLatestBlockFromPeers() { @@ -119,71 +117,4 @@ public String toString() { sb.append('}'); return sb.toString(); } - - /** - * The main starting point of the blockchain demo. At first, add some peers (option 1) and mine some data - * by choosing a particular peer (option 2). You would soon see that the newly mined block is broadcast to - * all the peers. - * - * @param args - */ - public static void main(String[] args) { - try { - int menuChoice; - int peerIndex; - String data; - Scanner s = new Scanner(System.in); - Blockchain blockchain = new Blockchain(new ArrayList<>(), 3); - - while (true) { - - System.out.println("\n======= Welcome to Blockchain in Java ======="); - System.out.println("1. Add Peer"); - System.out.println("2. Mine data in peer"); - System.out.println("3. Remove peer"); - System.out.println("4. Show peers"); - System.out.println("5. Exit"); - - menuChoice = s.nextInt(); - - switch (menuChoice) { - case 1: - P2P.addPeer(blockchain); - System.out.println("New peer added!"); - P2P.showPeersWithBlockchain(); - break; - case 2: - System.out.println("Choose peer: (a number for ex. 1, 2, etc.)"); - P2P.showPeers(); - peerIndex = s.nextInt(); - Peer p = P2P.getPeer(peerIndex - 1); - System.out.println("Enter data: (a string with no spaces)"); - data = s.next(); - p.mine(data); - System.out.println("Data mined!"); - P2P.showPeersWithBlockchain(); - break; - case 3: - System.out.println("Choose peer: (a number for ex. 1, 2, etc.)"); - P2P.showPeers(); - peerIndex = s.nextInt(); - P2P.removePeer(peerIndex - 1); - System.out.println("Peer " + peerIndex + " removed!"); - P2P.showPeersWithBlockchain(); - break; - case 4: - P2P.showPeersWithBlockchain(); - break; - case 5: - P2P.removeAllPeers(); - System.out.println("Bye, see you soon!"); - System.exit(0); - default: - System.out.println("Wrong choice!"); - } - } - } catch (Exception e) { - throw new RuntimeException(e); - } - } } \ No newline at end of file From 59060f82287c40b30e2361ffad23acdb7ddec467 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sat, 30 Mar 2019 12:24:50 +0000 Subject: [PATCH 038/164] Added more info on bits readme --- .../treesandgraphs/RouteBetweenNodes.java | 9 +++- src/main/java/com/rampatra/bits/README.md | 43 +++++++++++++++++-- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/ctci/treesandgraphs/RouteBetweenNodes.java b/src/main/java/com/ctci/treesandgraphs/RouteBetweenNodes.java index 691d0d5b..66576b90 100644 --- a/src/main/java/com/ctci/treesandgraphs/RouteBetweenNodes.java +++ b/src/main/java/com/ctci/treesandgraphs/RouteBetweenNodes.java @@ -32,6 +32,13 @@ class Graph { private static final Map nodes = new HashMap<>(); + /** + * Adds an edge from a node with value {@code v1} to another node with value {@code v2}. + * Note: This code doesn't work for nodes having duplicate values. + * + * @param v1 + * @param v2 + */ void addEdge(int v1, int v2) { GraphNode n1 = nodes.get(v1); GraphNode n2 = nodes.get(v2); @@ -50,7 +57,7 @@ void addEdge(int v1, int v2) { /** * Checks for a path from a node with value {@code v1} to another node with value {@code v2} in a breadth-first - * manner. + * manner. Note: This code doesn't work for nodes having duplicate values. * * @param v1 the value of the first node or starting node. * @param v2 the value of the ending node. diff --git a/src/main/java/com/rampatra/bits/README.md b/src/main/java/com/rampatra/bits/README.md index ca236161..82737d57 100644 --- a/src/main/java/com/rampatra/bits/README.md +++ b/src/main/java/com/rampatra/bits/README.md @@ -70,18 +70,53 @@ _Disclaimer: We are taking `byte` (8 bits) as our datatype to explain the #### 1. Set the 4th bit from right: ```java -int mask = 1 << 3; +byte mask = 1 << 3; ``` -For example, +Explanation, ``` -00100000 | mask = 00101000 +00000001 << 3 = 00001000 ``` #### 2. Set the first 3 bits from right: ```java -int mask = (1 << 4) - 1; +byte mask = (1 << 3) - 1; ``` +Explanation, + +``` +00000001 << 3 = 00001000 + +00001000 - 00000001 = 00000111 +``` + +#### 3. Mask with alternating 1010...10 + +```java +byte mask = 0x55; +``` + +#### 4. Mask with alternating 0101...01 + +```java +byte mask = 0xaa; +``` + +#### 5. Unset the 4th bit + +```java +byte mask = 1 << 3; + +byte num = num & ~mask; +``` + +Explanation, + +``` +00000001 << 3 = 00001000 + +~(00001000) = 11110111 +``` \ No newline at end of file From 2f38c3e103501f9d5fcdb370dca9fbb8bcca67af Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sat, 30 Mar 2019 12:28:33 +0000 Subject: [PATCH 039/164] Fixed github.com markdown render issue --- src/main/java/com/rampatra/bits/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/rampatra/bits/README.md b/src/main/java/com/rampatra/bits/README.md index 82737d57..45b73717 100644 --- a/src/main/java/com/rampatra/bits/README.md +++ b/src/main/java/com/rampatra/bits/README.md @@ -13,12 +13,12 @@ #### OR: -| x | y | x `|` y | -|---|---|:-------:| -| 0 | 0 | 0 | -| 0 | 1 | 1 | -| 1 | 0 | 1 | -| 1 | 1 | 1 | +| x | y | x `\|` y | +|---|---|:--------:| +| 0 | 0 | 0 | +| 0 | 1 | 1 | +| 1 | 0 | 1 | +| 1 | 1 | 1 | #### XOR: From 083f426960f604139719d5e7b9548141b60a04ce Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sat, 30 Mar 2019 19:46:45 +0000 Subject: [PATCH 040/164] Added a readme about database --- .../ctci/bitmanipulation/PairwiseSwap.java | 2 +- src/main/java/com/rampatra/bits/README.md | 8 +-- src/main/java/com/rampatra/database/README.md | 54 +++++++++++++++++++ 3 files changed, 59 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/rampatra/database/README.md diff --git a/src/main/java/com/ctci/bitmanipulation/PairwiseSwap.java b/src/main/java/com/ctci/bitmanipulation/PairwiseSwap.java index ba54bdd2..a1219d47 100644 --- a/src/main/java/com/ctci/bitmanipulation/PairwiseSwap.java +++ b/src/main/java/com/ctci/bitmanipulation/PairwiseSwap.java @@ -34,7 +34,7 @@ public static void main(String[] args) { assert Integer.toBinaryString(swapBits(2680)).equals("10110110100"); // fyi + System.out.println(Integer.toBinaryString(0x55555555)); System.out.println(Integer.toBinaryString(0xaaaaaaaa)); - System.out.println(Integer.toBinaryString(0x99999999)); } } \ No newline at end of file diff --git a/src/main/java/com/rampatra/bits/README.md b/src/main/java/com/rampatra/bits/README.md index 45b73717..30119f20 100644 --- a/src/main/java/com/rampatra/bits/README.md +++ b/src/main/java/com/rampatra/bits/README.md @@ -1,6 +1,6 @@ -## Bits (Work In Progress) +# Bits -### Basic Operators +## Basic Operators #### AND: @@ -30,7 +30,7 @@ | 1 | 1 | 0 | -### Shifts +## Shifts _Disclaimer: We are taking `byte` (8 bits) as our datatype to explain the concepts instead of the usual integer._ @@ -65,7 +65,7 @@ _Disclaimer: We are taking `byte` (8 bits) as our datatype to explain the > 111000000 >>> 2 = 00111000 -### Helpful Masks +## Helpful Masks #### 1. Set the 4th bit from right: diff --git a/src/main/java/com/rampatra/database/README.md b/src/main/java/com/rampatra/database/README.md new file mode 100644 index 00000000..ffd58e42 --- /dev/null +++ b/src/main/java/com/rampatra/database/README.md @@ -0,0 +1,54 @@ +# Relational Database (WIP) + +## Types of SQL commands + +1. DDL +2. DML +3. DCL +4. TCL + +| Type | Command List | +|-------|-------------------| +| DDL | CREATE | +| | DROP | +| | ALTER | +| | RENAME | +| | TRUNCATE | +| | | +| DML | SELECT | +| | INSERT | +| | UPDATE | +| | DELETE | +| | | +| DCL | GRANT | +| | REVOKE | +| | | +| TCL | START TRANSACTION | +| | COMMIT | +| | ROLLBACK | + +## Types of Joins + +1. Inner Join +2. Left Outer Join +3. Right Outer Join +4. Full Join +5. Self Join + +## Normalization Forms + +1. 1NF +2. 2NF +3. 3NF +4. BCNF +5. 4NF +6. 5NF + +#### 1NF + +Required conditions: + +a. All values should be atomic (non-breakable). +b. There should be a candidate key or a composite key (basically you should be able to uniquely identify all records in the table). + + \ No newline at end of file From 2005be4ae23e15b136599b7ec1898e3e44d2106a Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sun, 31 Mar 2019 17:50:31 +0100 Subject: [PATCH 041/164] BuildOrder: done, time complexity: pending --- .../com/ctci/treesandgraphs/BuildOrder.java | 128 +++++++++++++++++- .../treesandgraphs/RouteBetweenNodes.java | 128 +++++++++--------- src/main/java/com/rampatra/database/README.md | 22 +++ 3 files changed, 211 insertions(+), 67 deletions(-) diff --git a/src/main/java/com/ctci/treesandgraphs/BuildOrder.java b/src/main/java/com/ctci/treesandgraphs/BuildOrder.java index 4afab552..cb5b72fc 100644 --- a/src/main/java/com/ctci/treesandgraphs/BuildOrder.java +++ b/src/main/java/com/ctci/treesandgraphs/BuildOrder.java @@ -1,14 +1,136 @@ package com.ctci.treesandgraphs; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Stream; + /** * @author rampatra * @since 2019-02-21 */ public class BuildOrder { - // todo - + private class Project { + String name; + Set dependencies = new HashSet<>(); + + Project(String name) { + this.name = name; + } + + @Override + public String toString() { + return name; + } + } + + private final Map projects = new HashMap<>(); + + private void addProjects(Stream projectNames) { + projectNames.forEach(name -> projects.put(name, new Project(name))); + } + + /** + * Adds a directed edge from {@code projectName2} to {@code ProjectName1}. This means {@code projectName2} is + * dependent on {@code projectName1}, i.e, {@code projectName1} has to be built before {@code projectName2}. + * + * @param projectName1 name of project 1 + * @param projectName2 name of project 2 + */ + private void addDependency(String projectName1, String projectName2) { + Project p1 = projects.get(projectName1); + Project p2 = projects.get(projectName2); + + if (p1 == null) { + p1 = new Project(projectName1); + projects.put(projectName1, p1); + } + if (p2 == null) { + p2 = new Project(projectName2); + projects.put(projectName2, p2); + } + + p2.dependencies.add(p1); + } + + /** + * Determines the order in which the projects need to be built. + * Time complexity: TODO + * + * @return a list of projects in the order they should be built, the first project should be built first and so on. + */ + private List getBuildOrder() { + Map projectsBuilt = new LinkedHashMap<>(); // linked hashmap is needed to maintain the insertion order + + while (projectsBuilt.size() != projects.size()) { + // find the projects which are not dependent on any project + Set nextProjectsToBuild = getProjectsWithNoDependencies(projectsBuilt); + + // if there are no further independent projects to build, then we can't proceed further + if (nextProjectsToBuild.size() == 0) { + throw new IllegalStateException("Error: Projects can't be built."); + } + nextProjectsToBuild.forEach(p -> projectsBuilt.put(p.name, p)); + + // once a project is built, remove the dependencies from all other projects dependent on this + removeDependency(nextProjectsToBuild); + } + + return new ArrayList<>(projectsBuilt.values()); + } + + private Set getProjectsWithNoDependencies(Map alreadyBuildProjects) { + Set unBuiltProjectsWithZeroDependencies = new HashSet<>(); + + for (Map.Entry entry : projects.entrySet()) { + if (entry.getValue().dependencies.size() == 0 && alreadyBuildProjects.get(entry.getKey()) == null) { + unBuiltProjectsWithZeroDependencies.add(entry.getValue()); + } + } + + return unBuiltProjectsWithZeroDependencies; + } + + private void removeDependency(Set newlyBuiltProjects) { + projects.forEach((n, p) -> p.dependencies.removeAll(newlyBuiltProjects)); + } + + public static void main(String[] args) { + /* test case 1 + ––––––––––– b + | ↑ + ↓ | + f <–– a <–– d <–– c + + + */ + BuildOrder buildOrder = new BuildOrder(); + buildOrder.addProjects(Stream.of("a", "b", "c", "d", "e", "f")); + buildOrder.addDependency("a", "d"); + buildOrder.addDependency("f", "b"); + buildOrder.addDependency("b", "d"); + buildOrder.addDependency("f", "a"); + buildOrder.addDependency("d", "c"); + System.out.println(buildOrder.getBuildOrder()); + + // test case 2 + buildOrder = new BuildOrder(); + buildOrder.addProjects(Stream.of("a", "b", "c", "d", "e", "f", "g")); + buildOrder.addDependency("d", "g"); + buildOrder.addDependency("f", "b"); + buildOrder.addDependency("f", "c"); + buildOrder.addDependency("f", "a"); + buildOrder.addDependency("c", "a"); + buildOrder.addDependency("b", "a"); + buildOrder.addDependency("b", "e"); + buildOrder.addDependency("a", "e"); + System.out.println(buildOrder.getBuildOrder()); } -} +} \ No newline at end of file diff --git a/src/main/java/com/ctci/treesandgraphs/RouteBetweenNodes.java b/src/main/java/com/ctci/treesandgraphs/RouteBetweenNodes.java index 66576b90..b849b8c8 100644 --- a/src/main/java/com/ctci/treesandgraphs/RouteBetweenNodes.java +++ b/src/main/java/com/ctci/treesandgraphs/RouteBetweenNodes.java @@ -13,82 +13,82 @@ */ public class RouteBetweenNodes { - public static void main(String[] args) { - Graph g = new Graph(); - g.addEdge(1, 2); - g.addEdge(2, 3); - g.addEdge(4, 5); - g.addEdge(5, 6); - System.out.println("Route exists from 1 to 2: " + g.isRoutePresent(1, 2)); - System.out.println("Route exists from 2 to 5: " + g.isRoutePresent(2, 5)); - System.out.println("Route exists from 1 to 3: " + g.isRoutePresent(1, 3)); - System.out.println("Route exists from 4 to 6: " + g.isRoutePresent(4, 6)); - System.out.println("Route exists from 6 to 4: " + g.isRoutePresent(6, 4)); - System.out.println("Route exists from 6 to 5: " + g.isRoutePresent(6, 5)); - } -} + class Graph { -class Graph { + private final Map nodes = new HashMap<>(); - private static final Map nodes = new HashMap<>(); + /** + * Adds an edge from a node with value {@code v1} to another node with value {@code v2}. + * Note: This code doesn't work for nodes having duplicate values. + * + * @param v1 + * @param v2 + */ + void addEdge(int v1, int v2) { + GraphNode n1 = nodes.get(v1); + GraphNode n2 = nodes.get(v2); - /** - * Adds an edge from a node with value {@code v1} to another node with value {@code v2}. - * Note: This code doesn't work for nodes having duplicate values. - * - * @param v1 - * @param v2 - */ - void addEdge(int v1, int v2) { - GraphNode n1 = nodes.get(v1); - GraphNode n2 = nodes.get(v2); + if (n1 == null) { + n1 = new GraphNode(v1); + nodes.put(v1, n1); + } + if (n2 == null) { + n2 = new GraphNode(v2); + nodes.put(v2, n2); + } - if (n1 == null) { - n1 = new GraphNode(v1); - nodes.put(v1, n1); + n1.adjacent.add(n2); // as it is a directed graph } - if (n2 == null) { - n2 = new GraphNode(v2); - nodes.put(v2, n2); - } - - n1.adjacent.add(n2); // as it is a directed graph - } - /** - * Checks for a path from a node with value {@code v1} to another node with value {@code v2} in a breadth-first - * manner. Note: This code doesn't work for nodes having duplicate values. - * - * @param v1 the value of the first node or starting node. - * @param v2 the value of the ending node. - * @return {@code true} if path exists, {@code false} otherwise. - */ - boolean isRoutePresent(int v1, int v2) { - Queue queue = new ArrayDeque<>(); - Set visited = new HashSet<>(); + /** + * Checks for a path from a node with value {@code v1} to another node with value {@code v2} in a breadth-first + * manner. Note: This code doesn't work for nodes having duplicate values. + * + * @param v1 the value of the first node or starting node. + * @param v2 the value of the ending node. + * @return {@code true} if path exists, {@code false} otherwise. + */ + boolean isRoutePresent(int v1, int v2) { + Queue queue = new ArrayDeque<>(); + Set visited = new HashSet<>(); - GraphNode n1 = nodes.get(v1); - GraphNode n2 = nodes.get(v2); + GraphNode n1 = nodes.get(v1); + GraphNode n2 = nodes.get(v2); - if (n1 == null || n2 == null) { - return false; - } + if (n1 == null || n2 == null) { + return false; + } - queue.add(n1); + queue.add(n1); - while (!queue.isEmpty()) { - GraphNode n = queue.poll(); + while (!queue.isEmpty()) { + GraphNode n = queue.poll(); - if (visited.contains(n)) { - continue; - } - if (n.adjacent.contains(n2)) { - return true; + if (visited.contains(n)) { + continue; + } + if (n.adjacent.contains(n2)) { + return true; + } + queue.addAll(n.adjacent); + visited.add(n); } - queue.addAll(n.adjacent); - visited.add(n); + + return false; } + } - return false; + public static void main(String[] args) { + Graph g = new RouteBetweenNodes().new Graph(); + g.addEdge(1, 2); + g.addEdge(2, 3); + g.addEdge(4, 5); + g.addEdge(5, 6); + System.out.println("Route exists from 1 to 2: " + g.isRoutePresent(1, 2)); + System.out.println("Route exists from 2 to 5: " + g.isRoutePresent(2, 5)); + System.out.println("Route exists from 1 to 3: " + g.isRoutePresent(1, 3)); + System.out.println("Route exists from 4 to 6: " + g.isRoutePresent(4, 6)); + System.out.println("Route exists from 6 to 4: " + g.isRoutePresent(6, 4)); + System.out.println("Route exists from 6 to 5: " + g.isRoutePresent(6, 5)); } -} +} \ No newline at end of file diff --git a/src/main/java/com/rampatra/database/README.md b/src/main/java/com/rampatra/database/README.md index ffd58e42..0ea2737c 100644 --- a/src/main/java/com/rampatra/database/README.md +++ b/src/main/java/com/rampatra/database/README.md @@ -1,5 +1,27 @@ # Relational Database (WIP) +A __relational database__ is a digital database based on +the [relational model](https://en.wikipedia.org/wiki/Relational_model) of +data. In simple words, it is a collection of data items with pre-defined +relationships between them. These items are organized as a set of tables, +with columns and rows. Each column stores some specific attribute of an object/entity and the +row represents a specific object/entity. + +A software system used to maintain relational databases is a __relational +database management system (RDBMS)__, for e.g., MySQL, Oracle DB, PostgreSQL, etc. +Virtually all relational database systems use __SQL (Structured Query Language)__ +for querying and maintaining the database. + +## Basic Definitions + +1. Primary Key + +2. Candidate Key + +3. Composite Key + +4. Prime/Non-prime attribute + ## Types of SQL commands 1. DDL From 89667bdfadccf1e47b62eef0ce1af55865e361b9 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sun, 31 Mar 2019 17:54:27 +0100 Subject: [PATCH 042/164] Added some comments --- src/main/java/com/ctci/treesandgraphs/BuildOrder.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/ctci/treesandgraphs/BuildOrder.java b/src/main/java/com/ctci/treesandgraphs/BuildOrder.java index cb5b72fc..6d64e48a 100644 --- a/src/main/java/com/ctci/treesandgraphs/BuildOrder.java +++ b/src/main/java/com/ctci/treesandgraphs/BuildOrder.java @@ -10,6 +10,13 @@ import java.util.stream.Stream; /** + * You are given a list of projects and a list of dependencies (which is a list of pairs of projects, where the second + * project is dependent on the first project). All of a project's dependencies must be built before the project is. Find + * a build order that will allow the projects to be built. If there is no valid build order, return an error. + * EXAMPLE + * Input: projects: a, b, c, d, e, f and dependencies: (a, d), (f, b), (b, d), (f, a), (d, c) + * Output: f, e, a, b, d, c + * * @author rampatra * @since 2019-02-21 */ @@ -109,7 +116,8 @@ public static void main(String[] args) { ↓ | f <–– a <–– d <–– c - + Note: Project "a" is dependent on "f", and project "d" is dependent on "a", and so on. + */ BuildOrder buildOrder = new BuildOrder(); buildOrder.addProjects(Stream.of("a", "b", "c", "d", "e", "f")); From 176b5a891f839f0a92de82e1b3eb8f4a49db5687 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Mon, 1 Apr 2019 23:23:33 +0100 Subject: [PATCH 043/164] Parsing integers: 90% done --- .../com/rampatra/strings/IntegerToString.java | 51 +++++++++++++++ .../com/rampatra/strings/StringToInteger.java | 64 +++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 src/main/java/com/rampatra/strings/IntegerToString.java create mode 100644 src/main/java/com/rampatra/strings/StringToInteger.java diff --git a/src/main/java/com/rampatra/strings/IntegerToString.java b/src/main/java/com/rampatra/strings/IntegerToString.java new file mode 100644 index 00000000..08d27131 --- /dev/null +++ b/src/main/java/com/rampatra/strings/IntegerToString.java @@ -0,0 +1,51 @@ +package com.rampatra.strings; + +/** + * @author rampatra + * @since 2019-04-01 + */ +public class IntegerToString { + + private static final int[] sizeTable = {9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, + 999999999, Integer.MAX_VALUE}; + + private static String getStringFromInteger(int num) { + boolean isNegative = num < 0; + num = isNegative ? -num : num; + int size = getStringSize(num); + size = isNegative ? size + 1 : size; + char[] chars = new char[size]; + + int rem; + for (int i = size - 1; isNegative ? i > 0 : i >= 0; i--) { + rem = num % 10; + num = num / 10; + chars[i] = (char) (rem + '0'); + } + + if (isNegative) { + chars[0] = '-'; + } + + return new String(chars); + } + + private static int getStringSize(int num) { + if (num == Integer.MAX_VALUE) return 10; + + for (int i = 0; ; i++) { + if (num < sizeTable[i]) { + return i + 1; + } + } + } + + public static void main(String[] args) { + System.out.println(getStringFromInteger(0)); + System.out.println(getStringFromInteger(123)); + System.out.println(getStringFromInteger(+123)); + System.out.println(getStringFromInteger(-123)); + System.out.println(getStringFromInteger(Integer.MAX_VALUE)); + System.out.println(getStringFromInteger(Integer.MIN_VALUE)); // not working + } +} \ No newline at end of file diff --git a/src/main/java/com/rampatra/strings/StringToInteger.java b/src/main/java/com/rampatra/strings/StringToInteger.java new file mode 100644 index 00000000..53b386e7 --- /dev/null +++ b/src/main/java/com/rampatra/strings/StringToInteger.java @@ -0,0 +1,64 @@ +package com.rampatra.strings; + +/** + * @author rampatra + * @since 2019-04-01 + */ +public class StringToInteger { + + /** + * This method converts a {@code String} to an {@code int}. It assumes the {@code string} contains ASCII + * characters only. + * + * @param str the input string, for example, 0, 123, +123, -123, etc. + * @return the equivalent integer. + */ + private static int getIntegerFromString(String str) { + int number = 0; + int digit; + char ch; + int weight = 0; + boolean isNegative = false; + + // remove all leading and trailing whitespaces + str = str.trim(); + if (str.length() == 0) { + throw new NumberFormatException("Empty string"); + } + + for (int i = str.length() - 1; i >= 0; i--) { + ch = str.charAt(i); + if (ch == '-' && i == 0) { + isNegative = true; + continue; + } else if (ch == '+' && i == 0) { + continue; + } + + digit = ch - '0'; + + if (digit < 0 || digit > 9) { + throw new NumberFormatException("Invalid characters"); + } + + number += digit * (Math.pow(10, weight++)); + } + return isNegative ? -number : number; + } + + public static void main(String[] args) { + // normal cases + System.out.println(getIntegerFromString("0")); + System.out.println(getIntegerFromString("123")); + System.out.println(getIntegerFromString("0123")); + System.out.println(getIntegerFromString("+123")); + System.out.println(getIntegerFromString("-123")); + + // error cases + System.out.println(getIntegerFromString("1-23")); + System.out.println(getIntegerFromString("")); + System.out.println(getIntegerFromString(" ")); + System.out.println(getIntegerFromString(" ")); + System.out.println(getIntegerFromString("123L")); + } +} \ No newline at end of file From eac6a74beb1aa839d931632155a14b6bd8dcb93a Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Tue, 2 Apr 2019 21:55:36 +0100 Subject: [PATCH 044/164] Second smallest element in BST: done --- .../com/rampatra/base/BinarySearchTree.java | 15 ++- .../java/com/rampatra/trees/CheckForBST.java | 8 +- .../rampatra/trees/LeastCommonAncestor.java | 4 +- .../rampatra/trees/SecondSmallestInBST.java | 108 ++++++++++++++++++ 4 files changed, 127 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/rampatra/trees/SecondSmallestInBST.java diff --git a/src/main/java/com/rampatra/base/BinarySearchTree.java b/src/main/java/com/rampatra/base/BinarySearchTree.java index 9766a1e3..644f1e7d 100644 --- a/src/main/java/com/rampatra/base/BinarySearchTree.java +++ b/src/main/java/com/rampatra/base/BinarySearchTree.java @@ -5,11 +5,16 @@ import static java.lang.System.out; /** - * Created by IntelliJ IDEA. - * User: rampatra - * Date: 4/19/15 - * Time: 6:36 PM - * To change this template go to Preferences | IDE Settings | File and Code Templates + * A binary search tree is a binary tree in which every node fits a specific ordering property: all left + * descendents <= n < all right descendents. This must be true for each node n. + *

+ * Note: The definition of a binary search tree can vary slightly with respect to equality. Under some definitions, the + * tree cannot have duplicate values. In others, the duplicate values will be on the right or can be on either side. All + * are valid definitions, but you should clarify this with your interviewer + * + * @author rampatra + * @since 4/19/15 + * @param */ public class BinarySearchTree> extends BinaryTree { diff --git a/src/main/java/com/rampatra/trees/CheckForBST.java b/src/main/java/com/rampatra/trees/CheckForBST.java index d0e323e0..aea4bc19 100644 --- a/src/main/java/com/rampatra/trees/CheckForBST.java +++ b/src/main/java/com/rampatra/trees/CheckForBST.java @@ -9,11 +9,15 @@ import static java.lang.System.out; /** - * Created by IntelliJ IDEA. + * A binary search tree is a binary tree in which every node fits a specific ordering property: all left + * descendents <= n < all right descendents. This must be true for each node n. + *

+ * Note: The definition of a binary search tree can vary slightly with respect to equality. Under some definitions, the + * tree cannot have duplicate values. In others, the duplicate values will be on the right or can be on either side. All + * are valid definitions, but you should clarify this with your interviewer * * @author rampatra * @since 6/26/15 - * @time: 7:14 PM */ public class CheckForBST { diff --git a/src/main/java/com/rampatra/trees/LeastCommonAncestor.java b/src/main/java/com/rampatra/trees/LeastCommonAncestor.java index 6ed648b6..d9363125 100644 --- a/src/main/java/com/rampatra/trees/LeastCommonAncestor.java +++ b/src/main/java/com/rampatra/trees/LeastCommonAncestor.java @@ -42,7 +42,9 @@ public void leastCommonAncestor() { * @return */ public static > BinaryNode leastCommonAncestor(BinaryNode node, E value1, E value2) { - if (node == null || value1.compareTo(value2) > 0) throw new NoSuchElementException(); + if (node == null || value1 == null || value2 == null || value1.compareTo(value2) > 0) { + throw new NoSuchElementException(); + } if (value1.compareTo(node.value) <= 0 && value2.compareTo(node.value) >= 0) { return node; diff --git a/src/main/java/com/rampatra/trees/SecondSmallestInBST.java b/src/main/java/com/rampatra/trees/SecondSmallestInBST.java new file mode 100644 index 00000000..4e287365 --- /dev/null +++ b/src/main/java/com/rampatra/trees/SecondSmallestInBST.java @@ -0,0 +1,108 @@ +package com.rampatra.trees; + +/** + * Given a Binary Search Tree, find out the second smallest element in the tree. + * + * @author rampatra + * @since 2019-04-02 + */ +public class SecondSmallestInBST { + + private static class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int val) { + this.val = val; + } + } + + private static TreeNode getSecondSmallestNode(TreeNode root) { + if (root == null) return null; + + TreeNode curr = root; + + if (curr.left == null) { + if (curr.right == null) { + return null; + } else { + return curr; + } + } + + while (curr.left.left != null) { + curr = curr.left; + } + + if (curr.left.right != null) { + return curr.left.right; + } else { + return curr; + } + } + + public static void main(String[] args) { + /* + The BST looks like: + + 4 + / \ + 2 8 + / \ / \ + 1 3 6 9 + / + 0 + + */ + TreeNode treeRoot = new TreeNode(4); + treeRoot.left = new TreeNode(2); + treeRoot.right = new TreeNode(8); + treeRoot.left.left = new TreeNode(1); + treeRoot.left.right = new TreeNode(3); + treeRoot.left.left.left = new TreeNode(0); + treeRoot.right.left = new TreeNode(6); + treeRoot.right.right = new TreeNode(9); + + System.out.println(getSecondSmallestNode(treeRoot).val); + + /* + The BST looks like: + + 4 + / \ + 2 8 + / \ / \ + 1 3 6 9 + + */ + treeRoot = new TreeNode(4); + treeRoot.left = new TreeNode(2); + treeRoot.right = new TreeNode(8); + treeRoot.left.left = new TreeNode(1); + treeRoot.left.right = new TreeNode(3); + treeRoot.right.left = new TreeNode(6); + treeRoot.right.right = new TreeNode(9); + + System.out.println(getSecondSmallestNode(treeRoot).val); + + /* + The BST looks like: + + 4 + / \ + 2 8 + \ / \ + 3 6 9 + + */ + treeRoot = new TreeNode(4); + treeRoot.left = new TreeNode(2); + treeRoot.right = new TreeNode(8); + treeRoot.left.right = new TreeNode(3); + treeRoot.right.left = new TreeNode(6); + treeRoot.right.right = new TreeNode(9); + + System.out.println(getSecondSmallestNode(treeRoot).val); + } +} \ No newline at end of file From d7ddaa663098787138127064962d66bf34f6946d Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Tue, 2 Apr 2019 23:04:10 +0100 Subject: [PATCH 045/164] Connect nodes at same level in a binary tree: done --- .../trees/ConnectNodesAtSameLevel.java | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 src/main/java/com/rampatra/trees/ConnectNodesAtSameLevel.java diff --git a/src/main/java/com/rampatra/trees/ConnectNodesAtSameLevel.java b/src/main/java/com/rampatra/trees/ConnectNodesAtSameLevel.java new file mode 100644 index 00000000..0be4a17e --- /dev/null +++ b/src/main/java/com/rampatra/trees/ConnectNodesAtSameLevel.java @@ -0,0 +1,124 @@ +package com.rampatra.trees; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.List; +import java.util.Queue; + +/** + * @author rampatra + * @since 2019-04-02 + */ +public class ConnectNodesAtSameLevel { + + private static class TreeNode { + Integer val; + TreeNode left; + TreeNode right; + + TreeNode(Integer val) { + this.val = val; + } + + @Override + public String toString() { + return Integer.toString(val); + } + } + + private static List> connectNodes(TreeNode root) { + if (root == null) return null; + + Queue queue = new ArrayDeque<>(); + List> allNodes = new ArrayList<>(); + List connectedNodesAtLevel = new ArrayList<>(); + + queue.add(root); + queue.add(new TreeNode(null)); + + while (!queue.isEmpty()) { + TreeNode node = queue.poll(); + + if (node.val != null) { + connectedNodesAtLevel.add(node); + } else { + allNodes.add(connectedNodesAtLevel); + connectedNodesAtLevel = new ArrayList<>(); + if (queue.peek() != null) queue.add(new TreeNode(null)); + continue; + } + + if (node.left != null) queue.add(node.left); + if (node.right != null) queue.add(node.right); + } + + return allNodes; + } + + public static void main(String[] args) { + /* + The BST looks like: + + 4 + / \ + 2 8 + / \ / \ + 1 3 6 9 + / + 0 + + */ + TreeNode treeRoot = new TreeNode(4); + treeRoot.left = new TreeNode(2); + treeRoot.right = new TreeNode(8); + treeRoot.left.left = new TreeNode(1); + treeRoot.left.right = new TreeNode(3); + treeRoot.left.left.left = new TreeNode(0); + treeRoot.right.left = new TreeNode(6); + treeRoot.right.right = new TreeNode(9); + + connectNodes(treeRoot).forEach(System.out::println); + System.out.println("--------------"); + + /* + The BST looks like: + + 4 + / \ + 2 8 + \ / \ + 3 6 9 + + */ + treeRoot = new TreeNode(4); + treeRoot.left = new TreeNode(2); + treeRoot.right = new TreeNode(8); + treeRoot.left.right = new TreeNode(3); + treeRoot.right.left = new TreeNode(6); + treeRoot.right.right = new TreeNode(9); + + connectNodes(treeRoot).forEach(System.out::println); + System.out.println("--------------"); + + + /* + The BST looks like: + + 4 + / \ + 2 8 + / \ / \ + 1 3 6 9 + + */ + treeRoot = new TreeNode(4); + treeRoot.left = new TreeNode(2); + treeRoot.right = new TreeNode(8); + treeRoot.left.left = new TreeNode(1); + treeRoot.left.right = new TreeNode(3); + treeRoot.right.left = new TreeNode(6); + treeRoot.right.right = new TreeNode(9); + + connectNodes(treeRoot).forEach(System.out::println); + } +} From 9a2ac5f884abbb2f65936cf818b68b98f1471ea7 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Tue, 2 Apr 2019 23:13:45 +0100 Subject: [PATCH 046/164] Added some comments --- .../java/com/rampatra/trees/ConnectNodesAtSameLevel.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/rampatra/trees/ConnectNodesAtSameLevel.java b/src/main/java/com/rampatra/trees/ConnectNodesAtSameLevel.java index 0be4a17e..684e3e01 100644 --- a/src/main/java/com/rampatra/trees/ConnectNodesAtSameLevel.java +++ b/src/main/java/com/rampatra/trees/ConnectNodesAtSameLevel.java @@ -6,6 +6,9 @@ import java.util.Queue; /** + * Given a binary tree, return lists of nodes at each level. The number of lists in the output will be equal to + * the number of levels in the tree. + * * @author rampatra * @since 2019-04-02 */ @@ -34,14 +37,14 @@ private static List> connectNodes(TreeNode root) { List connectedNodesAtLevel = new ArrayList<>(); queue.add(root); - queue.add(new TreeNode(null)); + queue.add(new TreeNode(null)); // we use a node with null value as a marker for each level while (!queue.isEmpty()) { TreeNode node = queue.poll(); - + if (node.val != null) { connectedNodesAtLevel.add(node); - } else { + } else { // when we encounter a null in the queue, we know that a level is completed allNodes.add(connectedNodesAtLevel); connectedNodesAtLevel = new ArrayList<>(); if (queue.peek() != null) queue.add(new TreeNode(null)); From 1cf23dc57ab815f4ace2395e73089fc8c5611d1b Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Tue, 2 Apr 2019 23:53:10 +0100 Subject: [PATCH 047/164] Remove duplicates and arrange letters lexicographically --- .../RemoveDuplicatesAndArrangeLetters.java | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/main/java/com/rampatra/strings/RemoveDuplicatesAndArrangeLetters.java diff --git a/src/main/java/com/rampatra/strings/RemoveDuplicatesAndArrangeLetters.java b/src/main/java/com/rampatra/strings/RemoveDuplicatesAndArrangeLetters.java new file mode 100644 index 00000000..edb99699 --- /dev/null +++ b/src/main/java/com/rampatra/strings/RemoveDuplicatesAndArrangeLetters.java @@ -0,0 +1,37 @@ +package com.rampatra.strings; + +import java.util.Set; +import java.util.TreeSet; +import java.util.stream.Collectors; + +/** + * @author rampatra + * @since 2019-04-02 + */ +public class RemoveDuplicatesAndArrangeLetters { + + private static String removeDuplicatesAndArrangeLettersLexicographically(String str) { + Set charSet = new TreeSet<>(); + char[] chars = str.toCharArray(); + + for (char ch : chars) { + charSet.add(ch); + } + + return charSet.toString(); + } + + private static String removeDuplicatesAndArrangeLettersLexicographically_Java8(String str) { + return str.chars() + .distinct() + .sorted() + .mapToObj(i -> (char) i) + .map(String::valueOf) + .collect(Collectors.joining()); + } + + public static void main(String[] args) { + System.out.println(removeDuplicatesAndArrangeLettersLexicographically("algo&dsInJava")); + System.out.println(removeDuplicatesAndArrangeLettersLexicographically_Java8("algo&dsInJava")); + } +} From 8923cd67abd7bbbd72b76e66000439ecb0299c10 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Wed, 3 Apr 2019 21:31:02 +0100 Subject: [PATCH 048/164] Random node in BT: done --- .../com/rampatra/trees/RandomNodeInBT.java | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 src/main/java/com/rampatra/trees/RandomNodeInBT.java diff --git a/src/main/java/com/rampatra/trees/RandomNodeInBT.java b/src/main/java/com/rampatra/trees/RandomNodeInBT.java new file mode 100644 index 00000000..a2719bc7 --- /dev/null +++ b/src/main/java/com/rampatra/trees/RandomNodeInBT.java @@ -0,0 +1,82 @@ +package com.rampatra.trees; + +import java.util.Random; + +/** + * You are implementing a binary tree class from scratch, which has a method getRandomNode() which returns a + * random node from the tree. All nodes should be equally likely to be chosen. Design and implement an algorithm + * for getRandomNode(). + * + * @author rampatra + * @since 2019-04-03 + */ +public class RandomNodeInBT { + + private static class TreeNode { + int val; + TreeNode left; + TreeNode right; + int size; // num of nodes in left subtree + 1 + num of nodes in right subtree + + TreeNode(int val, int size) { + this.val = val; + this.size = size; + } + + TreeNode getRandomNode() { + int randomNum = new Random().nextInt(this.size); // generates a random num from 0 to size - 1 (both inclusive) + + /* + the below makes all nodes equally likely because the probability is distributed + evenly (approximately) depending on the number of children + */ + if (this.left != null && randomNum < this.left.size) { + return left.getRandomNode(); + } else if (this.right != null && randomNum > this.right.size) { + return right.getRandomNode(); + } else { + return this; + } + } + } + + public static void main(String[] args) { + /* + The BST looks like: + + 4 + / \ + 2 8 + / \ / \ + 1 3 6 9 + + */ + TreeNode treeRoot = new TreeNode(4, 7); + treeRoot.left = new TreeNode(2, 3); + treeRoot.right = new TreeNode(8, 3); + treeRoot.left.left = new TreeNode(1, 1); + treeRoot.left.right = new TreeNode(3, 1); + treeRoot.right.left = new TreeNode(6, 1); + treeRoot.right.right = new TreeNode(9, 1); + + System.out.println(treeRoot.getRandomNode().val); + System.out.println(treeRoot.getRandomNode().val); + System.out.println(treeRoot.getRandomNode().val); + System.out.println(treeRoot.getRandomNode().val); + System.out.println(treeRoot.getRandomNode().val); + System.out.println(treeRoot.getRandomNode().val); + System.out.println(treeRoot.getRandomNode().val); + System.out.println(treeRoot.getRandomNode().val); + + System.out.println("-------"); + + System.out.println(new Random().nextInt(8)); + System.out.println(new Random().nextInt(8)); + System.out.println(new Random().nextInt(8)); + System.out.println(new Random().nextInt(8)); + System.out.println(new Random().nextInt(8)); + System.out.println(new Random().nextInt(8)); + System.out.println(new Random().nextInt(8)); + System.out.println(new Random().nextInt(8)); + } +} \ No newline at end of file From 6682be2e5e05384f32a3f66465ba5b0144ab1924 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Thu, 4 Apr 2019 18:56:53 +0100 Subject: [PATCH 049/164] Rotated index: done --- .../rampatra/arrays/PivotedBinarySearch.java | 48 +++++++++------- .../com/rampatra/arrays/RotatedIndex.java | 55 +++++++++++++++++++ src/main/java/com/rampatra/base/Trie.java | 27 +++++---- 3 files changed, 95 insertions(+), 35 deletions(-) create mode 100644 src/main/java/com/rampatra/arrays/RotatedIndex.java diff --git a/src/main/java/com/rampatra/arrays/PivotedBinarySearch.java b/src/main/java/com/rampatra/arrays/PivotedBinarySearch.java index a87875b5..2f104e6f 100644 --- a/src/main/java/com/rampatra/arrays/PivotedBinarySearch.java +++ b/src/main/java/com/rampatra/arrays/PivotedBinarySearch.java @@ -7,62 +7,68 @@ * * @author rampatra * @since 5/31/15 - * @time: 10:44 PM */ public class PivotedBinarySearch { /** - * Search an element in a sorted pivoted array {@param a}. + * Search an element in a sorted pivoted array {@code arr}. *

* Example, * 1) For array [3,4,5,1,2] pivot is 5 * 2) For array [6,7,8,5,4] pivot is 8 * - * @param a + * @param arr * @param n * @return */ - public static int pivotedBinarySearch(int a[], int n) { - int pivot = findPivot(a, 0, a.length - 1); + public static int pivotedBinarySearch(int[] arr, int n) { + int pivot = findPivotIndex(arr, 0, arr.length - 1); - if (pivot == -1 || a[pivot] == n) { + if (pivot == -1 || arr[pivot] == n) { return pivot; - } else if (n <= a[0]) { - return BinarySearch.binarySearch(a, n, pivot + 1, a.length - 1); + } else if (n < arr[0]) { + return BinarySearch.binarySearch(arr, n, pivot + 1, arr.length - 1); } else { - return BinarySearch.binarySearch(a, n, 0, pivot - 1); + return BinarySearch.binarySearch(arr, n, 0, pivot - 1); } } /** - * Finds the pivot element in array {@param a}. Pivot element is the only + * Finds the pivot element in array {@code arr}. Pivot element is the only * element for which next element to it is smaller than it. * - * @param a + * @param arr * @param low * @param high - * @return + * @return the index of the pivot element in the {@code arr}. */ - public static int findPivot(int a[], int low, int high) { + public static int findPivotIndex(int[] arr, int low, int high) { if (low > high) return -1; - if (low == high) return low; int mid = (low + high) / 2; - if (a[mid] > a[mid + 1] && a[mid] > a[mid - 1]) { + if (mid == 0 || mid == arr.length - 1) return -1; + + if (arr[mid] > arr[mid + 1] && arr[mid] > arr[mid - 1]) { return mid; - } else if (a[mid] > a[mid - 1] && a[mid] < a[mid + 1]) { - return findPivot(a, mid + 1, a.length - 1); + } else if (arr[mid] > arr[mid - 1] && arr[mid] < arr[mid + 1]) { + return findPivotIndex(arr, mid + 1, arr.length - 1); } else { - return findPivot(a, 0, mid - 1); + return findPivotIndex(arr, 0, mid - 1); } } public static void main(String[] args) { - System.out.println("Pivot: " + findPivot(new int[]{1, 2, 3, 4, 5}, 0, 3)); + System.out.println("Pivot: " + findPivotIndex(new int[]{3, 4, 5, 1, 2}, 0, 4)); + System.out.println("Index: " + pivotedBinarySearch(new int[]{3, 4, 5, 1, 2}, 5)); + + System.out.println("Pivot: " + findPivotIndex(new int[]{1, 2, 3, 4, 5}, 0, 4)); System.out.println("Index: " + pivotedBinarySearch(new int[]{1, 2, 3, 4, 5}, 4)); - System.out.println("Pivot: " + findPivot(new int[]{5}, 0, 0)); - System.out.println("Index: " + pivotedBinarySearch(new int[]{5}, 5)); + System.out.println("Pivot: " + findPivotIndex(new int[]{5, 4, 3, 2, 1}, 0, 4)); + System.out.println("Index: " + pivotedBinarySearch(new int[]{5, 4, 3, 2, 1}, 4)); + + System.out.println("Pivot: " + findPivotIndex(new int[]{5}, 0, -1)); + System.out.println("Index: " + pivotedBinarySearch(new int[]{5}, -1)); } } diff --git a/src/main/java/com/rampatra/arrays/RotatedIndex.java b/src/main/java/com/rampatra/arrays/RotatedIndex.java new file mode 100644 index 00000000..4478e5e3 --- /dev/null +++ b/src/main/java/com/rampatra/arrays/RotatedIndex.java @@ -0,0 +1,55 @@ +package com.rampatra.arrays; + +/** + * @author rampatra + * @since 2019-04-04 + */ +public class RotatedIndex { + + private static int findIndexOfRotationPoint(String[] words) { + return findIndexOfRotationPoint(words, 0, words.length - 1); + } + + private static int findIndexOfRotationPoint(String[] words, int start, int end) { + if (start > end) return -1; + + int mid = (start + end) / 2; + + if (mid == 0 || mid == words.length - 1) return -1; + + if (words[mid].compareTo(words[mid - 1]) < 0 && words[mid].compareTo(words[mid + 1]) < 0) { + return mid; + } else if (words[mid].compareTo(words[mid - 1]) > 0 && words[mid].compareTo(words[mid + 1]) < 0) { + return findIndexOfRotationPoint(words, start, mid - 1); + } else { + return findIndexOfRotationPoint(words, mid + 1, end); + } + } + + public static void main(String[] args) { + System.out.println(findIndexOfRotationPoint(new String[]{ + "ptolemaic", + "retrograde", + "supplant", + "undulate", + "xenoepist", + "asymptote", // <-- rotates here! + "babka", + "banoffee", + "engender", + "karpatka", + "othellolagkage", + })); + + System.out.println(findIndexOfRotationPoint(new String[]{})); + + System.out.println(findIndexOfRotationPoint(new String[]{ + "asymptote", + "babka", + "banoffee", + "engender", + "karpatka", + "othellolagkage", + })); + } +} \ No newline at end of file diff --git a/src/main/java/com/rampatra/base/Trie.java b/src/main/java/com/rampatra/base/Trie.java index 608bd081..9f867f91 100644 --- a/src/main/java/com/rampatra/base/Trie.java +++ b/src/main/java/com/rampatra/base/Trie.java @@ -3,8 +3,6 @@ import java.util.HashMap; /** - * Created by IntelliJ IDEA. - *

* Trie also called digital tree and sometimes radix tree or prefix tree (as they can be * searched by prefixes), is an ordered tree data structure that is used to store a dynamic * set or associative array where the keys are usually strings. @@ -12,19 +10,20 @@ * You can think it as HashMap of HashMap of HashMap and so on. Each key in the HashMap is a * single digit/letter of the data you want to store and {@code data} is the final full word * you want to save in trie. + *

+ * Some resources: + * Trie Data Structure + * More about Tries * * @author rampatra * @since 9/22/15 - * @time: 8:19 PM - * @see: https://en.wikipedia.org/wiki/Trie - * @see: https://www.topcoder.com/community/data-science/data-science-tutorials/using-tries */ public class Trie { TrieNode root; Trie() { - root = new TrieNode<>(null, new HashMap>()); + root = new TrieNode<>(null, new HashMap<>()); } /** @@ -48,7 +47,7 @@ public void insert(E data) { } while (i < str.length()) { - curr.children.put(str.substring(i, i + 1), new TrieNode<>(null, new HashMap>())); + curr.children.put((E) str.substring(i, i + 1), new TrieNode<>(null, new HashMap<>())); curr = curr.children.get(str.substring(i, i + 1)); i++; } @@ -57,10 +56,10 @@ public void insert(E data) { } /** - * Searches {@param data} in trie. + * Searches {@code data} in trie. * - * @param data - * @return {@code true} if {@param data} is present, {@code false} otherwise. + * @param data the value to search. + * @return {@code true} if {@code data} is present, {@code false} otherwise. */ public boolean search(E data) { @@ -79,11 +78,11 @@ public boolean search(E data) { return curr.data != null && curr.data.equals(data); } - private class TrieNode { - E data; // stores the complete string (required to determine whether the string is in the trie) - HashMap> children; + private class TrieNode { + T data; // stores the complete string (required to determine whether the string is in the trie) + HashMap> children; - TrieNode(E data, HashMap> children) { + TrieNode(T data, HashMap> children) { this.data = data; this.children = children; } From f8a51bae3f8ebde9901d0dca1745a3d7d936072a Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Fri, 5 Apr 2019 14:52:46 +0100 Subject: [PATCH 050/164] Max rectangle of 1s: done --- .../dynamicprogramming/FibonacciNumbers.java | 2 +- .../LongestIncreasingSubSequence.java | 11 +-- .../MaximumRectangleOf1sInMatrix.java | 79 +++++++++++++++++++ .../stacks/MaxRectangleAreaInHistogram.java | 79 +++++++++++++++++++ 4 files changed, 163 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/rampatra/dynamicprogramming/MaximumRectangleOf1sInMatrix.java create mode 100644 src/main/java/com/rampatra/stacks/MaxRectangleAreaInHistogram.java diff --git a/src/main/java/com/rampatra/dynamicprogramming/FibonacciNumbers.java b/src/main/java/com/rampatra/dynamicprogramming/FibonacciNumbers.java index 17483cbf..8d102ef7 100644 --- a/src/main/java/com/rampatra/dynamicprogramming/FibonacciNumbers.java +++ b/src/main/java/com/rampatra/dynamicprogramming/FibonacciNumbers.java @@ -13,7 +13,7 @@ public class FibonacciNumbers { /** - * Computes first {@param k} fibonacci numbers using + * Computes first {@code k} fibonacci numbers using * bottom-up DP approach. *

* Time complexity: O(k) diff --git a/src/main/java/com/rampatra/dynamicprogramming/LongestIncreasingSubSequence.java b/src/main/java/com/rampatra/dynamicprogramming/LongestIncreasingSubSequence.java index 4521b4fa..7372a9a8 100644 --- a/src/main/java/com/rampatra/dynamicprogramming/LongestIncreasingSubSequence.java +++ b/src/main/java/com/rampatra/dynamicprogramming/LongestIncreasingSubSequence.java @@ -1,11 +1,8 @@ package com.rampatra.dynamicprogramming; /** - * Created by IntelliJ IDEA. - * * @author rampatra * @since 9/29/15 - * @time: 10:15 PM */ public class LongestIncreasingSubSequence { @@ -26,11 +23,11 @@ public class LongestIncreasingSubSequence { * To get LIS of a given array, we need to return max(L(i)) where 0 < i < n So the LIS problem has optimal * substructure property as the main problem can be solved using solutions to sub-problems. * - * @param a + * @param arr * @return */ - public static int getLongestIncreasingSubSequenceLength(int[] a) { - int len = a.length, maxLisLength = 0; + public static int getLongestIncreasingSubSequenceLength(int[] arr) { + int len = arr.length, maxLisLength = 0; int[] lis = new int[len]; for (int i = 0; i < len; i++) { @@ -39,7 +36,7 @@ public static int getLongestIncreasingSubSequenceLength(int[] a) { for (int i = 1; i < len; i++) { for (int j = 0; j < i; j++) { - if (a[i] > a[j] && lis[i] < lis[j] + 1) + if (arr[i] > arr[j] && lis[i] < lis[j] + 1) lis[i] = lis[j] + 1; } } diff --git a/src/main/java/com/rampatra/dynamicprogramming/MaximumRectangleOf1sInMatrix.java b/src/main/java/com/rampatra/dynamicprogramming/MaximumRectangleOf1sInMatrix.java new file mode 100644 index 00000000..b49f55b6 --- /dev/null +++ b/src/main/java/com/rampatra/dynamicprogramming/MaximumRectangleOf1sInMatrix.java @@ -0,0 +1,79 @@ +package com.rampatra.dynamicprogramming; + +import com.rampatra.stacks.MaxRectangleAreaInHistogram; + +/** + * Given a 2D matrix of 0s and 1s. Find the largest rectangle of all 1s in this matrix. + *

+ * Level: Hard + * Time Complexity: O(rows * cols) + * Space Complexity: O(cols) + *

+ * Note: If the number of cols is too large as compared to rows then you can process the matrix column-wise and create + * the histogram for each column. In this way the hist[] array will be of size = number of rows in the matrix. + * + * @author rampatra + * @since 2019-04-05 + */ +public class MaximumRectangleOf1sInMatrix { + + private static int getMaxRectangleSizeOf1s(int[][] binaryMatrix) { + int area; + int maxArea = 0; + int[] hist = new int[binaryMatrix[0].length]; + + /* + Create a histogram with the rows. Start with the first row, create a histogram and then extend this + histogram based on the elements in the next rows. If the element in the row is a 0 then make the bar in + the histogram 0 or else just increase the bar in the histogram. + + Basically, we are creating a histogram with all the 1s in the matrix and then finding the maximum + rectangle size of this histogram. + */ + for (int row = 0; row < binaryMatrix.length; row++) { + for (int col = 0; col < binaryMatrix[0].length; col++) { + if (binaryMatrix[row][col] == 0) { + hist[col] = 0; + } else { + hist[col] += binaryMatrix[row][col]; + } + } + area = MaxRectangleAreaInHistogram.getMaxRectangleArea(hist); + maxArea = Math.max(maxArea, area); + } + return maxArea; + } + + public static void main(String[] args) { + System.out.println(getMaxRectangleSizeOf1s( + new int[][]{{0, 1, 1}, + {0, 0, 1}, + {0, 1, 1}})); + + System.out.println(getMaxRectangleSizeOf1s( + new int[][]{{0, 1, 1, 1, 0}, + {0, 0, 1, 1, 0}, + {0, 1, 1, 1, 0}})); + + System.out.println(getMaxRectangleSizeOf1s( + new int[][]{{1, 1, 1, 0}, + {1, 1, 1, 1}, + {0, 1, 1, 0}, + {0, 1, 1, 1}, + {1, 0, 0, 1}, + {1, 1, 1, 1}})); + + // edge cases + System.out.println(getMaxRectangleSizeOf1s( + new int[][]{{}})); + + System.out.println(getMaxRectangleSizeOf1s( + new int[][]{{0}})); + + System.out.println(getMaxRectangleSizeOf1s( + new int[][]{{0, 0, 0}})); + + System.out.println(getMaxRectangleSizeOf1s( + new int[][]{{1}})); + } +} diff --git a/src/main/java/com/rampatra/stacks/MaxRectangleAreaInHistogram.java b/src/main/java/com/rampatra/stacks/MaxRectangleAreaInHistogram.java new file mode 100644 index 00000000..8494b0e7 --- /dev/null +++ b/src/main/java/com/rampatra/stacks/MaxRectangleAreaInHistogram.java @@ -0,0 +1,79 @@ +package com.rampatra.stacks; + +/** + * Given a bar histogram, calculate the maximum possible rectangle area in the histogram. Consider each bar is 1 unit + * wide. + *

+ * Level: Hard + * Time Complexity: O(n) + * Space Complexity: O(n) + * + * @author rampatra + * @since 2019-04-04 + */ +public class MaxRectangleAreaInHistogram { + + public static int getMaxRectangleArea(int[] hist) { + Stack stack = new Stack<>(); + int area; + int maxArea = 0; + int currMaxIndex; + int i = 0; + + while (i < hist.length) { + // keep adding indexes of bars which are equal to or larger than what's there in stack currently + if (stack.isEmpty() || hist[i] >= hist[stack.peek()]) { + stack.push(i); + i++; + } else { + /* + Whenever we encounter a bar smaller than what is there in the stack, we pop the topmost + element and compute the area. + */ + currMaxIndex = stack.pop(); + /* + Compute area from stack.peek() to (i - 1), + + Why (i - 1)? Because i has been incremented and is now pointing to the next bar in the + histogram + + Why stack.peak()? Because hist[stack.peek() + 1] is the last bar in the histogram with height more + than or equal to the current bar height + */ + area = hist[currMaxIndex] * (i - (stack.isEmpty() ? 0 : stack.peek() + 1)); + maxArea = Math.max(maxArea, area); + } + } + + /* + Process the left over elements in the stack. Note: the below code can also be merged with the loop + above but I have separated it out for simplicity. + */ + while (!stack.isEmpty()) { + currMaxIndex = stack.pop(); + area = hist[currMaxIndex] * (i - (stack.isEmpty() ? 0 : stack.peek() + 1)); + maxArea = Math.max(maxArea, area); + } + + return maxArea; + } + + public static void main(String[] args) { + /* + ___ + ___ | | ___ + | |__| |__| | + | | | | | | + 2 1 3 1 2 + + Max. area in this histogram is 5, which is the bottom horizontal rectangle. + */ + System.out.println(getMaxRectangleArea(new int[]{2, 1, 3, 1, 2})); // maxArea = 5 + System.out.println(getMaxRectangleArea(new int[]{2, 1, 5, 6, 2, 3})); // maxArea = 10 + System.out.println(getMaxRectangleArea(new int[]{2, 2, 2, 6, 1, 5, 4, 2, 2, 2, 2})); // maxArea = 12 + + // edge cases + System.out.println(getMaxRectangleArea(new int[]{})); // maxArea = 0 + System.out.println(getMaxRectangleArea(new int[]{1})); // maxArea = 1 + } +} \ No newline at end of file From 88699f6634c2bf90ef85bf7ff05e241cf5cd185f Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Fri, 5 Apr 2019 20:13:25 +0100 Subject: [PATCH 051/164] Loop detection improved --- .../com/ctci/linkedlists/LoopDetection.java | 4 +- .../linkedlists/DetectAndRemoveLoop.java | 67 +++++++++---------- .../com/rampatra/linkedlists/DetectLoop.java | 18 ++--- 3 files changed, 44 insertions(+), 45 deletions(-) diff --git a/src/main/java/com/ctci/linkedlists/LoopDetection.java b/src/main/java/com/ctci/linkedlists/LoopDetection.java index e99084cc..d0a9a110 100644 --- a/src/main/java/com/ctci/linkedlists/LoopDetection.java +++ b/src/main/java/com/ctci/linkedlists/LoopDetection.java @@ -14,6 +14,8 @@ public class LoopDetection { * EXAMPLE * Input: A -> B -> C -> D -> E -> C [the same C as earlier] * Output: C + *

+ * See {@link com.rampatra.linkedlists.DetectAndRemoveLoop} for a slightly more complex problem. * * @param head the starting node of the linked list * @return the {@code Node} where the loop starts, {@code null} otherwise. @@ -62,4 +64,4 @@ public static void main(String[] args) { l1.next.next.next.next.next.next = l1.next.next.next; System.out.println(findLoopStartNode(l1).val); } -} +} \ No newline at end of file diff --git a/src/main/java/com/rampatra/linkedlists/DetectAndRemoveLoop.java b/src/main/java/com/rampatra/linkedlists/DetectAndRemoveLoop.java index 63faa3be..ade19e90 100644 --- a/src/main/java/com/rampatra/linkedlists/DetectAndRemoveLoop.java +++ b/src/main/java/com/rampatra/linkedlists/DetectAndRemoveLoop.java @@ -4,59 +4,56 @@ import com.rampatra.base.SingleLinkedNode; /** - * Created by IntelliJ IDEA. + * See this Stackoverflow post to understand + * how to find the starting node of the loop. + *

+ * Proof for Flyod's Loop Detection Algorithm: + *

+ * Suppose fastRunner had just skipped over slowRunner. fastRunner would only be 1 node ahead of slowRunner, since their + * speeds differ by only 1. So we would have something like this: + *

+ * [ ] -> [s] -> [f] + *

+ * What would the step right before this "skipping step" look like? fastRunner would be 2 nodes back, and slowRunner + * would be 1 node back. But wait, that means they would be at the same node! So fastRunner didn't skip over slowRunner! + * (This is a proof by contradiction.) * * @author rampatra * @since 7/1/15 - * @time: 12:39 PM */ public class DetectAndRemoveLoop { /** - * Detects loop if any in {@param list} and removes it. - *

- * Algorithm: + * Detects loop, if any, in {@code list} and removes it. *

+ * Approach: * 1) Use Floyd's cycle detection algorithm to detect loop. * 2) Acc. to FCD, once the fast pointer meets the slow pointer we conclude that there is a loop. - * 3) Now compute the length 'l' of the loop. - * 4) Move the fast pointer length 'l' from head. - * 5) Now move both slow and fast pointer at same pace and where they meet is the starting point of the loop. - * 6) Lastly, to remove the loop make the next of the node (before the starting point of loop) to null. + * 4) Now that we have concluded there is a loop, let's detect the starting node and remove the loop: + * i. Move the slow pointer to head. + * ii. Now, move both slow and fast pointer at same pace and where they meet is the starting point of the loop. + * iii. Lastly, to remove the loop make the next of the node (before the starting point of loop) to null. * * @param list * @param * @return {@code true} if loop exists {@code false} otherwise. */ public static > boolean detectAndRemoveLoop(SingleLinkedList list) { - int i = 0, length = 0; boolean isLoopPresent = false; - SingleLinkedNode slow = list.head, fast = slow.next; + SingleLinkedNode slow = list.head, fast = list.head; while (fast != null && fast.next != null) { + slow = slow.next; + fast = fast.next.next; if (slow == fast) { isLoopPresent = true; break; } - slow = slow.next; - fast = fast.next.next; } - if (isLoopPresent == false) return false; - - // compute length of loop - while (fast.next != slow) { - fast = fast.next; - length++; - } - - // move fast pointer from head by the length of loop - slow = fast = list.head; - while (i <= length) { - fast = fast.next; - i++; - } + if (!isLoopPresent) return false; + slow = list.head; // move both pointers at same pace to determine the starting node of loop while (true) { slow = slow.next; @@ -72,14 +69,14 @@ public static > boolean detectAndRemoveLoop(SingleLinked public static void main(String[] args) { SingleLinkedList linkedList = new SingleLinkedList<>(); - linkedList.add(00); - linkedList.add(11); - linkedList.add(22); - linkedList.add(33); - linkedList.add(44); - linkedList.add(55); - linkedList.getNode(1).next = linkedList.getNode(0); + linkedList.add(0); + linkedList.add(1); + linkedList.add(2); + linkedList.add(3); + linkedList.add(4); + linkedList.add(5); + linkedList.getNode(4).next = linkedList.getNode(2); System.out.println(detectAndRemoveLoop(linkedList)); linkedList.printList(); } -} +} \ No newline at end of file diff --git a/src/main/java/com/rampatra/linkedlists/DetectLoop.java b/src/main/java/com/rampatra/linkedlists/DetectLoop.java index ad9d13c0..45bd6b6f 100644 --- a/src/main/java/com/rampatra/linkedlists/DetectLoop.java +++ b/src/main/java/com/rampatra/linkedlists/DetectLoop.java @@ -10,7 +10,6 @@ * * @author rampatra * @since 6/19/15 - * @time: 9:24 AM */ public class DetectLoop { @@ -24,20 +23,21 @@ public class DetectLoop { * there is a loop. If pointers do not meet * then linked list does not have loop. *

- * Time: O(n) - * Space: O(1) + * Level: Easy + * Time Complexity: O(n) + * Space Complexity: O(1) * * @param list * @return */ public static > boolean isLoopPresent(SingleLinkedList list) { - SingleLinkedNode slow = list.head, fast = slow.next; + SingleLinkedNode slow = list.head, fast = list.head; while (fast != null && fast.next != null) { + slow = slow.next; + fast = fast.next.next; if (slow == fast) { return true; } - slow = slow.next; - fast = fast.next.next; } return false; } @@ -45,8 +45,8 @@ public static > boolean isLoopPresent(SingleLinkedList - * Time: O(n) - * Space: O(n) + * Time Complexity: O(n) + * Space Complexity: O(n) * * @param node * @return @@ -75,4 +75,4 @@ public static void main(String[] args) { linkedList.getNode(4).next = linkedList.getNode(3); System.out.println(isLoopPresent(linkedList)); } -} +} \ No newline at end of file From f29161ae385323edab3c44184f5797e069b0cb31 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sat, 6 Apr 2019 15:54:27 +0100 Subject: [PATCH 052/164] Two swapped nodes in BST: done --- .../rampatra/trees/TwoSwappedNodesInBST.java | 141 ++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 src/main/java/com/rampatra/trees/TwoSwappedNodesInBST.java diff --git a/src/main/java/com/rampatra/trees/TwoSwappedNodesInBST.java b/src/main/java/com/rampatra/trees/TwoSwappedNodesInBST.java new file mode 100644 index 00000000..f39a9b69 --- /dev/null +++ b/src/main/java/com/rampatra/trees/TwoSwappedNodesInBST.java @@ -0,0 +1,141 @@ +package com.rampatra.trees; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Two nodes are swapped in a BST, write a function to find these two nodes. + *

+ * Approach: + * 1. We perform an in-order traversal of the tree and find the 2 discontinuities, i.e, the nodes which are larger than their next node. + * 2. We take the left node of the first discontinuity and the right node of the second. + *

+ * Note: There is one edge case where the two nodes swapped are parent and child nodes. This means that in the in-order + * traversal these two nodes will be adjacent. Therefore, in this case, these two nodes will be our answer. + * + * @author rampatra + * @since 2019-04-06 + */ +public class TwoSwappedNodesInBST { + + private static class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int val) { + this.val = val; + } + + @Override + public String toString() { + return String.valueOf(val); + } + } + + private static List findSwappedNodes(TreeNode root) { + List inOrderTraversal = new ArrayList<>(); + TreeNode firstSwappedNode = null; + TreeNode secondSwappedNode = null; + TreeNode plausibleSwappedNode = null; + + traverseInOrder(root, inOrderTraversal); + + for (int i = 0; i < inOrderTraversal.size() - 1; i++) { + // find nodes not in ascending order + if (inOrderTraversal.get(i).val > inOrderTraversal.get(i + 1).val) { + if (firstSwappedNode == null) { + firstSwappedNode = inOrderTraversal.get(i); // take the left node from the first violation + plausibleSwappedNode = inOrderTraversal.get(i + 1); + } else { + secondSwappedNode = inOrderTraversal.get(i + 1); // take the right node from the second violation + } + } + } + + return Arrays.asList(firstSwappedNode, secondSwappedNode == null ? plausibleSwappedNode : secondSwappedNode); + } + + private static void traverseInOrder(TreeNode node, List inOrderTraversal) { + if (node == null) return; + + traverseInOrder(node.left, inOrderTraversal); + inOrderTraversal.add(node); + traverseInOrder(node.right, inOrderTraversal); + } + + public static void main(String[] args) { + /* + + Test case 1: Node 8 and node 2 are swapped + + The current BST looks like: + + 4 + / \ + 8 2 + / \ / \ + 1 3 6 9 + / + 0 + + Instead, the correct BST should look like: + + 4 + / \ + 2 8 + / \ / \ + 1 3 6 9 + / + 0 + + */ + TreeNode treeRoot = new TreeNode(4); + treeRoot.left = new TreeNode(8); + treeRoot.right = new TreeNode(2); + treeRoot.left.left = new TreeNode(1); + treeRoot.left.right = new TreeNode(3); + treeRoot.left.left.left = new TreeNode(0); + treeRoot.right.left = new TreeNode(6); + treeRoot.right.right = new TreeNode(9); + + System.out.println(findSwappedNodes(treeRoot)); + + /* + + Test case 2: Node 3 and node 2 are swapped (note: these are parent child nodes) + + The current BST looks like: + + 4 + / \ + 3 8 + / \ / \ + 1 2 6 9 + / + 0 + + Instead, the correct BST should look like: + + 4 + / \ + 2 8 + / \ / \ + 1 3 6 9 + / + 0 + + */ + treeRoot = new TreeNode(4); + treeRoot.left = new TreeNode(3); + treeRoot.right = new TreeNode(8); + treeRoot.left.left = new TreeNode(1); + treeRoot.left.right = new TreeNode(2); + treeRoot.left.left.left = new TreeNode(0); + treeRoot.right.left = new TreeNode(6); + treeRoot.right.right = new TreeNode(9); + + System.out.println(findSwappedNodes(treeRoot)); + } +} \ No newline at end of file From 8a563ab879ca1421a407d98d0f52480fd85f2f03 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sat, 6 Apr 2019 18:08:42 +0100 Subject: [PATCH 053/164] LCA in BT: done --- ...tor.java => LeastCommonAncestorInBST.java} | 2 +- .../trees/LeastCommonAncestorInBT.java | 77 +++++++++++++++++++ .../rampatra/trees/TwoSwappedNodesInBST.java | 2 + 3 files changed, 80 insertions(+), 1 deletion(-) rename src/main/java/com/rampatra/trees/{LeastCommonAncestor.java => LeastCommonAncestorInBST.java} (98%) create mode 100644 src/main/java/com/rampatra/trees/LeastCommonAncestorInBT.java diff --git a/src/main/java/com/rampatra/trees/LeastCommonAncestor.java b/src/main/java/com/rampatra/trees/LeastCommonAncestorInBST.java similarity index 98% rename from src/main/java/com/rampatra/trees/LeastCommonAncestor.java rename to src/main/java/com/rampatra/trees/LeastCommonAncestorInBST.java index d9363125..1d195b90 100644 --- a/src/main/java/com/rampatra/trees/LeastCommonAncestor.java +++ b/src/main/java/com/rampatra/trees/LeastCommonAncestorInBST.java @@ -12,7 +12,7 @@ * @since 6/26/15 * @time: 7:38 PM */ -public class LeastCommonAncestor { +public class LeastCommonAncestorInBST { public void leastCommonAncestor() { diff --git a/src/main/java/com/rampatra/trees/LeastCommonAncestorInBT.java b/src/main/java/com/rampatra/trees/LeastCommonAncestorInBT.java new file mode 100644 index 00000000..dfea8699 --- /dev/null +++ b/src/main/java/com/rampatra/trees/LeastCommonAncestorInBT.java @@ -0,0 +1,77 @@ +package com.rampatra.trees; + +/** + * Given a binary tree {@code root}, find the LCA of two given nodes {@code node1} and {@code node2}. LCA is a node + * which is closest to both of the nodes. + *

+ * See this youtube video for a visual understanding of the + * approach taken to solve this problem. + * + * @author rampatra + * @since 2019-04-06 + */ +public class LeastCommonAncestorInBT { + private static class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int val) { + this.val = val; + } + + @Override + public String toString() { + return String.valueOf(val); + } + } + + private static TreeNode findLCA(TreeNode root, TreeNode node1, TreeNode node2) { + if (root == null) return null; + + TreeNode left = findLCA(root.left, node1, node2); + TreeNode right = findLCA(root.right, node1, node2); + + if (root == node1 || root == node2) { + return root; + } else if (left != null && right != null) { // one node is in the left sub-tree and the other on the right sub-tree + return root; + } else if (left != null) { // we found one node in the left sub-tree + return left; + } else if (right != null) { // we found one node in the right sub-tree + return right; + } else { + return null; + } + } + + public static void main(String[] args) { + /* + The BST looks like: + + 4 + / \ + 2 8 + / \ / \ + 1 3 6 9 + / + 0 + + */ + TreeNode treeRoot = new TreeNode(4); + treeRoot.left = new TreeNode(2); + treeRoot.right = new TreeNode(8); + treeRoot.left.left = new TreeNode(1); + treeRoot.left.right = new TreeNode(3); + treeRoot.left.left.left = new TreeNode(0); + treeRoot.right.left = new TreeNode(6); + treeRoot.right.right = new TreeNode(9); + + System.out.println(findLCA(treeRoot, treeRoot, treeRoot).val); // findLCA(4, 4) + System.out.println(findLCA(treeRoot, treeRoot.left, treeRoot.right).val); // findLCA(2, 8) + System.out.println(findLCA(treeRoot, treeRoot.left, treeRoot.left.left).val); // findLCA(2, 1) + System.out.println(findLCA(treeRoot, treeRoot.left.left, treeRoot.left).val); // findLCA(1, 2) + System.out.println(findLCA(treeRoot, treeRoot.left.left.left, treeRoot.right.left).val); // findLCA(0, 6) + System.out.println(findLCA(treeRoot, treeRoot.right, treeRoot.right.right).val); // findLCA(8, 9) + } +} \ No newline at end of file diff --git a/src/main/java/com/rampatra/trees/TwoSwappedNodesInBST.java b/src/main/java/com/rampatra/trees/TwoSwappedNodesInBST.java index f39a9b69..4ec473da 100644 --- a/src/main/java/com/rampatra/trees/TwoSwappedNodesInBST.java +++ b/src/main/java/com/rampatra/trees/TwoSwappedNodesInBST.java @@ -13,6 +13,8 @@ *

* Note: There is one edge case where the two nodes swapped are parent and child nodes. This means that in the in-order * traversal these two nodes will be adjacent. Therefore, in this case, these two nodes will be our answer. + *

+ * See this youtube video for a visual understanding. * * @author rampatra * @since 2019-04-06 From 0dec287163f47b81360fb380aa978772da9478aa Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sat, 6 Apr 2019 18:16:13 +0100 Subject: [PATCH 054/164] Some optimization in LCA in BT --- .../com/ctci/treesandgraphs/FirstCommonAncestor.java | 2 ++ .../com/rampatra/trees/LeastCommonAncestorInBT.java | 12 +++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/ctci/treesandgraphs/FirstCommonAncestor.java b/src/main/java/com/ctci/treesandgraphs/FirstCommonAncestor.java index 7a6ebc97..f1fc5293 100644 --- a/src/main/java/com/ctci/treesandgraphs/FirstCommonAncestor.java +++ b/src/main/java/com/ctci/treesandgraphs/FirstCommonAncestor.java @@ -17,6 +17,8 @@ public class FirstCommonAncestor { * - Returns q, if root's subtree includes q (and not p). * - Returns null, if neither p nor q are in root's subtree. * - Else, returns the common ancestor of p and q. + *

+ * See {@link com.rampatra.trees.LeastCommonAncestorInBT} for a simpler version. * * @param root * @param a diff --git a/src/main/java/com/rampatra/trees/LeastCommonAncestorInBT.java b/src/main/java/com/rampatra/trees/LeastCommonAncestorInBT.java index dfea8699..24bd6786 100644 --- a/src/main/java/com/rampatra/trees/LeastCommonAncestorInBT.java +++ b/src/main/java/com/rampatra/trees/LeastCommonAncestorInBT.java @@ -29,12 +29,18 @@ public String toString() { private static TreeNode findLCA(TreeNode root, TreeNode node1, TreeNode node2) { if (root == null) return null; + /* + optimal: check this first before checking the child nodes recursively because even if the other node + is in one of the sub-trees the LCA would be root node + */ + if (root == node1 || root == node2) { + return root; + } + TreeNode left = findLCA(root.left, node1, node2); TreeNode right = findLCA(root.right, node1, node2); - if (root == node1 || root == node2) { - return root; - } else if (left != null && right != null) { // one node is in the left sub-tree and the other on the right sub-tree + if (left != null && right != null) { // one node is in the left sub-tree and the other on the right sub-tree return root; } else if (left != null) { // we found one node in the left sub-tree return left; From 42c1fd6c73f6bd1c47852a30b85868194c393173 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sun, 7 Apr 2019 16:57:38 +0100 Subject: [PATCH 055/164] Some minor improvements --- .../com/ctci/treesandgraphs/CheckBalanced.java | 2 +- .../com/rampatra/arrays/SortedSubSequence.java | 17 ++++++++--------- .../java/com/rampatra/trees/HeightBalanced.java | 7 ++++++- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/ctci/treesandgraphs/CheckBalanced.java b/src/main/java/com/ctci/treesandgraphs/CheckBalanced.java index 6bc04803..d7658cd8 100644 --- a/src/main/java/com/ctci/treesandgraphs/CheckBalanced.java +++ b/src/main/java/com/ctci/treesandgraphs/CheckBalanced.java @@ -57,7 +57,7 @@ private static int checkHeightAndBalance(TreeNode node) { return Math.max(leftHeight, rightHeight) + 1; } - private static boolean isBalancedOptimized(TreeNode node) { + public static boolean isBalancedOptimized(TreeNode node) { return checkHeightAndBalance(node) != Integer.MIN_VALUE; } diff --git a/src/main/java/com/rampatra/arrays/SortedSubSequence.java b/src/main/java/com/rampatra/arrays/SortedSubSequence.java index 7e689389..b6cd1b5c 100644 --- a/src/main/java/com/rampatra/arrays/SortedSubSequence.java +++ b/src/main/java/com/rampatra/arrays/SortedSubSequence.java @@ -5,7 +5,6 @@ * * @author rampatra * @since 10/12/15 - * @time: 8:32 PM */ public class SortedSubSequence { @@ -19,18 +18,18 @@ public class SortedSubSequence { * 2) Create another auxiliary array greater[0..n-1]. greater[i] should store the index of a number which is greater than arr[i] and is on right side of arr[i]. greater[i] should contain -1 if there is no such element. * 3) Finally traverse both smaller[] and greater[] and find the index i for which both smaller[i] and greater[i] are not -1. * - * @param a + * @param arr */ - public static void printSortedSubSequenceOfSize3(int[] a) { - int len = a.length, min = a[0], max = a[len - 1]; + public static void printSortedSubSequenceOfSize3(int[] arr) { + int len = arr.length, min = arr[0], max = arr[len - 1]; int[] smaller = new int[len], larger = new int[len]; smaller[0] = -1; for (int i = 1; i < len; i++) { - if (a[i] < min) { + if (arr[i] < min) { smaller[i] = -1; - min = a[i]; + min = arr[i]; } else { smaller[i] = min; } @@ -38,9 +37,9 @@ public static void printSortedSubSequenceOfSize3(int[] a) { larger[len - 1] = -1; for (int i = len - 2; i >= 0; i--) { - if (a[i] > max) { + if (arr[i] > max) { larger[i] = -1; - max = a[i]; + max = arr[i]; } else { larger[i] = max; } @@ -48,7 +47,7 @@ public static void printSortedSubSequenceOfSize3(int[] a) { for (int i = 0; i < len; i++) { if (smaller[i] != -1 && larger[i] != -1) { - System.out.println(smaller[i] + "," + a[i] + "," + larger[i]); + System.out.println(smaller[i] + "," + arr[i] + "," + larger[i]); break; } } diff --git a/src/main/java/com/rampatra/trees/HeightBalanced.java b/src/main/java/com/rampatra/trees/HeightBalanced.java index 24dbed99..20e24201 100644 --- a/src/main/java/com/rampatra/trees/HeightBalanced.java +++ b/src/main/java/com/rampatra/trees/HeightBalanced.java @@ -1,5 +1,6 @@ package com.rampatra.trees; +import com.ctci.treesandgraphs.TreeNode; import com.rampatra.base.BinaryNode; import com.rampatra.base.BinarySearchTree; @@ -19,7 +20,11 @@ public class HeightBalanced> extends BinarySearchTree * 1) Left subtree of T is balanced * 2) Right subtree of T is balanced * 3) The difference between heights of left subtree and right subtree is not more than 1. - * + * + * This approach is simple but we are traversing each node multiple times while calculating the height. For a more + * optimized approach see {@link com.ctci.treesandgraphs.CheckBalanced#isBalancedOptimized(TreeNode)} where while + * calculating the height of tree we check whether it is balanced or not simultaneously. + * * @return True if tree is height balanced otherwise false. */ public boolean isHeightBalanced() { From 3abc42e6c7689cb0e497af51b3cb9b1fe2213099 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sun, 7 Apr 2019 17:19:15 +0100 Subject: [PATCH 056/164] Fixed JavaDoc --- .../com/rampatra/linkedlists/CloneWithRandPointers.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/rampatra/linkedlists/CloneWithRandPointers.java b/src/main/java/com/rampatra/linkedlists/CloneWithRandPointers.java index c6f69bbd..e2910786 100644 --- a/src/main/java/com/rampatra/linkedlists/CloneWithRandPointers.java +++ b/src/main/java/com/rampatra/linkedlists/CloneWithRandPointers.java @@ -4,12 +4,10 @@ import com.rampatra.base.DoubleLinkedNode; /** - * Created by IntelliJ IDEA. + * Find the question here. * * @author rampatra * @since 6/20/15 - * @time: 1:00 PM - * @see: http://www.geeksforgeeks.org/a-linked-list-with-next-and-arbit-pointer/ */ public class CloneWithRandPointers { @@ -45,7 +43,7 @@ public static > DoubleLinkedList clone(DoubleLinkedLi DoubleLinkedNode dupNode; while (curr != null && curr.next != null) { dupNode = curr.next; - curr.next = (dupNode != null) ? dupNode.next : null; + curr.next = dupNode.next; dupNode.next = (curr.next != null) ? curr.next.next : null; curr = curr.next; } From 4d398102dbb0979ffd02d38c470d76fbfa02f1d7 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Mon, 8 Apr 2019 13:13:42 +0100 Subject: [PATCH 057/164] Simplified the code --- .../linkedlists/CloneWithRandPointers.java | 11 +++---- .../rampatra/strings/AnagramsTogether.java | 3 +- .../AnagramsTogetherLexicographically.java | 31 ++++++++----------- .../strings/KeepOnlyKConsecutiveLetters.java | 21 +++++-------- 4 files changed, 27 insertions(+), 39 deletions(-) diff --git a/src/main/java/com/rampatra/linkedlists/CloneWithRandPointers.java b/src/main/java/com/rampatra/linkedlists/CloneWithRandPointers.java index e2910786..53795113 100644 --- a/src/main/java/com/rampatra/linkedlists/CloneWithRandPointers.java +++ b/src/main/java/com/rampatra/linkedlists/CloneWithRandPointers.java @@ -25,8 +25,7 @@ public static > DoubleLinkedList clone(DoubleLinkedLi // copy each node and insert after it while (curr != null) { - DoubleLinkedNode newNode = new DoubleLinkedNode<>(null, curr.item, curr.next); - curr.next = newNode; + curr.next = new DoubleLinkedNode<>(null, curr.item, curr.next); curr = curr.next.next; } @@ -53,10 +52,10 @@ public static > DoubleLinkedList clone(DoubleLinkedLi public static void main(String[] args) { DoubleLinkedList linkedList = new DoubleLinkedList<>(); - linkedList.add(00); - linkedList.add(11); - linkedList.add(22); - linkedList.add(33); + linkedList.add(0); + linkedList.add(1); + linkedList.add(2); + linkedList.add(3); linkedList.getNode(0).prev = null; linkedList.getNode(1).prev = linkedList.getNode(2); linkedList.getNode(2).prev = linkedList.getNode(0); diff --git a/src/main/java/com/rampatra/strings/AnagramsTogether.java b/src/main/java/com/rampatra/strings/AnagramsTogether.java index caf1dc26..7ae8a8b0 100644 --- a/src/main/java/com/rampatra/strings/AnagramsTogether.java +++ b/src/main/java/com/rampatra/strings/AnagramsTogether.java @@ -11,7 +11,6 @@ * * @author rampatra * @since 9/23/15 - * @time: 8:11 PM */ public class AnagramsTogether { @@ -24,7 +23,7 @@ public class AnagramsTogether { * * @param s */ - public static void printAnagramsTogether(String[] s) { + private static void printAnagramsTogether(String[] s) { // each key holds all the indexes of a anagram HashMap> hashMap = new HashMap<>(); diff --git a/src/main/java/com/rampatra/strings/AnagramsTogetherLexicographically.java b/src/main/java/com/rampatra/strings/AnagramsTogetherLexicographically.java index afa6bc1a..6b48badd 100644 --- a/src/main/java/com/rampatra/strings/AnagramsTogetherLexicographically.java +++ b/src/main/java/com/rampatra/strings/AnagramsTogetherLexicographically.java @@ -12,28 +12,25 @@ public class AnagramsTogetherLexicographically { /** - * Takes an array of String {@param s} and prints anagrams in groups where the groups + * Takes an array of String {@code strings} and prints anagrams in groups where the groups * are arranged lexicographically and the strings within each group are also arranged * lexicographically. * - * @param s + * @param strings */ - public static void printAnagramsTogether(String[] s) { + public static void printAnagramsTogether(String[] strings) { HashMap> hashMap = new HashMap<>(); - TreeSet> treeSet = new TreeSet<>(new Comparator() { - @Override - public int compare(Object o1, Object o2) { - if (o1 instanceof List && o2 instanceof List) { - return ((List) o1).get(0).compareTo(((List) o2).get(0)); - } else { - return 0; - } + TreeSet> treeSet = new TreeSet<>((Comparator) (o1, o2) -> { + if (o1 instanceof List && o2 instanceof List) { + return ((List) o1).get(0).compareTo(((List) o2).get(0)); + } else { + return 0; } }); - for (int i = 0; i < s.length; i++) { - String removeSpaces = s[i].replaceAll("\\s+", ""); + for (int i = 0; i < strings.length; i++) { + String removeSpaces = strings[i].replaceAll("\\s+", ""); char[] chars = removeSpaces.toCharArray(); Arrays.sort(chars); @@ -50,17 +47,14 @@ public int compare(Object o1, Object o2) { List anagrams = new ArrayList<>(); for (int i = 0; i < entry.getValue().size(); i++) { - anagrams.add(s[entry.getValue().get(i)]); + anagrams.add(strings[entry.getValue().get(i)]); } Collections.sort(anagrams); // arrange anagrams lexicographically within a single line treeSet.add(anagrams); // sort the entire output lexicographically } - Iterator iterator = treeSet.iterator(); - while (iterator.hasNext()) { - System.out.println(iterator.next()); - } + treeSet.stream().flatMap(Collection::stream).forEach(System.out::println); } /** @@ -72,6 +66,7 @@ public static void main(String[] args) { Scanner in = new Scanner(System.in); List strings = new ArrayList<>(); String s; + System.out.println("Input string in separate lines (blank string to stop):"); // you should use in.hasNextLine() while (!(s = in.nextLine()).trim().equals("")) { strings.add(s); diff --git a/src/main/java/com/rampatra/strings/KeepOnlyKConsecutiveLetters.java b/src/main/java/com/rampatra/strings/KeepOnlyKConsecutiveLetters.java index 59374fea..aab4df26 100644 --- a/src/main/java/com/rampatra/strings/KeepOnlyKConsecutiveLetters.java +++ b/src/main/java/com/rampatra/strings/KeepOnlyKConsecutiveLetters.java @@ -18,27 +18,22 @@ public class KeepOnlyKConsecutiveLetters { * * @param str input string * @param k - * @return + * @return a string with at most {@code k} consecutive characters */ private static String keepOnlyKConsecutiveLetters(String str, int k) { StringBuilder sb = new StringBuilder(); + int count = 0; for (int i = 0; i < str.length(); i++) { - char ch = str.charAt(i); - - for (int j = 0; i + j < str.length() && j < k; j++) { - char ch2 = str.charAt(i + j); - if (ch2 == ch) { - sb.append(ch2); - } else { - break; - } + if (i != 0 && str.charAt(i) != str.charAt(i - 1)) { + count = 0; } - - while (i + 1 < str.length() && str.charAt(i + 1) == str.charAt(i)) { - i++; + if (count < k) { + sb.append(str.charAt(i)); + count++; } } + return sb.toString(); } From d60e416b8e6532be5ca3167d2fd92f2f4a29d3cd Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Mon, 8 Apr 2019 13:53:36 +0100 Subject: [PATCH 058/164] Compress string: done --- .../com/rampatra/strings/CompressString.java | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/main/java/com/rampatra/strings/CompressString.java diff --git a/src/main/java/com/rampatra/strings/CompressString.java b/src/main/java/com/rampatra/strings/CompressString.java new file mode 100644 index 00000000..ed3ce3d1 --- /dev/null +++ b/src/main/java/com/rampatra/strings/CompressString.java @@ -0,0 +1,60 @@ +package com.rampatra.strings; + +/** + * @author rampatra + * @since 2019-04-08 + */ +public class CompressString { + + /** + * Compress a string, consisting of only alphabets, such that the compressed string contains the letter and + * a number next to it representing the number of times it is repeated. Also, compress only if the letter is + * repeated more than once and ignore it occurs just once. + * EXAMPLE: + * Input: aaabbcdd + * Output: a3b2cd2 + *

+ * Time Complexity: O(n) + * Space Complexity: O(n) + * where, + * n is the number of characters in the input string + * + * @param str the input string consisting on only alphabets + * @return the compressed string + */ + private static String compress(String str) { + // some basic validation + if (str.length() == 0) { + throw new IllegalArgumentException("Empty String"); + } + + StringBuilder sb = new StringBuilder(); + int letterCount = 0; + + for (int i = 0; i < str.length(); i++) { + /* + When the current character is a different one, append the previous character and its count to the + result, and finally, reset the counter + */ + if (i != 0 && str.charAt(i) != str.charAt(i - 1)) { + sb.append(str.charAt(i - 1)); + if (letterCount > 1) sb.append(letterCount); + letterCount = 0; + } + letterCount++; + } + + // last character + sb.append(str.charAt(str.length() - 1)); + if (letterCount > 1) sb.append(letterCount); + + return sb.toString(); + } + + public static void main(String[] args) { + System.out.println(compress("a")); + System.out.println(compress("aabbcc")); + System.out.println(compress("aabcc")); + System.out.println(compress("aaaabbbccaad")); + } +} \ No newline at end of file From 137ca858521781c6637c566b2f55fd35f0f125f5 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Mon, 8 Apr 2019 14:11:44 +0100 Subject: [PATCH 059/164] Renamed variables to make more sense --- .../com/rampatra/strings/AnagramsTogether.java | 15 +++++++-------- .../AnagramsTogetherLexicographically.java | 5 ++--- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/rampatra/strings/AnagramsTogether.java b/src/main/java/com/rampatra/strings/AnagramsTogether.java index 7ae8a8b0..87ee6569 100644 --- a/src/main/java/com/rampatra/strings/AnagramsTogether.java +++ b/src/main/java/com/rampatra/strings/AnagramsTogether.java @@ -15,21 +15,20 @@ public class AnagramsTogether { /** - * Prints all the anagrams together from the string - * array {@param s}. + * Prints all the anagrams together from the string array {@code strings}. *

* Anagrams are words consisting of the same letters but in the same or different * order. For example, "cat" and "tac" are anagrams. Same as "god" and "dog". * - * @param s + * @param strings */ - private static void printAnagramsTogether(String[] s) { + private static void printAnagramsTogether(String[] strings) { // each key holds all the indexes of a anagram HashMap> hashMap = new HashMap<>(); - for (int i = 0; i < s.length; i++) { - char[] chars = s[i].toCharArray(); + for (int i = 0; i < strings.length; i++) { + char[] chars = strings[i].toCharArray(); Arrays.sort(chars); List indexes = hashMap.get(String.valueOf(chars)); @@ -42,7 +41,7 @@ private static void printAnagramsTogether(String[] s) { for (Map.Entry> entry : hashMap.entrySet()) { for (int i = 0; i < entry.getValue().size(); i++) { - System.out.println(s[entry.getValue().get(i)]); + System.out.println(strings[entry.getValue().get(i)]); } System.out.println("------"); } @@ -52,4 +51,4 @@ public static void main(String[] args) { printAnagramsTogether(new String[]{"cat", "dog", "tac", "god", "act"}); printAnagramsTogether(new String[]{"cat", "tac", "act", "god", "dog"}); } -} +} \ No newline at end of file diff --git a/src/main/java/com/rampatra/strings/AnagramsTogetherLexicographically.java b/src/main/java/com/rampatra/strings/AnagramsTogetherLexicographically.java index 6b48badd..c1390646 100644 --- a/src/main/java/com/rampatra/strings/AnagramsTogetherLexicographically.java +++ b/src/main/java/com/rampatra/strings/AnagramsTogetherLexicographically.java @@ -7,7 +7,6 @@ * * @author rampatra * @since 10/11/15 - * @time: 7:56 PM */ public class AnagramsTogetherLexicographically { @@ -30,8 +29,8 @@ public static void printAnagramsTogether(String[] strings) { }); for (int i = 0; i < strings.length; i++) { - String removeSpaces = strings[i].replaceAll("\\s+", ""); - char[] chars = removeSpaces.toCharArray(); + String spaceRemovedStr = strings[i].replaceAll("\\s+", ""); + char[] chars = spaceRemovedStr.toCharArray(); Arrays.sort(chars); List indexes = hashMap.get(String.valueOf(chars)); From 1dfcc73eaa5bf6d74c139f077f2a6755640e7677 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Mon, 8 Apr 2019 20:03:25 +0100 Subject: [PATCH 060/164] Minor improvements --- .../arrays/ArrangeNosToFormBiggestNo.java | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/rampatra/arrays/ArrangeNosToFormBiggestNo.java b/src/main/java/com/rampatra/arrays/ArrangeNosToFormBiggestNo.java index 8d6adcdd..79877175 100644 --- a/src/main/java/com/rampatra/arrays/ArrangeNosToFormBiggestNo.java +++ b/src/main/java/com/rampatra/arrays/ArrangeNosToFormBiggestNo.java @@ -1,19 +1,17 @@ package com.rampatra.arrays; import java.util.Arrays; -import java.util.Comparator; /** * Created by IntelliJ IDEA. * * @author rampatra * @since 11/1/15 - * @time: 8:53 PM */ public class ArrangeNosToFormBiggestNo { /** - * Sorts no.s in array {@param a} such that if you form a number {@code n} + * Sorts {@code numbers} such that if you form a number {@code n} * by concatenating digits in order a[0]....a[size], it results being the * largest number possible. *

@@ -24,19 +22,14 @@ public class ArrangeNosToFormBiggestNo { * I/P: {1, 34, 3, 98, 9, 76, 45, 4} * O/P: {9, 98, 76, 45, 4, 34, 3, 1} i.e, 998764543431 * - * @param a - * @return + * @param numbers input integer array + * @return integer array where if you concatenate all its elements, you will get the largest number */ - public static Integer[] arrangeArrayOfNosToFormBiggestNo(Integer[] a) { + private static Integer[] arrangeArrayOfNosToFormBiggestNo(Integer[] numbers) { - Arrays.sort(a, new Comparator() { - @Override - public int compare(Integer o1, Integer o2) { - return Integer.parseInt(o1 + "" + o2) > Integer.parseInt(o2 + "" + o1) ? -1 : 1; - } - }); + Arrays.sort(numbers, (o1, o2) -> Integer.parseInt(o1 + "" + o2) >= Integer.parseInt(o2 + "" + o1) ? -1 : 1); - return a; + return numbers; } public static void main(String[] args) { @@ -44,4 +37,4 @@ public static void main(String[] args) { System.out.println(Arrays.toString(arrangeArrayOfNosToFormBiggestNo(new Integer[]{54, 546, 548, 60}))); System.out.println(Arrays.toString(arrangeArrayOfNosToFormBiggestNo(new Integer[]{1, 34, 3, 98, 9, 76, 45, 4}))); } -} +} \ No newline at end of file From ccd625df466e7e678d7eec16e07bbebc060d915a Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Mon, 8 Apr 2019 20:06:53 +0100 Subject: [PATCH 061/164] Added some comments --- .../com/rampatra/arrays/ArrangeNosToFormBiggestNo.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/com/rampatra/arrays/ArrangeNosToFormBiggestNo.java b/src/main/java/com/rampatra/arrays/ArrangeNosToFormBiggestNo.java index 79877175..c45b9f96 100644 --- a/src/main/java/com/rampatra/arrays/ArrangeNosToFormBiggestNo.java +++ b/src/main/java/com/rampatra/arrays/ArrangeNosToFormBiggestNo.java @@ -29,6 +29,16 @@ private static Integer[] arrangeArrayOfNosToFormBiggestNo(Integer[] numbers) { Arrays.sort(numbers, (o1, o2) -> Integer.parseInt(o1 + "" + o2) >= Integer.parseInt(o2 + "" + o1) ? -1 : 1); + /* + Use the below version (without lambda) if you use JDK < 8 + + Arrays.sort(numbers, new Comparator() { + @Override + public int compare(Integer o1, Integer o2) { + return Integer.parseInt(o1 + "" + o2) >= Integer.parseInt(o2 + "" + o1) ? -1 : 1; + } + }); + */ return numbers; } From 43c7782afcd3cf2c0a42a9e08175f1ec2f4d6560 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Mon, 8 Apr 2019 20:13:11 +0100 Subject: [PATCH 062/164] Minor improvements --- .../arrays/LongestConsecutiveSubsequence.java | 25 +++++++++++-------- .../linkedlists/DeleteAlternateNodes.java | 15 ++++++----- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/rampatra/arrays/LongestConsecutiveSubsequence.java b/src/main/java/com/rampatra/arrays/LongestConsecutiveSubsequence.java index a8f41c87..8e6a99f8 100644 --- a/src/main/java/com/rampatra/arrays/LongestConsecutiveSubsequence.java +++ b/src/main/java/com/rampatra/arrays/LongestConsecutiveSubsequence.java @@ -10,9 +10,8 @@ public class LongestConsecutiveSubsequence { /** - * Given an array of integers, find the length of the longest sub-sequence such that - * elements in the subsequence are consecutive integers, the consecutive numbers can - * be in any order. + * Given an array of distinct integers, find the length of the longest sub-sequence such that + * elements in the subsequence are consecutive integers, the consecutive numbers can be in any order. *

* Examples: * Input: arr[] = {1, 9, 3, 10, 4, 20, 2}; @@ -24,14 +23,14 @@ public class LongestConsecutiveSubsequence { * Output: 5 * The subsequence {36, 35, 33, 34, 32} is the longest subsequence * of consecutive elements. - * + *

* NOTE: You can also sort this array and check for consecutive elements. You can take this approach if interviewer * asks to solve with no additional space but do bear in mind that some sorting algorithms do require extra space. * - * @param arr unsorted array of integers + * @param arr unsorted array of non-repeating integers * @return the length of the longest consecutive subsequence */ - private static int findLongestConsecutiveSubsequence(int[] arr) { + private static int findLengthOfLongestConsecutiveSubsequence(int[] arr) { int longestSubseqCount = 0; int subseqCount; int currElem; @@ -67,11 +66,15 @@ private static int findLongestConsecutiveSubsequence(int[] arr) { } public static void main(String[] args) { - System.out.println("{1, 9, 3, 10, 4, 20, 2}: " + findLongestConsecutiveSubsequence(new int[]{1, 9, 3, 10, 4, 20, 2})); + + System.out.println("{1, 9, 3, 10, 4, 20, 2}: " + + findLengthOfLongestConsecutiveSubsequence(new int[]{1, 9, 3, 10, 4, 20, 2})); System.out.println("{36, 41, 56, 35, 44, 33, 34, 92, 43, 32, 42}: " + - findLongestConsecutiveSubsequence(new int[]{36, 41, 56, 35, 44, 33, 34, 92, 43, 32, 42})); - System.out.println("{1}: " + findLongestConsecutiveSubsequence(new int[]{1})); - System.out.println("{}: " + findLongestConsecutiveSubsequence(new int[]{})); - System.out.println("{1,5,8,3}: " + findLongestConsecutiveSubsequence(new int[]{1, 5, 8, 3})); + findLengthOfLongestConsecutiveSubsequence(new int[]{36, 41, 56, 35, 44, 33, 34, 92, 43, 32, 42})); + System.out.println("{1,5,8,3}: " + findLengthOfLongestConsecutiveSubsequence(new int[]{1, 5, 8, 3})); + + // corner cases + System.out.println("{1}: " + findLengthOfLongestConsecutiveSubsequence(new int[]{1})); + System.out.println("{}: " + findLengthOfLongestConsecutiveSubsequence(new int[]{})); } } diff --git a/src/main/java/com/rampatra/linkedlists/DeleteAlternateNodes.java b/src/main/java/com/rampatra/linkedlists/DeleteAlternateNodes.java index 6a8c21d2..45670941 100644 --- a/src/main/java/com/rampatra/linkedlists/DeleteAlternateNodes.java +++ b/src/main/java/com/rampatra/linkedlists/DeleteAlternateNodes.java @@ -4,11 +4,10 @@ import com.rampatra.base.SingleLinkedNode; /** - * Created by IntelliJ IDEA. + * Delete alternate nodes in a single linked list. * * @author rampatra * @since 6/27/15 - * @time: 5:27 PM */ public class DeleteAlternateNodes { @@ -26,12 +25,12 @@ public static > void deleteAlternateNodes(SingleLinkedNo public static void main(String[] args) { SingleLinkedList linkedList = new SingleLinkedList<>(); - linkedList.add(00); - linkedList.add(11); - linkedList.add(22); - linkedList.add(33); - linkedList.add(44); - linkedList.add(55); + linkedList.add(0); + linkedList.add(1); + linkedList.add(2); + linkedList.add(3); + linkedList.add(4); + linkedList.add(5); linkedList.printList(); deleteAlternateNodes(linkedList); linkedList.printList(); From a30ac9e8b5aeb441dfe6892937234a7d28446cd6 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Wed, 10 Apr 2019 11:48:25 +0100 Subject: [PATCH 063/164] Minor improvements/corrections --- .../arrays/ArrangeNosToFormBiggestNo.java | 4 +-- .../com/rampatra/arrays/CountDivisors.java | 17 +++++++----- .../rampatra/arrays/DuplicatesInArray.java | 3 +-- .../DuplicatesInArrayWithinKDistance.java | 3 +-- .../com/rampatra/arrays/MajorityElement.java | 20 +++++--------- .../arrays/MajorityElementInSortedArray.java | 27 +++++++++---------- 6 files changed, 35 insertions(+), 39 deletions(-) diff --git a/src/main/java/com/rampatra/arrays/ArrangeNosToFormBiggestNo.java b/src/main/java/com/rampatra/arrays/ArrangeNosToFormBiggestNo.java index c45b9f96..ce069e34 100644 --- a/src/main/java/com/rampatra/arrays/ArrangeNosToFormBiggestNo.java +++ b/src/main/java/com/rampatra/arrays/ArrangeNosToFormBiggestNo.java @@ -17,10 +17,10 @@ public class ArrangeNosToFormBiggestNo { *

* For example, * I/P: {54, 546, 548, 60} - * O/P: {60, 548, 546, 54} i.e, 6054854654 + * O/P: {60, 548, 546, 54}, i.e, 6054854654 *

* I/P: {1, 34, 3, 98, 9, 76, 45, 4} - * O/P: {9, 98, 76, 45, 4, 34, 3, 1} i.e, 998764543431 + * O/P: {9, 98, 76, 45, 4, 34, 3, 1}, i.e, 998764543431 * * @param numbers input integer array * @return integer array where if you concatenate all its elements, you will get the largest number diff --git a/src/main/java/com/rampatra/arrays/CountDivisors.java b/src/main/java/com/rampatra/arrays/CountDivisors.java index af1c5a43..3023dc3c 100644 --- a/src/main/java/com/rampatra/arrays/CountDivisors.java +++ b/src/main/java/com/rampatra/arrays/CountDivisors.java @@ -1,20 +1,21 @@ package com.rampatra.arrays; /** - * Created by rampatra on 31/05/2016. + * @author rampatra + * @since 31/05/2016 */ public class CountDivisors { /** - * Counts the number of integers in the range {@param begin} and - * {@param end} that are divisible by {@param n}. + * Counts the number of integers in the range {@code begin} + * and {@code end} that are divisible by {@code n}. * * @param begin * @param end * @param n * @return */ - public static int countDivisorsInRange(int begin, int end, int n) { + private static int countDivisorsInRange(int begin, int end, int n) { int b = end / n + 1; // From 0 to end the integers divisible by n int a = begin / n + 1; // From 0 to begin the integers divisible by n @@ -25,6 +26,10 @@ public static int countDivisorsInRange(int begin, int end, int n) { } public static void main(String[] args) { - countDivisorsInRange(0, 2000000000, 5); + System.out.println(countDivisorsInRange(0, 0, 5)); + System.out.println(countDivisorsInRange(1, 1, 5)); + System.out.println(countDivisorsInRange(0, 1, 5)); + System.out.println(countDivisorsInRange(0, 10, 5)); + System.out.println(countDivisorsInRange(0, 2000000000, 5)); } -} +} \ No newline at end of file diff --git a/src/main/java/com/rampatra/arrays/DuplicatesInArray.java b/src/main/java/com/rampatra/arrays/DuplicatesInArray.java index a101aa7f..5cb9cbe8 100644 --- a/src/main/java/com/rampatra/arrays/DuplicatesInArray.java +++ b/src/main/java/com/rampatra/arrays/DuplicatesInArray.java @@ -7,14 +7,13 @@ * * @author rampatra * @since 8/21/15 - * @time: 9:41 AM */ public class DuplicatesInArray { /** * Given an array of n elements which contains elements from 0 to n-1, with any of * these numbers appearing any number of times. Find these repeating numbers in O(n) - * and using only constant memory space. + * time complexity. *

* For example, let n be 7 and array be {1, 2, 3, 1, 3, 6, 6}, the answer should be * 1, 3 and 6. diff --git a/src/main/java/com/rampatra/arrays/DuplicatesInArrayWithinKDistance.java b/src/main/java/com/rampatra/arrays/DuplicatesInArrayWithinKDistance.java index 1cf4cbb7..2117d712 100644 --- a/src/main/java/com/rampatra/arrays/DuplicatesInArrayWithinKDistance.java +++ b/src/main/java/com/rampatra/arrays/DuplicatesInArrayWithinKDistance.java @@ -8,12 +8,11 @@ * * @author rampatra * @since 10/18/15 - * @time: 8:40 PM */ public class DuplicatesInArrayWithinKDistance { /** - * Finds duplicates in an unsorted array {@param a} which are + * Finds duplicates in an unsorted array {@code a} which are * only k distance apart from each other. * * @param a diff --git a/src/main/java/com/rampatra/arrays/MajorityElement.java b/src/main/java/com/rampatra/arrays/MajorityElement.java index e7785f90..51e5d11f 100644 --- a/src/main/java/com/rampatra/arrays/MajorityElement.java +++ b/src/main/java/com/rampatra/arrays/MajorityElement.java @@ -1,24 +1,18 @@ package com.rampatra.arrays; -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 5/20/15 - * @time: 2:36 PM - */ - - /** * The algorithm for finding a possible candidate * works in O(n) which is known as Moore’s Voting Algorithm. * Basic idea of the algorithm is if we cancel out each * occurrence of an element e with all the other elements - * that are different from e then e will exist till end + * that are different from e then e will exist until end * if it is a majority element. *

* Time Complexity: O(n) * Auxiliary Space : O(1) + * + * @author rampatra + * @since 5/20/15 */ public class MajorityElement { @@ -29,7 +23,7 @@ public class MajorityElement { * @param a * @return */ - public static int findCandidate(int a[]) { + public static int findCandidate(int[] a) { int candidate = a[0], count = 1; for (int i = 1; i < a.length; i++) { if (candidate == a[i]) { @@ -45,7 +39,7 @@ public static int findCandidate(int a[]) { return candidate; } - public static void majorityElement(int a[]) { + public static void majorityElement(int[] a) { int candidate = findCandidate(a), count = 0; @@ -65,4 +59,4 @@ public static void majorityElement(int a[]) { public static void main(String[] args) { majorityElement(new int[]{1, 6, 2, 2, 2, 1, 2, 2, 7, 2}); } -} +} \ No newline at end of file diff --git a/src/main/java/com/rampatra/arrays/MajorityElementInSortedArray.java b/src/main/java/com/rampatra/arrays/MajorityElementInSortedArray.java index 56e5ff21..ded2db27 100644 --- a/src/main/java/com/rampatra/arrays/MajorityElementInSortedArray.java +++ b/src/main/java/com/rampatra/arrays/MajorityElementInSortedArray.java @@ -5,28 +5,27 @@ * * @author rampatra * @since 7/31/15 - * @time: 10:02 AM */ public class MajorityElementInSortedArray { /** - * Checks if {@param n} is a majority element in array {@param a} + * Checks if {@code n} is a majority element in array {@code arr} * by performing a binary search. *

* Time complexity: O(log n) * - * @param a + * @param arr * @param n * @return */ - public static boolean isMajorityElement(int[] a, int n) { - int l = a.length; - int startIndex = getFirstIndexOf(a, n, 0, l - 1); + public static boolean isMajorityElement(int[] arr, int n) { + int l = arr.length; + int startIndex = getFirstIndexOf(arr, n, 0, l - 1); // element not found if (startIndex == -1) return false; - if (startIndex + l / 2 < l && a[startIndex + l / 2] == n) { + if (startIndex + l / 2 < l && arr[startIndex + l / 2] == n) { return true; } else { return false; @@ -35,15 +34,15 @@ public static boolean isMajorityElement(int[] a, int n) { } /** - * Returns the index of first occurrence of {@param n} in array {@param a}. + * Returns the index of first occurrence of {@code n} in array {@code arr}. * - * @param a + * @param arr * @param low * @param high * @param n * @return */ - public static int getFirstIndexOf(int[] a, int n, int low, int high) { + public static int getFirstIndexOf(int[] arr, int n, int low, int high) { if (low <= high) { int mid = (low + high) / 2; /** @@ -53,12 +52,12 @@ public static int getFirstIndexOf(int[] a, int n, int low, int high) { * (i) mid == 0 and a[mid] == n * (ii) n > a[mid-1] and a[mid] == n */ - if (a[mid] == n && (mid == 0 || n > a[mid - 1])) { + if (arr[mid] == n && (mid == 0 || n > arr[mid - 1])) { return mid; - } else if (n <= a[mid]) { - return getFirstIndexOf(a, n, low, mid - 1); + } else if (n <= arr[mid]) { + return getFirstIndexOf(arr, n, low, mid - 1); } else { - return getFirstIndexOf(a, n, mid + 1, high); + return getFirstIndexOf(arr, n, mid + 1, high); } } return -1; From c41d117570d248d895b3029365867b5858ffe843 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Wed, 10 Apr 2019 16:22:33 +0100 Subject: [PATCH 064/164] Trie code improved --- src/main/java/com/rampatra/base/Trie.java | 52 +++++++++++------------ 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/rampatra/base/Trie.java b/src/main/java/com/rampatra/base/Trie.java index 9f867f91..5e22ec3b 100644 --- a/src/main/java/com/rampatra/base/Trie.java +++ b/src/main/java/com/rampatra/base/Trie.java @@ -14,20 +14,30 @@ * Some resources: * Trie Data Structure * More about Tries + * Video explanation from Gayle McDowell * * @author rampatra * @since 9/22/15 */ public class Trie { - TrieNode root; + private class TrieNode { + HashMap> children; + boolean isCompleteWord; // to mark a complete word in the tri data structure + + TrieNode(HashMap> children) { + this.children = children; + } + } + + private TrieNode root; Trie() { - root = new TrieNode<>(null, new HashMap<>()); + root = new TrieNode<>(new HashMap<>()); } /** - * Inserts {@param data} in trie. + * Inserts {@code data} in trie. * * @param data */ @@ -35,11 +45,11 @@ public void insert(E data) { int i = 0; String str = data.toString(); - TrieNode curr = root; + TrieNode curr = root; while (i < str.length()) { - if (curr.children.get(str.substring(i, i + 1)) != null) { - curr = curr.children.get(str.substring(i, i + 1)); + if (curr.children.get(str.charAt(i)) != null) { + curr = curr.children.get(str.charAt(i)); i++; } else { break; @@ -47,12 +57,12 @@ public void insert(E data) { } while (i < str.length()) { - curr.children.put((E) str.substring(i, i + 1), new TrieNode<>(null, new HashMap<>())); - curr = curr.children.get(str.substring(i, i + 1)); + curr.children.put(str.charAt(i), new TrieNode<>(new HashMap<>())); + curr = curr.children.get(str.charAt(i)); i++; } - curr.data = data; + curr.isCompleteWord = true; } /** @@ -63,29 +73,17 @@ public void insert(E data) { */ public boolean search(E data) { - int i = 0; String str = data.toString(); - TrieNode curr = root; + TrieNode curr = root; - while (i < str.length()) { - if (curr.children.get(str.substring(i, i + 1)) == null) { + for (int i = 0; i < str.length(); i++) { + if (curr.children.get(str.charAt(i)) == null) { return false; } - curr = curr.children.get(str.substring(i, i + 1)); - i++; + curr = curr.children.get(str.charAt(i)); } - return curr.data != null && curr.data.equals(data); - } - - private class TrieNode { - T data; // stores the complete string (required to determine whether the string is in the trie) - HashMap> children; - - TrieNode(T data, HashMap> children) { - this.data = data; - this.children = children; - } + return curr.isCompleteWord; } // unit testing @@ -101,4 +99,4 @@ public static void main(String[] args) { System.out.println(trie.search("raz")); System.out.println(trie.search("rampatra")); } -} +} \ No newline at end of file From 83635789a37e3d4b82022f7b224dc8b67cb25e33 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Wed, 10 Apr 2019 20:31:33 +0100 Subject: [PATCH 065/164] MergeSort space optimized made simple --- .../java/com/rampatra/sorting/MergeSort.java | 12 ++-- .../sorting/MergeSortSpaceOptimized.java | 69 +++++++++---------- 2 files changed, 40 insertions(+), 41 deletions(-) diff --git a/src/main/java/com/rampatra/sorting/MergeSort.java b/src/main/java/com/rampatra/sorting/MergeSort.java index c5a890d5..eb95cf79 100644 --- a/src/main/java/com/rampatra/sorting/MergeSort.java +++ b/src/main/java/com/rampatra/sorting/MergeSort.java @@ -19,20 +19,20 @@ public class MergeSort { * Time complexity: O(n log n) * Space complexity: O(n) (also needs O(log n) stack space as it is recursive) * - * @param a + * @param arr * @return */ - public static int[] mergeSort(int[] a) { - if (a.length == 1) return a; + public static int[] mergeSort(int[] arr) { + if (arr.length == 1) return arr; - int[] x = mergeSort(Arrays.copyOfRange(a, 0, a.length / 2)); - int[] y = mergeSort(Arrays.copyOfRange(a, a.length / 2, a.length)); + int[] x = mergeSort(Arrays.copyOfRange(arr, 0, arr.length / 2)); + int[] y = mergeSort(Arrays.copyOfRange(arr, arr.length / 2, arr.length)); return merge(x, y); } /** - * Merges two sorted arrays {@param a} and {@param b}. + * Merges two sorted arrays {@code a} and {@code b}. * * @param a * @param b diff --git a/src/main/java/com/rampatra/sorting/MergeSortSpaceOptimized.java b/src/main/java/com/rampatra/sorting/MergeSortSpaceOptimized.java index 4d249a9a..1b80caf8 100644 --- a/src/main/java/com/rampatra/sorting/MergeSortSpaceOptimized.java +++ b/src/main/java/com/rampatra/sorting/MergeSortSpaceOptimized.java @@ -10,59 +10,58 @@ public class MergeSortSpaceOptimized { /** * This is entry point. You can call this method to sort - * an array {@code a}. + * an array {@code arr}. * - * @param a array to be sorted + * @param arr array to be sorted */ - public static void mergeSort(int[] a) { - mergeSort(a, new int[a.length], 0, a.length - 1); + public static void mergeSort(int[] arr) { + mergeSort(arr, new int[arr.length], 0, arr.length - 1); } - private static void mergeSort(int[] a, int[] helper, int low, int high) { + private static void mergeSort(int[] arr, int[] helper, int low, int high) { if (low < high) { int mid = (low + high) / 2; // to prevent overflow you can instead do: mid = low + (high - low) / 2 - mergeSort(a, helper, low, mid); - mergeSort(a, helper, mid + 1, high); + mergeSort(arr, helper, low, mid); + mergeSort(arr, helper, mid + 1, high); - merge(a, helper, low, mid, high); + merge(arr, helper, low, mid, high); } } - private static void merge(int[] a, int[] helper, int low, int mid, int high) { - // have a helper array from which you will choose numbers and finally place it in a - for (int i = low; i <= high; i++) { - helper[i] = a[i]; - } - - int helperLeft = low; - int helperRight = mid + 1; - int current = low; + private static void merge(int[] arr, int[] helper, int low, int mid, int high) { + int k = low; - // check left half of the helper array with the right half - while (helperLeft <= mid && helperRight <= high) { - if (helper[helperLeft] < helper[helperRight]) { - a[current++] = helper[helperLeft++]; - } else { - a[current++] = helper[helperRight++]; + /* + Similar to merging two sorted arrays, i.e, merge two parts of arr[], arr[low..mid] and arr[mid+1..high], + and store in helper[] + */ + for (int i = low, j = mid + 1; i <= mid || j <= high; ) { + if (i > mid) { + helper[k++] = arr[j++]; + } else if (j > high) { + helper[k++] = arr[i++]; + } else if (arr[i] <= arr[j]) { + helper[k++] = arr[i++]; + } else if (arr[i] > arr[j]) { + helper[k++] = arr[j++]; } } - // copy the left half of the helper array and not the right - // half as the right half is already there in array a - for (int i = helperLeft; i <= mid; i++) { - a[current++] = helper[i]; + // finally copy the sorted result from helper[] to arr[] + for (int i = low; i <= high; i++) { // note: we can use System.arraycopy() for better performance + arr[i] = helper[i]; } } public static void main(String[] args) { - int[] a = {3, 6, 8, 9, 1, 2, 4}; - System.out.println(Arrays.toString(a)); - mergeSort(a); - System.out.println(Arrays.toString(a)); - a = new int[]{5, 8, 1, 2, 5, 3, 0, 1, 2, 4}; - System.out.println(Arrays.toString(a)); - mergeSort(a); - System.out.println(Arrays.toString(a)); + int[] arr = {3, 6, 8, 9, 1, 2, 4}; + System.out.println(Arrays.toString(arr)); + mergeSort(arr); + System.out.println(Arrays.toString(arr)); + arr = new int[]{5, 8, 1, 2, 5, 3, 0, 1, 2, 4}; + System.out.println(Arrays.toString(arr)); + mergeSort(arr); + System.out.println(Arrays.toString(arr)); } } From e34600d6d88233c74304466782420b9bef31dd56 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Thu, 11 Apr 2019 22:27:38 +0100 Subject: [PATCH 066/164] Improved trie code + leetcode longest word done --- .../java/com/leetcode/trie/LongestWord.java | 77 +++++++++++++++++++ src/main/java/com/rampatra/base/Trie.java | 45 ++++------- 2 files changed, 94 insertions(+), 28 deletions(-) create mode 100644 src/main/java/com/leetcode/trie/LongestWord.java diff --git a/src/main/java/com/leetcode/trie/LongestWord.java b/src/main/java/com/leetcode/trie/LongestWord.java new file mode 100644 index 00000000..8bfec339 --- /dev/null +++ b/src/main/java/com/leetcode/trie/LongestWord.java @@ -0,0 +1,77 @@ +package com.leetcode.trie; + +import java.util.HashMap; +import java.util.Stack; + +/** + * Leetcode Problem: https://leetcode.com/problems/longest-word-in-dictionary/ + * + * @author rampatra + * @since 2019-04-10 + */ +public class LongestWord { + + private class TrieNode { + char ch; + HashMap children = new HashMap<>(); + String completeWord; // to mark a complete word in the tri data structure + + TrieNode(char ch) { + this.ch = ch; + } + } + + private TrieNode root = new TrieNode('0'); + + /** + * Inserts {@code data} in trie. + * + * @param str + */ + public void insert(String str) { + char c; + TrieNode curr = root; + + for (int i = 0; i < str.length(); i++) { + c = str.charAt(i); + curr.children.putIfAbsent(c, new TrieNode(c)); + curr = curr.children.get(c); + } + + curr.completeWord = str; + } + + public String longestWord(String[] words) { + for (int i = 0; i < words.length; i++) { + insert(words[i]); + } + + return longestWord(); + } + + private String longestWord() { + String longestWord = ""; + TrieNode curr; + Stack stack = new Stack<>(); + stack.addAll(root.children.values()); + + while (!stack.empty()) { + curr = stack.pop(); + if (curr.completeWord != null) { + if (curr.completeWord.length() > longestWord.length() || + (curr.completeWord.length() == longestWord.length() && + curr.completeWord.compareTo(longestWord) < 0)) { + longestWord = curr.completeWord; + } + stack.addAll(curr.children.values()); + } + } + return longestWord; + } + + public static void main(String[] args) { + LongestWord longestWord = new LongestWord(); + System.out.println(longestWord.longestWord(new String[]{"w", "wo", "wor", "worl", "world"})); + System.out.println(longestWord.longestWord(new String[]{"a", "banana", "app", "appl", "ap", "apply", "apple"})); + } +} \ No newline at end of file diff --git a/src/main/java/com/rampatra/base/Trie.java b/src/main/java/com/rampatra/base/Trie.java index 5e22ec3b..65cb7cbb 100644 --- a/src/main/java/com/rampatra/base/Trie.java +++ b/src/main/java/com/rampatra/base/Trie.java @@ -19,47 +19,37 @@ * @author rampatra * @since 9/22/15 */ -public class Trie { +public class Trie { private class TrieNode { - HashMap> children; + char ch; + HashMap> children = new HashMap<>(); boolean isCompleteWord; // to mark a complete word in the tri data structure - TrieNode(HashMap> children) { - this.children = children; + TrieNode(char ch) { + this.ch = ch; } } private TrieNode root; Trie() { - root = new TrieNode<>(new HashMap<>()); + root = new TrieNode<>('0'); } /** * Inserts {@code data} in trie. * - * @param data + * @param str */ - public void insert(E data) { - - int i = 0; - String str = data.toString(); + public void insert(String str) { + char c; TrieNode curr = root; - while (i < str.length()) { - if (curr.children.get(str.charAt(i)) != null) { - curr = curr.children.get(str.charAt(i)); - i++; - } else { - break; - } - } - - while (i < str.length()) { - curr.children.put(str.charAt(i), new TrieNode<>(new HashMap<>())); - curr = curr.children.get(str.charAt(i)); - i++; + for (int i = 0; i < str.length(); i++) { + c = str.charAt(i); + curr.children.putIfAbsent(c, new TrieNode<>(c)); + curr = curr.children.get(c); } curr.isCompleteWord = true; @@ -68,12 +58,11 @@ public void insert(E data) { /** * Searches {@code data} in trie. * - * @param data the value to search. - * @return {@code true} if {@code data} is present, {@code false} otherwise. + * @param str the value to search. + * @return {@code true} if {@code str} is present, {@code false} otherwise. */ - public boolean search(E data) { + public boolean search(String str) { - String str = data.toString(); TrieNode curr = root; for (int i = 0; i < str.length(); i++) { @@ -88,7 +77,7 @@ public boolean search(E data) { // unit testing public static void main(String[] args) { - Trie trie = new Trie<>(); + Trie trie = new Trie(); trie.insert("ram"); trie.insert("r"); trie.insert("rama"); From 2a01fac59845b3fe0e383b6401a344cb6c0308e3 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Fri, 12 Apr 2019 16:20:34 +0100 Subject: [PATCH 067/164] Subtree check done (comments pending) --- .../com/ctci/treesandgraphs/CheckSubtree.java | 79 +++++++++++++++++-- .../java/com/leetcode/trie/LongestWord.java | 2 +- 2 files changed, 74 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/ctci/treesandgraphs/CheckSubtree.java b/src/main/java/com/ctci/treesandgraphs/CheckSubtree.java index 79e2e58e..4bfdbd77 100644 --- a/src/main/java/com/ctci/treesandgraphs/CheckSubtree.java +++ b/src/main/java/com/ctci/treesandgraphs/CheckSubtree.java @@ -6,13 +6,80 @@ */ public class CheckSubtree { - /*private static boolean isT2SubtreeofT1(TreeNode t1, TreeNode t2) { - + private static boolean isT2SubtreeOfT1(TreeNode t1, TreeNode t2) { + if (t1 == null) { + return false; + } else if (t2 == null) { + return true; + } + + if (t1.val == t2.val) { + if (matchTree(t1, t2)) { + return true; + } + } + return isT2SubtreeOfT1(t1.left, t2) || isT2SubtreeOfT1(t1.right, t2); } - + private static boolean matchTree(TreeNode a, TreeNode b) { - }*/ - + if (a == null && b == null) { + return true; + } else if (a == null) { + return false; + } else if (b == null) { + return true; + } else if (a.val != b.val) { + return false; + } else { + return matchTree(a.left, b.left) && matchTree(a.right, b.right); + } + } + public static void main(String[] args) { + /* + The BST looks like: + + 4 + / \ + 2 8 + / \ / \ + 1 3 6 9 + / + 0 + + */ + TreeNode treeRoot = new TreeNode(4); + treeRoot.left = new TreeNode(2); + treeRoot.right = new TreeNode(8); + treeRoot.left.left = new TreeNode(1); + treeRoot.left.right = new TreeNode(3); + treeRoot.left.left.left = new TreeNode(0); + treeRoot.right.left = new TreeNode(6); + treeRoot.right.right = new TreeNode(9); + System.out.println(isT2SubtreeOfT1(treeRoot, treeRoot)); + System.out.println(isT2SubtreeOfT1(treeRoot, treeRoot.left)); + System.out.println(isT2SubtreeOfT1(treeRoot, treeRoot.right)); + + /* + The sub-tree: + + 8 + / + 6 + */ + TreeNode treeRoot2 = new TreeNode(8); + treeRoot2.left = new TreeNode(6); + System.out.println(isT2SubtreeOfT1(treeRoot, treeRoot2)); + + /* + The sub-tree: + + 8 + / + 9 + */ + TreeNode treeRoot3 = new TreeNode(8); + treeRoot3.left = new TreeNode(9); + System.out.println(isT2SubtreeOfT1(treeRoot, treeRoot3)); } -} +} \ No newline at end of file diff --git a/src/main/java/com/leetcode/trie/LongestWord.java b/src/main/java/com/leetcode/trie/LongestWord.java index 8bfec339..f0e1c21d 100644 --- a/src/main/java/com/leetcode/trie/LongestWord.java +++ b/src/main/java/com/leetcode/trie/LongestWord.java @@ -14,7 +14,7 @@ public class LongestWord { private class TrieNode { char ch; HashMap children = new HashMap<>(); - String completeWord; // to mark a complete word in the tri data structure + String completeWord; // to mark a complete word in the trie data structure TrieNode(char ch) { this.ch = ch; From 56f0fa2644e6b382c96103016ddda9a768f4e500 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Fri, 12 Apr 2019 16:22:46 +0100 Subject: [PATCH 068/164] Added one more test case --- .../com/ctci/treesandgraphs/CheckSubtree.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/ctci/treesandgraphs/CheckSubtree.java b/src/main/java/com/ctci/treesandgraphs/CheckSubtree.java index 4bfdbd77..a49f1b74 100644 --- a/src/main/java/com/ctci/treesandgraphs/CheckSubtree.java +++ b/src/main/java/com/ctci/treesandgraphs/CheckSubtree.java @@ -70,6 +70,17 @@ public static void main(String[] args) { TreeNode treeRoot2 = new TreeNode(8); treeRoot2.left = new TreeNode(6); System.out.println(isT2SubtreeOfT1(treeRoot, treeRoot2)); + + /* + The sub-tree: + + 2 + / + 1 + */ + TreeNode treeRoot3 = new TreeNode(2); + treeRoot3.left = new TreeNode(1); + System.out.println(isT2SubtreeOfT1(treeRoot, treeRoot3)); /* The sub-tree: @@ -78,8 +89,8 @@ public static void main(String[] args) { / 9 */ - TreeNode treeRoot3 = new TreeNode(8); - treeRoot3.left = new TreeNode(9); - System.out.println(isT2SubtreeOfT1(treeRoot, treeRoot3)); + TreeNode treeRoot4 = new TreeNode(8); + treeRoot4.left = new TreeNode(9); + System.out.println(isT2SubtreeOfT1(treeRoot, treeRoot4)); } } \ No newline at end of file From 88248f2fc4c4486bf791e92890f0840e2175b8a1 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sat, 13 Apr 2019 13:15:19 +0100 Subject: [PATCH 069/164] Anagrams in string: naive sol. done --- .../leetcode/strings/AnagramsInString.java | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/main/java/com/leetcode/strings/AnagramsInString.java diff --git a/src/main/java/com/leetcode/strings/AnagramsInString.java b/src/main/java/com/leetcode/strings/AnagramsInString.java new file mode 100644 index 00000000..e646e671 --- /dev/null +++ b/src/main/java/com/leetcode/strings/AnagramsInString.java @@ -0,0 +1,52 @@ +package com.leetcode.strings; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Leetcode Problem: https://leetcode.com/problems/find-all-anagrams-in-a-string/ + * + * @author rampatra + * @since 2019-04-13 + */ +public class AnagramsInString { + + private static List findAllAnagramsInTextNaive(String text, String pattern) { + List indexes = new ArrayList<>(); + + int textLen = text.length(); + int patternLen = pattern.length(); + + char[] patternChars = pattern.toCharArray(); + Arrays.sort(patternChars); // takes O(m log m) time + String sortedPattern = String.valueOf(patternChars); + + String subText; + char[] subTextChars; + String sortedSubText; + + for (int i = 0; i <= textLen - patternLen; i++) { // loops n-m number of times + subText = text.substring(i, i + patternLen); + subTextChars = subText.toCharArray(); + Arrays.sort(subTextChars); // sorts m number of characters, takes O(m log m) + sortedSubText = String.valueOf(subTextChars); + + if (sortedSubText.equals(sortedPattern)) { // compare m characters takes m time + indexes.add(i); + } + } + return indexes; + } + + public static void main(String[] args) { + // basic use cases + System.out.println(findAllAnagramsInTextNaive("cbaebabacd", "abc")); + System.out.println(findAllAnagramsInTextNaive("abab", "ab")); + + // corner cases + System.out.println(findAllAnagramsInTextNaive("abab", "")); + System.out.println(findAllAnagramsInTextNaive("", "ab")); + System.out.println(findAllAnagramsInTextNaive("", "")); + } +} \ No newline at end of file From 0406fe11b8830bd5d73b40cfc781154c17d1d30a Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sat, 13 Apr 2019 15:01:57 +0100 Subject: [PATCH 070/164] Variable name modified --- src/main/java/com/leetcode/strings/AnagramsInString.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/leetcode/strings/AnagramsInString.java b/src/main/java/com/leetcode/strings/AnagramsInString.java index e646e671..a524b39f 100644 --- a/src/main/java/com/leetcode/strings/AnagramsInString.java +++ b/src/main/java/com/leetcode/strings/AnagramsInString.java @@ -20,19 +20,19 @@ private static List findAllAnagramsInTextNaive(String text, String patt char[] patternChars = pattern.toCharArray(); Arrays.sort(patternChars); // takes O(m log m) time - String sortedPattern = String.valueOf(patternChars); + String patternSorted = String.valueOf(patternChars); String subText; char[] subTextChars; - String sortedSubText; + String subTextSorted; for (int i = 0; i <= textLen - patternLen; i++) { // loops n-m number of times subText = text.substring(i, i + patternLen); subTextChars = subText.toCharArray(); Arrays.sort(subTextChars); // sorts m number of characters, takes O(m log m) - sortedSubText = String.valueOf(subTextChars); + subTextSorted = String.valueOf(subTextChars); - if (sortedSubText.equals(sortedPattern)) { // compare m characters takes m time + if (subTextSorted.equals(patternSorted)) { // compare m characters takes m time indexes.add(i); } } From 50de25757b7c329dc35d7544ffb951d38c3cb7b4 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Tue, 16 Apr 2019 21:54:31 +0100 Subject: [PATCH 071/164] Anagrams in string: done --- README.md | 3 +- .../leetcode/strings/AnagramsInString.java | 79 ++++++++++++++++--- 2 files changed, 69 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 79c62a96..989a3224 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,8 @@ You can also refer to my [Java Notes](http://java.ramswaroop.me) for a quick ref 4. [Trees and Graphs](/src/main/java/com/ctci/treesandgraphs) 5. [Bit Manipulation](/src/main/java/com/ctci/bitmanipulation) 6. [Recursion and DP](/src/main/java/com/ctci/recursionanddp) -3. [HackerRank](/src/main/java/com/hackerrank). +3. [LeetCode](/src/main/java/com/leetcode). +4. [HackerRank](/src/main/java/com/hackerrank). ## Environment diff --git a/src/main/java/com/leetcode/strings/AnagramsInString.java b/src/main/java/com/leetcode/strings/AnagramsInString.java index a524b39f..9243d015 100644 --- a/src/main/java/com/leetcode/strings/AnagramsInString.java +++ b/src/main/java/com/leetcode/strings/AnagramsInString.java @@ -6,47 +6,102 @@ /** * Leetcode Problem: https://leetcode.com/problems/find-all-anagrams-in-a-string/ - * + * * @author rampatra * @since 2019-04-13 */ public class AnagramsInString { + /** + * Time complexity: O ((n-m) * m log m) + * where, + * n = text length + * m = pattern length + * + * @param text + * @param pattern + * @return + */ private static List findAllAnagramsInTextNaive(String text, String pattern) { List indexes = new ArrayList<>(); - + int textLen = text.length(); int patternLen = pattern.length(); - + char[] patternChars = pattern.toCharArray(); Arrays.sort(patternChars); // takes O(m log m) time String patternSorted = String.valueOf(patternChars); - + String subText; char[] subTextChars; String subTextSorted; - + for (int i = 0; i <= textLen - patternLen; i++) { // loops n-m number of times - subText = text.substring(i, i + patternLen); + subText = text.substring(i, i + patternLen); subTextChars = subText.toCharArray(); Arrays.sort(subTextChars); // sorts m number of characters, takes O(m log m) subTextSorted = String.valueOf(subTextChars); - + if (subTextSorted.equals(patternSorted)) { // compare m characters takes m time indexes.add(i); } } return indexes; } - + + /** + * Time complexity: O(n). Completes within 7ms on + * leetcode. + * + * @param text + * @param pattern + * @return + */ + private static List findAllAnagramsInText(String text, String pattern) { + List indices = new ArrayList<>(); + + int textLen = text.length(); + int patternLen = pattern.length(); + + int[] textCharCountInWindow = new int[26]; + int[] patternCharCount = new int[26]; + + for (int i = 0; i < patternLen; i++) { + patternCharCount[pattern.charAt(i) - 'a']++; + } + + for (int i = 0; i < textLen; i++) { + textCharCountInWindow[text.charAt(i) - 'a']++; + if (i >= patternLen) { + textCharCountInWindow[text.charAt(i - patternLen) - 'a']--; + } + if (Arrays.equals(textCharCountInWindow, patternCharCount)) { // loops 26 times no matter the text/pattern length + indices.add(i - patternLen + 1); + } + } + + return indices; + } + public static void main(String[] args) { // basic use cases System.out.println(findAllAnagramsInTextNaive("cbaebabacd", "abc")); System.out.println(findAllAnagramsInTextNaive("abab", "ab")); - - // corner cases - System.out.println(findAllAnagramsInTextNaive("abab", "")); + System.out.println(findAllAnagramsInTextNaive("af", "af")); + System.out.println(findAllAnagramsInTextNaive("af", "be")); + + // corner case System.out.println(findAllAnagramsInTextNaive("", "ab")); - System.out.println(findAllAnagramsInTextNaive("", "")); + + System.out.println("-----"); + + // basic use cases + System.out.println(findAllAnagramsInText("cbaebabacd", "abc")); + System.out.println(findAllAnagramsInText("abab", "ab")); + System.out.println(findAllAnagramsInText("af", "af")); + System.out.println(findAllAnagramsInText("af", "be")); + + // corner case + System.out.println(findAllAnagramsInText("", "ab")); } } \ No newline at end of file From b6a3322649a6e1a7944a226a98edb5d28ec820d4 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Tue, 16 Apr 2019 22:11:51 +0100 Subject: [PATCH 072/164] Unique char in string: done --- .../leetcode/strings/AnagramsInString.java | 6 ++- .../strings/UniqueCharacterInString.java | 37 +++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/leetcode/strings/UniqueCharacterInString.java diff --git a/src/main/java/com/leetcode/strings/AnagramsInString.java b/src/main/java/com/leetcode/strings/AnagramsInString.java index 9243d015..0c113569 100644 --- a/src/main/java/com/leetcode/strings/AnagramsInString.java +++ b/src/main/java/com/leetcode/strings/AnagramsInString.java @@ -50,8 +50,10 @@ private static List findAllAnagramsInTextNaive(String text, String patt } /** - * Time complexity: O(n). Completes within 7ms on - * leetcode. + * Completes within 7ms on leetcode. + * Time complexity: O(n) + * where, + * n = length of text or number of characters in text * * @param text * @param pattern diff --git a/src/main/java/com/leetcode/strings/UniqueCharacterInString.java b/src/main/java/com/leetcode/strings/UniqueCharacterInString.java new file mode 100644 index 00000000..b5a84b1a --- /dev/null +++ b/src/main/java/com/leetcode/strings/UniqueCharacterInString.java @@ -0,0 +1,37 @@ +package com.leetcode.strings; + +/** + * Leetcode Problem: https://leetcode.com/problems/first-unique-character-in-a-string/ + * + * @author rampatra + * @since 2019-04-16 + */ +public class UniqueCharacterInString { + + /** + * Completes within 7ms on leetcode. + * Time complexity: O(n) + * + * @param str the input string + * @return the index of the first non-repeating character in {@code str}, {@code -1} otherwise. + */ + private static int findFirstUniqueCharacterInString(String str) { + int[] charCount = new int[26]; + + for (int i = 0; i < str.length(); i++) { + charCount[str.charAt(i) - 'a']++; + } + + for (int i = 0; i < str.length(); i++) { + if (charCount[str.charAt(i) - 'a'] == 1) { + return i; + } + } + return -1; + } + + public static void main(String[] args) { + System.out.println(findFirstUniqueCharacterInString("leetcode")); + System.out.println(findFirstUniqueCharacterInString("loveleetcode")); + } +} From 733cdd7467a10f17df651d2493ebe7a187e406c5 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Fri, 19 Apr 2019 12:32:19 +0100 Subject: [PATCH 073/164] Reverse vowels done + some comments refactoring --- .../leetcode/strings/AnagramsInString.java | 5 +- .../com/leetcode/strings/ReverseVowels.java | 65 +++++++++++++++++++ .../leetcode/strings/StringCompression.java | 15 +++++ .../strings/UniqueCharacterInString.java | 2 +- 4 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/leetcode/strings/ReverseVowels.java create mode 100644 src/main/java/com/leetcode/strings/StringCompression.java diff --git a/src/main/java/com/leetcode/strings/AnagramsInString.java b/src/main/java/com/leetcode/strings/AnagramsInString.java index 0c113569..5c1acd9e 100644 --- a/src/main/java/com/leetcode/strings/AnagramsInString.java +++ b/src/main/java/com/leetcode/strings/AnagramsInString.java @@ -13,7 +13,7 @@ public class AnagramsInString { /** - * Time complexity: O ((n-m) * m log m) + * Time complexity: O((n-m) * m log m) * where, * n = text length * m = pattern length @@ -50,10 +50,11 @@ private static List findAllAnagramsInTextNaive(String text, String patt } /** - * Completes within 7ms on leetcode. * Time complexity: O(n) * where, * n = length of text or number of characters in text + *

+ * Runtime: 7 ms on leetcode. * * @param text * @param pattern diff --git a/src/main/java/com/leetcode/strings/ReverseVowels.java b/src/main/java/com/leetcode/strings/ReverseVowels.java new file mode 100644 index 00000000..ce6bdefc --- /dev/null +++ b/src/main/java/com/leetcode/strings/ReverseVowels.java @@ -0,0 +1,65 @@ +package com.leetcode.strings; + +/** + * Leetcode Problem: https://leetcode.com/problems/reverse-vowels-of-a-string/ + * + * @author rampatra + * @since 2019-04-19 + */ +public class ReverseVowels { + + /** + * Reverse only the vowels in the string {@code str}. + *

+ * Time Complexity: O(n) + * where, + * n = no. of characters in the string + *

+ * Runtime: 2 ms on leetcode. + * + * @param str + * @return + */ + private static String reverseVowels(String str) { + + char[] chars = str.toCharArray(); + char temp; + int left = 0; + int right = str.length() - 1; + + while (left < right) { + // find the vowel from left + while (!isVowel(chars[left]) && left < right) { + left++; + } + // find the vowel from right + while (!isVowel(chars[right]) && left < right) { + right--; + } + + if (!isVowel(chars[left]) || !isVowel(chars[right])) { + break; + } + + // swap the characters + temp = chars[left]; + chars[left] = chars[right]; + chars[right] = temp; + + left++; + right--; + } + return new String(chars); + } + + private static boolean isVowel(char c) { + return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' || + c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U'; + } + + public static void main(String[] args) { + System.out.println(reverseVowels("hello")); + System.out.println(reverseVowels("a")); + System.out.println(reverseVowels("")); + } +} \ No newline at end of file diff --git a/src/main/java/com/leetcode/strings/StringCompression.java b/src/main/java/com/leetcode/strings/StringCompression.java new file mode 100644 index 00000000..7697f591 --- /dev/null +++ b/src/main/java/com/leetcode/strings/StringCompression.java @@ -0,0 +1,15 @@ +package com.leetcode.strings; + +/** + * @author rampatra + * @since 2019-04-16 + */ +public class StringCompression { + + private static int compress(char[] chars) { + return -1; + } + + public static void main(String[] args) { + } +} diff --git a/src/main/java/com/leetcode/strings/UniqueCharacterInString.java b/src/main/java/com/leetcode/strings/UniqueCharacterInString.java index b5a84b1a..33236436 100644 --- a/src/main/java/com/leetcode/strings/UniqueCharacterInString.java +++ b/src/main/java/com/leetcode/strings/UniqueCharacterInString.java @@ -9,8 +9,8 @@ public class UniqueCharacterInString { /** - * Completes within 7ms on leetcode. * Time complexity: O(n) + * Runtime: 7 ms on leetcode. * * @param str the input string * @return the index of the first non-repeating character in {@code str}, {@code -1} otherwise. From bcdc91aa9d14cf6e79daa7c91ec34504d55c25ef Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Fri, 19 Apr 2019 21:24:22 +0100 Subject: [PATCH 074/164] Valid palindrome done --- .../com/leetcode/strings/ValidPalindrome.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/main/java/com/leetcode/strings/ValidPalindrome.java diff --git a/src/main/java/com/leetcode/strings/ValidPalindrome.java b/src/main/java/com/leetcode/strings/ValidPalindrome.java new file mode 100644 index 00000000..621d2923 --- /dev/null +++ b/src/main/java/com/leetcode/strings/ValidPalindrome.java @@ -0,0 +1,56 @@ +package com.leetcode.strings; + +/** + * @author rampatra + * @since 2019-04-19 + */ +public class ValidPalindrome { + + /** + * Time complexity: O(n) + * where, + * n = no. of characters in the string + *

+ * Runtime: 2 ms on leetcode. + * + * @param str + * @return + */ + private static boolean isPalindrome(String str) { + char[] chars = str.toCharArray(); + int left = 0; + int right = chars.length - 1; + + while (left < right) { + // if it's not alphanumeric then move the left pointer forward + while (!isAlphaNumeric(chars[left]) && left < right) { + left++; + } + // if it's not alphanumeric then move the right pointer backward + while (!isAlphaNumeric(chars[right]) && left < right) { + right--; + } + + // case insensitive comparison + if (Character.toLowerCase(chars[left]) != Character.toLowerCase(chars[right])) { + return false; + } + + left++; + right--; + } + + return true; + } + + private static boolean isAlphaNumeric(char c) { + int i = (int) c; + return (i >= 48 && i <= 57) || (i >= 65 && i <= 90) || (i >= 97 && i <= 122); + } + + public static void main(String[] args) { + System.out.println(isPalindrome("A man, a plan, a canal: Panama")); + System.out.println(isPalindrome("race a car")); + System.out.println(isPalindrome("0P")); + } +} \ No newline at end of file From 1853108c1bc6906ff8a83333908e75803d5f6bb7 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Fri, 19 Apr 2019 22:14:45 +0100 Subject: [PATCH 075/164] Ransom note done --- .../java/com/leetcode/strings/RansomNote.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/main/java/com/leetcode/strings/RansomNote.java diff --git a/src/main/java/com/leetcode/strings/RansomNote.java b/src/main/java/com/leetcode/strings/RansomNote.java new file mode 100644 index 00000000..ad2a68a5 --- /dev/null +++ b/src/main/java/com/leetcode/strings/RansomNote.java @@ -0,0 +1,39 @@ +package com.leetcode.strings; + +/** + * Problem: https://leetcode.com/problems/ransom-note/ + * + * @author rampatra + * @since 2019-04-19 + */ +public class RansomNote { + + /** + * Runtime: 4 ms/a>. + * + * @param ransomNote + * @param magazine + * @return + */ + public static boolean canConstruct(String ransomNote, String magazine) { + char[] charCount = new char[26]; + + for (int i = 0; i < magazine.length(); i++) { + charCount[magazine.charAt(i) - 'a']++; + } + + for (int i = 0; i < ransomNote.length(); i++) { + if (charCount[ransomNote.charAt(i) - 'a']-- == 0) { + return false; + } + } + return true; + } + + public static void main(String[] args) { + System.out.println(canConstruct("", "")); + System.out.println(canConstruct("a", "a")); + System.out.println(canConstruct("ab", "ab")); + System.out.println(canConstruct("aab", "ab")); + } +} From 933bc3812ade945f3612bd4b03d86b28db9bbd51 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sat, 20 Apr 2019 12:33:01 +0100 Subject: [PATCH 076/164] Reverse String II done --- .../java/com/leetcode/strings/RansomNote.java | 2 +- .../com/leetcode/strings/ReverseStringII.java | 51 +++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/leetcode/strings/ReverseStringII.java diff --git a/src/main/java/com/leetcode/strings/RansomNote.java b/src/main/java/com/leetcode/strings/RansomNote.java index ad2a68a5..76a44f2b 100644 --- a/src/main/java/com/leetcode/strings/RansomNote.java +++ b/src/main/java/com/leetcode/strings/RansomNote.java @@ -36,4 +36,4 @@ public static void main(String[] args) { System.out.println(canConstruct("ab", "ab")); System.out.println(canConstruct("aab", "ab")); } -} +} \ No newline at end of file diff --git a/src/main/java/com/leetcode/strings/ReverseStringII.java b/src/main/java/com/leetcode/strings/ReverseStringII.java new file mode 100644 index 00000000..7f12cf31 --- /dev/null +++ b/src/main/java/com/leetcode/strings/ReverseStringII.java @@ -0,0 +1,51 @@ +package com.leetcode.strings; + +/** + * Problem: https://leetcode.com/problems/reverse-string-ii/ + * + * @author rampatra + * @since 2019-04-20 + */ +public class ReverseStringII { + + /** + * Time complexity: O(n) + * where, + * n = no. of characters in string + *

+ * Runtime: 0 ms. + * + * @param str + * @param k + * @return + */ + public static String reverseStr(String str, int k) { + char[] chars = str.toCharArray(); + int len = str.length(); + int i = 0; + while (i < len) { + if (len - i + 1 >= 2 * k) { + reverse(chars, i, i + k); + } else { + reverse(chars, i, Math.min(len, i + k)); + } + i += 2 * k; + } + return new String(chars); + } + + private static void reverse(char[] chars, int start, int end) { + char temp; + for (int i = start, j = end - 1; i < j; i++, j--) { + temp = chars[i]; + chars[i] = chars[j]; + chars[j] = temp; + } + } + + public static void main(String[] args) { + System.out.println(reverseStr("abcdefg", 2)); + System.out.println(reverseStr("abcdef", 2)); + System.out.println(reverseStr("abcde", 2)); + } +} From fd7915785d6c00523ea98bd1a301d2f265b87f8d Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sat, 20 Apr 2019 12:37:29 +0100 Subject: [PATCH 077/164] Refactored the code a bit --- .../java/com/leetcode/strings/ReverseStringII.java | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/leetcode/strings/ReverseStringII.java b/src/main/java/com/leetcode/strings/ReverseStringII.java index 7f12cf31..bad406ab 100644 --- a/src/main/java/com/leetcode/strings/ReverseStringII.java +++ b/src/main/java/com/leetcode/strings/ReverseStringII.java @@ -2,7 +2,7 @@ /** * Problem: https://leetcode.com/problems/reverse-string-ii/ - * + * * @author rampatra * @since 2019-04-20 */ @@ -13,7 +13,7 @@ public class ReverseStringII { * where, * n = no. of characters in string *

- * Runtime: 0 ms. + * Runtime: 0 ms. * * @param str * @param k @@ -22,14 +22,8 @@ public class ReverseStringII { public static String reverseStr(String str, int k) { char[] chars = str.toCharArray(); int len = str.length(); - int i = 0; - while (i < len) { - if (len - i + 1 >= 2 * k) { - reverse(chars, i, i + k); - } else { - reverse(chars, i, Math.min(len, i + k)); - } - i += 2 * k; + for (int i = 0; i < len; i += 2 * k) { + reverse(chars, i, Math.min(len, i + k)); } return new String(chars); } From c06923c3e95b2f695d46d06a54952d98df9d6beb Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sat, 20 Apr 2019 15:04:15 +0100 Subject: [PATCH 078/164] Count and say done --- .../com/leetcode/strings/CountAndSay.java | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 src/main/java/com/leetcode/strings/CountAndSay.java diff --git a/src/main/java/com/leetcode/strings/CountAndSay.java b/src/main/java/com/leetcode/strings/CountAndSay.java new file mode 100644 index 00000000..ea7fb3c4 --- /dev/null +++ b/src/main/java/com/leetcode/strings/CountAndSay.java @@ -0,0 +1,47 @@ +package com.leetcode.strings; + +/** + * Problem: https://leetcode.com/problems/count-and-say/ + * + * @author rampatra + * @since 2019-04-20 + */ +public class CountAndSay { + + /** + * Time complexity: + * Runtime: 1 ms. + * + * @param n + * @return + */ + public static String countAndSay(int n) { + if (n == 1) return "1"; + + String s = countAndSay(n - 1); + StringBuilder sb = new StringBuilder(); + int count = 0; + + for (int i = 0; i < s.length(); i++) { + count++; + + if (i + 1 >= s.length() || s.charAt(i) != s.charAt(i + 1)) { + sb.append(count); + sb.append(s.charAt(i)); + count = 0; + } + } + + return sb.toString(); + } + + public static void main(String[] args) { + System.out.println(countAndSay(1)); + System.out.println(countAndSay(2)); + System.out.println(countAndSay(3)); + System.out.println(countAndSay(4)); + System.out.println(countAndSay(5)); + System.out.println(countAndSay(6)); + System.out.println(countAndSay(10)); + } +} \ No newline at end of file From df817535c7a21984dd838e173edfe81ac59df278 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sat, 20 Apr 2019 15:54:42 +0100 Subject: [PATCH 079/164] Longest Common Prefix done --- .../leetcode/strings/LongestCommonPrefix.java | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/main/java/com/leetcode/strings/LongestCommonPrefix.java diff --git a/src/main/java/com/leetcode/strings/LongestCommonPrefix.java b/src/main/java/com/leetcode/strings/LongestCommonPrefix.java new file mode 100644 index 00000000..bea07d03 --- /dev/null +++ b/src/main/java/com/leetcode/strings/LongestCommonPrefix.java @@ -0,0 +1,54 @@ +package com.leetcode.strings; + +/** + * Problem: https://leetcode.com/problems/longest-common-prefix/ + * + * @author rampatra + * @since 2019-04-20 + */ +public class LongestCommonPrefix { + + /** + * Time complexity: O(r * c) + * where, + * r = no. of strings + * c = max. no. of characters in a particular string + *

+ * Runtime: 1 ms. + * + * @param strs + * @return + */ + public static String longestCommonPrefix(String[] strs) { + StringBuilder sb = new StringBuilder(); + + int row; + for (int col = 0; col < Integer.MAX_VALUE; col++) { + for (row = 0; row < strs.length - 1; row++) { + // once we find a different character under one column, break the loop + if (col == strs[row].length() + || col == strs[row + 1].length() + || strs[row].charAt(col) != strs[row + 1].charAt(col)) { + break; + } + } + + // check the row counter to figure whether all characters in a particular column are identical + if (row == strs.length - 1 && strs[0].length() > 0 && col < strs[0].length()) { + sb.append(strs[0].charAt(col)); + } else { + break; + } + } + + return sb.toString(); + } + + public static void main(String[] args) { + System.out.println(longestCommonPrefix(new String[]{})); + System.out.println(longestCommonPrefix(new String[]{""})); + System.out.println(longestCommonPrefix(new String[]{"a"})); + System.out.println(longestCommonPrefix(new String[]{"flower", "flow", "flight"})); + System.out.println(longestCommonPrefix(new String[]{"dog", "racecar", "car"})); + } +} From 1b3594f6362970f577474eee02711d2f1fe2ee8d Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sat, 20 Apr 2019 16:06:17 +0100 Subject: [PATCH 080/164] Longest common prefix refactored and made simpler --- .../leetcode/strings/LongestCommonPrefix.java | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/leetcode/strings/LongestCommonPrefix.java b/src/main/java/com/leetcode/strings/LongestCommonPrefix.java index bea07d03..04d7f623 100644 --- a/src/main/java/com/leetcode/strings/LongestCommonPrefix.java +++ b/src/main/java/com/leetcode/strings/LongestCommonPrefix.java @@ -14,34 +14,27 @@ public class LongestCommonPrefix { * r = no. of strings * c = max. no. of characters in a particular string *

- * Runtime: 1 ms. + * Runtime: 1 ms. * * @param strs * @return */ public static String longestCommonPrefix(String[] strs) { - StringBuilder sb = new StringBuilder(); + if (strs == null || strs.length == 0) return ""; int row; - for (int col = 0; col < Integer.MAX_VALUE; col++) { + for (int col = 0; col < strs[0].length(); col++) { for (row = 0; row < strs.length - 1; row++) { - // once we find a different character under one column, break the loop + // once we find a different character under one column, return the characters read so far if (col == strs[row].length() || col == strs[row + 1].length() || strs[row].charAt(col) != strs[row + 1].charAt(col)) { - break; + return strs[row].substring(0, col); } } - - // check the row counter to figure whether all characters in a particular column are identical - if (row == strs.length - 1 && strs[0].length() > 0 && col < strs[0].length()) { - sb.append(strs[0].charAt(col)); - } else { - break; - } } - return sb.toString(); + return strs[0]; } public static void main(String[] args) { From 35713270f0505f20147f94a04511ac73edff4ee4 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sat, 20 Apr 2019 21:14:02 +0100 Subject: [PATCH 081/164] Pascals triangle done --- .../com/leetcode/arrays/PascalsTriangle.java | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/main/java/com/leetcode/arrays/PascalsTriangle.java diff --git a/src/main/java/com/leetcode/arrays/PascalsTriangle.java b/src/main/java/com/leetcode/arrays/PascalsTriangle.java new file mode 100644 index 00000000..d45bde12 --- /dev/null +++ b/src/main/java/com/leetcode/arrays/PascalsTriangle.java @@ -0,0 +1,52 @@ +package com.leetcode.arrays; + +import java.util.ArrayList; +import java.util.List; + +/** + * Problem: https://leetcode.com/problems/pascals-triangle/ + * + * @author rampatra + * @since 2019-04-20 + */ +public class PascalsTriangle { + + /** + * Time complexity: O(numRows^2) + * Space complexity: O(numRows^2) + *

+ * Runtime: 0 ms. + * + * @param numRows + * @return + */ + public static List> generatePascalsTriangle(int numRows) { + List> pascalsTriangle = new ArrayList<>(); + + if (numRows == 0) return pascalsTriangle; + + List firstRow = new ArrayList<>(); + firstRow.add(1); + pascalsTriangle.add(firstRow); + + List prevRow; + for (int i = 1; i < numRows; i++) { + prevRow = pascalsTriangle.get(i - 1); + + List currRow = new ArrayList<>(); + currRow.add(1); + for (int j = 0; j < prevRow.size() - 1; j++) { + currRow.add(prevRow.get(j) + prevRow.get(j + 1)); + } + currRow.add(1); + + pascalsTriangle.add(currRow); + } + + return pascalsTriangle; + } + + public static void main(String[] args) { + System.out.println(generatePascalsTriangle(5)); + } +} From 39ec46fd90e0ed762a3fe28cf2bdaa99e24562b8 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Tue, 23 Apr 2019 13:28:19 +0100 Subject: [PATCH 082/164] Rotate array done + some minor refactorings --- .../java/com/leetcode/arrays/RotateArray.java | 71 +++++++++++++++++++ .../leetcode/strings/AnagramsInString.java | 2 +- .../com/leetcode/strings/ReverseVowels.java | 2 +- .../strings/UniqueCharacterInString.java | 2 +- .../com/leetcode/strings/ValidPalindrome.java | 2 + .../java/com/leetcode/trie/LongestWord.java | 2 +- 6 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/leetcode/arrays/RotateArray.java diff --git a/src/main/java/com/leetcode/arrays/RotateArray.java b/src/main/java/com/leetcode/arrays/RotateArray.java new file mode 100644 index 00000000..23d3d3e5 --- /dev/null +++ b/src/main/java/com/leetcode/arrays/RotateArray.java @@ -0,0 +1,71 @@ +package com.leetcode.arrays; + +import java.util.Arrays; + +/** + * Problem: https://leetcode.com/problems/rotate-array/ + * + * @author rampatra + * @since 2019-04-20 + */ +public class RotateArray { + + /** + * Time complexity: O(n) + * where, + * n = no. of elements in the array + *

+ * Runtime: 0 ms. + * + * @param nums + * @param k + */ + public static void rotate(int[] nums, int k) { + + if (k > nums.length) { + k = k % nums.length; + } + + reverse(nums, 0, nums.length); + reverse(nums, 0, k); + reverse(nums, k, nums.length); + } + + private static void reverse(int[] nums, int start, int end) { + int temp; + for (int i = start, j = end - 1; i < j; i++, j--) { + temp = nums[i]; + nums[i] = nums[j]; + nums[j] = temp; + } + } + + public static void main(String[] args) { + // normal case + int[] arr = {1, 2, 3, 4, 5, 6, 7}; + System.out.println(Arrays.toString(arr)); + rotate(arr, 3); + System.out.println(Arrays.toString(arr)); + + // edge cases + arr = new int[]{1, 2}; + System.out.println(Arrays.toString(arr)); + rotate(arr, 2); + System.out.println(Arrays.toString(arr)); // should be [1, 2] + + arr = new int[]{1, 2}; + System.out.println(Arrays.toString(arr)); + rotate(arr, 3); + System.out.println(Arrays.toString(arr)); // should be [2, 1] + + arr = new int[]{1, 2, 3}; + System.out.println(Arrays.toString(arr)); + rotate(arr, 4); + System.out.println(Arrays.toString(arr)); // should be [3, 1, 2] + + arr = new int[]{1}; + System.out.println(Arrays.toString(arr)); + rotate(arr, 2); + System.out.println(Arrays.toString(arr)); + } +} \ No newline at end of file diff --git a/src/main/java/com/leetcode/strings/AnagramsInString.java b/src/main/java/com/leetcode/strings/AnagramsInString.java index 5c1acd9e..470acb2d 100644 --- a/src/main/java/com/leetcode/strings/AnagramsInString.java +++ b/src/main/java/com/leetcode/strings/AnagramsInString.java @@ -5,7 +5,7 @@ import java.util.List; /** - * Leetcode Problem: https://leetcode.com/problems/find-all-anagrams-in-a-string/ + * Problem: https://leetcode.com/problems/find-all-anagrams-in-a-string/ * * @author rampatra * @since 2019-04-13 diff --git a/src/main/java/com/leetcode/strings/ReverseVowels.java b/src/main/java/com/leetcode/strings/ReverseVowels.java index ce6bdefc..cb3bf0ff 100644 --- a/src/main/java/com/leetcode/strings/ReverseVowels.java +++ b/src/main/java/com/leetcode/strings/ReverseVowels.java @@ -1,7 +1,7 @@ package com.leetcode.strings; /** - * Leetcode Problem: https://leetcode.com/problems/reverse-vowels-of-a-string/ + * Problem: https://leetcode.com/problems/reverse-vowels-of-a-string/ * * @author rampatra * @since 2019-04-19 diff --git a/src/main/java/com/leetcode/strings/UniqueCharacterInString.java b/src/main/java/com/leetcode/strings/UniqueCharacterInString.java index 33236436..37123284 100644 --- a/src/main/java/com/leetcode/strings/UniqueCharacterInString.java +++ b/src/main/java/com/leetcode/strings/UniqueCharacterInString.java @@ -1,7 +1,7 @@ package com.leetcode.strings; /** - * Leetcode Problem: https://leetcode.com/problems/first-unique-character-in-a-string/ + * Problem: https://leetcode.com/problems/first-unique-character-in-a-string/ * * @author rampatra * @since 2019-04-16 diff --git a/src/main/java/com/leetcode/strings/ValidPalindrome.java b/src/main/java/com/leetcode/strings/ValidPalindrome.java index 621d2923..b48f2150 100644 --- a/src/main/java/com/leetcode/strings/ValidPalindrome.java +++ b/src/main/java/com/leetcode/strings/ValidPalindrome.java @@ -1,6 +1,8 @@ package com.leetcode.strings; /** + * Problem: https://leetcode.com/problems/valid-palindrome/ + * * @author rampatra * @since 2019-04-19 */ diff --git a/src/main/java/com/leetcode/trie/LongestWord.java b/src/main/java/com/leetcode/trie/LongestWord.java index f0e1c21d..00c28681 100644 --- a/src/main/java/com/leetcode/trie/LongestWord.java +++ b/src/main/java/com/leetcode/trie/LongestWord.java @@ -4,7 +4,7 @@ import java.util.Stack; /** - * Leetcode Problem: https://leetcode.com/problems/longest-word-in-dictionary/ + * Problem: https://leetcode.com/problems/longest-word-in-dictionary/ * * @author rampatra * @since 2019-04-10 From fcc1c4a2f12d884e611fc55558ec251a7b95781f Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Tue, 23 Apr 2019 17:41:12 +0100 Subject: [PATCH 083/164] Stock prices I done --- .../com/leetcode/arrays/BuySellStocks.java | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/main/java/com/leetcode/arrays/BuySellStocks.java diff --git a/src/main/java/com/leetcode/arrays/BuySellStocks.java b/src/main/java/com/leetcode/arrays/BuySellStocks.java new file mode 100644 index 00000000..70b597c8 --- /dev/null +++ b/src/main/java/com/leetcode/arrays/BuySellStocks.java @@ -0,0 +1,46 @@ +package com.leetcode.arrays; + +/** + * Problem: https://leetcode.com/problems/best-time-to-buy-and-sell-stock/ + * + * @author rampatra + * @since 2019-04-23 + */ +public class BuySellStocks { + + /** + * Time complexity: O(n) + * where, + * n = no. of stock prices + *

+ * Runtime: 0 ms. + * + * @param prices + * @return + */ + public static int maxProfit(int[] prices) { + int profit = 0; + int buyPrice = Integer.MAX_VALUE; + + for (int i = 0; i < prices.length; i++) { + if (prices[i] < buyPrice) { + buyPrice = prices[i]; + } else if (prices[i] - buyPrice > profit) { + profit = prices[i] - buyPrice; + } + } + + return profit; + } + + public static void main(String[] args) { + + System.out.println(maxProfit(new int[]{7, 1, 5, 3, 6, 4})); + System.out.println(maxProfit(new int[]{7, 1, 5, 0, 6, 4})); + System.out.println(maxProfit(new int[]{4, 3, 2, 1})); + + // edge cases + System.out.println(maxProfit(new int[]{})); + System.out.println(maxProfit(new int[]{1})); + } +} \ No newline at end of file From 7eca377c8621da68235b5e31b0db1a95924f2658 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Wed, 24 Apr 2019 14:29:50 +0100 Subject: [PATCH 084/164] Buy and sell stocks 2 done --- .../com/leetcode/arrays/BuySellStocks.java | 1 + .../com/leetcode/arrays/BuySellStocksII.java | 94 +++++++++++++++++++ .../com/leetcode/arrays/PascalsTriangle.java | 1 + .../java/com/leetcode/arrays/RotateArray.java | 1 + .../leetcode/strings/AnagramsInString.java | 1 + .../com/leetcode/strings/CountAndSay.java | 1 + .../leetcode/strings/LongestCommonPrefix.java | 1 + .../java/com/leetcode/strings/RansomNote.java | 1 + .../com/leetcode/strings/ReverseStringII.java | 1 + .../com/leetcode/strings/ReverseVowels.java | 1 + .../strings/UniqueCharacterInString.java | 1 + .../com/leetcode/strings/ValidPalindrome.java | 1 + .../java/com/leetcode/trie/LongestWord.java | 1 + 13 files changed, 106 insertions(+) create mode 100644 src/main/java/com/leetcode/arrays/BuySellStocksII.java diff --git a/src/main/java/com/leetcode/arrays/BuySellStocks.java b/src/main/java/com/leetcode/arrays/BuySellStocks.java index 70b597c8..d94c3296 100644 --- a/src/main/java/com/leetcode/arrays/BuySellStocks.java +++ b/src/main/java/com/leetcode/arrays/BuySellStocks.java @@ -1,6 +1,7 @@ package com.leetcode.arrays; /** + * Level: Easy * Problem: https://leetcode.com/problems/best-time-to-buy-and-sell-stock/ * * @author rampatra diff --git a/src/main/java/com/leetcode/arrays/BuySellStocksII.java b/src/main/java/com/leetcode/arrays/BuySellStocksII.java new file mode 100644 index 00000000..47966b48 --- /dev/null +++ b/src/main/java/com/leetcode/arrays/BuySellStocksII.java @@ -0,0 +1,94 @@ +package com.leetcode.arrays; + +/** + * Level: Easy + * Problem Link: https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/ + * Problem Description: + * 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 (i.e., buy one and sell one share of the stock multiple times). + *

+ * Note: You may not engage in multiple transactions at the same time (i.e., you must sell the stock + * before you buy again). + * + * @author rampatra + * @since 2019-04-23 + */ +public class BuySellStocksII { + + /** + * The key point is we need to consider every peak immediately following a valley to maximize the profit. In case + * we skip one of the peaks (trying to obtain more profit), we will end up losing the profit over one of the + * transactions leading to an overall lesser profit. + * Read this to learn more. + *

+ * Time complexity: O(n) + * where, + * n = no. of stock prices + *

+ * Runtime: 0 ms. + * + * @param prices + * @return + */ + public static int maxProfit(int[] prices) { + int valley; + int peak; + int maxProfit = 0; + + for (int i = 0; i < prices.length; i++) { + while (i < prices.length - 1 && prices[i] > prices[i + 1]) { + i++; + } + valley = i; + + while (i < prices.length - 1 && prices[i] < prices[i + 1]) { + i++; + } + peak = i; + + maxProfit += prices[peak] - prices[valley]; + } + + return maxProfit; + } + + /** + * This solution follows the logic used in the above approach {@link #maxProfit(int[])}, but with only a slight + * variation. In this case, instead of looking for every peak following a valley, we can simply go on crawling over + * the slope and keep on adding the profit obtained from every consecutive transaction. + * In the end, we will be using the peaks and valleys effectively, but we need not track the costs corresponding to + * the peaks and valleys along with the maximum profit, but we can directly keep on adding the difference between the + * consecutive numbers of the array if the second number is larger than the first one, and at the total sum we obtain + * will be the maximum profit. This approach will simplify the solution. + *

+ * Time complexity: O(n) + * where, + * n = no. of stock prices + * + * @param prices + * @return + */ + public static int maxProfitSimplified(int[] prices) { + int maxProfit = 0; + for (int i = 1; i < prices.length; i++) { + if (prices[i] > prices[i - 1]) { + maxProfit += prices[i] - prices[i - 1]; + } + } + return maxProfit; + } + + public static void main(String[] args) { + System.out.println(maxProfit(new int[]{7, 1, 5, 3, 6, 4})); + System.out.println(maxProfit(new int[]{1, 2, 3, 4, 5})); + System.out.println(maxProfit(new int[]{7, 6, 4, 3, 1})); + + System.out.println("----"); + + System.out.println(maxProfitSimplified(new int[]{7, 1, 5, 3, 6, 4})); + System.out.println(maxProfitSimplified(new int[]{1, 2, 3, 4, 5})); + System.out.println(maxProfitSimplified(new int[]{7, 6, 4, 3, 1})); + } +} \ No newline at end of file diff --git a/src/main/java/com/leetcode/arrays/PascalsTriangle.java b/src/main/java/com/leetcode/arrays/PascalsTriangle.java index d45bde12..5f32d69f 100644 --- a/src/main/java/com/leetcode/arrays/PascalsTriangle.java +++ b/src/main/java/com/leetcode/arrays/PascalsTriangle.java @@ -4,6 +4,7 @@ import java.util.List; /** + * Level: Easy * Problem: https://leetcode.com/problems/pascals-triangle/ * * @author rampatra diff --git a/src/main/java/com/leetcode/arrays/RotateArray.java b/src/main/java/com/leetcode/arrays/RotateArray.java index 23d3d3e5..e4f6de33 100644 --- a/src/main/java/com/leetcode/arrays/RotateArray.java +++ b/src/main/java/com/leetcode/arrays/RotateArray.java @@ -3,6 +3,7 @@ import java.util.Arrays; /** + * Level: Easy * Problem: https://leetcode.com/problems/rotate-array/ * * @author rampatra diff --git a/src/main/java/com/leetcode/strings/AnagramsInString.java b/src/main/java/com/leetcode/strings/AnagramsInString.java index 470acb2d..afdb3f9f 100644 --- a/src/main/java/com/leetcode/strings/AnagramsInString.java +++ b/src/main/java/com/leetcode/strings/AnagramsInString.java @@ -5,6 +5,7 @@ import java.util.List; /** + * Level: Easy * Problem: https://leetcode.com/problems/find-all-anagrams-in-a-string/ * * @author rampatra diff --git a/src/main/java/com/leetcode/strings/CountAndSay.java b/src/main/java/com/leetcode/strings/CountAndSay.java index ea7fb3c4..24f41a3e 100644 --- a/src/main/java/com/leetcode/strings/CountAndSay.java +++ b/src/main/java/com/leetcode/strings/CountAndSay.java @@ -1,6 +1,7 @@ package com.leetcode.strings; /** + * Level: Easy * Problem: https://leetcode.com/problems/count-and-say/ * * @author rampatra diff --git a/src/main/java/com/leetcode/strings/LongestCommonPrefix.java b/src/main/java/com/leetcode/strings/LongestCommonPrefix.java index 04d7f623..07bd6392 100644 --- a/src/main/java/com/leetcode/strings/LongestCommonPrefix.java +++ b/src/main/java/com/leetcode/strings/LongestCommonPrefix.java @@ -1,6 +1,7 @@ package com.leetcode.strings; /** + * Level: Easy * Problem: https://leetcode.com/problems/longest-common-prefix/ * * @author rampatra diff --git a/src/main/java/com/leetcode/strings/RansomNote.java b/src/main/java/com/leetcode/strings/RansomNote.java index 76a44f2b..c6b66fb0 100644 --- a/src/main/java/com/leetcode/strings/RansomNote.java +++ b/src/main/java/com/leetcode/strings/RansomNote.java @@ -1,6 +1,7 @@ package com.leetcode.strings; /** + * Level: Easy * Problem: https://leetcode.com/problems/ransom-note/ * * @author rampatra diff --git a/src/main/java/com/leetcode/strings/ReverseStringII.java b/src/main/java/com/leetcode/strings/ReverseStringII.java index bad406ab..4a5aabd4 100644 --- a/src/main/java/com/leetcode/strings/ReverseStringII.java +++ b/src/main/java/com/leetcode/strings/ReverseStringII.java @@ -1,6 +1,7 @@ package com.leetcode.strings; /** + * Level: Easy * Problem: https://leetcode.com/problems/reverse-string-ii/ * * @author rampatra diff --git a/src/main/java/com/leetcode/strings/ReverseVowels.java b/src/main/java/com/leetcode/strings/ReverseVowels.java index cb3bf0ff..25518cac 100644 --- a/src/main/java/com/leetcode/strings/ReverseVowels.java +++ b/src/main/java/com/leetcode/strings/ReverseVowels.java @@ -1,6 +1,7 @@ package com.leetcode.strings; /** + * Level: Easy * Problem: https://leetcode.com/problems/reverse-vowels-of-a-string/ * * @author rampatra diff --git a/src/main/java/com/leetcode/strings/UniqueCharacterInString.java b/src/main/java/com/leetcode/strings/UniqueCharacterInString.java index 37123284..da155710 100644 --- a/src/main/java/com/leetcode/strings/UniqueCharacterInString.java +++ b/src/main/java/com/leetcode/strings/UniqueCharacterInString.java @@ -1,6 +1,7 @@ package com.leetcode.strings; /** + * Level: Easy * Problem: https://leetcode.com/problems/first-unique-character-in-a-string/ * * @author rampatra diff --git a/src/main/java/com/leetcode/strings/ValidPalindrome.java b/src/main/java/com/leetcode/strings/ValidPalindrome.java index b48f2150..451849b6 100644 --- a/src/main/java/com/leetcode/strings/ValidPalindrome.java +++ b/src/main/java/com/leetcode/strings/ValidPalindrome.java @@ -1,6 +1,7 @@ package com.leetcode.strings; /** + * Level: Easy * Problem: https://leetcode.com/problems/valid-palindrome/ * * @author rampatra diff --git a/src/main/java/com/leetcode/trie/LongestWord.java b/src/main/java/com/leetcode/trie/LongestWord.java index 00c28681..155ea295 100644 --- a/src/main/java/com/leetcode/trie/LongestWord.java +++ b/src/main/java/com/leetcode/trie/LongestWord.java @@ -4,6 +4,7 @@ import java.util.Stack; /** + * Level: Easy * Problem: https://leetcode.com/problems/longest-word-in-dictionary/ * * @author rampatra From 08d0d61e47a484240f00bc3fb37281d77261834f Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Wed, 24 Apr 2019 21:26:08 +0100 Subject: [PATCH 085/164] Remove duplicates in place: done --- .../com/leetcode/arrays/RemoveDuplicates.java | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/main/java/com/leetcode/arrays/RemoveDuplicates.java diff --git a/src/main/java/com/leetcode/arrays/RemoveDuplicates.java b/src/main/java/com/leetcode/arrays/RemoveDuplicates.java new file mode 100644 index 00000000..caad6202 --- /dev/null +++ b/src/main/java/com/leetcode/arrays/RemoveDuplicates.java @@ -0,0 +1,60 @@ +package com.leetcode.arrays; + +import java.util.Arrays; + +/** + * Level: Easy + * Problem Link: https://leetcode.com/problems/remove-duplicates-from-sorted-array/ + * Problem Description: + * Given a sorted array nums, remove the duplicates in-place such that each element appear only once and return the new length. + *

+ * Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory. + * Example 1: + *

+ * Given nums = [1,1,2] + *

+ * Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. + *

+ * It doesn't matter what you leave beyond the returned length. + * + * @author rampatra + * @since 2019-04-24 + */ +public class RemoveDuplicates { + + /** + * Time complexity: O(n) + * where, + * n = no. of elements in the array + *

+ * Runtime: 1 ms. + * + * @param nums + * @return + */ + public static int removeDuplicatesInSortedArray(int[] nums) { + int insertIndex = 0; + + for (int i = 1; i < nums.length; i++) { + if (nums[i] != nums[i - 1]) { + nums[++insertIndex] = nums[i]; + } + } + + return insertIndex + 1; + } + + public static void main(String[] args) { + int[] arr = new int[]{1, 1, 2}; + System.out.println(removeDuplicatesInSortedArray(arr)); + System.out.println(Arrays.toString(arr)); + + arr = new int[]{0, 0, 1, 1, 1, 2, 2, 3, 3, 4}; + System.out.println(removeDuplicatesInSortedArray(arr)); + System.out.println(Arrays.toString(arr)); + + arr = new int[]{0, 1, 2, 3, 4, 5}; + System.out.println(removeDuplicatesInSortedArray(arr)); + System.out.println(Arrays.toString(arr)); + } +} \ No newline at end of file From 56554517a8c3903a8650e41db75a830ff8c379a9 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Thu, 25 Apr 2019 13:31:33 +0100 Subject: [PATCH 086/164] Custom HashSet done --- .../com/leetcode/arrays/RemoveDuplicates.java | 4 +- .../hashtables/ContainsDuplicates.java | 49 ++++++++++ .../com/leetcode/hashtables/MyHashSet.java | 92 +++++++++++++++++++ 3 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/leetcode/hashtables/ContainsDuplicates.java create mode 100644 src/main/java/com/leetcode/hashtables/MyHashSet.java diff --git a/src/main/java/com/leetcode/arrays/RemoveDuplicates.java b/src/main/java/com/leetcode/arrays/RemoveDuplicates.java index caad6202..57eba5ad 100644 --- a/src/main/java/com/leetcode/arrays/RemoveDuplicates.java +++ b/src/main/java/com/leetcode/arrays/RemoveDuplicates.java @@ -15,7 +15,7 @@ *

* Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. *

- * It doesn't matter what you leave beyond the returned length. + * NOTE: It doesn't matter what you leave beyond the returned length. * * @author rampatra * @since 2019-04-24 @@ -23,6 +23,8 @@ public class RemoveDuplicates { /** + * This removes the duplicates from the array in-place. + *

* Time complexity: O(n) * where, * n = no. of elements in the array diff --git a/src/main/java/com/leetcode/hashtables/ContainsDuplicates.java b/src/main/java/com/leetcode/hashtables/ContainsDuplicates.java new file mode 100644 index 00000000..7b12311b --- /dev/null +++ b/src/main/java/com/leetcode/hashtables/ContainsDuplicates.java @@ -0,0 +1,49 @@ +package com.leetcode.hashtables; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** + * Level: Easy + * Problem Link: https://leetcode.com/problems/contains-duplicate/ + * + * @author rampatra + * @since 2019-04-24 + */ +public class ContainsDuplicates { + + public static boolean containsDuplicates(int[] nums) { + Set numSet = new HashSet<>(); + for (int num : nums) { + if (!numSet.add(num)) { + return true; + } + } + return false; + } + + /** + * Runtime: 5 ms. + * + * @param nums + * @return + */ + public static boolean containsDuplicatesWithoutSet(int[] nums) { + Arrays.sort(nums); + for (int i = 0; i < nums.length - 1; i++) { + if (nums[i] == nums[i + 1]) { + return true; + } + } + return false; + } + + public static void main(String[] args) { + System.out.println(containsDuplicates(new int[]{1, 2, 3, 1})); + System.out.println(containsDuplicates(new int[]{1, 2, 3, 4})); + + System.out.println(containsDuplicatesWithoutSet(new int[]{1, 2, 3, 1})); + System.out.println(containsDuplicatesWithoutSet(new int[]{1, 2, 3, 4})); + } +} diff --git a/src/main/java/com/leetcode/hashtables/MyHashSet.java b/src/main/java/com/leetcode/hashtables/MyHashSet.java new file mode 100644 index 00000000..5c07a5a3 --- /dev/null +++ b/src/main/java/com/leetcode/hashtables/MyHashSet.java @@ -0,0 +1,92 @@ +package com.leetcode.hashtables; + +/** + * Level: Learning Cards + * Problem Link: https://leetcode.com/explore/learn/card/hash-table/182/practical-applications/1139/ + * + * @author rampatra + * @since 2019-04-24 + */ +public class MyHashSet { + + private final int SIZE = 10000; + private final Entry[] entries; + + class Entry { + int key; + Entry next; + + Entry(int key) { + this.key = key; + } + } + + /** + * Initialize your data structure here. + */ + public MyHashSet() { + entries = new Entry[SIZE]; + } + + public void add(int key) { + if (contains(key)) return; + + Entry newEntry = new Entry(key); + int bucket = key % SIZE; + + newEntry.next = entries[bucket]; + entries[bucket] = newEntry; + } + + public void remove(int key) { + int bucket = key % SIZE; + Entry entry = entries[bucket]; + + if (entry != null && entry.key == key) { + entries[bucket] = entry.next; + return; + } + + Entry curr = new Entry(0); + curr.next = entry; + + while (curr.next != null && curr.next.key != key) { + curr = curr.next; + } + + if (curr.next != null) { + curr.next = curr.next.next; + } + } + + /** + * Returns true if this set contains the specified element + */ + public boolean contains(int key) { + int bucket = key % SIZE; + Entry entry = entries[bucket]; + + while (entry != null) { + if (entry.key == key) { + return true; + } + entry = entry.next; + } + + return false; + } + + public static void main(String[] args) { + MyHashSet set = new MyHashSet(); + set.add(1); + set.add(2); + set.add(3); + System.out.println(set.contains(1)); + System.out.println(set.contains(2)); + set.remove(2); + System.out.println(set.contains(2)); + System.out.println(set.contains(3)); + set.remove(3); + System.out.println(set.contains(3)); + } +} \ No newline at end of file From e1cc48e49e4a6ffea2273119368e7d32837347e4 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Thu, 25 Apr 2019 20:09:50 +0100 Subject: [PATCH 087/164] HashMap done --- .../com/leetcode/hashtables/MyHashMap.java | 105 ++++++++++++++++++ .../com/leetcode/hashtables/MyHashSet.java | 11 +- 2 files changed, 111 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/leetcode/hashtables/MyHashMap.java diff --git a/src/main/java/com/leetcode/hashtables/MyHashMap.java b/src/main/java/com/leetcode/hashtables/MyHashMap.java new file mode 100644 index 00000000..cf13c344 --- /dev/null +++ b/src/main/java/com/leetcode/hashtables/MyHashMap.java @@ -0,0 +1,105 @@ +package com.leetcode.hashtables; + +/** + * Level: Learning cards + * Problem Link: https://leetcode.com/explore/learn/card/hash-table/182/practical-applications/1140/ + * Runtime: https://leetcode.com/submissions/detail/224928756/ + * + * @author rampatra + * @since 2019-04-25 + */ +public class MyHashMap { + + class Entry { + int key; + int value; + Entry next; + + Entry(int key, int value) { + this.key = key; + this.value = value; + } + } + + private final int SIZE = 10000; + private final Entry[] entries; + + /** + * Initialize your data structure here. + */ + public MyHashMap() { + entries = new Entry[SIZE]; + } + + /** + * value will always be non-negative. + */ + public void put(int key, int value) { + int bucket = key % SIZE; + Entry entry = entries[bucket]; + + if (entry == null) { + entries[bucket] = new Entry(key, value); + } else { + while (entry.next != null && entry.key != key) { + entry = entry.next; + } + + if (entry.key == key) { + entry.value = value; + } else { + entry.next = new Entry(key, value); + } + } + } + + /** + * Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key + */ + public int get(int key) { + int bucket = key % SIZE; + Entry entry = entries[bucket]; + while (entry != null) { + if (entry.key == key) { + return entry.value; + } + entry = entry.next; + } + return -1; + } + + /** + * Removes the mapping of the specified value key if this map contains a mapping for the key + */ + public void remove(int key) { + int bucket = key % SIZE; + Entry entry = entries[bucket]; + + if (entry != null && entry.key == key) { + entries[bucket] = entry.next; + return; + } + + Entry curr = new Entry(0, 0); + curr.next = entry; + + while (curr.next != null && curr.next.key != key) { + curr = curr.next; + } + + if (curr.next != null) { + curr.next = curr.next.next; + } + } + + public static void main(String[] args) { + MyHashMap map = new MyHashMap(); + map.put(1, 2); + System.out.println("1 -> " + map.get(1)); + map.put(1, 4); + System.out.println("1 -> " + map.get(1)); + map.remove(1); + System.out.println("1 -> " + map.get(1)); + System.out.println("5 -> " + map.get(5)); + } +} \ No newline at end of file diff --git a/src/main/java/com/leetcode/hashtables/MyHashSet.java b/src/main/java/com/leetcode/hashtables/MyHashSet.java index 5c07a5a3..3c13d488 100644 --- a/src/main/java/com/leetcode/hashtables/MyHashSet.java +++ b/src/main/java/com/leetcode/hashtables/MyHashSet.java @@ -3,6 +3,7 @@ /** * Level: Learning Cards * Problem Link: https://leetcode.com/explore/learn/card/hash-table/182/practical-applications/1139/ + * Runtime: https://leetcode.com/submissions/detail/224872991/ * * @author rampatra * @since 2019-04-24 @@ -30,7 +31,7 @@ public MyHashSet() { public void add(int key) { if (contains(key)) return; - + Entry newEntry = new Entry(key); int bucket = key % SIZE; @@ -41,19 +42,19 @@ public void add(int key) { public void remove(int key) { int bucket = key % SIZE; Entry entry = entries[bucket]; - + if (entry != null && entry.key == key) { entries[bucket] = entry.next; return; } - + Entry curr = new Entry(0); curr.next = entry; - + while (curr.next != null && curr.next.key != key) { curr = curr.next; } - + if (curr.next != null) { curr.next = curr.next.next; } From 50f24108ef2004c76fe8c232554c9589eb5b6b22 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Fri, 26 Apr 2019 21:34:41 +0100 Subject: [PATCH 088/164] - maximum sub array - merge sorted array --- src/main/java/com/leetcode/arrays/MaximumSubArray.java | 8 ++++++++ src/main/java/com/leetcode/arrays/MergeSortedArray.java | 8 ++++++++ 2 files changed, 16 insertions(+) create mode 100644 src/main/java/com/leetcode/arrays/MaximumSubArray.java create mode 100644 src/main/java/com/leetcode/arrays/MergeSortedArray.java diff --git a/src/main/java/com/leetcode/arrays/MaximumSubArray.java b/src/main/java/com/leetcode/arrays/MaximumSubArray.java new file mode 100644 index 00000000..2a50dcbb --- /dev/null +++ b/src/main/java/com/leetcode/arrays/MaximumSubArray.java @@ -0,0 +1,8 @@ +package com.leetcode.arrays; + +/** + * @author rampatra + * @since 2019-04-26 + */ +public class MaximumSubarray { +} diff --git a/src/main/java/com/leetcode/arrays/MergeSortedArray.java b/src/main/java/com/leetcode/arrays/MergeSortedArray.java new file mode 100644 index 00000000..0ef5c0d3 --- /dev/null +++ b/src/main/java/com/leetcode/arrays/MergeSortedArray.java @@ -0,0 +1,8 @@ +package com.leetcode.arrays; + +/** + * @author rampatra + * @since 2019-04-26 + */ +public class MergeSortedArray { +} From 26facf58be2c868b6917f9aa85e75d37e1d73bd5 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Fri, 26 Apr 2019 21:36:04 +0100 Subject: [PATCH 089/164] - Maximum sub array - Merge sorted array Done and comments added --- .../com/leetcode/arrays/MaximumSubArray.java | 100 +++++++++++++++++- .../com/leetcode/arrays/MergeSortedArray.java | 67 +++++++++++- 2 files changed, 164 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/leetcode/arrays/MaximumSubArray.java b/src/main/java/com/leetcode/arrays/MaximumSubArray.java index 2a50dcbb..f9a64a3f 100644 --- a/src/main/java/com/leetcode/arrays/MaximumSubArray.java +++ b/src/main/java/com/leetcode/arrays/MaximumSubArray.java @@ -1,8 +1,104 @@ package com.leetcode.arrays; /** + * Level: Easy + * Problem Link: https://leetcode.com/problems/maximum-subarray + * * @author rampatra * @since 2019-04-26 */ -public class MaximumSubarray { -} +public class MaximumSubArray { + + /** + * Time complexity: O(n) + * Runtime: 0 ms. + * + * @param nums + * @return + */ + public static int maxSubArray(int[] nums) { + if (nums.length == 0) { + return 0; + } + + int consecutiveSum = nums[0]; + int maxSum = nums[0]; + + for (int i = 1; i < nums.length; i++) { + consecutiveSum += nums[i]; + + /* if the current number is larger than the summation of all the + previous numbers then start from current number */ + if (nums[i] > consecutiveSum) { + consecutiveSum = nums[i]; + } + + if (consecutiveSum > maxSum) { + maxSum = consecutiveSum; + } + } + + return maxSum; + } + + + /** + * Divide and Conquer approach. + * Time complexity: O(n log n). See Master's Theorem to understand how. + * Runtime: 1 ms. + * + * @param nums + * @return + */ + public static int maxSubArrayDivideAndConquer(int[] nums) { + return maxSubArrayDivideAndConquer(nums, 0, nums.length - 1); + } + + public static int maxSubArrayDivideAndConquer(int[] nums, int start, int end) { + if (start == end) { + return nums[start]; + } + + int mid = start + (end - start) / 2; + int leftSASum = maxSubArrayDivideAndConquer(nums, start, mid); + int rightSASum = maxSubArrayDivideAndConquer(nums, mid + 1, end); + + int leftSum = Integer.MIN_VALUE; + int rightSum = Integer.MIN_VALUE; + + // compute consecutive sum from mid towards start + int sum = 0; + for (int i = mid; i >= start; i--) { + sum += nums[i]; + if (sum > leftSum) { + leftSum = sum; + } + } + + // compute consecutive sum from mid towards end + sum = 0; + for (int i = mid + 1; i <= end; i++) { + sum += nums[i]; + if (sum > rightSum) { + rightSum = sum; + } + } + + // return the max of left sub-array, right sub-array, and the consecutive sum between start and end via mid + return Math.max(Math.max(leftSASum, rightSASum), leftSum + rightSum); + } + + public static void main(String[] args) { + System.out.println(maxSubArray(new int[]{3})); + System.out.println(maxSubArray(new int[]{-3})); + System.out.println(maxSubArray(new int[]{-2, 1, -3, 4, -1, 2, 1, -5, 4})); + System.out.println(maxSubArray(new int[]{4, -5, 1, 2, -1, 4, -3, 1, -2})); + + System.out.println("----"); + + System.out.println(maxSubArrayDivideAndConquer(new int[]{3})); + System.out.println(maxSubArrayDivideAndConquer(new int[]{-3})); + System.out.println(maxSubArrayDivideAndConquer(new int[]{-2, 1, -3, 4, -1, 2, 1, -5, 4})); + System.out.println(maxSubArrayDivideAndConquer(new int[]{4, -5, 1, 2, -1, 4, -3, 1, -2})); + } +} \ No newline at end of file diff --git a/src/main/java/com/leetcode/arrays/MergeSortedArray.java b/src/main/java/com/leetcode/arrays/MergeSortedArray.java index 0ef5c0d3..09cd730d 100644 --- a/src/main/java/com/leetcode/arrays/MergeSortedArray.java +++ b/src/main/java/com/leetcode/arrays/MergeSortedArray.java @@ -1,8 +1,73 @@ package com.leetcode.arrays; +import java.util.Arrays; + /** + * Level: Easy + * Problem Link: https://leetcode.com/problems/merge-sorted-array/ + * * @author rampatra * @since 2019-04-26 */ public class MergeSortedArray { -} + + /** + * Time complexity: O(m*n) + * Runtime: 1 ms. + * + * @param nums1 + * @param m + * @param nums2 + * @param n + */ + public static void mergeSimple(int[] nums1, int m, int[] nums2, int n) { + int i = 0; + + for (int j = 0; j < n; j++) { + // find the index where the element from nums2 need to be inserted + while (i < m + j && nums1[i] < nums2[j]) { + i++; + } + // copy elements from i+1th position to one position right + for (int k = m + j; k > i; k--) { // note: replacing this with System.arraycopy() gives a 0 ms runtime + nums1[k] = nums1[k - 1]; + } + nums1[i] = nums2[j]; + } + } + + /** + * Time complexity: O(m+n) + * Runtime: 0 ms. + * + * @param nums1 + * @param m + * @param nums2 + * @param n + */ + public static void merge(int[] nums1, int m, int[] nums2, int n) { + for (int i = m + n - 1; i >= 0; i--) { + if (m == 0) { + nums1[i] = nums2[--n]; + } else if (n == 0) { // we ran out of nums2 elements so there is nothing left to merge + return; + } else if (nums1[m - 1] > nums2[n - 1]) { + nums1[i] = nums1[--m]; + } else { + nums1[i] = nums2[--n]; + } + } + } + + public static void main(String[] args) { + int[] nums1 = {1, 2, 3, 0, 0, 0}; + int[] nums2 = {4, 5, 6}; + merge(nums1, 3, nums2, 3); + System.out.println(Arrays.toString(nums1)); + + nums1 = new int[]{4, 5, 6, 0, 0, 0}; + nums2 = new int[]{1, 2, 3}; + merge(nums1, 3, nums2, 3); + System.out.println(Arrays.toString(nums1)); + } +} \ No newline at end of file From 0d96dcf5cd72a3662aaefe5df97bad07a93b8a60 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sat, 27 Apr 2019 18:10:36 +0100 Subject: [PATCH 090/164] Majority element done --- .../com/leetcode/arrays/MajorityElement.java | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 src/main/java/com/leetcode/arrays/MajorityElement.java diff --git a/src/main/java/com/leetcode/arrays/MajorityElement.java b/src/main/java/com/leetcode/arrays/MajorityElement.java new file mode 100644 index 00000000..c29ecf1c --- /dev/null +++ b/src/main/java/com/leetcode/arrays/MajorityElement.java @@ -0,0 +1,47 @@ +package com.leetcode.arrays; + +/** + * Level: Easy + * Problem Link: https://leetcode.com/problems/majority-element/ + * Problem Description: + * Given an array of size n, find the majority element. The majority element is the element + * that appears more than ⌊ n/2 ⌋ times. You may assume that the array is non-empty and the + * majority element always exist in the array. + * + * @author rampatra + * @since 2019-04-27 + */ +public class MajorityElement { + + /** + * Time complexity: O(n) + * Runtime: 1 ms. + * + * @param nums + * @return + */ + public static int majorityElement(int[] nums) { + int count = 0; + int majElem = nums[0]; + + for (int i = 0; i < nums.length; i++) { + if (count <= 0) { + majElem = nums[i]; + count = 0; + } + if (majElem == nums[i]) { + count++; + } else { + count--; + } + } + + return majElem; + } + + public static void main(String[] args) { + System.out.println(majorityElement(new int[]{10, 9, 9, 9, 10})); + System.out.println(majorityElement(new int[]{2, 3, 2, 2, 3, 2})); + System.out.println(majorityElement(new int[]{2, 3, 2, 2, 2, 3})); + } +} From 97addbef13fcbcffaf83bac6d85c42cd36290314 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sun, 28 Apr 2019 21:45:40 +0100 Subject: [PATCH 091/164] strstr done --- .../com/leetcode/arrays/MajorityElement.java | 6 +- .../java/com/leetcode/strings/StrStr.java | 59 +++++++++++++++++++ 2 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/leetcode/strings/StrStr.java diff --git a/src/main/java/com/leetcode/arrays/MajorityElement.java b/src/main/java/com/leetcode/arrays/MajorityElement.java index c29ecf1c..2ccdd116 100644 --- a/src/main/java/com/leetcode/arrays/MajorityElement.java +++ b/src/main/java/com/leetcode/arrays/MajorityElement.java @@ -15,16 +15,16 @@ public class MajorityElement { /** * Time complexity: O(n) - * Runtime: 1 ms. + * Runtime: 1 ms. * * @param nums * @return */ public static int majorityElement(int[] nums) { - int count = 0; + int count = 1; int majElem = nums[0]; - for (int i = 0; i < nums.length; i++) { + for (int i = 1; i < nums.length; i++) { if (count <= 0) { majElem = nums[i]; count = 0; diff --git a/src/main/java/com/leetcode/strings/StrStr.java b/src/main/java/com/leetcode/strings/StrStr.java new file mode 100644 index 00000000..aa3bc896 --- /dev/null +++ b/src/main/java/com/leetcode/strings/StrStr.java @@ -0,0 +1,59 @@ +package com.leetcode.strings; + +/** + * Level: Easy + * Problem Link: https://leetcode.com/problems/implement-strstr/ + * Problem Description: + * Implement strStr(). Return the index of the first occurrence of needle in haystack, or -1 if needle + * is not part of haystack. + *

+ * Example 1: + *

+ * Input: haystack = "hello", needle = "ll" + * Output: 2 + * Example 2: + *

+ * Input: haystack = "aaaaa", needle = "bba" + * Output: -1 + * + * @author rampatra + * @since 2019-04-28 + */ +public class StrStr { + + /** + * Time complexity: O(m*n) + * where, + * m = length of haystack + * n = length of needle + *

+ * Runtime: 3 ms. + * + * @param haystack + * @param needle + * @return + */ + public static int strStr(String haystack, String needle) { + for (int i = 0; ; i++) { + for (int j = 0; ; j++) { + if (j == needle.length()) return i; + if (i + j == haystack.length()) return -1; + if (needle.charAt(j) != haystack.charAt(i + j)) break; + } + } + } + + public static void main(String[] args) { + System.out.println(strStr("hello", "ll")); + System.out.println(strStr("leet", "e")); + System.out.println(strStr("mississippi", "issip")); + System.out.println(strStr("mississippi", "pi")); + System.out.println(strStr("aaaa", "bba")); + + // edge cases + System.out.println(strStr("aaa", "aaaa")); + System.out.println(strStr("aaaa", "")); + System.out.println(strStr("", "abc")); + System.out.println(strStr("", "")); + } +} From d7899c397de65e517e951e011e23b27f9d4151d5 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Wed, 15 May 2019 16:34:24 +0100 Subject: [PATCH 092/164] map with timestamp done --- .../com/rampatra/java8/FlatMapInStreams.java | 7 ++- .../com/rampatra/misc/MapWithTimestamp.java | 50 +++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/rampatra/misc/MapWithTimestamp.java diff --git a/src/main/java/com/rampatra/java8/FlatMapInStreams.java b/src/main/java/com/rampatra/java8/FlatMapInStreams.java index 996830f5..e5258deb 100644 --- a/src/main/java/com/rampatra/java8/FlatMapInStreams.java +++ b/src/main/java/com/rampatra/java8/FlatMapInStreams.java @@ -11,7 +11,10 @@ public class FlatMapInStreams { public static long countTotalIngredientsInAllDishes(List dishes) { - return dishes.stream().map(Dish::getIngredients).flatMap(List::stream).count(); + return dishes.stream() + .map(Dish::getIngredients) + .flatMap(List::stream) + .count(); } public static void main(String[] args) { @@ -21,7 +24,7 @@ public static void main(String[] args) { ingredients.add("haldi"); List dishes = Arrays.asList( new Dish("biriyani", 600, ingredients), - new Dish("biriyani", 600, new ArrayList<>())); + new Dish("pulao", 600, new ArrayList<>())); // to show whether empty List is counted in flatMap System.out.println(countTotalIngredientsInAllDishes(dishes)); } diff --git a/src/main/java/com/rampatra/misc/MapWithTimestamp.java b/src/main/java/com/rampatra/misc/MapWithTimestamp.java new file mode 100644 index 00000000..184656a7 --- /dev/null +++ b/src/main/java/com/rampatra/misc/MapWithTimestamp.java @@ -0,0 +1,50 @@ +package com.rampatra.misc; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +/** + * @author rampatra + * @since 2019-05-15 + */ +public class MapWithTimestamp { + + private final Map> map = new HashMap<>(); + + public V get(K key, Long timestamp) { + Map entry = map.get(key); + + return entry != null ? entry.get(timestamp) : null; + } + + public void put(K key, Long timestamp, V value) { + Map entry = map.get(key); + + if (entry == null) { + map.put(key, new HashMap() {{ + put(timestamp, value); + }}); + } else { + entry.put(timestamp, value); + } + } + + public static void main(String[] args) throws Exception { + MapWithTimestamp mapWithTimestamp = new MapWithTimestamp<>(); + long timestamp1; + long timestamp2; + long timestamp3; + + mapWithTimestamp.put(1, timestamp1 = new Date().getTime(), 10_0); + mapWithTimestamp.put(2, timestamp2 = new Date().getTime(), 20_0); + Thread.sleep(100); + mapWithTimestamp.put(2, new Date().getTime(), 20_1); + Thread.sleep(100); + mapWithTimestamp.put(2, new Date().getTime(), 20_2); + mapWithTimestamp.put(3, timestamp3 = new Date().getTime(), 30_0); + System.out.println(mapWithTimestamp.get(2, timestamp2)); + System.out.println(mapWithTimestamp.get(3, timestamp2)); + System.out.println(mapWithTimestamp.get(3, timestamp3)); + } +} \ No newline at end of file From e4db572272c2809287a6ccc60d5cd27cf5de1ec5 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Wed, 15 May 2019 20:43:24 +0100 Subject: [PATCH 093/164] Added another approach for max value in stream --- src/main/java/com/rampatra/java8/Streams.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/rampatra/java8/Streams.java b/src/main/java/com/rampatra/java8/Streams.java index 8376b503..86cd0336 100644 --- a/src/main/java/com/rampatra/java8/Streams.java +++ b/src/main/java/com/rampatra/java8/Streams.java @@ -123,10 +123,15 @@ public static Integer[] getAllTransValuesFromTradersInCambridge() { } public static int findHighestTransactionValue() { + return transactions.stream() + .mapToInt(Transaction::getValue) + .max().getAsInt(); + + /* this is another solution return transactions.stream() .map(Transaction::getValue) .reduce((t1, t2) -> (t1 > t2) ? t1 : t2) // you can replace with .reduce(Integer::max) - .get(); + .get();*/ } public static Transaction getSmallestTransaction() { From 8c24e355cee1e58d6c03ac95929ef825c66a3e88 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Wed, 15 May 2019 21:53:46 +0100 Subject: [PATCH 094/164] Some basic date time api usage (introduced in Java 8) --- .../java/com/rampatra/java8/DateTime.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/main/java/com/rampatra/java8/DateTime.java diff --git a/src/main/java/com/rampatra/java8/DateTime.java b/src/main/java/com/rampatra/java8/DateTime.java new file mode 100644 index 00000000..c564b7b4 --- /dev/null +++ b/src/main/java/com/rampatra/java8/DateTime.java @@ -0,0 +1,29 @@ +package com.rampatra.java8; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Date; + +/** + * @author rampatra + * @since 2019-05-15 + */ +public class DateTime { + + private static long getCurrentTimestampFromInstant() { + return Instant.now().toEpochMilli(); + } + + private static String addTwoDays() { + LocalDateTime now = LocalDateTime.ofInstant(Instant.now(), ZoneId.of("UTC")); + LocalDateTime afterTwoDays = now.plusDays(2); + return afterTwoDays.getDayOfMonth() + "-" + afterTwoDays.getMonthValue() + "-" + afterTwoDays.getYear(); + } + + public static void main(String[] args) { + System.out.println("Timestamp from Instant: " + getCurrentTimestampFromInstant() + + "\nTimestamp from Legacy Date: " + new Date().getTime()); + System.out.println("Add Two days: " + addTwoDays()); + } +} \ No newline at end of file From 4a0c4809102e9eef2d23d2bb8bd91fc492bc579b Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Thu, 23 May 2019 22:17:17 +0100 Subject: [PATCH 095/164] Minor fix --- src/main/java/com/rampatra/strings/WithoutString.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/rampatra/strings/WithoutString.java b/src/main/java/com/rampatra/strings/WithoutString.java index 3269d093..859b6a76 100644 --- a/src/main/java/com/rampatra/strings/WithoutString.java +++ b/src/main/java/com/rampatra/strings/WithoutString.java @@ -39,7 +39,7 @@ private static String withoutString(String base, String remove) { public static void main(String[] args) { Assert.check(withoutString("Hello there", "llo").equals("He there")); - Assert.check(withoutString("THIS is a FISH", "is").equals("TH a FH")); + Assert.check(withoutString("THIS is a FISH", "is").equals("TH a FH")); Assert.check(withoutString("xxx", "x").equals("")); } } From 62efe961d9afd22c6942574e9b0d06d86bb41012 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Fri, 24 May 2019 19:51:17 +0100 Subject: [PATCH 096/164] Minor indentation fixed --- src/main/java/com/ctci/stacksandqueues/StackMin.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/ctci/stacksandqueues/StackMin.java b/src/main/java/com/ctci/stacksandqueues/StackMin.java index 780ecc9e..0a5d2d59 100644 --- a/src/main/java/com/ctci/stacksandqueues/StackMin.java +++ b/src/main/java/com/ctci/stacksandqueues/StackMin.java @@ -58,6 +58,5 @@ public static void main(String[] args) { Assert.check(min() == 1); pop(); Assert.check(min() == 2); - } -} +} \ No newline at end of file From 94bfb85d6d805a3cfc3ab48cd46d31caa51bea06 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Fri, 24 May 2019 19:59:22 +0100 Subject: [PATCH 097/164] Minor refactorings --- .../java/com/rampatra/misc/RandomTest.java | 7 ++--- ...aceAll.java => RegexReplaceAllSpaces.java} | 5 +-- .../{Regex.java => RegexValidateLatLong.java} | 5 +-- src/main/java/com/rampatra/misc/SPOJ1.java | 31 ------------------- 4 files changed, 4 insertions(+), 44 deletions(-) rename src/main/java/com/rampatra/misc/{ReplaceAll.java => RegexReplaceAllSpaces.java} (81%) rename src/main/java/com/rampatra/misc/{Regex.java => RegexValidateLatLong.java} (93%) delete mode 100644 src/main/java/com/rampatra/misc/SPOJ1.java diff --git a/src/main/java/com/rampatra/misc/RandomTest.java b/src/main/java/com/rampatra/misc/RandomTest.java index 9ff2a683..5c9590cc 100644 --- a/src/main/java/com/rampatra/misc/RandomTest.java +++ b/src/main/java/com/rampatra/misc/RandomTest.java @@ -3,11 +3,8 @@ import java.util.Random; /** - * Created by IntelliJ IDEA. - * User: rampatra - * Date: 2/23/15 - * Time: 12:48 PM - * To change this template go to Preferences | IDE Settings | File and Code Templates + * @author rampatra + * @since 2/23/15 */ public class RandomTest { public static void main(String[] args) { diff --git a/src/main/java/com/rampatra/misc/ReplaceAll.java b/src/main/java/com/rampatra/misc/RegexReplaceAllSpaces.java similarity index 81% rename from src/main/java/com/rampatra/misc/ReplaceAll.java rename to src/main/java/com/rampatra/misc/RegexReplaceAllSpaces.java index cc17b70f..04b33db6 100644 --- a/src/main/java/com/rampatra/misc/ReplaceAll.java +++ b/src/main/java/com/rampatra/misc/RegexReplaceAllSpaces.java @@ -1,13 +1,10 @@ package com.rampatra.misc; /** - * Created by IntelliJ IDEA. - * * @author rampatra * @since 11/3/15 - * @time: 2:21 PM */ -public class ReplaceAll { +public class RegexReplaceAllSpaces { public static String replaceAll(String str, String regex, String replacement) { return str.replaceAll(regex, replacement); diff --git a/src/main/java/com/rampatra/misc/Regex.java b/src/main/java/com/rampatra/misc/RegexValidateLatLong.java similarity index 93% rename from src/main/java/com/rampatra/misc/Regex.java rename to src/main/java/com/rampatra/misc/RegexValidateLatLong.java index 19fcdf11..e8d8d2d6 100644 --- a/src/main/java/com/rampatra/misc/Regex.java +++ b/src/main/java/com/rampatra/misc/RegexValidateLatLong.java @@ -5,13 +5,10 @@ import java.util.regex.Pattern; /** - * Created by IntelliJ IDEA. - * * @author rampatra * @since 9/12/15 - * @time: 1:49 PM */ -public class Regex { +public class RegexValidateLatLong { /** * Validates latitude/longitude in the form (+75, 180) etc. diff --git a/src/main/java/com/rampatra/misc/SPOJ1.java b/src/main/java/com/rampatra/misc/SPOJ1.java deleted file mode 100644 index fc1ad7a4..00000000 --- a/src/main/java/com/rampatra/misc/SPOJ1.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.rampatra.misc; - -import java.util.ArrayList; -import java.util.List; -import java.util.Scanner; - -/** - * Created by IntelliJ IDEA. - * User: rampatra - * Date: 4/22/15 - * Time: 7:40 PM - * To change this template go to Preferences | IDE Settings | File and Code Templates - */ -class SPOJ1 { - - public static void main(String[] args) { - Scanner in = new Scanner(System.in); - - List inputList = new ArrayList<>(); - int input; - for (; ; ) { - input = Integer.parseInt(in.nextLine()); - if (input == 42) break; - inputList.add(input); - } - - for (long i : inputList) { - System.out.println(i); - } - } -} From cde6e836f02b1b456d24e18f24846e5c7464c8d2 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Fri, 31 May 2019 11:54:54 +0100 Subject: [PATCH 098/164] FlattenArray done --- .../com/rampatra/arrays/FlattenArray.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/main/java/com/rampatra/arrays/FlattenArray.java diff --git a/src/main/java/com/rampatra/arrays/FlattenArray.java b/src/main/java/com/rampatra/arrays/FlattenArray.java new file mode 100644 index 00000000..e68c250b --- /dev/null +++ b/src/main/java/com/rampatra/arrays/FlattenArray.java @@ -0,0 +1,39 @@ +package com.rampatra.arrays; + +import java.util.ArrayList; +import java.util.List; + +public class FlattenArray { + + /** + * Given a nested array like [[1, 2], 3, [4]], return an array like [1, 2, 3, 4, 5]. + * + * @param nestedArray an Object array + * @return a list of all elements in the nestedArray but all at the same level + */ + private static List flattenArray(Object[] nestedArray) { + if (nestedArray == null || nestedArray.length == 0) return new ArrayList<>(); + + List flattenedArray = new ArrayList<>(); + + for (Object obj : nestedArray) { + if (obj instanceof Object[]) { + flattenedArray.addAll(flattenArray((Object[]) obj)); + } else if (obj instanceof Integer) { + flattenedArray.add((Integer) obj); + } + } + + return flattenedArray; + } + + public static void main(String[] args) { + System.out.println(flattenArray(null)); + System.out.println(flattenArray(new Object[]{null})); + System.out.println(flattenArray(new Object[]{new Object[]{}})); + System.out.println(flattenArray(new Object[]{new Object[]{1, 2}})); + System.out.println(flattenArray(new Object[]{1, 2, new Object[]{4, 5}, 6})); + System.out.println(flattenArray(new Object[]{new Object[]{4, 5}, 1, 2, 6})); + System.out.println(flattenArray(new Object[]{1, 2, 6, new Object[]{4, 5}})); + } +} \ No newline at end of file From 270ed1b7c8bd0327bd53f5bb44816c6b20b38df7 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Fri, 31 May 2019 21:17:42 +0100 Subject: [PATCH 099/164] ReverseInteger done --- .../com/leetcode/math/ReverseInteger.java | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 src/main/java/com/leetcode/math/ReverseInteger.java diff --git a/src/main/java/com/leetcode/math/ReverseInteger.java b/src/main/java/com/leetcode/math/ReverseInteger.java new file mode 100644 index 00000000..7e540778 --- /dev/null +++ b/src/main/java/com/leetcode/math/ReverseInteger.java @@ -0,0 +1,62 @@ +package com.leetcode.math; + +/** + * Level: Easy + * Problem Link: https://leetcode.com/problems/reverse-integer/ + * Problem Description: + * Given a 32-bit signed integer, reverse digits of an integer. + *

+ * Example 1: + * Input: 123 + * Output: 321 + *

+ * Example 2: + * Input: -123 + * Output: -321 + *

+ * Example 3: + * Input: 120 + * Output: 21 + *

+ * Note: Assume we are dealing with an environment which could only store integers within the 32-bit signed + * integer range: [−2^31, 2^31 − 1]. For the purpose of this problem, assume that your function returns 0 when + * the reversed integer overflows. + * + * @author rampatra + * @since 2019-05-31 + */ +public class ReverseInteger { + + /** + * Reverses the input integer. + * Time complexity: O(d) + * where, + * d = number of digits in num + *

+ * Runtime: 1 ms. + * + * @param num an integer. + * @return the reverse of {@code num}. + */ + private static int reverse(int num) { + long reverse = 0; + int pop; + + while (num != 0) { + pop = num % 10; + num = num / 10; + reverse = reverse * 10 + pop; + } + + return reverse < Integer.MIN_VALUE || reverse > Integer.MAX_VALUE ? 0 : (int) reverse; + } + + public static void main(String[] args) { + System.out.println(reverse(0)); + System.out.println(reverse(-0)); + System.out.println(reverse(123)); + System.out.println(reverse(-123)); + System.out.println(reverse(Integer.MAX_VALUE)); + System.out.println(reverse(Integer.MIN_VALUE)); + } +} \ No newline at end of file From 43b4bd740ad7adfd7002e78243abd2d390c3de86 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Mon, 3 Jun 2019 20:25:40 +0100 Subject: [PATCH 100/164] Distinct pairs done --- .../leetcode/math/ExcelSheetColumnNumber.java | 44 ++++++++++++++++ .../com/rampatra/arrays/DistinctPairs.java | 50 +++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 src/main/java/com/leetcode/math/ExcelSheetColumnNumber.java create mode 100644 src/main/java/com/rampatra/arrays/DistinctPairs.java diff --git a/src/main/java/com/leetcode/math/ExcelSheetColumnNumber.java b/src/main/java/com/leetcode/math/ExcelSheetColumnNumber.java new file mode 100644 index 00000000..29e1dded --- /dev/null +++ b/src/main/java/com/leetcode/math/ExcelSheetColumnNumber.java @@ -0,0 +1,44 @@ +package com.leetcode.math; + +/** + * Level: Easy + * Problem Link: https://leetcode.com/problems/excel-sheet-column-number/ + * Problem Description: + * Given a column title as appear in an Excel sheet, return its corresponding column number. + * + * For example: + * + * A -> 1 + * B -> 2 + * C -> 3 + * ... + * Z -> 26 + * AA -> 27 + * AB -> 28 + * ... + * + * Example 1: + * Input: "A" + * Output: 1 + * + * Example 2: + * Input: "AB" + * Output: 28 + * + * Example 3: + * Input: "ZY" + * Output: 701 + * + * @author rampatra + * @since 2019-05-31 + */ +public class ExcelSheetColumnNumber { + + private static int titleToNumber(String title) { + return 0; + } + + public static void main(String[] args) { + + } +} diff --git a/src/main/java/com/rampatra/arrays/DistinctPairs.java b/src/main/java/com/rampatra/arrays/DistinctPairs.java new file mode 100644 index 00000000..3ba861ab --- /dev/null +++ b/src/main/java/com/rampatra/arrays/DistinctPairs.java @@ -0,0 +1,50 @@ +package com.rampatra.arrays; + +import java.util.HashSet; +import java.util.Set; + +/** + * Level: Easy + * Problem Description: + * Given an array and a target sum, return the number of distinct pairs whose sum is equal to the target sum. + *

+ * For Example, given an array [1, 2, 3, 6, 7, 8, 9, 1] and a target sum of 10, + * the 7 pairs, i.e, (1, 9), (2, 8), (3, 7), (8, 2), (9, 1), (9, 1), and (1, 9) all sum to 10 but there are only + * three distinct pairs, i.e, (1, 9), (2, 8), and (3, 7) so the answer would be 3. + * + * @author rampatra + * @since 2019-06-03 + */ +public class DistinctPairs { + + /** + * Time complexity: O(n), n = size of the array + * Space complexity: O(n) + * + * @param arr + * @param targetSum + * @return + */ + private static int numberOfDistinctPairs(int[] arr, int targetSum) { + Set numSet = new HashSet<>(); + Set> pairSet = new HashSet<>(); + + for (int i = 0; i < arr.length; i++) { + if (numSet.contains(targetSum - arr[i])) { + Set pair = new HashSet<>(); + pair.add(arr[i]); + pair.add(targetSum - arr[i]); + pairSet.add(pair); + } + numSet.add(arr[i]); + } + + return pairSet.size(); + } + + public static void main(String[] args) { + System.out.println(numberOfDistinctPairs(new int[]{1, 2, 3, 6, 7, 8, 9, 1}, 1)); + System.out.println(numberOfDistinctPairs(new int[]{1, 2, 3, 6, 7, 8, 9, 1}, 2)); + System.out.println(numberOfDistinctPairs(new int[]{1, 2, 3, 6, 7, 8, 9, 1}, 10)); + } +} \ No newline at end of file From 51d8742fac616ba0746ee5ba21324a96708be0da Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Mon, 3 Jun 2019 23:04:41 +0100 Subject: [PATCH 101/164] Read file in Java: done --- src/main/java/com/rampatra/misc/ReadFile.java | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 src/main/java/com/rampatra/misc/ReadFile.java diff --git a/src/main/java/com/rampatra/misc/ReadFile.java b/src/main/java/com/rampatra/misc/ReadFile.java new file mode 100644 index 00000000..c5c64540 --- /dev/null +++ b/src/main/java/com/rampatra/misc/ReadFile.java @@ -0,0 +1,71 @@ +package com.rampatra.misc; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + + +/** + * Various ways to read a file in Java. + * + * @author rampatra + * @since 2019-06-03 + */ +public class ReadFile { + + private static Stream readFile(String filePath) throws IOException { + return Files.lines(Paths.get(filePath)); // use Files.readAllLines() to return a List instead of Stream + } + + private static String readFile(Path filePath) throws IOException { + Stream lines = Files.lines(filePath); + String data = lines.collect(Collectors.joining("\n")); + lines.close(); + return data; + } + + private static List readLargeFile(Path filePath) throws IOException { + try (BufferedReader reader = Files.newBufferedReader(filePath)) { + List result = new ArrayList<>(); + for (; ; ) { + String line = reader.readLine(); + if (line == null) + break; + result.add(line); + } + return result; + } + } + + private static String readFileOldWay(String filePath) throws IOException { + try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) { + StringBuilder builder = new StringBuilder(); + String currentLine = reader.readLine(); + while (currentLine != null) { + builder.append(currentLine); + builder.append("\n"); + currentLine = reader.readLine(); + } + // reader.close(); not required as try-with-resources is used + + return builder.toString(); + } + } + + public static void main(String[] args) throws IOException { + readFile("src/main/java/com/rampatra/misc/reverseandadd.txt").forEach(System.out::println); + System.out.println("=================="); + System.out.println(readFile(Paths.get("src/main/java/com/rampatra/misc/reverseandadd.txt"))); + System.out.println("=================="); + System.out.println(readLargeFile(Paths.get("src/main/java/com/rampatra/misc/reverseandadd.txt"))); + System.out.println("=================="); + System.out.println(readFileOldWay("src/main/java/com/rampatra/misc/reverseandadd.txt")); + } +} From c5071d709d34d1468c02f22d4f64e7b834d72cd6 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Wed, 19 Jun 2019 16:50:31 +0100 Subject: [PATCH 102/164] Add one to linked list: done --- .../ctci/linkedlists/DeleteMiddleNode.java | 18 ++-- .../com/ctci/linkedlists/Intersection.java | 14 ++- .../ctci/linkedlists/KthToLastElement.java | 8 +- src/main/java/com/ctci/linkedlists/Node.java | 6 +- .../java/com/ctci/linkedlists/Palindrome.java | 10 +- .../java/com/ctci/linkedlists/Partition.java | 22 ++--- .../ctci/linkedlists/RemoveDuplicates.java | 24 +++-- .../java/com/ctci/linkedlists/SumLists.java | 20 ++-- .../linkedlists/AddOneToNumberInList.java | 91 +++++++++++++++++++ .../java/com/leetcode/linkedlists/Node.java | 23 +++++ 10 files changed, 167 insertions(+), 69 deletions(-) create mode 100644 src/main/java/com/leetcode/linkedlists/AddOneToNumberInList.java create mode 100644 src/main/java/com/leetcode/linkedlists/Node.java diff --git a/src/main/java/com/ctci/linkedlists/DeleteMiddleNode.java b/src/main/java/com/ctci/linkedlists/DeleteMiddleNode.java index 469690c7..c4b4052e 100644 --- a/src/main/java/com/ctci/linkedlists/DeleteMiddleNode.java +++ b/src/main/java/com/ctci/linkedlists/DeleteMiddleNode.java @@ -1,7 +1,5 @@ package com.ctci.linkedlists; -import static com.ctci.linkedlists.Node.printList; - /** * @author rampatra * @since 2019-01-27 @@ -35,33 +33,33 @@ public static void main(String[] args) { l1.next.next.next = new Node(4); l1.next.next.next.next = new Node(5); l1.next.next.next.next.next = new Node(6); - printList(l1); + l1.print(); deleteMiddleNode(l1.next.next); - printList(l1); + l1.print(); System.out.println("----"); l1 = new Node(1); l1.next = new Node(2); l1.next.next = new Node(3); - printList(l1); + l1.print(); deleteMiddleNode(l1.next); - printList(l1); + l1.print(); System.out.println("----"); l1 = new Node(1); l1.next = new Node(3); - printList(l1); + l1.print(); deleteMiddleNode(l1); - printList(l1); + l1.print(); System.out.println("----"); l1 = new Node(1); l1.next = new Node(3); - printList(l1); + l1.print(); deleteMiddleNode(l1.next); - printList(l1); + l1.print(); } } diff --git a/src/main/java/com/ctci/linkedlists/Intersection.java b/src/main/java/com/ctci/linkedlists/Intersection.java index c9d11b72..4665fe43 100644 --- a/src/main/java/com/ctci/linkedlists/Intersection.java +++ b/src/main/java/com/ctci/linkedlists/Intersection.java @@ -1,7 +1,5 @@ package com.ctci.linkedlists; -import static com.ctci.linkedlists.Node.printList; - /** * @author rampatra * @since 2019-02-02 @@ -75,16 +73,16 @@ public static void main(String[] args) { l2.next.next = new Node(2); l2.next.next.next = new Node(3); l2.next.next.next.next = l1.next.next.next; - printList(l1); - printList(l2); + l1.print(); + l2.print(); System.out.println(findIntersectingNode(l1, l2).val); // may throw NPE, not handling for the sake of simplicity System.out.println("----"); l1 = new Node(1); l2 = l1; - printList(l1); - printList(l2); + l1.print(); + l2.print(); System.out.println(findIntersectingNode(l1, l2).val); // may throw NPE, not handling for the sake of simplicity System.out.println("----"); @@ -99,8 +97,8 @@ public static void main(String[] args) { l2.next = new Node(4); l2.next.next = new Node(2); l2.next.next.next = new Node(3); - printList(l1); - printList(l2); + l1.print(); + l2.print(); System.out.println(findIntersectingNode(l1, l2)); } } diff --git a/src/main/java/com/ctci/linkedlists/KthToLastElement.java b/src/main/java/com/ctci/linkedlists/KthToLastElement.java index 9758d2f7..8fff3f9d 100644 --- a/src/main/java/com/ctci/linkedlists/KthToLastElement.java +++ b/src/main/java/com/ctci/linkedlists/KthToLastElement.java @@ -1,7 +1,5 @@ package com.ctci.linkedlists; -import static com.ctci.linkedlists.Node.printList; - /** * @author rampatra * @since 21/11/2018 @@ -60,7 +58,7 @@ public static void main(String[] args) { l1.next.next.next = new Node(4); l1.next.next.next.next = new Node(5); l1.next.next.next.next.next = new Node(7); - printList(l1); + l1.print(); System.out.println("k=2: " + getKthToLastElement(l1, 2).val); // NPE check is omitted intentionally to keep it simple System.out.print("k=2: "); printKthToLastElement(l1, 2); @@ -71,7 +69,7 @@ public static void main(String[] args) { l2.next.next.next = new Node(3); l2.next.next.next.next = new Node(4); l2.next.next.next.next.next = new Node(7); - printList(l2); + l2.print(); System.out.println("k=1: " + getKthToLastElement(l2, 1).val); System.out.print("k=1: "); printKthToLastElement(l2, 1); @@ -82,7 +80,7 @@ public static void main(String[] args) { l3.next.next.next = new Node(3); l3.next.next.next.next = new Node(4); l3.next.next.next.next.next = new Node(7); - printList(l3); + l3.print(); System.out.println("k=6: " + getKthToLastElement(l3, 6).val); System.out.print("k=6: "); printKthToLastElement(l3, 6); diff --git a/src/main/java/com/ctci/linkedlists/Node.java b/src/main/java/com/ctci/linkedlists/Node.java index a0f68cb1..5c0d1ec3 100644 --- a/src/main/java/com/ctci/linkedlists/Node.java +++ b/src/main/java/com/ctci/linkedlists/Node.java @@ -12,10 +12,8 @@ class Node { this.val = val; } - public static void printList(Node head) { - if (head == null) return; - - Node curr = head; + public void print() { + Node curr = this; while (curr.next != null) { System.out.print(curr.val + "->"); curr = curr.next; diff --git a/src/main/java/com/ctci/linkedlists/Palindrome.java b/src/main/java/com/ctci/linkedlists/Palindrome.java index 717a478e..57bb184d 100644 --- a/src/main/java/com/ctci/linkedlists/Palindrome.java +++ b/src/main/java/com/ctci/linkedlists/Palindrome.java @@ -2,8 +2,6 @@ import java.util.Stack; -import static com.ctci.linkedlists.Node.printList; - /** * @author rampatra * @since 2019-02-02 @@ -75,7 +73,7 @@ public static void main(String[] args) { l1.next.next.next = new Node(3); l1.next.next.next.next = new Node(2); l1.next.next.next.next.next = new Node(1); - printList(l1); + l1.print(); System.out.println(isPalindrome(l1)); System.out.println(isPalindromeOptimized(l1)); System.out.println("------"); @@ -85,7 +83,7 @@ public static void main(String[] args) { l1.next.next = new Node(3); l1.next.next.next = new Node(2); l1.next.next.next.next = new Node(1); - printList(l1); + l1.print(); System.out.println(isPalindrome(l1)); System.out.println(isPalindromeOptimized(l1)); System.out.println("------"); @@ -95,13 +93,13 @@ public static void main(String[] args) { l1.next.next = new Node(3); l1.next.next.next = new Node(3); l1.next.next.next.next = new Node(0); - printList(l1); + l1.print(); System.out.println(isPalindrome(l1)); System.out.println(isPalindromeOptimized(l1)); System.out.println("------"); l1 = new Node(1); - printList(l1); + l1.print(); System.out.println(isPalindrome(l1)); System.out.println(isPalindromeOptimized(l1)); diff --git a/src/main/java/com/ctci/linkedlists/Partition.java b/src/main/java/com/ctci/linkedlists/Partition.java index 406be3e5..8876a424 100644 --- a/src/main/java/com/ctci/linkedlists/Partition.java +++ b/src/main/java/com/ctci/linkedlists/Partition.java @@ -1,7 +1,5 @@ package com.ctci.linkedlists; -import static com.ctci.linkedlists.Node.printList; - /** * Write code to partition a linked list around a value x, such that all nodes less than x come before all * nodes greater than or equal to x. If x is contained within the list, the values of x only need to be @@ -59,36 +57,36 @@ public static void main(String[] args) { l1.next.next.next.next = new Node(10); l1.next.next.next.next.next = new Node(2); l1.next.next.next.next.next.next = new Node(1); - printList(l1); - printList(partition(l1, 5)); + l1.print(); + l1.print(); System.out.println("----"); l1 = new Node(1); l1.next = new Node(2); l1.next.next = new Node(3); - printList(l1); - printList(partition(l1, 2)); + l1.print(); + l1.print(); System.out.println("----"); l1 = new Node(3); l1.next = new Node(2); l1.next.next = new Node(1); - printList(l1); - printList(partition(l1, 2)); + l1.print(); + l1.print(); System.out.println("----"); l1 = new Node(1); - printList(l1); - printList(partition(l1, 1)); + l1.print(); + l1.print(); System.out.println("----"); l1 = null; - printList(l1); - printList(partition(l1, 1)); + l1.print(); + l1.print(); System.out.println("----"); } diff --git a/src/main/java/com/ctci/linkedlists/RemoveDuplicates.java b/src/main/java/com/ctci/linkedlists/RemoveDuplicates.java index df65cf06..31029188 100644 --- a/src/main/java/com/ctci/linkedlists/RemoveDuplicates.java +++ b/src/main/java/com/ctci/linkedlists/RemoveDuplicates.java @@ -3,8 +3,6 @@ import java.util.HashSet; import java.util.Set; -import static com.ctci.linkedlists.Node.printList; - /** * @author rampatra * @since 21/11/2018 @@ -44,10 +42,10 @@ public static void main(String[] args) { l1.next.next.next.next = new Node(5); l1.next.next.next.next.next = new Node(5); System.out.print("With dups: "); - printList(l1); + l1.print(); removeDuplicatesFromUnsortedList(l1); System.out.print("Without dups: "); - printList(l1); + l1.print(); Node l2 = new Node(1); l2.next = new Node(1); @@ -56,10 +54,10 @@ public static void main(String[] args) { l2.next.next.next.next = new Node(4); l2.next.next.next.next.next = new Node(5); System.out.print("\nWith dups: "); - printList(l2); + l2.print(); removeDuplicatesFromUnsortedList(l2); System.out.print("Without dups: "); - printList(l2); + l2.print(); Node l3 = new Node(1); l3.next = new Node(2); @@ -68,23 +66,23 @@ public static void main(String[] args) { l3.next.next.next.next = new Node(4); l3.next.next.next.next.next = new Node(5); System.out.print("\nWith dups: "); - printList(l3); + l3.print(); removeDuplicatesFromUnsortedList(l3); System.out.print("Without dups: "); - printList(l3); - + l3.print(); + Node l4 = new Node(1); System.out.print("\nWith dups: "); - printList(l4); + l4.print(); removeDuplicatesFromUnsortedList(l4); System.out.print("Without dups: "); - printList(l4); + l4.print(); Node l5 = null; System.out.print("\nWith dups: "); - printList(l5); + l5.print(); removeDuplicatesFromUnsortedList(l5); System.out.print("Without dups: "); - printList(l5); + l5.print(); } } \ No newline at end of file diff --git a/src/main/java/com/ctci/linkedlists/SumLists.java b/src/main/java/com/ctci/linkedlists/SumLists.java index e3ebc677..befdfc3e 100644 --- a/src/main/java/com/ctci/linkedlists/SumLists.java +++ b/src/main/java/com/ctci/linkedlists/SumLists.java @@ -1,7 +1,5 @@ package com.ctci.linkedlists; -import static com.ctci.linkedlists.Node.printList; - /** * @author rampatra * @since 2019-01-31 @@ -59,9 +57,9 @@ public static void main(String[] args) { l2.next = new Node(9); l2.next.next = new Node(9); - printList(l1); - printList(l2); - printList(sumLists(l1, l2)); + l1.print(); + l2.print(); + sumLists(l1, l2).print(); System.out.println("-----------"); l1 = new Node(9); @@ -71,9 +69,9 @@ public static void main(String[] args) { l2.next = new Node(9); l2.next.next = new Node(9); - printList(l1); - printList(l2); - printList(sumLists(l1, l2)); + l1.print(); + l2.print(); + sumLists(l1, l2).print(); System.out.println("-----------"); l1 = null; @@ -81,8 +79,8 @@ public static void main(String[] args) { l2.next = new Node(9); l2.next.next = new Node(8); - printList(l1); - printList(l2); - printList(sumLists(l1, l2)); + l1.print(); + l2.print(); + sumLists(l1, l2).print(); } } diff --git a/src/main/java/com/leetcode/linkedlists/AddOneToNumberInList.java b/src/main/java/com/leetcode/linkedlists/AddOneToNumberInList.java new file mode 100644 index 00000000..8e96d7eb --- /dev/null +++ b/src/main/java/com/leetcode/linkedlists/AddOneToNumberInList.java @@ -0,0 +1,91 @@ +package com.leetcode.linkedlists; + +/** + * Level: Easy + * Problem Link: https://leetcode.com/problems/plus-one-linked-list/ + * Problem Description: Given a non-empty single linked list representing a number where the head is the + * most significant bit, add one to the number and modify the same linked list. + * + * @author rampatra + * @since 2019-06-19 + */ +public class AddOneToNumberInList { + + + /** + * Add {@code one} to the number represented by linked list {@code head}. + * + * @param head the starting node of the linked list + * @return the head of the linked list after adding {@code one} + */ + private static Node addOne(Node head) { + Node currOrig = reverse(head); + Node currRes = null; + Node res = null; + + int sum = 1; + int carry = 0; + int rem; + + while (currOrig != null) { + sum += carry + currOrig.val; + rem = sum % 10; + carry = sum / 10; + + if (res == null) { + res = currRes = new Node(rem); + } else { + currRes.next = new Node(rem); + currRes = currRes.next; + } + + sum = 0; + currOrig = currOrig.next; + } + + if (carry != 0) { + currRes.next = new Node(carry); + } + + return reverse(res); + } + + private static Node reverse(Node head) { + Node prev = null; + Node curr = head; + Node next; + + while (curr != null) { + next = curr.next; + curr.next = prev; + + prev = curr; + curr = next; + } + + return prev; + } + + + public static void main(String[] args) { + Node node = new Node(9); + node.next = new Node(9); + node.next.next = new Node(9); + node.print(); + addOne(node).print(); + + System.out.println("---------"); + + node = new Node(1); + node.next = new Node(9); + node.next.next = new Node(9); + node.print(); + addOne(node).print(); + + System.out.println("---------"); + + node = new Node(0); + node.print(); + addOne(node).print(); + } +} \ No newline at end of file diff --git a/src/main/java/com/leetcode/linkedlists/Node.java b/src/main/java/com/leetcode/linkedlists/Node.java new file mode 100644 index 00000000..3276413f --- /dev/null +++ b/src/main/java/com/leetcode/linkedlists/Node.java @@ -0,0 +1,23 @@ +package com.leetcode.linkedlists; + +/** + * @author rampatra + * @since 21/11/2018 + */ +class Node { + int val; + Node next; + + Node(int val) { + this.val = val; + } + + public void print() { + Node curr = this; + while (curr.next != null) { + System.out.print(curr.val + "->"); + curr = curr.next; + } + System.out.println(curr.val); + } +} From b11f798038804c3f978365562a86c4e4de97b5fb Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Wed, 19 Jun 2019 16:52:44 +0100 Subject: [PATCH 103/164] Minor correction in question --- .../java/com/leetcode/linkedlists/AddOneToNumberInList.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/leetcode/linkedlists/AddOneToNumberInList.java b/src/main/java/com/leetcode/linkedlists/AddOneToNumberInList.java index 8e96d7eb..9f0a029c 100644 --- a/src/main/java/com/leetcode/linkedlists/AddOneToNumberInList.java +++ b/src/main/java/com/leetcode/linkedlists/AddOneToNumberInList.java @@ -4,7 +4,7 @@ * Level: Easy * Problem Link: https://leetcode.com/problems/plus-one-linked-list/ * Problem Description: Given a non-empty single linked list representing a number where the head is the - * most significant bit, add one to the number and modify the same linked list. + * most significant bit, add one to the number and return a new linked list. * * @author rampatra * @since 2019-06-19 From 4d4353a31372e227fd86b25bc6774050174563a3 Mon Sep 17 00:00:00 2001 From: Ram <2862724+rampatra@users.noreply.github.com> Date: Thu, 20 Jun 2019 22:08:57 +0100 Subject: [PATCH 104/164] Create FUNDING.yml --- .github/FUNDING.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..f344b865 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +patreon: rampatra # Replace with a single Patreon username +open_collective: jbot # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: https://www.paypal.me/ramswaroop # Replace with a single custom sponsorship URL From 035140bc702506ac8a1013101aaaba8b29eeb55f Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sun, 30 Jun 2019 23:15:03 +0100 Subject: [PATCH 105/164] Added basic producer/consumer --- .../java/advanced/JavaVisitorPattern.java | 8 ++ .../hackerrank/java/bignumber/BigDecimal.java | 40 +++++++++ .../java/com/rampatra/threads/NamePrint.java | 13 +-- .../ProducerConsumerUsingWaitNotify.java | 84 +++++++++++++++++++ .../com/rampatra/threads/SimpleDeadlock.java | 2 + 5 files changed, 141 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/hackerrank/java/advanced/JavaVisitorPattern.java create mode 100644 src/main/java/com/hackerrank/java/bignumber/BigDecimal.java create mode 100644 src/main/java/com/rampatra/threads/ProducerConsumerUsingWaitNotify.java diff --git a/src/main/java/com/hackerrank/java/advanced/JavaVisitorPattern.java b/src/main/java/com/hackerrank/java/advanced/JavaVisitorPattern.java new file mode 100644 index 00000000..a40151be --- /dev/null +++ b/src/main/java/com/hackerrank/java/advanced/JavaVisitorPattern.java @@ -0,0 +1,8 @@ +package com.hackerrank.java.advanced; + +/** + * @author rampatra + * @since 2019-06-22 + */ +public class JavaVisitorPattern { +} diff --git a/src/main/java/com/hackerrank/java/bignumber/BigDecimal.java b/src/main/java/com/hackerrank/java/bignumber/BigDecimal.java new file mode 100644 index 00000000..7e1b804e --- /dev/null +++ b/src/main/java/com/hackerrank/java/bignumber/BigDecimal.java @@ -0,0 +1,40 @@ +package com.hackerrank.java.bignumber; + +import java.util.Arrays; +import java.util.List; +import java.util.Scanner; + +/** + * Problem Link: https://www.hackerrank.com/challenges/java-bigdecimal/ + * + * @author rampatra + * @since 2019-06-22 + */ +class BigDecimal { + public static void main(String[] args) { + //Input + Scanner sc = new Scanner(System.in); + int n = sc.nextInt(); + String[] s = new String[n + 2]; + for (int i = 0; i < n; i++) { + s[i] = sc.next(); + } + sc.close(); + + //Write your code here + s = Arrays.copyOfRange(s, 0, s.length - 2); + List input = Arrays.asList(s); + Arrays.sort(s, (s1, s2) -> { + int compare = new java.math.BigDecimal(s2).compareTo(new java.math.BigDecimal(s1)); + if (compare == 0) { + return Integer.compare(input.indexOf(s1), input.indexOf(s2)); + } + return compare; + }); + + //Output + for (int i = 0; i < n; i++) { + System.out.println(s[i]); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/rampatra/threads/NamePrint.java b/src/main/java/com/rampatra/threads/NamePrint.java index b87f3e5a..05e19820 100644 --- a/src/main/java/com/rampatra/threads/NamePrint.java +++ b/src/main/java/com/rampatra/threads/NamePrint.java @@ -1,13 +1,10 @@ package com.rampatra.threads; /** - * Created by IntelliJ IDEA. - *

- * Question: Print first name and last name (in order) using two different threads multiple times. + * Problem Description: Print first name and last name (in order) using two different threads 1000 times. * * @author rampatra * @since 10/6/15 - * @time: 7:10 PM */ public class NamePrint { @@ -21,7 +18,9 @@ public void run() { for (int i = 0; i < 1000; i++) { try { // wait if first name is printed but not the last name - if (isFirstNamePrinted) lock.wait(); + if (isFirstNamePrinted) { + lock.wait(); + } } catch (InterruptedException e) { e.printStackTrace(); } @@ -40,7 +39,9 @@ public void run() { for (int i = 0; i < 1000; i++) { try { // wait if first name is not printed - if (!isFirstNamePrinted) lock.wait(); + if (!isFirstNamePrinted) { + lock.wait(); + } } catch (InterruptedException e) { e.printStackTrace(); } diff --git a/src/main/java/com/rampatra/threads/ProducerConsumerUsingWaitNotify.java b/src/main/java/com/rampatra/threads/ProducerConsumerUsingWaitNotify.java new file mode 100644 index 00000000..3c626401 --- /dev/null +++ b/src/main/java/com/rampatra/threads/ProducerConsumerUsingWaitNotify.java @@ -0,0 +1,84 @@ +package com.rampatra.threads; + +/** + * Problem Description: A simple Producer/Consumer using Wait/Notify pattern. + * + * @author rampatra + * @since 2019-06-30 + */ +public class ProducerConsumerUsingWaitNotify { + + private static int currSize = 0; + private static int totalSize = 10; + private static int[] buffer = new int[totalSize]; + private static Object lock = new Object(); + + static class Producer { + void produce() throws InterruptedException { + synchronized (lock) { + if (isFull()) { + lock.wait(); + } + buffer[currSize++] = 1; + lock.notify(); + } + } + } + + static class Consumer { + void consume() throws InterruptedException { + synchronized (lock) { + if (isEmpty()) { + lock.wait(); + } + System.out.println(buffer[currSize--]); + lock.notify(); + } + } + } + + private static boolean isFull() { + return currSize >= totalSize - 1; // as index starts from zero + } + + private static boolean isEmpty() { + return currSize == 0; + } + + public static void main(String[] args) throws InterruptedException { + + Runnable producerTask = () -> { + for (int i = 0; i < 1000; i++) { + try { + new Producer().produce(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }; + + Runnable consumerTask = () -> { + for (int i = 0; i < 1000; i++) { + try { + new Consumer().consume(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }; + + Thread producer = new Thread(producerTask); + Thread consumer = new Thread(consumerTask); + + // start both the threads + producer.start(); + consumer.start(); + + // wait for both the threads to complete + producer.join(); + consumer.join(); + + // as produce() and consume() are called equal number of times, this should be zero in the end + System.out.println("Buffer Size: " + currSize); + } +} \ No newline at end of file diff --git a/src/main/java/com/rampatra/threads/SimpleDeadlock.java b/src/main/java/com/rampatra/threads/SimpleDeadlock.java index a9e41491..b3b749a4 100644 --- a/src/main/java/com/rampatra/threads/SimpleDeadlock.java +++ b/src/main/java/com/rampatra/threads/SimpleDeadlock.java @@ -5,6 +5,8 @@ import java.lang.management.ThreadMXBean; /** + * Problem Description: Deadlock example. + * * @author rampatra * @since 2019-03-13 */ From 2866ce43cedc0a1eedb0eb7c4ca6cf6efb4e44e2 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Thu, 11 Jul 2019 15:15:31 +0100 Subject: [PATCH 106/164] Added Producer Consumer using Lock Api --- .../threads/ProducerConsumerUsingLockApi.java | 106 ++++++++++++++++++ .../ProducerConsumerUsingWaitNotify.java | 5 +- 2 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/rampatra/threads/ProducerConsumerUsingLockApi.java diff --git a/src/main/java/com/rampatra/threads/ProducerConsumerUsingLockApi.java b/src/main/java/com/rampatra/threads/ProducerConsumerUsingLockApi.java new file mode 100644 index 00000000..4c1443e0 --- /dev/null +++ b/src/main/java/com/rampatra/threads/ProducerConsumerUsingLockApi.java @@ -0,0 +1,106 @@ +package com.rampatra.threads; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +/** + * Problem Description: A simple Producer/Consumer using the Lock and Condition Api pattern. For the language primitive, + * i.e, synchronize and wait/notify pattern, please see {@link ProducerConsumerUsingWaitNotify}. + *

+ *

+ * There are a few advantages of going with the Lock Api pattern instead of the language primitive synchronize and + * wait/notify pattern: + *

+ * - Can be interrupted which means that the application won't continue to run forever in weird situations. Consider this + * example, what happens if the Consumer starts first and there are no elements to consume and the Producer also fails + * due to some exception. In wait/notify the Consumer would stall forever. You would have to restart the JVM to get + * rid of this. However, with Lock api, you can use {@link Lock#lockInterruptibly()}. + *

+ * - Timed lock acquisition. You can try to acquire a lock and if it is not instantly available then do something else. + * See {@link Lock#tryLock()} to learn more. You can also wait for a certain amount of time before giving up with the + * {@link Lock#tryLock(long, TimeUnit)} method. This isn't possible with the primitive pattern. + *

+ * - A fair Lock generates a fair Condition. Fair here means the first thread in the waiting queue will be picked first + * by the scheduler. This is a costly operation so use it only when necessary. + * + * @author rampatra + * @since 2019-07-10 + */ +public class ProducerConsumerUsingLockApi { + + private static int currSize = 0; + private static int totalSize = 10; + private static int[] buffer = new int[totalSize]; + private static Lock lock = new ReentrantLock(); + private static Condition isEmpty = lock.newCondition(); + private static Condition isFull = lock.newCondition(); + + static class Producer { + static void produce() { + try { + + lock.lock(); + while (currSize >= totalSize) { + isFull.await(); + } + buffer[currSize++] = 1; + isEmpty.signal(); + + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + lock.unlock(); + } + } + } + + static class Consumer { + static void consume() { + try { + + lock.lock(); + while (currSize <= 0) { + isEmpty.await(); + } + System.out.println(buffer[--currSize]); + isFull.signal(); + + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + lock.unlock(); + } + } + } + + public static void main(String[] args) throws InterruptedException { + + ExecutorService executorService = Executors.newFixedThreadPool(2); + + Runnable producerTask = () -> { + for (int i = 0; i < 1000; i++) { + Producer.produce(); + } + }; + + Runnable consumerTask = () -> { + for (int i = 0; i < 1000; i++) { + Consumer.consume(); + } + }; + + executorService.submit(producerTask); + executorService.submit(consumerTask); + + executorService.awaitTermination(3000, TimeUnit.MILLISECONDS); + + // as produce() and consume() are called equal number of times, this should be zero in the end + System.out.println("Buffer Size: " + currSize); + + executorService.shutdown(); + } +} \ No newline at end of file diff --git a/src/main/java/com/rampatra/threads/ProducerConsumerUsingWaitNotify.java b/src/main/java/com/rampatra/threads/ProducerConsumerUsingWaitNotify.java index 3c626401..df65fa2f 100644 --- a/src/main/java/com/rampatra/threads/ProducerConsumerUsingWaitNotify.java +++ b/src/main/java/com/rampatra/threads/ProducerConsumerUsingWaitNotify.java @@ -1,7 +1,8 @@ package com.rampatra.threads; /** - * Problem Description: A simple Producer/Consumer using Wait/Notify pattern. + * Problem Description: A simple Producer/Consumer using Synchronize and Wait/Notify pattern. For a better + * solution, please see {@link ProducerConsumerUsingLockApi}. * * @author rampatra * @since 2019-06-30 @@ -31,7 +32,7 @@ void consume() throws InterruptedException { if (isEmpty()) { lock.wait(); } - System.out.println(buffer[currSize--]); + System.out.println(buffer[--currSize]); lock.notify(); } } From 82cbaa669fb8aef37e514a0567f3c989068b8248 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Thu, 11 Jul 2019 15:16:34 +0100 Subject: [PATCH 107/164] Made the lock object final --- .../com/rampatra/threads/ProducerConsumerUsingWaitNotify.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/rampatra/threads/ProducerConsumerUsingWaitNotify.java b/src/main/java/com/rampatra/threads/ProducerConsumerUsingWaitNotify.java index df65fa2f..da753f04 100644 --- a/src/main/java/com/rampatra/threads/ProducerConsumerUsingWaitNotify.java +++ b/src/main/java/com/rampatra/threads/ProducerConsumerUsingWaitNotify.java @@ -12,7 +12,7 @@ public class ProducerConsumerUsingWaitNotify { private static int currSize = 0; private static int totalSize = 10; private static int[] buffer = new int[totalSize]; - private static Object lock = new Object(); + private static final Object lock = new Object(); static class Producer { void produce() throws InterruptedException { From 904753ca14282a350bccb62b5067e424b4594e66 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Mon, 22 Jul 2019 14:48:59 +0100 Subject: [PATCH 108/164] Merge Intervals done --- .../com/leetcode/arrays/MergeIntervals.java | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 src/main/java/com/leetcode/arrays/MergeIntervals.java diff --git a/src/main/java/com/leetcode/arrays/MergeIntervals.java b/src/main/java/com/leetcode/arrays/MergeIntervals.java new file mode 100644 index 00000000..3efe59e0 --- /dev/null +++ b/src/main/java/com/leetcode/arrays/MergeIntervals.java @@ -0,0 +1,75 @@ +package com.leetcode.arrays; + +import java.util.Arrays; +import java.util.Comparator; + +/** + * Level: Medium + * Problem Link: https://leetcode.com/problems/merge-intervals/ + * Problem Description: + *

+ * Given a collection of intervals, merge all overlapping intervals. + *

+ * Example 1: + * Input: [[1,3],[2,6],[8,10],[15,18]] + * Output: [[1,6],[8,10],[15,18]] + * Explanation: Since intervals [1,3] and [2,6] overlaps, merge them into [1,6]. + *

+ * Example 2: + * Input: [[1,4],[4,5]] + * Output: [[1,5]] + * Explanation: Intervals [1,4] and [4,5] are considered overlapping. + * + * @author rampatra + * @since 2019-07-22 + */ +public class MergeIntervals { + + /** + * Time complexity: O(n log n) + * Space complexity: O(n) + * Runtime: 6 ms + * + * @param intervals a list of intervals, may not be sorted + * @return a list of intervals, with overlapping intervals merged + */ + public static int[][] merge(int[][] intervals) { + // some validations + if (intervals.length == 0) return new int[0][2]; + + // we first sort the intervals based on their start times + Arrays.sort(intervals, new IntervalComparator()); + + int[][] mergedIntervals = new int[intervals.length][2]; + int lastMergedIndex = 0; + mergedIntervals[lastMergedIndex] = intervals[0]; + + for (int i = 1; i < intervals.length; i++) { + if (isOverlap(mergedIntervals[lastMergedIndex], intervals[i])) { + // if two intervals overlap, then merge the two + mergedIntervals[lastMergedIndex] = new int[]{Math.min(mergedIntervals[lastMergedIndex][0], intervals[i][0]), + Math.max(mergedIntervals[lastMergedIndex][1], intervals[i][1])}; + } else { + mergedIntervals[++lastMergedIndex] = intervals[i]; + } + } + + return Arrays.copyOfRange(mergedIntervals, 0, lastMergedIndex + 1); + } + + private static boolean isOverlap(int[] interval1, int[] interval2) { + return interval1[0] <= interval2[0] && interval1[1] >= interval2[0]; + } + + private static class IntervalComparator implements Comparator { + @Override + public int compare(int[] interval1, int[] interval2) { + return interval1[0] - interval2[0]; + } + } + + public static void main(String[] args) { + System.out.println(Arrays.deepToString(merge(new int[][]{{1, 3}, {2, 6}, {8, 10}, {15, 18}}))); + System.out.println(Arrays.deepToString(merge(new int[][]{{1, 4}, {4, 5}}))); + } +} \ No newline at end of file From 775fed8bf1b0b9dca546fa280afdb121ede2a9d0 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Tue, 23 Jul 2019 22:25:26 +0100 Subject: [PATCH 109/164] Insert Interval done --- .../com/leetcode/arrays/InsertInterval.java | 78 +++++++++++++++++++ .../com/leetcode/arrays/MergeIntervals.java | 3 + 2 files changed, 81 insertions(+) create mode 100644 src/main/java/com/leetcode/arrays/InsertInterval.java diff --git a/src/main/java/com/leetcode/arrays/InsertInterval.java b/src/main/java/com/leetcode/arrays/InsertInterval.java new file mode 100644 index 00000000..519ea854 --- /dev/null +++ b/src/main/java/com/leetcode/arrays/InsertInterval.java @@ -0,0 +1,78 @@ +package com.leetcode.arrays; + +import java.util.Arrays; + +/** + * Level: Hard + * Problem Link: https://leetcode.com/problems/insert-interval/ + * Problem Description: + * Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary). + *

+ * You may assume that the intervals were initially sorted according to their start times. + *

+ * Example 1: + * Input: intervals = [[1,3],[6,9]], newInterval = [2,5] + * Output: [[1,5],[6,9]] + *

+ * Example 2: + * Input: intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8] + * Output: [[1,2],[3,10],[12,16]] + * Explanation: Because the new interval [4,8] overlaps with [3,5],[6,7],[8,10]. + *

+ * Companies: LinkedIn + * Related: {@link MergeIntervals}. + * + * @author rampatra + * @since 2019-07-23 + */ +public class InsertInterval { + + /** + * Time Complexity: O(n) + * Space Complexity: O(n) + * Runtime: 2 ms. + * + * @param intervals + * @param newInterval + * @return + */ + public static int[][] insert(int[][] intervals, int[] newInterval) { + if (intervals.length == 0 && newInterval.length == 0) { + return new int[][]{}; + } else if (intervals.length == 0) { + return new int[][]{newInterval}; + } + + int[][] mergedIntervals = new int[intervals.length + 1][2]; + int j = 0; + + for (int i = 0; i < intervals.length; i++) { + if (newInterval == null || newInterval[0] > intervals[i][1]) { // newInterval is after the ith interval + mergedIntervals[j++] = intervals[i]; + } else if (newInterval[1] < intervals[i][0]) { // newInterval is before the ith interval + mergedIntervals[j++] = newInterval; + mergedIntervals[j++] = intervals[i]; + newInterval = null; + } else { // if overlapping + newInterval[0] = Math.min(newInterval[0], intervals[i][0]); + newInterval[1] = Math.max(newInterval[1], intervals[i][1]); + } + } + + if (newInterval != null) { + mergedIntervals[j++] = newInterval; + } + + return Arrays.copyOfRange(mergedIntervals, 0, j); + } + + public static void main(String[] args) { + System.out.println(Arrays.deepToString(insert(new int[][]{}, new int[]{}))); + System.out.println(Arrays.deepToString(insert(new int[][]{}, new int[]{5, 7}))); + System.out.println(Arrays.deepToString(insert(new int[][]{{1, 5}}, new int[]{0, 0}))); + System.out.println(Arrays.deepToString(insert(new int[][]{{1, 5}}, new int[]{2, 3}))); + System.out.println(Arrays.deepToString(insert(new int[][]{{2, 5}, {6, 7}, {8, 9}}, new int[]{0, 1}))); + System.out.println(Arrays.deepToString(insert(new int[][]{{1, 3}, {6, 9}}, new int[]{2, 5}))); + System.out.println(Arrays.deepToString(insert(new int[][]{{1, 2}, {3, 5}, {6, 7}, {8, 10}, {12, 16}}, new int[]{4, 8}))); + } +} \ No newline at end of file diff --git a/src/main/java/com/leetcode/arrays/MergeIntervals.java b/src/main/java/com/leetcode/arrays/MergeIntervals.java index 3efe59e0..58f56ebc 100644 --- a/src/main/java/com/leetcode/arrays/MergeIntervals.java +++ b/src/main/java/com/leetcode/arrays/MergeIntervals.java @@ -19,6 +19,9 @@ * Input: [[1,4],[4,5]] * Output: [[1,5]] * Explanation: Intervals [1,4] and [4,5] are considered overlapping. + *

+ * Companies: LinkedIn + * Related: {@link InsertInterval}. * * @author rampatra * @since 2019-07-22 From dc0b538a72fa8f23ac294d32d68444611417384f Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Wed, 24 Jul 2019 22:50:56 +0100 Subject: [PATCH 110/164] Added junit + paint house 2 --- pom.xml | 8 + .../java/advanced/JavaVisitorPattern.java | 220 +++++++++++++++++- .../com/leetcode/arrays/InsertInterval.java | 2 +- .../dynamicprogramming/PaintHouse.java | 50 ++++ .../dynamicprogramming/PaintHouseII.java | 120 ++++++++++ 5 files changed, 398 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/leetcode/dynamicprogramming/PaintHouse.java create mode 100644 src/main/java/com/leetcode/dynamicprogramming/PaintHouseII.java diff --git a/pom.xml b/pom.xml index 84c22245..43d083ac 100644 --- a/pom.xml +++ b/pom.xml @@ -54,6 +54,14 @@ ${java.version} + + + junit + junit + 4.12 + + + release diff --git a/src/main/java/com/hackerrank/java/advanced/JavaVisitorPattern.java b/src/main/java/com/hackerrank/java/advanced/JavaVisitorPattern.java index a40151be..5f91e9b5 100644 --- a/src/main/java/com/hackerrank/java/advanced/JavaVisitorPattern.java +++ b/src/main/java/com/hackerrank/java/advanced/JavaVisitorPattern.java @@ -1,8 +1,226 @@ package com.hackerrank.java.advanced; +import java.util.*; + /** + * Level: Medium + * Problem Link: https://www.hackerrank.com/challenges/java-vistor-pattern/ + * * @author rampatra * @since 2019-06-22 */ -public class JavaVisitorPattern { +enum Color { + RED, GREEN +} + +abstract class Tree { + + private int value; + private Color color; + private int depth; + + public Tree(int value, Color color, int depth) { + this.value = value; + this.color = color; + this.depth = depth; + } + + public int getValue() { + return value; + } + + public Color getColor() { + return color; + } + + public int getDepth() { + return depth; + } + + public abstract void accept(TreeVis visitor); + + +} + +class TreeNode extends Tree { + + private ArrayList children = new ArrayList<>(); + + public TreeNode(int value, Color color, int depth) { + super(value, color, depth); + } + + public void accept(TreeVis visitor) { + visitor.visitNode(this); + + for (Tree child : children) { + child.accept(visitor); + } + } + + public void addChild(Tree child) { + children.add(child); + } +} + +class TreeLeaf extends Tree { + + public TreeLeaf(int value, Color color, int depth) { + super(value, color, depth); + } + + public void accept(TreeVis visitor) { + visitor.visitLeaf(this); + } +} + +abstract class TreeVis { + public abstract int getResult(); + + public abstract void visitNode(TreeNode node); + + public abstract void visitLeaf(TreeLeaf leaf); + +} + +class SumInLeavesVisitor extends TreeVis { + int nodeSum = 0; + int leafSum = 0; + + public int getResult() { + //implement this + return leafSum; + } + + public void visitNode(TreeNode node) { + //implement this + //nodeSum += node.getValue(); + } + + public void visitLeaf(TreeLeaf leaf) { + //implement this + leafSum += leaf.getValue(); + } +} + +class ProductOfRedNodesVisitor extends TreeVis { + int prodOfRedNodesAndLeaves = 1; + private final int M = 1000000007; + + public int getResult() { + //implement this + return prodOfRedNodesAndLeaves; + } + + public void visitNode(TreeNode node) { + //implement this + if (node.getColor() == Color.RED) { + prodOfRedNodesAndLeaves *= (node.getValue() % M); + } + } + + public void visitLeaf(TreeLeaf leaf) { + //implement this + if (leaf.getColor() == Color.RED) { + prodOfRedNodesAndLeaves *= (leaf.getValue() % M); + } + } +} + +class FancyVisitor extends TreeVis { + int sumOfNodesAtEvenDepth = 0; + int sumOfGreenLeaves = 0; + + public int getResult() { + //implement this + return Math.abs(sumOfNodesAtEvenDepth - sumOfGreenLeaves); + } + + public void visitNode(TreeNode node) { + //implement this + if (node.getDepth() % 2 == 0) { + sumOfNodesAtEvenDepth += node.getValue(); + } + } + + public void visitLeaf(TreeLeaf leaf) { + //implement this + if (leaf.getColor() == Color.GREEN) { + sumOfGreenLeaves += leaf.getValue(); + } + } } + +public class JavaVisitorPattern { + + public static Tree solve() { + //read the tree from STDIN and return its root as a return value of this function + Scanner s = new Scanner(System.in); + + int numOfNodes = s.nextInt(); + int[] nodeValues = new int[numOfNodes]; + int[] nodeColors = new int[numOfNodes]; + Map> parentToChildMap = new HashMap<>(); + Map childToParentMap = new HashMap<>(); + + for (int i = 0; i < numOfNodes; i++) { + nodeValues[i] = s.nextInt(); + } + for (int i = 0; i < numOfNodes; i++) { + nodeColors[i] = s.nextInt(); + } + for (int i = 0; i < numOfNodes - 1; i++) { + int parentIndex = s.nextInt(); + int childIndex = s.nextInt(); + + Set children = parentToChildMap.get(parentIndex - 1) != null ? parentToChildMap.get(parentIndex - 1) : new HashSet<>(); + children.add(childIndex - 1); + parentToChildMap.put(parentIndex - 1, children); + childToParentMap.put(childIndex - 1, parentIndex - 1); + } + + List nodes = new ArrayList<>(numOfNodes); + for (int i = 0; i < numOfNodes; i++) { + + int depth = childToParentMap.get(i) == null ? -1 : nodes.get(childToParentMap.get(i)).getDepth(); + + if (parentToChildMap.get(i) != null) { + nodes.add(new TreeNode(nodeValues[i], nodeColors[i] == 0 ? Color.RED : Color.GREEN, depth + 1)); + } else { + nodes.add(new TreeLeaf(nodeValues[i], nodeColors[i] == 0 ? Color.RED : Color.GREEN, depth + 1)); + } + } + + + for (Map.Entry> entry : parentToChildMap.entrySet()) { + + TreeNode parent = (TreeNode) nodes.get(entry.getKey()); + + for (Integer childIndex : entry.getValue()) { + parent.addChild(nodes.get(childIndex)); + } + } + + return nodes.get(0); + } + + + public static void main(String[] args) { + Tree root = solve(); + SumInLeavesVisitor vis1 = new SumInLeavesVisitor(); + ProductOfRedNodesVisitor vis2 = new ProductOfRedNodesVisitor(); + FancyVisitor vis3 = new FancyVisitor(); + + root.accept(vis1); + root.accept(vis2); + root.accept(vis3); + + int res1 = vis1.getResult(); + int res2 = vis2.getResult(); + int res3 = vis3.getResult(); + + System.out.println(res1); + System.out.println(res2); + System.out.println(res3); + } +} \ No newline at end of file diff --git a/src/main/java/com/leetcode/arrays/InsertInterval.java b/src/main/java/com/leetcode/arrays/InsertInterval.java index 519ea854..52155f19 100644 --- a/src/main/java/com/leetcode/arrays/InsertInterval.java +++ b/src/main/java/com/leetcode/arrays/InsertInterval.java @@ -19,7 +19,7 @@ * Output: [[1,2],[3,10],[12,16]] * Explanation: Because the new interval [4,8] overlaps with [3,5],[6,7],[8,10]. *

- * Companies: LinkedIn + * Companies: LinkedIn. * Related: {@link MergeIntervals}. * * @author rampatra diff --git a/src/main/java/com/leetcode/dynamicprogramming/PaintHouse.java b/src/main/java/com/leetcode/dynamicprogramming/PaintHouse.java new file mode 100644 index 00000000..ae5db698 --- /dev/null +++ b/src/main/java/com/leetcode/dynamicprogramming/PaintHouse.java @@ -0,0 +1,50 @@ +package com.leetcode.dynamicprogramming; + +/** + * Level: Easy + * Problem Link: https://leetcode.com/problems/paint-house/ (premium) + * Problem Description: + * There are a row of n houses, each house can be painted with one of the three colors: red, blue or green. The cost + * of painting each house with a certain color is different. You have to paint all the houses such that no two adjacent + * houses have the same color. The cost of painting each house with a certain color is represented by a n x 3 cost matrix. + *

+ * For example, costs[0][0] is the cost of painting house 0 with color red; costs[1][2] is the cost of painting + * house 1 with color green, and so on... Find the minimum cost to paint all houses. + *

+ * Companies: LinkedIn. + * Related: {@link PaintHouseII}. + * + * @author rampatra + * @since 2019-07-23 + */ +public class PaintHouse { + + /** + * @param costs of coloring the houses with red, blue, and green respectively. 1st row represents house 1, 2nd row + * house 2 and so on + * @return the minimum cost to paint all houses such that no two adjacent houses are of same color + */ + public static int minCost(int[][] costs) { + if (costs == null || costs.length == 0) return 0; + + for (int i = 1; i < costs.length; i++) { + costs[i][0] += Math.min(costs[i - 1][1], costs[i - 1][2]); + costs[i][1] += Math.min(costs[i - 1][0], costs[i - 1][2]); + costs[i][2] += Math.min(costs[i - 1][0], costs[i - 1][1]); + } + + int lastRow = costs.length - 1; + return Math.min(Math.min(costs[lastRow][0], costs[lastRow][1]), costs[lastRow][2]); + } + + public static void main(String[] args) { + System.out.println(minCost(new int[][]{ + })); + + System.out.println(minCost(new int[][]{ + {2, 3, 4}, + {5, 7, 6}, + {8, 7, 2} + })); + } +} \ No newline at end of file diff --git a/src/main/java/com/leetcode/dynamicprogramming/PaintHouseII.java b/src/main/java/com/leetcode/dynamicprogramming/PaintHouseII.java new file mode 100644 index 00000000..4c44e28d --- /dev/null +++ b/src/main/java/com/leetcode/dynamicprogramming/PaintHouseII.java @@ -0,0 +1,120 @@ +package com.leetcode.dynamicprogramming; + +import static org.junit.Assert.assertEquals; + +/** + * Level: Hard + * Problem Link: https://leetcode.com/problems/paint-house-ii/ (premium) + * Problem Description: + * There are a row of n houses, each house can be painted with one of the m colors. + * The cost of painting each house with a certain color is different. + * You have to paint all the houses such that no two adjacent houses have the same color. + *

+ * The cost of painting each house with a certain color is represented by a n x m cost matrix. + *

+ * For example, costs[0][0] is the cost of painting house 0 with color 0; + * costs[1][2] is the cost of painting house 1 with color 2, and so on... + * Find the minimum cost to paint all houses. + *

+ * Note: All costs are positive integers. + *

+ * Follow up: Could you solve it in O(n * m) runtime? // TODO + * + * Companies: LinkedIn. + * Related: {@link PaintHouse}. + * + * @author rampatra + * @since 2019-07-24 + */ +public class PaintHouseII { + + /** + * The approach is similar to {@link PaintHouse} but slightly complex as the number of colors are arbitrary + * instead of the 3 fixed colors. So, we use two additional for loops to cycle through all the colors. + * Time Complexity: O(n * m * m) + * Space Complexity: O(1) + * + * @param costs the costs of coloring the house, each row represents the cost of coloring a particular + * house with different colors + * @return the minimum cost to paint all houses such that no two adjacent houses are of same color + */ + public static int minCost(int[][] costs) { + if (costs == null || costs.length == 0) return 0; + + for (int i = 1; i < costs.length; i++) { + for (int j = 0; j < costs[0].length; j++) { + int min = Integer.MAX_VALUE; + // loop through all colors for the previous house except the color of the current house + for (int k = 0; k < costs[0].length; k++) { + if (k != j) { + min = Math.min(costs[i - 1][k], min); + } + } + costs[i][j] += min; + } + } + + int minCost = Integer.MAX_VALUE; + for (int i = 0; i < costs[0].length; i++) { + minCost = Math.min(costs[costs.length - 1][i], minCost); + } + + return minCost; + } + + public static void main(String[] args) { + assertEquals(0, minCost(new int[][]{})); + + assertEquals(10, minCost(new int[][]{ + {2, 3, 4}, + {5, 7, 6}, + {8, 7, 2} + })); + + assertEquals(10, minCost(new int[][]{{10, 30, 20}})); + + assertEquals(3, minCost(new int[][]{{1, 1, 1}, + {1, 1, 1}, + {1, 1, 1}})); + + assertEquals(5, minCost(new int[][]{{1, 2, 3}, + {3, 2, 1}, + {2, 2, 2}, + {3, 1, 2}})); + + assertEquals(10, minCost(new int[][]{{17, 2, 17}, + {16, 16, 5}, + {14, 3, 19}})); + + assertEquals(5, minCost(new int[][]{{1, 5, 3}, + {2, 9, 4}})); + + assertEquals(8, minCost(new int[][]{{8}})); + + assertEquals(143, minCost(new int[][]{{12, 1, 19}, + {15, 1, 10}, + {3, 11, 10}, + {9, 3, 10}, + {4, 8, 7}, + {4, 18, 2}, + {16, 6, 6}, + {3, 3, 6}, + {10, 18, 16}, + {5, 4, 8}, + {5, 3, 16}, + {11, 8, 19}, + {18, 15, 18}, + {16, 4, 15}, + {10, 7, 13}, + {11, 10, 14}, + {3, 9, 8}, + {5, 2, 2}, + {3, 2, 5}, + {2, 19, 14}, + {17, 3, 6}, + {6, 4, 17}, + {5, 15, 19}, + {2, 14, 14}, + {19, 4, 16}})); + } +} From ac90ee642b8f6186144cd3a737c87c6713a9b900 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Thu, 25 Jul 2019 22:21:12 +0100 Subject: [PATCH 111/164] can place flowers done --- .../com/leetcode/arrays/CanPlaceFlowers.java | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/main/java/com/leetcode/arrays/CanPlaceFlowers.java diff --git a/src/main/java/com/leetcode/arrays/CanPlaceFlowers.java b/src/main/java/com/leetcode/arrays/CanPlaceFlowers.java new file mode 100644 index 00000000..36e8a491 --- /dev/null +++ b/src/main/java/com/leetcode/arrays/CanPlaceFlowers.java @@ -0,0 +1,67 @@ +package com.leetcode.arrays; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * Level: Easy + * Problem Link: https://leetcode.com/problems/can-place-flowers/ + * Problem Description: + * Suppose you have a long flowerBed in which some of the plots are planted and some are not. However, flowers cannot + * be planted in adjacent plots - they would compete for water and both would die. + *

+ * Given a flowerBed (represented as an array containing 0 and 1, where 0 means empty and 1 means not empty), and a + * number n, return if n new flowers can be planted in it without violating the no-adjacent-flowers rule. + *

+ * Example 1: + * Input: flowerBed = [1,0,0,0,1], n = 1 + * Output: True + *

+ * Example 2: + * Input: flowerBed = [1,0,0,0,1], n = 2 + * Output: False + *

+ * Note: + * The input array won't violate no-adjacent-flowers rule. + * The input array size is in the range of [1, 20000]. + * n is a non-negative integer which won't exceed the input array size. + * + * @author rampatra + * @since 2019-07-24 + */ +public class CanPlaceFlowers { + + /** + * Time Complexity: O(n) + * Space Complexity: O(1) + * Runtime: 1 ms. + * + * @param flowerBed + * @param n + * @return + */ + public static boolean canPlaceFlowers(int[] flowerBed, int n) { + int i = 0, count = 0; + while (i < flowerBed.length) { + if (flowerBed[i] == 0 && (i == 0 || flowerBed[i - 1] == 0) && (i == flowerBed.length - 1 || flowerBed[i + 1] == 0)) { + flowerBed[i++] = 1; + count++; + } + if (count >= n) + return true; + i++; + } + return false; + } + + public static void main(String[] args) { + assertTrue(canPlaceFlowers(new int[]{0}, 0)); + assertTrue(canPlaceFlowers(new int[]{0}, 1)); + assertTrue(canPlaceFlowers(new int[]{1}, 0)); + assertFalse(canPlaceFlowers(new int[]{1}, 1)); + assertTrue(canPlaceFlowers(new int[]{1, 0, 0, 0, 1}, 1)); + assertFalse(canPlaceFlowers(new int[]{1, 0, 0, 0, 1}, 2)); + assertFalse(canPlaceFlowers(new int[]{1, 0, 0, 0, 0, 1}, 2)); + assertTrue(canPlaceFlowers(new int[]{1, 0, 0, 0, 1, 0, 0}, 2)); + } +} \ No newline at end of file From 511a132dfb41cf019326c0ac4a98ef04dee7f1ad Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Thu, 25 Jul 2019 23:32:16 +0100 Subject: [PATCH 112/164] Symmetric Tree Recursive solution done --- .../com/leetcode/trees/SymmetricTree.java | 77 +++++++++++++++++++ .../java/com/leetcode/trees/TreeNode.java | 16 ++++ 2 files changed, 93 insertions(+) create mode 100644 src/main/java/com/leetcode/trees/SymmetricTree.java create mode 100644 src/main/java/com/leetcode/trees/TreeNode.java diff --git a/src/main/java/com/leetcode/trees/SymmetricTree.java b/src/main/java/com/leetcode/trees/SymmetricTree.java new file mode 100644 index 00000000..bd536c9a --- /dev/null +++ b/src/main/java/com/leetcode/trees/SymmetricTree.java @@ -0,0 +1,77 @@ +package com.leetcode.trees; + +import static org.junit.Assert.assertTrue; + +/** + * Level: Easy + * Problem Link: https://leetcode.com/problems/symmetric-tree/ + * Problem Description: + * Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). + * + * For example, this binary tree [1,2,2,3,4,4,3] is symmetric: + * + * 1 + * / \ + * 2 2 + * / \ / \ + * 3 4 4 3 + * + * + * But the following [1,2,2,null,3,null,3] is not: + * + * 1 + * / \ + * 2 2 + * \ \ + * 3 3 + * + * + * Note: + * Bonus points if you could solve it both recursively and iteratively. + * + * @author rampatra + * @since 2019-07-25 + */ +public class SymmetricTree { + + /** + * Time Complexity: O(n) Because we traverse the entire input tree once, the total run time is O(n), where n is + * the total number of nodes in the tree. + * Space Complexity: O(n) The number of recursive calls is bound by the height of the tree. In the worst case, the + * tree is linear and the height is in O(n). Therefore, space complexity due to recursive calls on the stack is + * O(n) in the worst case. + * Runtime: 0 ms. + * + * @param root + * @return + */ + public static boolean isSymmetric(TreeNode root) { + if (root == null) { + return true; + } + + return isSymmetric(root.left, root.right); + } + + private static boolean isSymmetric(TreeNode leftRoot, TreeNode rightRoot) { + if (leftRoot == null && rightRoot == null) { + return true; + } else if (leftRoot == null || rightRoot == null) { + return false; + } + + return isSymmetric(leftRoot.left, rightRoot.right) && isSymmetric(leftRoot.right, rightRoot.left) && leftRoot.val == rightRoot.val; + } + + public static void main(String[] args) { + TreeNode root = new TreeNode(1); + root.left = new TreeNode(2); + root.right = new TreeNode(2); + root.left.left = new TreeNode(4); + root.left.right = new TreeNode(3); + root.right.left = new TreeNode(3); + root.right.right = new TreeNode(4); + + assertTrue(isSymmetric(root)); + } +} diff --git a/src/main/java/com/leetcode/trees/TreeNode.java b/src/main/java/com/leetcode/trees/TreeNode.java new file mode 100644 index 00000000..632e7c3e --- /dev/null +++ b/src/main/java/com/leetcode/trees/TreeNode.java @@ -0,0 +1,16 @@ +package com.leetcode.trees; + +/** + * @author rampatra + * @since 2019-07-25 + */ +public class TreeNode { + + int val; + TreeNode left; + TreeNode right; + + public TreeNode(int val) { + this.val = val; + } +} \ No newline at end of file From 5d759f8eb4700af9a1cf4a9734b2fc428717250a Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sat, 27 Jul 2019 15:31:30 +0100 Subject: [PATCH 113/164] Iterative approach done for Symmetric Tree --- .../com/leetcode/trees/SymmetricTree.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/main/java/com/leetcode/trees/SymmetricTree.java b/src/main/java/com/leetcode/trees/SymmetricTree.java index bd536c9a..bfd4c6ae 100644 --- a/src/main/java/com/leetcode/trees/SymmetricTree.java +++ b/src/main/java/com/leetcode/trees/SymmetricTree.java @@ -1,5 +1,8 @@ package com.leetcode.trees; +import java.util.LinkedList; +import java.util.Queue; + import static org.junit.Assert.assertTrue; /** @@ -63,6 +66,42 @@ private static boolean isSymmetric(TreeNode leftRoot, TreeNode rightRoot) { return isSymmetric(leftRoot.left, rightRoot.right) && isSymmetric(leftRoot.right, rightRoot.left) && leftRoot.val == rightRoot.val; } + /** + * Time Complexity: O(n) Because we traverse the entire input tree once, the total run time is O(n), where n is the + * total number of nodes in the tree. + * Space Complexity: There is additional space required for the search queue. In the worst case, we have to + * insert O(n) nodes in the queue. Therefore, space complexity is O(n). + * Runtime: 1 ms. + * + * @param root + * @return + */ + public static boolean isSymmetricIterative(TreeNode root) { + if (root == null || (root.left == null && root.right == null)) return true; + if (root.left == null || root.right == null) return false; + + Queue queue = new LinkedList<>(); + queue.add(root.left); + queue.add(root.right); + + while (!queue.isEmpty()) { + TreeNode t1 = queue.poll(); + TreeNode t2 = queue.poll(); + + if (t1 == null && t2 == null) continue; + if (t1 == null || t2 == null) return false; + if (t1.val != t2.val) return false; + + // enqueue left and then right child of t1 but do the opposite for t2 + queue.add(t1.left); + queue.add(t2.right); + queue.add(t1.right); + queue.add(t2.left); + } + + return true; + } + public static void main(String[] args) { TreeNode root = new TreeNode(1); root.left = new TreeNode(2); @@ -73,5 +112,6 @@ public static void main(String[] args) { root.right.right = new TreeNode(4); assertTrue(isSymmetric(root)); + assertTrue(isSymmetricIterative(root)); } } From b0c095942c0d6d5771ff2f636eaf92432499be80 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Tue, 30 Jul 2019 10:23:34 +0100 Subject: [PATCH 114/164] Updated Junit version --- pom.xml | 8 ++++---- .../java/com/leetcode/arrays/NestedListWeightSumI.java | 8 ++++++++ src/main/java/com/leetcode/maps/RepeatedDnaSequence.java | 8 ++++++++ .../java/com/leetcode/stacks/ReversePolishNotation.java | 8 ++++++++ 4 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/leetcode/arrays/NestedListWeightSumI.java create mode 100644 src/main/java/com/leetcode/maps/RepeatedDnaSequence.java create mode 100644 src/main/java/com/leetcode/stacks/ReversePolishNotation.java diff --git a/pom.xml b/pom.xml index 43d083ac..4db680c0 100644 --- a/pom.xml +++ b/pom.xml @@ -49,16 +49,16 @@ UTF-8 1.8 - 1.4.0.RELEASE ${java.version} ${java.version} + - junit - junit - 4.12 + org.junit.jupiter + junit-jupiter-api + 5.5.1 diff --git a/src/main/java/com/leetcode/arrays/NestedListWeightSumI.java b/src/main/java/com/leetcode/arrays/NestedListWeightSumI.java new file mode 100644 index 00000000..93451550 --- /dev/null +++ b/src/main/java/com/leetcode/arrays/NestedListWeightSumI.java @@ -0,0 +1,8 @@ +package com.leetcode.arrays; + +/** + * @author rampatra + * @since 2019-07-27 + */ +public class NestedListWeightSumI { +} diff --git a/src/main/java/com/leetcode/maps/RepeatedDnaSequence.java b/src/main/java/com/leetcode/maps/RepeatedDnaSequence.java new file mode 100644 index 00000000..6be6e256 --- /dev/null +++ b/src/main/java/com/leetcode/maps/RepeatedDnaSequence.java @@ -0,0 +1,8 @@ +package com.leetcode.maps; + +/** + * @author rampatra + * @since 2019-07-29 + */ +public class RepeatedDnaSequence { +} diff --git a/src/main/java/com/leetcode/stacks/ReversePolishNotation.java b/src/main/java/com/leetcode/stacks/ReversePolishNotation.java new file mode 100644 index 00000000..83a381a0 --- /dev/null +++ b/src/main/java/com/leetcode/stacks/ReversePolishNotation.java @@ -0,0 +1,8 @@ +package com.leetcode.stacks; + +/** + * @author rampatra + * @since 2019-07-27 + */ +public class ReversePolishNotation { +} From f836481b7edd5ff3c04570e6637ac89899c2fff9 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Tue, 30 Jul 2019 10:26:20 +0100 Subject: [PATCH 115/164] Updated JUnit version + Repeated DNA Sequence done --- .../com/leetcode/arrays/CanPlaceFlowers.java | 5 +- .../leetcode/arrays/NestedListWeightSumI.java | 8 ++ .../dynamicprogramming/PaintHouseII.java | 2 +- .../leetcode/maps/RepeatedDnaSequence.java | 63 +++++++++++++- .../stacks/ReversePolishNotation.java | 85 +++++++++++++++++++ .../com/leetcode/trees/SymmetricTree.java | 2 +- 6 files changed, 160 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/leetcode/arrays/CanPlaceFlowers.java b/src/main/java/com/leetcode/arrays/CanPlaceFlowers.java index 36e8a491..916499ac 100644 --- a/src/main/java/com/leetcode/arrays/CanPlaceFlowers.java +++ b/src/main/java/com/leetcode/arrays/CanPlaceFlowers.java @@ -1,7 +1,8 @@ package com.leetcode.arrays; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * Level: Easy diff --git a/src/main/java/com/leetcode/arrays/NestedListWeightSumI.java b/src/main/java/com/leetcode/arrays/NestedListWeightSumI.java index 93451550..1367ed16 100644 --- a/src/main/java/com/leetcode/arrays/NestedListWeightSumI.java +++ b/src/main/java/com/leetcode/arrays/NestedListWeightSumI.java @@ -5,4 +5,12 @@ * @since 2019-07-27 */ public class NestedListWeightSumI { + + public long nestedSum(Object[] nestedList, long sum, int depth) { + return -1; + } + + public static void main(String[] args) { + + } } diff --git a/src/main/java/com/leetcode/dynamicprogramming/PaintHouseII.java b/src/main/java/com/leetcode/dynamicprogramming/PaintHouseII.java index 4c44e28d..1c51ee68 100644 --- a/src/main/java/com/leetcode/dynamicprogramming/PaintHouseII.java +++ b/src/main/java/com/leetcode/dynamicprogramming/PaintHouseII.java @@ -1,6 +1,6 @@ package com.leetcode.dynamicprogramming; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; /** * Level: Hard diff --git a/src/main/java/com/leetcode/maps/RepeatedDnaSequence.java b/src/main/java/com/leetcode/maps/RepeatedDnaSequence.java index 6be6e256..28767ca4 100644 --- a/src/main/java/com/leetcode/maps/RepeatedDnaSequence.java +++ b/src/main/java/com/leetcode/maps/RepeatedDnaSequence.java @@ -1,8 +1,69 @@ package com.leetcode.maps; +import java.util.*; + +import static org.junit.jupiter.api.Assertions.assertEquals; + /** * @author rampatra * @since 2019-07-29 */ public class RepeatedDnaSequence { -} + + /** + * Rabin-Karp Algorithm: https://brilliant.org/wiki/rabin-karp-algorithm/ + * + * @param s + * @return + */ + public static List findRepeatedDnaSequences(String s) { + if (s.length() < 10) return new ArrayList<>(); + + Set repeatedSequences = new HashSet<>(); + Map> hashToStringMap = new HashMap<>(); + long hashOfSequence = computeHash(s); + hashToStringMap.put(hashOfSequence, new HashSet() {{ + add(s.substring(0, 10)); + }}); + + long pow = (long) Math.pow(4, 9); + + for (int i = 10; i < s.length(); i++) { + hashOfSequence = (hashOfSequence - (pow * (s.charAt(i - 10) - 'A'))) * 4 + (s.charAt(i) - 'A'); + String subString = s.substring(i - 10 + 1, i + 1); + + if (hashToStringMap.get(hashOfSequence) != null && hashToStringMap.get(hashOfSequence).contains(subString)) { + repeatedSequences.add(subString); + continue; + } + + hashToStringMap.putIfAbsent(hashOfSequence, new HashSet<>()); + hashToStringMap.get(hashOfSequence).add(subString); + } + + return new ArrayList<>(repeatedSequences); + } + + private static long computeHash(String s) { + long hash = 0; + for (int i = 0; i < 10; i++) { + hash += (Math.pow(4, i) * (s.charAt(9 - i) - 'A')); + } + return hash; + } + + public static void main(String[] args) { + + assertEquals(new ArrayList<>(), + findRepeatedDnaSequences("AAAAACCC")); + + assertEquals(Arrays.asList("AAAAACCCCC", "CCCCCAAAAA"), + findRepeatedDnaSequences("AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT")); + + assertEquals(Collections.singletonList("AAAAAAAAAA"), + findRepeatedDnaSequences("AAAAAAAAAAAA")); + + assertEquals(Collections.singletonList("BBBBBBBBBB"), + findRepeatedDnaSequences("BBBBBBBBBBBB")); + } +} \ No newline at end of file diff --git a/src/main/java/com/leetcode/stacks/ReversePolishNotation.java b/src/main/java/com/leetcode/stacks/ReversePolishNotation.java index 83a381a0..f917099a 100644 --- a/src/main/java/com/leetcode/stacks/ReversePolishNotation.java +++ b/src/main/java/com/leetcode/stacks/ReversePolishNotation.java @@ -1,8 +1,93 @@ package com.leetcode.stacks; +import java.util.Stack; + +import static org.junit.jupiter.api.Assertions.assertEquals; + /** + * Level: Medium + * Problem Link: https://leetcode.com/problems/evaluate-reverse-polish-notation + * Problem Description: + * 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 + * * @author rampatra * @since 2019-07-27 */ public class ReversePolishNotation { + + /** + * Time Complexity: + * Space Complexity: + * Runtime: 5 ms. + * + * @param tokens + * @return + */ + public static int evalRPN(String[] tokens) { + int operand1; + int operand2; + + Stack stack = new Stack<>(); + + for (String s : tokens) { + switch (s) { + case "+": + stack.push(stack.pop() + stack.pop()); + break; + case "-": + operand1 = stack.pop(); + operand2 = stack.pop(); + stack.push(operand2 - operand1); + break; + case "*": + stack.push(stack.pop() * stack.pop()); + break; + case "/": + operand1 = stack.pop(); + operand2 = stack.pop(); + stack.push(operand2 / operand1); + break; + default: + stack.push(Integer.parseInt(s)); + } + } + + return stack.pop(); + } + + public static void main(String[] args) { + assertEquals(18, evalRPN(new String[]{"18"})); + assertEquals(9, evalRPN(new String[]{"2", "1", "+", "3", "*"})); + assertEquals(6, evalRPN(new String[]{"4", "13", "5", "/", "+"})); + assertEquals(22, evalRPN(new String[]{"10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"})); + } } diff --git a/src/main/java/com/leetcode/trees/SymmetricTree.java b/src/main/java/com/leetcode/trees/SymmetricTree.java index bfd4c6ae..093d9a6f 100644 --- a/src/main/java/com/leetcode/trees/SymmetricTree.java +++ b/src/main/java/com/leetcode/trees/SymmetricTree.java @@ -3,7 +3,7 @@ import java.util.LinkedList; import java.util.Queue; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * Level: Easy From 9e3d03ce5e6d5b66989018d95a60dcbc65da615e Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Wed, 31 Jul 2019 21:47:07 +0100 Subject: [PATCH 116/164] Closest binary search tree value done --- .../com/leetcode/trees/ClosestBinarySearchTreeValueI.java | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValueI.java diff --git a/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValueI.java b/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValueI.java new file mode 100644 index 00000000..7bfb21c2 --- /dev/null +++ b/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValueI.java @@ -0,0 +1,8 @@ +package com.leetcode.trees; + +/** + * @author rampatra + * @since 2019-07-31 + */ +public class ClosestBinarySearchTreeValue { +} From 63a6b374b0fb66cfc9534b92148f0092eb932977 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Wed, 31 Jul 2019 21:47:48 +0100 Subject: [PATCH 117/164] Closest binary search tree value done --- .../leetcode/arrays/NestedListWeightSumI.java | 49 +++++++++++-- .../leetcode/maps/RepeatedDnaSequence.java | 22 +++++- .../trees/ClosestBinarySearchTreeValueI.java | 70 ++++++++++++++++++- 3 files changed, 135 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/leetcode/arrays/NestedListWeightSumI.java b/src/main/java/com/leetcode/arrays/NestedListWeightSumI.java index 1367ed16..5992920e 100644 --- a/src/main/java/com/leetcode/arrays/NestedListWeightSumI.java +++ b/src/main/java/com/leetcode/arrays/NestedListWeightSumI.java @@ -1,16 +1,57 @@ package com.leetcode.arrays; +import static org.junit.jupiter.api.Assertions.assertEquals; + /** + * Level: Easy + * Problem Link: https://leetcode.com/problems/nested-list-weight-sum/ (premium) + * Problem Description: + * Given a nested list of integers, return the sum of all integers in the list weighted by their depth. Each element + * is either an integer, or a list – whose elements may also be integers or other lists. + *

+ * Example 1: + * Given the list [[1,1],2,[1,1]], return 10. (four 1’s at depth 2, one 2 at depth 1) + *

+ * Example 2: + * Given the list [1,[4,[6]]], return 27. (one 1 at depth 1, one 4 at depth 2, and one 6 at depth 3; 1 + 42 + 63 = 27) + * + * Note: For a more complex variant, see {@link NestedListWeightSumII}. + * * @author rampatra * @since 2019-07-27 */ public class NestedListWeightSumI { - public long nestedSum(Object[] nestedList, long sum, int depth) { - return -1; + /** + * Time Complexity: The algorithm takes O(N) time, where N is the total number of nested elements in the input + * list. For example, the list [ [[[[1]]]], 2 ] contains 4 nested lists and 2 nested integers (11 and 22), so N=6. + * Space Complexity: In terms of space, at most O(D) recursive calls are placed on the stack, where D is the + * maximum level of nesting in the input. For example, D=2 for the input [[1,1],2,[1,1]], and D=3 for the + * input [1,[4,[6]]]. + * + * @param nestedList + * @return + */ + public static long nestedSum(Object[] nestedList) { + return nestedSum(nestedList, 1); } - public static void main(String[] args) { + private static long nestedSum(Object[] nestedList, int depth) { + long sum = 0; + for (int i = 0; i < nestedList.length; i++) { + if (nestedList[i] instanceof Integer) { + sum += ((int) nestedList[i] * depth); + } else { + sum += nestedSum((Object[]) nestedList[i], depth + 1); + } + } + return sum; + } + public static void main(String[] args) { + assertEquals(0, nestedSum(new Object[]{})); + assertEquals(0, nestedSum(new Object[]{new Object[]{}})); + assertEquals(10, nestedSum(new Object[]{new Object[]{1, 1}, 2, new Object[]{1, 1}})); + assertEquals(27, nestedSum(new Object[]{1, new Object[]{4, new Object[]{6}}})); } -} +} \ No newline at end of file diff --git a/src/main/java/com/leetcode/maps/RepeatedDnaSequence.java b/src/main/java/com/leetcode/maps/RepeatedDnaSequence.java index 28767ca4..a4eddb4a 100644 --- a/src/main/java/com/leetcode/maps/RepeatedDnaSequence.java +++ b/src/main/java/com/leetcode/maps/RepeatedDnaSequence.java @@ -5,6 +5,20 @@ import static org.junit.jupiter.api.Assertions.assertEquals; /** + * Level: Medium + * Problem Link: https://leetcode.com/problems/repeated-dna-sequences/submissions/ + * Problem Description: + * All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: "ACGAATTCCG". When + * studying DNA, it is sometimes useful to identify repeated sequences within the DNA. + * + * Write a function to find all the 10-letter-long sequences (substrings) that occur more than once in a DNA molecule. + * + * Example: + * Input: s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT" + * Output: ["AAAAACCCCC", "CCCCCAAAAA"] + * + * TODO: Figure another method which would have a better runtime. + * * @author rampatra * @since 2019-07-29 */ @@ -12,6 +26,13 @@ public class RepeatedDnaSequence { /** * Rabin-Karp Algorithm: https://brilliant.org/wiki/rabin-karp-algorithm/ + * Following Rabin-Karp's approach let's you avoid spurious hits (worst case scenario) but once the hash matches, + * you will have to compare and check the string you're searching. I tried to just rely on the hash and few test + * cases failed for me (https://leetcode.com/submissions/detail/247342702/). + *

+ * Time Complexity: + * Space Complexity: + * Runtime: 38 ms. * * @param s * @return @@ -53,7 +74,6 @@ private static long computeHash(String s) { } public static void main(String[] args) { - assertEquals(new ArrayList<>(), findRepeatedDnaSequences("AAAAACCC")); diff --git a/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValueI.java b/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValueI.java index 7bfb21c2..a7de4bf3 100644 --- a/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValueI.java +++ b/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValueI.java @@ -1,8 +1,76 @@ package com.leetcode.trees; +import static org.junit.jupiter.api.Assertions.assertEquals; + /** + * Level: Easy + * Problem Link: https://leetcode.com/problems/closest-binary-search-tree-value/ + * Problem Description: + * * @author rampatra * @since 2019-07-31 */ -public class ClosestBinarySearchTreeValue { +public class ClosestBinarySearchTreeValueI { + + public static TreeNode findNodeWithClosestValue(TreeNode node, TreeNode parentNode, int val, int diff) { + if (node == null) return parentNode; + + if (Math.abs(node.val - val) > diff) return parentNode; + + if (node.val > val) { + return findNodeWithClosestValue(node.left, node, val, Math.abs(node.val - val)); + } else { + return findNodeWithClosestValue(node.right, node, val, Math.abs(node.val - val)); + } + } + + public static void main(String[] args) { + + /* + BST looks like: + + 9 + / \ + 7 13 + / \ \ + 5 8 20 + / \ + 2 6 + */ + TreeNode root = new TreeNode(9); + root.left = new TreeNode(7); + root.right = new TreeNode(13); + root.left.left = new TreeNode(5); + root.left.right = new TreeNode(8); + root.left.left.left = new TreeNode(2); + root.left.left.right = new TreeNode(6); + root.right.right = new TreeNode(20); + + assertEquals(13, findNodeWithClosestValue(root, root, 15, Integer.MAX_VALUE).val); + assertEquals(13, findNodeWithClosestValue(root, root, 13, Integer.MAX_VALUE).val); + assertEquals(9, findNodeWithClosestValue(root, root, 9, Integer.MAX_VALUE).val); + assertEquals(2, findNodeWithClosestValue(root, root, 2, Integer.MAX_VALUE).val); + assertEquals(2, findNodeWithClosestValue(root, root, 1, Integer.MAX_VALUE).val); + assertEquals(6, findNodeWithClosestValue(root, root, 6, Integer.MAX_VALUE).val); + assertEquals(13, findNodeWithClosestValue(root, root, 11, Integer.MAX_VALUE).val); // tie b/w 9 and 13 + + /* + BST looks like: + + 9 + / \ + 7 13 + / \ / \ + 5 8 13 20 + */ + root = new TreeNode(9); + root.left = new TreeNode(7); + root.right = new TreeNode(13); + root.left.left = new TreeNode(5); + root.left.right = new TreeNode(8); + root.right.left = new TreeNode(13); + root.right.right = new TreeNode(20); + + assertEquals(13, findNodeWithClosestValue(root, root, 15, Integer.MAX_VALUE).val); + } } From 5e7a814a4ca7551798642a136937cfc695d62cb0 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Wed, 31 Jul 2019 22:27:35 +0100 Subject: [PATCH 118/164] Added some more comments and minor refactorings --- ...ightSumI.java => NestedListWeightSum.java} | 2 +- .../arrays/NestedListWeightSumII.java | 115 ++++++++++++++++++ .../leetcode/arrays/ShortestWordDistance.java | 64 ++++++++++ .../leetcode/maps/ShortestWordDistanceII.java | 34 ++++++ ...java => ClosestBinarySearchTreeValue.java} | 12 +- 5 files changed, 224 insertions(+), 3 deletions(-) rename src/main/java/com/leetcode/arrays/{NestedListWeightSumI.java => NestedListWeightSum.java} (98%) create mode 100644 src/main/java/com/leetcode/arrays/NestedListWeightSumII.java create mode 100644 src/main/java/com/leetcode/arrays/ShortestWordDistance.java create mode 100644 src/main/java/com/leetcode/maps/ShortestWordDistanceII.java rename src/main/java/com/leetcode/trees/{ClosestBinarySearchTreeValueI.java => ClosestBinarySearchTreeValue.java} (93%) diff --git a/src/main/java/com/leetcode/arrays/NestedListWeightSumI.java b/src/main/java/com/leetcode/arrays/NestedListWeightSum.java similarity index 98% rename from src/main/java/com/leetcode/arrays/NestedListWeightSumI.java rename to src/main/java/com/leetcode/arrays/NestedListWeightSum.java index 5992920e..b59a51ee 100644 --- a/src/main/java/com/leetcode/arrays/NestedListWeightSumI.java +++ b/src/main/java/com/leetcode/arrays/NestedListWeightSum.java @@ -20,7 +20,7 @@ * @author rampatra * @since 2019-07-27 */ -public class NestedListWeightSumI { +public class NestedListWeightSum { /** * Time Complexity: The algorithm takes O(N) time, where N is the total number of nested elements in the input diff --git a/src/main/java/com/leetcode/arrays/NestedListWeightSumII.java b/src/main/java/com/leetcode/arrays/NestedListWeightSumII.java new file mode 100644 index 00000000..85448337 --- /dev/null +++ b/src/main/java/com/leetcode/arrays/NestedListWeightSumII.java @@ -0,0 +1,115 @@ +package com.leetcode.arrays; + +import java.util.*; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Level: Medium + * Problem Link: https://leetcode.com/problems/nested-list-weight-sum-ii/ (premium) + * Problem Description: + * Given a nested list of integers, return the sum of all integers in the list weighted by their depth. Each element + * is either an integer, or a list – whose elements may also be integers or other lists. + *

+ * Different from {@link NestedListWeightSum} where weight is increasing from root to leaf, now the weight is defined + * from bottom up, i.e., the leaf level integers have weight 1, and the root level integers have the largest weight. + *

+ * Example 1: + * Given the list [[1,1],2,[1,1]], return 8. (four 1’s at depth 1, one 2 at depth 2) + *

+ * Example 2: + * Given the list [1,[4,[6]]], return 17. (one 1 at depth 3, one 4 at depth 2, and one 6 at depth 1; 13 + 42 + 6*1 = 17) + *

+ * Note: For a simpler variant, see {@link NestedListWeightSum}. + * + * @author rampatra + * @since 2019-07-27 + */ +public class NestedListWeightSumII { + + /** + * @param nestedList + * @return + */ + public static long nestedSum(List nestedList) { + long weightedSum = 0; + long unweightedSum = 0; + Queue queue = new LinkedList<>(); + + for (NestedInteger nestedInteger : nestedList) { + if (nestedInteger.isInteger()) { + unweightedSum += nestedInteger.getInteger(); + } else { + queue.addAll(nestedInteger.getList()); + while (!queue.isEmpty()) { + NestedInteger ni = queue.poll(); + if (ni.isInteger()) { + unweightedSum += ni.getInteger(); + } else { + nestedList.addAll(ni.getList()); + } + } + unweightedSum += unweightedSum; + weightedSum = unweightedSum; + } + } + + return weightedSum; + } + + public static void main(String[] args) { + assertEquals(0, nestedSum(Collections.singletonList(new NestedInteger()))); + + assertEquals(0, nestedSum(Collections.singletonList(new NestedInteger().add(new NestedInteger())))); + + NestedInteger ni = new NestedInteger(2); + ni.add(new NestedInteger().add(new NestedInteger(1)).add(new NestedInteger(1))); + ni.add(new NestedInteger().add(new NestedInteger(1)).add(new NestedInteger(1))); + + assertEquals(10, nestedSum(Collections.singletonList(ni))); + + ni = new NestedInteger(1); + ni.add(new NestedInteger(4).add(new NestedInteger(6))); + + assertEquals(27, nestedSum(Collections.singletonList(ni))); + + /*assertEquals(10, nestedSum(new Object[]{new Object[]{1, 1}, 2, new Object[]{1, 1}})); + assertEquals(27, nestedSum(new Object[]{1, new Object[]{4, new Object[]{6}}}));*/ + } +} + +class NestedInteger { + + private Integer integer; + private List list; + + public NestedInteger() { + this.list = new ArrayList<>(); + } + + public NestedInteger(int integer) { + this.integer = integer; + this.list = new ArrayList<>(); + } + + public boolean isInteger() { + return this.integer != null; + } + + public Integer getInteger() { + return integer; + } + + public void setInteger(Integer integer) { + this.integer = integer; + } + + public List getList() { + return list; + } + + public NestedInteger add(NestedInteger nestedInteger) { + this.list.add(nestedInteger); + return this; + } +} \ No newline at end of file diff --git a/src/main/java/com/leetcode/arrays/ShortestWordDistance.java b/src/main/java/com/leetcode/arrays/ShortestWordDistance.java new file mode 100644 index 00000000..44e90d1a --- /dev/null +++ b/src/main/java/com/leetcode/arrays/ShortestWordDistance.java @@ -0,0 +1,64 @@ +package com.leetcode.arrays; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Level: Easy + * Problem Link: + * Problem Description: + * Given a list of words and two words word1 and word2, return the shortest distance between these two words in the + * list of words. + * + * Example 1: + * Assume that words = ["practice", "makes", "perfect", "coding", "makes"]. + * Given word1 = "coding", word2 = "practice", return 3. + * Given word1 = "makes", word2 = "coding", return 1. + * + * Note: You may assume that word1 does not equal to word2, and word1 and word2 are both in the list. + * + * Lastly, for a more complex variant, see {@link com.leetcode.maps.ShortestWordDistanceII}. + * + * @author rampatra + * @since 2019-07-31 + */ +public class ShortestWordDistance { + + /** + * Time Complexity: + * Space Complexity: + * TODO + * + * @param words + * @param word1 + * @param word2 + * @return + */ + public static int findShortestDistance(String[] words, String word1, String word2) { + int startWord1 = Integer.MIN_VALUE; + int startWord2 = Integer.MAX_VALUE; + int minDistance = Integer.MAX_VALUE; + + for (int i = 0; i < words.length; i++) { + if (words[i].equals(word1)) { + startWord1 = i; + } + if (words[i].equals(word2)) { + startWord2 = i; + } + minDistance = Math.min(minDistance, Math.abs(startWord1 - startWord2)); + } + + return minDistance; + } + + public static void main(String[] args) { + assertEquals(3, findShortestDistance(new String[]{"practice", "makes", "perfect", "coding", "makes"}, + "practice", "coding")); + assertEquals(1, findShortestDistance(new String[]{"practice", "makes", "perfect", "coding", "makes"}, + "makes", "coding")); + assertEquals(0, findShortestDistance(new String[]{"practice", "makes", "perfect", "coding", "makes"}, + "perfect", "perfect")); + assertEquals(0, findShortestDistance(new String[]{"practice", "makes", "perfect", "coding", "makes"}, + "makes", "makes")); + } +} diff --git a/src/main/java/com/leetcode/maps/ShortestWordDistanceII.java b/src/main/java/com/leetcode/maps/ShortestWordDistanceII.java new file mode 100644 index 00000000..6d5795c6 --- /dev/null +++ b/src/main/java/com/leetcode/maps/ShortestWordDistanceII.java @@ -0,0 +1,34 @@ +package com.leetcode.maps; + +/** + * Level: Medium + * Problem Link: https://leetcode.com/problems/shortest-word-distance-ii/ (premium) + * Problem Description: + * This is a follow up of Shortest Word Distance. The only difference is now you are given the list of words and + * your method will be called repeatedly many times with different parameters. How would you optimize it? + *

+ * Design a class which receives a list of words in the constructor, and implements a method that takes two words + * word1 and word2 and return the shortest distance between these two words in the list. + *

+ * Example 1: + * Assume that words = ["practice", "makes", "perfect", "coding", "makes"]. + * Given word1 = "coding”, word2 = "practice”, return 3. + * Given word1 = "makes", word2 = "coding", return 1. + *

+ * Note: You may assume that word1 does not equal to word2, and word1 and word2 are both in the list. + *

+ * Lastly, for a simpler variant, see {@link com.leetcode.arrays.ShortestWordDistance}. + * + * @author rampatra + * @since 2019-07-31 + */ +public class ShortestWordDistanceII { + + public static int findShortestDistance(String[] words, String word1, String word2) { + return -1; + } + + public static void main(String[] args) { + + } +} diff --git a/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValueI.java b/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValue.java similarity index 93% rename from src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValueI.java rename to src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValue.java index a7de4bf3..80367748 100644 --- a/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValueI.java +++ b/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValue.java @@ -4,14 +4,22 @@ /** * Level: Easy - * Problem Link: https://leetcode.com/problems/closest-binary-search-tree-value/ + * Problem Link: https://leetcode.com/problems/closest-binary-search-tree-value/ (premium) * Problem Description: * * @author rampatra * @since 2019-07-31 */ -public class ClosestBinarySearchTreeValueI { +public class ClosestBinarySearchTreeValue { + /** + * + * @param node + * @param parentNode + * @param val + * @param diff + * @return + */ public static TreeNode findNodeWithClosestValue(TreeNode node, TreeNode parentNode, int val, int diff) { if (node == null) return parentNode; From 40c3eb1b6adfc61e5db7107a675a5c711c9d86af Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Fri, 2 Aug 2019 10:56:20 +0100 Subject: [PATCH 119/164] Leaves of binary tree: done --- .../leetcode/trees/LeavesOfBinaryTree.java | 97 +++++++++++++++++++ .../java/com/leetcode/trees/TreeNode.java | 5 + 2 files changed, 102 insertions(+) create mode 100644 src/main/java/com/leetcode/trees/LeavesOfBinaryTree.java diff --git a/src/main/java/com/leetcode/trees/LeavesOfBinaryTree.java b/src/main/java/com/leetcode/trees/LeavesOfBinaryTree.java new file mode 100644 index 00000000..8dcd0c1f --- /dev/null +++ b/src/main/java/com/leetcode/trees/LeavesOfBinaryTree.java @@ -0,0 +1,97 @@ +package com.leetcode.trees; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Level: Medium + * Problem Link: https://leetcode.com/problems/find-leaves-of-binary-tree/ + * Problem Description: + * Given a binary tree, collect a tree's nodes as if you were doing this: Collect and remove all leaves, repeat + * until the tree is empty. + * + * Example: + * Input: [1,2,3,4,5] + * + * 1 + * / \ + * 2 3 + * / \ + * 4 5 + * + * Output: [[4,5,3],[2],[1]] + * + * Explanation: + * 1. Removing the leaves [4,5,3] would result in this tree: + * 1 + * / + * 2 + * + * 2. Now removing the leaf [2] would result in this tree: + * 1 + * + * 3. Now removing the leaf [1] would result in the empty tree: + * [] + * + * @author rampatra + * @since 2019-08-01 + */ +public class LeavesOfBinaryTree { + + /** + * THe idea is to perform a DFS and backtrack. While backtracking, check the height of the node and insert + * the node into the list indexed by their heights. + * Time Complexity: + * Space Complexity: + * Runtime: . + * + * @param root + * @return + */ + public static List> findLeavesOfBinaryTree(TreeNode root) { + List> levels = new ArrayList<>(); + findLeavesOfBinaryTree(root, levels); + return levels; + } + + private static int findLeavesOfBinaryTree(TreeNode root, List> levels) { + if (root == null) return -1; + + int leftHeight = findLeavesOfBinaryTree(root.left, levels); + int rightHeight = findLeavesOfBinaryTree(root.right, levels); + int height = Math.max(leftHeight, rightHeight) + 1; + + if (height >= levels.size()) { + levels.add(height, new ArrayList<>()); + } + levels.get(height).add(root); + + return height; + } + + public static void main(String[] args) { + /* + BST looks like: + + 4 + / \ + 1 7 + / \ \ + 3 8 20 + / \ + 2 6 + */ + TreeNode root = new TreeNode(4); + root.left = new TreeNode(1); + root.right = new TreeNode(7); + root.left.left = new TreeNode(3); + root.left.right = new TreeNode(8); + root.left.left.left = new TreeNode(2); + root.left.left.right = new TreeNode(6); + root.right.right = new TreeNode(20); + + assertEquals("[[2, 6, 8, 20], [3, 7], [1], [4]]", findLeavesOfBinaryTree(root).toString()); + } +} \ No newline at end of file diff --git a/src/main/java/com/leetcode/trees/TreeNode.java b/src/main/java/com/leetcode/trees/TreeNode.java index 632e7c3e..4c4c2569 100644 --- a/src/main/java/com/leetcode/trees/TreeNode.java +++ b/src/main/java/com/leetcode/trees/TreeNode.java @@ -13,4 +13,9 @@ public class TreeNode { public TreeNode(int val) { this.val = val; } + + @Override + public String toString() { + return val + ""; + } } \ No newline at end of file From 067c0af3c298e24a787d3fbd14b5903b59cee0b1 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Fri, 2 Aug 2019 14:37:17 +0100 Subject: [PATCH 120/164] shortest word distance 1,2,3 done --- .../leetcode/arrays/ShortestWordDistance.java | 18 +++-- .../arrays/ShortestWordDistanceIII.java | 80 +++++++++++++++++++ .../leetcode/maps/ShortestWordDistanceII.java | 74 ++++++++++++++--- .../trees/ClosestBinarySearchTreeValue.java | 6 +- 4 files changed, 158 insertions(+), 20 deletions(-) create mode 100644 src/main/java/com/leetcode/arrays/ShortestWordDistanceIII.java diff --git a/src/main/java/com/leetcode/arrays/ShortestWordDistance.java b/src/main/java/com/leetcode/arrays/ShortestWordDistance.java index 44e90d1a..fbe9706f 100644 --- a/src/main/java/com/leetcode/arrays/ShortestWordDistance.java +++ b/src/main/java/com/leetcode/arrays/ShortestWordDistance.java @@ -4,7 +4,7 @@ /** * Level: Easy - * Problem Link: + * Problem Link: https://leetcode.com/problems/shortest-word-distance/ * Problem Description: * Given a list of words and two words word1 and word2, return the shortest distance between these two words in the * list of words. @@ -34,18 +34,20 @@ public class ShortestWordDistance { * @return */ public static int findShortestDistance(String[] words, String word1, String word2) { - int startWord1 = Integer.MIN_VALUE; - int startWord2 = Integer.MAX_VALUE; + int indexWord1 = -1; + int indexWord2 = -1; int minDistance = Integer.MAX_VALUE; for (int i = 0; i < words.length; i++) { if (words[i].equals(word1)) { - startWord1 = i; + indexWord1 = i; } if (words[i].equals(word2)) { - startWord2 = i; + indexWord2 = i; + } + if (indexWord1 != -1 && indexWord2 != -1) { + minDistance = Math.min(minDistance, Math.abs(indexWord1 - indexWord2)); } - minDistance = Math.min(minDistance, Math.abs(startWord1 - startWord2)); } return minDistance; @@ -54,8 +56,12 @@ public static int findShortestDistance(String[] words, String word1, String word public static void main(String[] args) { assertEquals(3, findShortestDistance(new String[]{"practice", "makes", "perfect", "coding", "makes"}, "practice", "coding")); + assertEquals(3, findShortestDistance(new String[]{"practice", "makes", "perfect", "coding", "makes"}, + "coding", "practice")); assertEquals(1, findShortestDistance(new String[]{"practice", "makes", "perfect", "coding", "makes"}, "makes", "coding")); + assertEquals(1, findShortestDistance(new String[]{"practice", "makes", "perfect", "coding", "makes"}, + "makes", "perfect")); assertEquals(0, findShortestDistance(new String[]{"practice", "makes", "perfect", "coding", "makes"}, "perfect", "perfect")); assertEquals(0, findShortestDistance(new String[]{"practice", "makes", "perfect", "coding", "makes"}, diff --git a/src/main/java/com/leetcode/arrays/ShortestWordDistanceIII.java b/src/main/java/com/leetcode/arrays/ShortestWordDistanceIII.java new file mode 100644 index 00000000..0d404633 --- /dev/null +++ b/src/main/java/com/leetcode/arrays/ShortestWordDistanceIII.java @@ -0,0 +1,80 @@ +package com.leetcode.arrays; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Level: Easy + * Problem Link: https://leetcode.com/problems/shortest-word-distance-iii/ + * Problem Description: + * This is a follow-up problem of {@link ShortestWordDistance}. The only difference is that now word1 could be the + * same as word2. + *

+ * Given a list of words and two words word1 and word2, return the shortest distance between these two words in the list. + * word1 and word2 may be the same and they represent two individual words in the list. + *

+ * For example, + * Assume that words = ["practice", "makes", "perfect", "coding", "makes"]. + * Given word1 = “makes”, word2 = “coding”, return 1. + * Given word1 = "makes", word2 = "makes", return 3. + *

+ * Note: You may assume word1 and word2 are both in the list. If they are same then it's guaranteed that there are + * two occurrences of the same. + * + * @author rampatra + * @since 2019-07-31 + */ +public class ShortestWordDistanceIII { + + /** + * Time Complexity: + * Space Complexity: + * TODO + * + * @param words + * @param word1 + * @param word2 + * @return + */ + public static int findShortestDistance(String[] words, String word1, String word2) { + int indexWord1 = -1; + int indexWord2 = -1; + int minDistance = Integer.MAX_VALUE; + + for (int i = 0; i < words.length; i++) { + if (words[i].equals(word1)) { + // if both words are same and the first index is already set then do nothing + if (word1.equals(word2) && indexWord1 != -1) { + + } else { + indexWord1 = i; + } + } + if (words[i].equals(word2)) { + // if both words are same and i is same as first index then it implies its the + // first occurrence, skip and continue look for the second occurrence + if (word1.equals(word2) && i == indexWord1) { + continue; + } + indexWord2 = i; + } + if (indexWord1 != -1 && indexWord2 != -1) { + minDistance = Math.min(minDistance, Math.abs(indexWord1 - indexWord2)); + } + } + + return minDistance; + } + + public static void main(String[] args) { + assertEquals(3, findShortestDistance(new String[]{"practice", "makes", "perfect", "coding", "makes"}, + "makes", "makes")); + assertEquals(3, findShortestDistance(new String[]{"practice", "makes", "perfect", "coding", "makes"}, + "coding", "practice")); + assertEquals(3, findShortestDistance(new String[]{"practice", "makes", "perfect", "coding", "makes"}, + "practice", "coding")); + assertEquals(1, findShortestDistance(new String[]{"practice", "makes", "perfect", "coding", "makes"}, + "makes", "coding")); + assertEquals(1, findShortestDistance(new String[]{"practice", "makes", "perfect", "coding", "makes"}, + "makes", "perfect")); + } +} diff --git a/src/main/java/com/leetcode/maps/ShortestWordDistanceII.java b/src/main/java/com/leetcode/maps/ShortestWordDistanceII.java index 6d5795c6..aed19c01 100644 --- a/src/main/java/com/leetcode/maps/ShortestWordDistanceII.java +++ b/src/main/java/com/leetcode/maps/ShortestWordDistanceII.java @@ -1,34 +1,82 @@ package com.leetcode.maps; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; + /** * Level: Medium * Problem Link: https://leetcode.com/problems/shortest-word-distance-ii/ (premium) * Problem Description: - * This is a follow up of Shortest Word Distance. The only difference is now you are given the list of words and - * your method will be called repeatedly many times with different parameters. How would you optimize it? - *

* Design a class which receives a list of words in the constructor, and implements a method that takes two words - * word1 and word2 and return the shortest distance between these two words in the list. + * word1 and word2 and return the shortest distance between these two words in the list. Your method will be called + * repeatedly many times with different parameters. For a simpler variant, see {@link com.leetcode.arrays.ShortestWordDistance}. *

- * Example 1: + * Examples: * Assume that words = ["practice", "makes", "perfect", "coding", "makes"]. - * Given word1 = "coding”, word2 = "practice”, return 3. - * Given word1 = "makes", word2 = "coding", return 1. *

- * Note: You may assume that word1 does not equal to word2, and word1 and word2 are both in the list. + * Input1: word1 = “coding”, word2 = “practice” + * Output1: 3 + *

+ * Input2: word1 = "makes", word2 = "coding" + * Output2: 1 *

- * Lastly, for a simpler variant, see {@link com.leetcode.arrays.ShortestWordDistance}. + * Note: You may assume that word1 does not equal to word2, and word1 and word2 are both in the list. * * @author rampatra * @since 2019-07-31 */ public class ShortestWordDistanceII { - public static int findShortestDistance(String[] words, String word1, String word2) { - return -1; + private String[] words; + private Map> wordsToIndexesMap; + + ShortestWordDistanceII(String[] words) { + this.words = words; + this.wordsToIndexesMap = getWordsToIndexesMap(); } - public static void main(String[] args) { + public int findShortestDistance(String word1, String word2) { + return findShortestDistance(wordsToIndexesMap.get(word1), wordsToIndexesMap.get(word2)); + } + private int findShortestDistance(List indexes1, List indexes2) { + int minDistance = Integer.MAX_VALUE; + + for (int i = 0, j = 0; i < indexes1.size() && j < indexes2.size(); ) { + if (indexes1.get(i) <= indexes2.get(j)) { + minDistance = Math.min(minDistance, Math.abs(indexes1.get(i) - indexes2.get(j))); + i++; + } else if (indexes1.get(i) > indexes2.get(j)) { + minDistance = Math.min(minDistance, Math.abs(indexes1.get(i) - indexes2.get(j))); + j++; + } + } + + return minDistance; + } + + private Map> getWordsToIndexesMap() { + Map> wordsToIndexesMap = new HashMap<>(); + + for (int i = 0; i < words.length; i++) { + wordsToIndexesMap.putIfAbsent(words[i], new ArrayList<>()); + wordsToIndexesMap.get(words[i]).add(i); + } + return wordsToIndexesMap; + } + + public static void main(String[] args) { + ShortestWordDistanceII shortestWordDist = new ShortestWordDistanceII(new String[]{"practice", "makes", "perfect", "coding", "makes"}); + assertEquals(1, shortestWordDist.findShortestDistance("coding", "makes")); + assertEquals(1, shortestWordDist.findShortestDistance("perfect", "makes")); + assertEquals(1, shortestWordDist.findShortestDistance("practice", "makes")); + assertEquals(1, shortestWordDist.findShortestDistance("makes", "practice")); + assertEquals(3, shortestWordDist.findShortestDistance("coding", "practice")); + assertEquals(0, shortestWordDist.findShortestDistance("coding", "coding")); + assertEquals(0, shortestWordDist.findShortestDistance("makes", "makes")); } -} +} \ No newline at end of file diff --git a/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValue.java b/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValue.java index 80367748..db62d927 100644 --- a/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValue.java +++ b/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValue.java @@ -6,6 +6,11 @@ * Level: Easy * Problem Link: https://leetcode.com/problems/closest-binary-search-tree-value/ (premium) * Problem Description: + * Given a non-empty binary search tree and a target value, find the value in the BST that is closest to the target. + *

+ * Note: + * - Given target value is a floating point. + * - You are guaranteed to have only one unique value in the BST that is closest to the target. * * @author rampatra * @since 2019-07-31 @@ -13,7 +18,6 @@ public class ClosestBinarySearchTreeValue { /** - * * @param node * @param parentNode * @param val From 57caf4da0aa2a8cc15b13c194f3d7869cc3405ae Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sat, 3 Aug 2019 18:29:45 +0100 Subject: [PATCH 121/164] Added comments, runtime, etc. --- .../arrays/NestedListWeightSumII.java | 50 ++++---- .../leetcode/arrays/ShortestWordDistance.java | 5 +- .../dynamicprogramming/PaintHouse.java | 2 + .../leetcode/maps/ShortestWordDistanceII.java | 7 ++ .../trees/ClosestBinarySearchTreeValueII.java | 76 ++++++++++++ .../leetcode/trees/LeavesOfBinaryTree.java | 10 +- .../trees/SecondMinNodeInBinaryTree.java | 108 ++++++++++++++++++ 7 files changed, 226 insertions(+), 32 deletions(-) create mode 100644 src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValueII.java create mode 100644 src/main/java/com/leetcode/trees/SecondMinNodeInBinaryTree.java diff --git a/src/main/java/com/leetcode/arrays/NestedListWeightSumII.java b/src/main/java/com/leetcode/arrays/NestedListWeightSumII.java index 85448337..669bc734 100644 --- a/src/main/java/com/leetcode/arrays/NestedListWeightSumII.java +++ b/src/main/java/com/leetcode/arrays/NestedListWeightSumII.java @@ -28,30 +28,31 @@ public class NestedListWeightSumII { /** + * Time Complexity: + * Space Complexity: + * Runtime: 1 ms. + * * @param nestedList * @return */ - public static long nestedSum(List nestedList) { - long weightedSum = 0; - long unweightedSum = 0; - Queue queue = new LinkedList<>(); - - for (NestedInteger nestedInteger : nestedList) { - if (nestedInteger.isInteger()) { - unweightedSum += nestedInteger.getInteger(); - } else { - queue.addAll(nestedInteger.getList()); - while (!queue.isEmpty()) { - NestedInteger ni = queue.poll(); - if (ni.isInteger()) { - unweightedSum += ni.getInteger(); - } else { - nestedList.addAll(ni.getList()); - } + public static int nestedSum(List nestedList) { + int weightedSum = 0; + int unweightedSum = 0; + + while (!nestedList.isEmpty()) { + List nextLevel = new ArrayList<>(); + + for (NestedInteger ni : nestedList) { + if (ni.isInteger()) { + unweightedSum += ni.getInteger(); + } else { + nextLevel.addAll(ni.getList()); } - unweightedSum += unweightedSum; - weightedSum = unweightedSum; } + + unweightedSum += unweightedSum; // multiplication by repetitive addition + weightedSum = unweightedSum; + nestedList = nextLevel; } return weightedSum; @@ -62,19 +63,20 @@ public static void main(String[] args) { assertEquals(0, nestedSum(Collections.singletonList(new NestedInteger().add(new NestedInteger())))); + // TODO: fix the test cases + + // {2, {1,1}, {1,1}} NestedInteger ni = new NestedInteger(2); ni.add(new NestedInteger().add(new NestedInteger(1)).add(new NestedInteger(1))); ni.add(new NestedInteger().add(new NestedInteger(1)).add(new NestedInteger(1))); - assertEquals(10, nestedSum(Collections.singletonList(ni))); + assertEquals(6, nestedSum(Collections.singletonList(ni))); + // {1, {4, {6}}} ni = new NestedInteger(1); ni.add(new NestedInteger(4).add(new NestedInteger(6))); - assertEquals(27, nestedSum(Collections.singletonList(ni))); - - /*assertEquals(10, nestedSum(new Object[]{new Object[]{1, 1}, 2, new Object[]{1, 1}})); - assertEquals(27, nestedSum(new Object[]{1, new Object[]{4, new Object[]{6}}}));*/ + assertEquals(17, nestedSum(Collections.singletonList(ni))); } } diff --git a/src/main/java/com/leetcode/arrays/ShortestWordDistance.java b/src/main/java/com/leetcode/arrays/ShortestWordDistance.java index fbe9706f..50b198cd 100644 --- a/src/main/java/com/leetcode/arrays/ShortestWordDistance.java +++ b/src/main/java/com/leetcode/arrays/ShortestWordDistance.java @@ -26,7 +26,7 @@ public class ShortestWordDistance { /** * Time Complexity: * Space Complexity: - * TODO + * Runtime: 1 ms. * * @param words * @param word1 @@ -41,8 +41,7 @@ public static int findShortestDistance(String[] words, String word1, String word for (int i = 0; i < words.length; i++) { if (words[i].equals(word1)) { indexWord1 = i; - } - if (words[i].equals(word2)) { + } else if (words[i].equals(word2)) { indexWord2 = i; } if (indexWord1 != -1 && indexWord2 != -1) { diff --git a/src/main/java/com/leetcode/dynamicprogramming/PaintHouse.java b/src/main/java/com/leetcode/dynamicprogramming/PaintHouse.java index ae5db698..788ac5ee 100644 --- a/src/main/java/com/leetcode/dynamicprogramming/PaintHouse.java +++ b/src/main/java/com/leetcode/dynamicprogramming/PaintHouse.java @@ -20,6 +20,8 @@ public class PaintHouse { /** + * Runtime: 1 ms. + * * @param costs of coloring the houses with red, blue, and green respectively. 1st row represents house 1, 2nd row * house 2 and so on * @return the minimum cost to paint all houses such that no two adjacent houses are of same color diff --git a/src/main/java/com/leetcode/maps/ShortestWordDistanceII.java b/src/main/java/com/leetcode/maps/ShortestWordDistanceII.java index aed19c01..fe2e24c0 100644 --- a/src/main/java/com/leetcode/maps/ShortestWordDistanceII.java +++ b/src/main/java/com/leetcode/maps/ShortestWordDistanceII.java @@ -39,6 +39,13 @@ public class ShortestWordDistanceII { this.wordsToIndexesMap = getWordsToIndexesMap(); } + /** + * Runtime: 65 ms. + * + * @param word1 + * @param word2 + * @return + */ public int findShortestDistance(String word1, String word2) { return findShortestDistance(wordsToIndexesMap.get(word1), wordsToIndexesMap.get(word2)); } diff --git a/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValueII.java b/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValueII.java new file mode 100644 index 00000000..953caf89 --- /dev/null +++ b/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValueII.java @@ -0,0 +1,76 @@ +package com.leetcode.trees; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Level: Hard + * Problem Link: https://leetcode.com/problems/closest-binary-search-tree-value-ii/ (premium) + * Problem Description: + * + * + * @author rampatra + * @since 2019-07-31 + */ +public class ClosestBinarySearchTreeValueII { + + /** + * @param node + * @param parentNode + * @param val + * @param diff + * @return + */ + public static TreeNode findNodeWithClosestValue(TreeNode node, TreeNode parentNode, int val, int diff) { + return null; + } + + public static void main(String[] args) { + + /* + BST looks like: + + 9 + / \ + 7 13 + / \ \ + 5 8 20 + / \ + 2 6 + */ + TreeNode root = new TreeNode(9); + root.left = new TreeNode(7); + root.right = new TreeNode(13); + root.left.left = new TreeNode(5); + root.left.right = new TreeNode(8); + root.left.left.left = new TreeNode(2); + root.left.left.right = new TreeNode(6); + root.right.right = new TreeNode(20); + + assertEquals(13, findNodeWithClosestValue(root, root, 15, Integer.MAX_VALUE).val); + assertEquals(13, findNodeWithClosestValue(root, root, 13, Integer.MAX_VALUE).val); + assertEquals(9, findNodeWithClosestValue(root, root, 9, Integer.MAX_VALUE).val); + assertEquals(2, findNodeWithClosestValue(root, root, 2, Integer.MAX_VALUE).val); + assertEquals(2, findNodeWithClosestValue(root, root, 1, Integer.MAX_VALUE).val); + assertEquals(6, findNodeWithClosestValue(root, root, 6, Integer.MAX_VALUE).val); + assertEquals(13, findNodeWithClosestValue(root, root, 11, Integer.MAX_VALUE).val); // tie b/w 9 and 13 + + /* + BST looks like: + + 9 + / \ + 7 13 + / \ / \ + 5 8 13 20 + */ + root = new TreeNode(9); + root.left = new TreeNode(7); + root.right = new TreeNode(13); + root.left.left = new TreeNode(5); + root.left.right = new TreeNode(8); + root.right.left = new TreeNode(13); + root.right.right = new TreeNode(20); + + assertEquals(13, findNodeWithClosestValue(root, root, 15, Integer.MAX_VALUE).val); + } +} diff --git a/src/main/java/com/leetcode/trees/LeavesOfBinaryTree.java b/src/main/java/com/leetcode/trees/LeavesOfBinaryTree.java index 8dcd0c1f..6ca15e22 100644 --- a/src/main/java/com/leetcode/trees/LeavesOfBinaryTree.java +++ b/src/main/java/com/leetcode/trees/LeavesOfBinaryTree.java @@ -45,18 +45,18 @@ public class LeavesOfBinaryTree { * the node into the list indexed by their heights. * Time Complexity: * Space Complexity: - * Runtime: . + * Runtime: 1 ms. * * @param root * @return */ - public static List> findLeavesOfBinaryTree(TreeNode root) { - List> levels = new ArrayList<>(); + public static List> findLeavesOfBinaryTree(TreeNode root) { + List> levels = new ArrayList<>(); findLeavesOfBinaryTree(root, levels); return levels; } - private static int findLeavesOfBinaryTree(TreeNode root, List> levels) { + private static int findLeavesOfBinaryTree(TreeNode root, List> levels) { if (root == null) return -1; int leftHeight = findLeavesOfBinaryTree(root.left, levels); @@ -66,7 +66,7 @@ private static int findLeavesOfBinaryTree(TreeNode root, List> le if (height >= levels.size()) { levels.add(height, new ArrayList<>()); } - levels.get(height).add(root); + levels.get(height).add(root.val); return height; } diff --git a/src/main/java/com/leetcode/trees/SecondMinNodeInBinaryTree.java b/src/main/java/com/leetcode/trees/SecondMinNodeInBinaryTree.java new file mode 100644 index 00000000..a8cddf74 --- /dev/null +++ b/src/main/java/com/leetcode/trees/SecondMinNodeInBinaryTree.java @@ -0,0 +1,108 @@ +package com.leetcode.trees; + +import java.util.Stack; + +/** + * Level: Easy + * Problem Link: https://leetcode.com/problems/second-minimum-node-in-a-binary-tree/ + * Problem Description: + * Given a non-empty special binary tree consisting of nodes with the non-negative value, where each node in this + * tree has exactly two or zero sub-node. If the node has two sub-nodes, then this node's value is the smaller value + * among its two sub-nodes. More formally, the property root.val = min(root.left.val, root.right.val) always holds. + * + * Given such a binary tree, you need to output the second minimum value in the set made of all the nodes' value in + * the whole tree. + * + * If no such second minimum value exists, output -1 instead. + * + * Example 1: + * Input: + * 2 + * / \ + * 2 5 + * / \ + * 5 7 + * + * Output: 5 + * Explanation: The smallest value is 2, the second smallest value is 5. + * + * + * Example 2: + * Input: + * 2 + * / \ + * 2 2 + * + * Output: -1 + * Explanation: The smallest value is 2, but there isn't any second smallest value. + * + * @author rampatra + * @since 2019-08-03 + */ +public class SecondMinNodeInBinaryTree { + + /** + * Time Complexity: O(n) + * Space Complexity: O(n) + * Runtime: 1 ms. + * @param root + * @return + */ + public static int findSecondMinimumValueIterative(TreeNode root) { + if (root == null || (root.left == null && root.right == null)) return -1; + + int min = root.val; + long secondMin = Long.MAX_VALUE; + + Stack stack = new Stack<>(); + stack.push(root); + + while (!stack.empty()) { + TreeNode node = stack.pop(); + if (node == null) continue; + + if (node.val > min && node.val < secondMin) { + secondMin = node.val; + } + stack.push(node.left); + stack.push(node.right); + } + + return secondMin == Long.MAX_VALUE ? -1 : (int) secondMin; + } + + + /** + * Time Complexity: + * Space Complexity: + * Runtime: 0 ms. + * + * @param root + * @return + */ + public static int findSecondMinimumValue(TreeNode root) { + // passing a long as secondMin because TreeNode can have Integer.MAX_VALUE as its value + long ans = findSecondMinimumValue(root, root.val, Long.MAX_VALUE); + return ans == Long.MAX_VALUE ? -1 : (int) ans; + } + + private static long findSecondMinimumValue(TreeNode root, int min, long secondMin) { + if (root == null) return Long.MAX_VALUE; + + if (root.val > min && root.val < secondMin) { + return root.val; + } else { + return Math.min(findSecondMinimumValue(root.left, min, secondMin), + findSecondMinimumValue(root.right, min, secondMin)); + } + } + + public static void main(String[] args) { + System.out.println((int) 2147483647L); + System.out.println(Integer.MAX_VALUE); + // TODO: A function called buildTree which would take an array like [1,1,3,1,1,3,4,3,1,1,1,3,8,4,8,3,3,1,6,2,1] + // and return a Binary Tree + //assertEquals(2, findSecondMinimumValue(buildTree(new int[]{1,1,3,1,1,3,4,3,1,1,1,3,8,4,8,3,3,1,6,2,1}))); + //assertEquals(2147483647, findSecondMinimumValue(buildTree(new int[]{2,2,2147483647}))); + } +} From d7183ac81db5f31786f7e520a40fdda81f4e3d19 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sat, 3 Aug 2019 21:25:51 +0100 Subject: [PATCH 122/164] TwoSummIII done --- .../arrays/NestedListWeightSumII.java | 1 - .../java/com/leetcode/maps/TwoSumIII.java | 78 +++++++++++++++++++ 2 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/leetcode/maps/TwoSumIII.java diff --git a/src/main/java/com/leetcode/arrays/NestedListWeightSumII.java b/src/main/java/com/leetcode/arrays/NestedListWeightSumII.java index 669bc734..1cb40945 100644 --- a/src/main/java/com/leetcode/arrays/NestedListWeightSumII.java +++ b/src/main/java/com/leetcode/arrays/NestedListWeightSumII.java @@ -64,7 +64,6 @@ public static void main(String[] args) { assertEquals(0, nestedSum(Collections.singletonList(new NestedInteger().add(new NestedInteger())))); // TODO: fix the test cases - // {2, {1,1}, {1,1}} NestedInteger ni = new NestedInteger(2); ni.add(new NestedInteger().add(new NestedInteger(1)).add(new NestedInteger(1))); diff --git a/src/main/java/com/leetcode/maps/TwoSumIII.java b/src/main/java/com/leetcode/maps/TwoSumIII.java new file mode 100644 index 00000000..22f0748f --- /dev/null +++ b/src/main/java/com/leetcode/maps/TwoSumIII.java @@ -0,0 +1,78 @@ +package com.leetcode.maps; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Level: Easy + * Problem Link: https://leetcode.com/problems/two-sum-iii-data-structure-design/ + * Problem Description: + * Design and implement a TwoSum class. It should support the following operations: add and find. + *

+ * add - Add the number to an internal data structure. + * find - Find if there exists any pair of numbers which sum is equal to the value. + *

+ * Example 1: + * add(1); add(3); add(5); + * find(4) -> true + * find(7) -> false + *

+ * Example 2: + * add(3); add(1); add(2); + * find(3) -> true + * find(6) -> false + * + * @author rampatra + * @since 2019-08-03 + */ +public class TwoSumIII { + + Map numCount; + + /** + * Initialize your data structure here. + */ + public TwoSumIII() { + this.numCount = new HashMap<>(); + } + + /** + * Add the number to an internal data structure.. + */ + public void add(int number) { + if (numCount.containsKey(number)) { + numCount.put(number, 2); + } else { + numCount.put(number, 1); + } + } + + /** + * Find if there exists any pair of numbers which sum is equal to the value. + */ + public boolean find(int value) { + for (Map.Entry entry : numCount.entrySet()) { + int num1 = entry.getKey(); + int num2 = value - num1; + if ((num2 == num1 && entry.getValue() == 2) || (num1 != num2 && numCount.containsKey(num2))) { + return true; + } + } + return false; + } + + /** + * Runtime: 115 ms. + * + * @param args + */ + public static void main(String[] args) { + TwoSumIII twoSumIII = new TwoSumIII(); + twoSumIII.add(0); + twoSumIII.add(-1); + twoSumIII.add(1); + assertTrue(twoSumIII.find(0)); + } +} \ No newline at end of file From 1908338f1f4c219890b49d2cc22f0777c7a296cb Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sun, 4 Aug 2019 12:54:08 +0100 Subject: [PATCH 123/164] binary tree upside down: done --- .../leetcode/trees/BinaryTreeUpsideDown.java | 207 ++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100644 src/main/java/com/leetcode/trees/BinaryTreeUpsideDown.java diff --git a/src/main/java/com/leetcode/trees/BinaryTreeUpsideDown.java b/src/main/java/com/leetcode/trees/BinaryTreeUpsideDown.java new file mode 100644 index 00000000..aa43bf50 --- /dev/null +++ b/src/main/java/com/leetcode/trees/BinaryTreeUpsideDown.java @@ -0,0 +1,207 @@ +package com.leetcode.trees; + +import java.util.Stack; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +/** + * Level: Medium + * Problem Link: https://leetcode.com/problems/binary-tree-upside-down/ + * Problem Description: + * 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. + * + * Example: + * Input: [1,2,3,4,5] + * + * 1 + * / \ + * 2 3 + * / \ + * 4 5 + * + * Output: return the root of the binary tree [4,5,2,#,#,3,1] + * + * 4 + * / \ + * 5 2 + * / \ + * 3 1 + * + * Clarification: + * Confused what [4,5,2,#,#,3,1] means? Read more below on how binary tree is serialized on OJ. The serialization of + * a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below. + * + * Here's an example: + * + * 1 + * / \ + * 2 3 + * / + * 4 + * \ + * 5 + * + * The above binary tree is serialized as [1,2,3,#,#,4,#,#,5]. + * + * @author rampatra + * @since 2019-08-04 + */ +public class BinaryTreeUpsideDown { + + /** + * The solution is simple, every node (except the root) on the left of the tree would have its parent's right child + * as it's left child and parent as its right child. That's all you have to do to flip the tree upside down. + * + * Time Complexity: O(h) + * Space Complexity: O(h) + * where, + * h = height of the tree + * + * Runtime: 1 ms. + * + * @param root + * @return + */ + public static TreeNode upsideDownBinaryTreeUsingStack(TreeNode root) { + if (root == null) return null; + + TreeNode curr = root; + TreeNode currParent; + TreeNode newRoot = null; + + // using stack to keep track of the parent node + Stack stack = new Stack<>(); + + while (curr != null) { + stack.add(curr); + curr = curr.left; + } + + while (!stack.empty()) { + curr = stack.pop(); + currParent = stack.empty() ? null : stack.peek(); + + if (newRoot == null) newRoot = curr; + + if (currParent != null) { + curr.left = currParent.right; + curr.right = currParent; + } else { + curr.left = null; + curr.right = null; + } + } + + return newRoot; + } + + /** + * The solution is simple, every node (except the root) on the left of the tree would have its parent's right child + * as it's left child and parent as its right child. That's all you have to do to flip the tree upside down. + * + * Time Complexity: O(h) + * Space Complexity: O(h) + * where, + * h = height of the tree + * + * Runtime: 0 ms. + * + * @param node + * @return + */ + public static TreeNode upsideDownBinaryTree(TreeNode node) { + if (node == null || node.left == null) return node; + + // go to the last node on the extreme left branch + TreeNode newRoot = upsideDownBinaryTree(node.left); + + // do the node changes as you backtrack + node.left.left = node.right; + node.left.right = node; + + // clean up + node.left = null; + node.right = null; + + return newRoot; + } + + public static void main(String[] args) { + /* + Binary Tree + + 1 + / \ + 2 3 + / \ + 4 5 + */ + TreeNode tree = new TreeNode(1); + tree.left = new TreeNode(2); + tree.right = new TreeNode(3); + tree.left.left = new TreeNode(4); + tree.left.right = new TreeNode(5); + + /* + Upside Down Binary Tree + + 4 + / \ + 5 2 + / \ + 3 1 + */ + TreeNode upsideDownTree = upsideDownBinaryTreeUsingStack(tree); + assertEquals(4, upsideDownTree.val); + assertEquals(5, upsideDownTree.left.val); + assertEquals(2, upsideDownTree.right.val); + assertEquals(1, upsideDownTree.right.right.val); + assertEquals(3, upsideDownTree.right.left.val); + assertNull(upsideDownTree.right.right.left); + assertNull(upsideDownTree.right.right.right); + + + + /****************************** + * + * Test for the recursive method + * + ******************************/ + + /* + Binary Tree + + 1 + / \ + 2 3 + / \ + 4 5 + */ + tree = new TreeNode(1); + tree.left = new TreeNode(2); + tree.right = new TreeNode(3); + tree.left.left = new TreeNode(4); + tree.left.right = new TreeNode(5); + + /* + Upside Down Binary Tree + + 4 + / \ + 5 2 + / \ + 3 1 + */ + upsideDownTree = upsideDownBinaryTree(tree); + assertEquals(4, upsideDownTree.val); + assertEquals(5, upsideDownTree.left.val); + assertEquals(2, upsideDownTree.right.val); + assertEquals(1, upsideDownTree.right.right.val); + assertEquals(3, upsideDownTree.right.left.val); + assertNull(upsideDownTree.right.right.right); + assertNull(upsideDownTree.right.right.left); + } +} \ No newline at end of file From 2dd2b814d5389b800cd9b5e4d493fba2d324febf Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sun, 4 Aug 2019 12:55:41 +0100 Subject: [PATCH 124/164] minor refactorings --- src/main/java/com/leetcode/arrays/NestedListWeightSum.java | 2 +- src/main/java/com/leetcode/arrays/NestedListWeightSumII.java | 2 +- src/main/java/com/leetcode/dynamicprogramming/PaintHouse.java | 2 +- src/main/java/com/leetcode/dynamicprogramming/PaintHouseII.java | 2 +- src/main/java/com/leetcode/maps/ShortestWordDistanceII.java | 2 +- .../java/com/leetcode/trees/ClosestBinarySearchTreeValue.java | 2 +- .../java/com/leetcode/trees/ClosestBinarySearchTreeValueII.java | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/leetcode/arrays/NestedListWeightSum.java b/src/main/java/com/leetcode/arrays/NestedListWeightSum.java index b59a51ee..4886c445 100644 --- a/src/main/java/com/leetcode/arrays/NestedListWeightSum.java +++ b/src/main/java/com/leetcode/arrays/NestedListWeightSum.java @@ -4,7 +4,7 @@ /** * Level: Easy - * Problem Link: https://leetcode.com/problems/nested-list-weight-sum/ (premium) + * Problem Link: https://leetcode.com/problems/nested-list-weight-sum/ * Problem Description: * Given a nested list of integers, return the sum of all integers in the list weighted by their depth. Each element * is either an integer, or a list – whose elements may also be integers or other lists. diff --git a/src/main/java/com/leetcode/arrays/NestedListWeightSumII.java b/src/main/java/com/leetcode/arrays/NestedListWeightSumII.java index 1cb40945..379c8f5e 100644 --- a/src/main/java/com/leetcode/arrays/NestedListWeightSumII.java +++ b/src/main/java/com/leetcode/arrays/NestedListWeightSumII.java @@ -6,7 +6,7 @@ /** * Level: Medium - * Problem Link: https://leetcode.com/problems/nested-list-weight-sum-ii/ (premium) + * Problem Link: https://leetcode.com/problems/nested-list-weight-sum-ii/ * Problem Description: * Given a nested list of integers, return the sum of all integers in the list weighted by their depth. Each element * is either an integer, or a list – whose elements may also be integers or other lists. diff --git a/src/main/java/com/leetcode/dynamicprogramming/PaintHouse.java b/src/main/java/com/leetcode/dynamicprogramming/PaintHouse.java index 788ac5ee..5692b0d8 100644 --- a/src/main/java/com/leetcode/dynamicprogramming/PaintHouse.java +++ b/src/main/java/com/leetcode/dynamicprogramming/PaintHouse.java @@ -2,7 +2,7 @@ /** * Level: Easy - * Problem Link: https://leetcode.com/problems/paint-house/ (premium) + * Problem Link: https://leetcode.com/problems/paint-house/ * Problem Description: * There are a row of n houses, each house can be painted with one of the three colors: red, blue or green. The cost * of painting each house with a certain color is different. You have to paint all the houses such that no two adjacent diff --git a/src/main/java/com/leetcode/dynamicprogramming/PaintHouseII.java b/src/main/java/com/leetcode/dynamicprogramming/PaintHouseII.java index 1c51ee68..431ce612 100644 --- a/src/main/java/com/leetcode/dynamicprogramming/PaintHouseII.java +++ b/src/main/java/com/leetcode/dynamicprogramming/PaintHouseII.java @@ -4,7 +4,7 @@ /** * Level: Hard - * Problem Link: https://leetcode.com/problems/paint-house-ii/ (premium) + * Problem Link: https://leetcode.com/problems/paint-house-ii/ * Problem Description: * There are a row of n houses, each house can be painted with one of the m colors. * The cost of painting each house with a certain color is different. diff --git a/src/main/java/com/leetcode/maps/ShortestWordDistanceII.java b/src/main/java/com/leetcode/maps/ShortestWordDistanceII.java index fe2e24c0..ecb6c9b9 100644 --- a/src/main/java/com/leetcode/maps/ShortestWordDistanceII.java +++ b/src/main/java/com/leetcode/maps/ShortestWordDistanceII.java @@ -9,7 +9,7 @@ /** * Level: Medium - * Problem Link: https://leetcode.com/problems/shortest-word-distance-ii/ (premium) + * Problem Link: https://leetcode.com/problems/shortest-word-distance-ii/ * Problem Description: * Design a class which receives a list of words in the constructor, and implements a method that takes two words * word1 and word2 and return the shortest distance between these two words in the list. Your method will be called diff --git a/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValue.java b/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValue.java index db62d927..83b87a9f 100644 --- a/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValue.java +++ b/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValue.java @@ -4,7 +4,7 @@ /** * Level: Easy - * Problem Link: https://leetcode.com/problems/closest-binary-search-tree-value/ (premium) + * Problem Link: https://leetcode.com/problems/closest-binary-search-tree-value/ * Problem Description: * Given a non-empty binary search tree and a target value, find the value in the BST that is closest to the target. *

diff --git a/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValueII.java b/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValueII.java index 953caf89..4f5cbe71 100644 --- a/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValueII.java +++ b/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValueII.java @@ -4,7 +4,7 @@ /** * Level: Hard - * Problem Link: https://leetcode.com/problems/closest-binary-search-tree-value-ii/ (premium) + * Problem Link: https://leetcode.com/problems/closest-binary-search-tree-value-ii/ * Problem Description: * * From 7d9dec6de6a972ee6bb60b1e379772d167ecb1f0 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sun, 4 Aug 2019 15:17:51 +0100 Subject: [PATCH 125/164] closest bst value: done --- .../trees/ClosestBinarySearchTreeValue.java | 58 +++++++++++++------ 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValue.java b/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValue.java index 83b87a9f..ca6d94b7 100644 --- a/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValue.java +++ b/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValue.java @@ -18,21 +18,29 @@ public class ClosestBinarySearchTreeValue { /** - * @param node - * @param parentNode - * @param val - * @param diff + * Runtime: 0 ms. + * + * @param root + * @param target * @return */ - public static TreeNode findNodeWithClosestValue(TreeNode node, TreeNode parentNode, int val, int diff) { - if (node == null) return parentNode; + public static int closestValue(TreeNode root, double target) { + if (root == null) return -1; - if (Math.abs(node.val - val) > diff) return parentNode; + return closestValue(root, root, target); + } + + private static int closestValue(TreeNode node, TreeNode closestNode, double val) { + if (node == null) return closestNode.val; + + if (Math.abs(node.val - val) < Math.abs(closestNode.val - val)) { + closestNode = node; + } if (node.val > val) { - return findNodeWithClosestValue(node.left, node, val, Math.abs(node.val - val)); + return closestValue(node.left, closestNode, val); } else { - return findNodeWithClosestValue(node.right, node, val, Math.abs(node.val - val)); + return closestValue(node.right, closestNode, val); } } @@ -54,17 +62,17 @@ public static void main(String[] args) { root.right = new TreeNode(13); root.left.left = new TreeNode(5); root.left.right = new TreeNode(8); - root.left.left.left = new TreeNode(2); root.left.left.right = new TreeNode(6); + root.left.left.left = new TreeNode(2); root.right.right = new TreeNode(20); - assertEquals(13, findNodeWithClosestValue(root, root, 15, Integer.MAX_VALUE).val); - assertEquals(13, findNodeWithClosestValue(root, root, 13, Integer.MAX_VALUE).val); - assertEquals(9, findNodeWithClosestValue(root, root, 9, Integer.MAX_VALUE).val); - assertEquals(2, findNodeWithClosestValue(root, root, 2, Integer.MAX_VALUE).val); - assertEquals(2, findNodeWithClosestValue(root, root, 1, Integer.MAX_VALUE).val); - assertEquals(6, findNodeWithClosestValue(root, root, 6, Integer.MAX_VALUE).val); - assertEquals(13, findNodeWithClosestValue(root, root, 11, Integer.MAX_VALUE).val); // tie b/w 9 and 13 + assertEquals(13, closestValue(root, 15)); + assertEquals(13, closestValue(root, 13)); + assertEquals(9, closestValue(root, 9)); + assertEquals(2, closestValue(root, 2)); + assertEquals(2, closestValue(root, 1)); + assertEquals(6, closestValue(root, 6)); + assertEquals(13, closestValue(root, 11)); // tie b/w 9 and 13 /* BST looks like: @@ -83,6 +91,20 @@ public static void main(String[] args) { root.right.left = new TreeNode(13); root.right.right = new TreeNode(20); - assertEquals(13, findNodeWithClosestValue(root, root, 15, Integer.MAX_VALUE).val); + assertEquals(13, closestValue(root, 15)); + + /* + BST looks like: + + 1500000000 + / + / + / + 1400000000 + */ + root = new TreeNode(1500000000); + root.left = new TreeNode(1400000000); + + assertEquals(1400000000, closestValue(root, -1500000000.0)); } } From cad93221a015af5453aafe18c3ad374d0eba0ffb Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sun, 4 Aug 2019 21:49:16 +0100 Subject: [PATCH 126/164] hit counter done --- .../com/leetcode/design/DesignHitCounter.java | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 src/main/java/com/leetcode/design/DesignHitCounter.java diff --git a/src/main/java/com/leetcode/design/DesignHitCounter.java b/src/main/java/com/leetcode/design/DesignHitCounter.java new file mode 100644 index 00000000..62133196 --- /dev/null +++ b/src/main/java/com/leetcode/design/DesignHitCounter.java @@ -0,0 +1,117 @@ +package com.leetcode.design; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Level: Medium + * Problem Link: https://leetcode.com/problems/design-hit-counter/ + * Problem Description: + * Design a hit counter which counts the number of hits received in the past 5 minutes. + * + * Each function accepts a timestamp parameter (in seconds granularity) and you may assume that calls are being made + * to the system in chronological order (ie, the timestamp is monotonically increasing). You may assume that the + * earliest timestamp starts at 1. + * + * It is possible that several hits arrive roughly at the same time. + * + * Example: + * + * HitCounter counter = new HitCounter(); + * + * // hit at timestamp 1. + * counter.hit(1); + * + * // hit at timestamp 2. + * counter.hit(2); + * + * // hit at timestamp 3. + * counter.hit(3); + * + * // get hits at timestamp 4, should return 3. + * counter.getHits(4); + * + * // hit at timestamp 300. + * counter.hit(300); + * + * // get hits at timestamp 300, should return 4. + * counter.getHits(300); + * + * // get hits at timestamp 301, should return 3. + * counter.getHits(301); + * + * Follow up: + * What if the number of hits per second could be very large? Does your design scale? + * + * Runtime: 42 ms (better than ~98%). + * + * @author rampatra + * @since 2019-08-04 + */ +public class DesignHitCounter { + + private int[] timestamps; + private int[] hits; + + /** + * Initialize your data structure here. + */ + public DesignHitCounter() { + this.timestamps = new int[300]; + this.hits = new int[300]; + } + + /** + * Record a hit. + * + * @param timestamp - The current timestamp (in seconds granularity). + */ + public void hit(int timestamp) { + int bucket = timestamp % 300; + if (timestamps[bucket] == timestamp) { + hits[bucket]++; + } else { + timestamps[bucket] = timestamp; + hits[bucket] = 1; + } + } + + /** + * Return the number of hits in the past 5 minutes. + * + * @param timestamp - The current timestamp (in seconds granularity). + */ + public int getHits(int timestamp) { + int totalHits = 0; + for (int i = 0; i < 300; i++) { + if (timestamp - 300 < timestamps[i]) { + totalHits += hits[i]; + } + } + return totalHits; + } + + public static void main(String[] args) { + DesignHitCounter counter = new DesignHitCounter(); + + // hit at timestamp 1. + counter.hit(1); + + // hit at timestamp 2. + counter.hit(2); + + // hit at timestamp 3. + counter.hit(3); + + // get hits at timestamp 4, should return 3. + assertEquals(3, counter.getHits(4)); + + // hit at timestamp 300. + counter.hit(300); + + // get hits at timestamp 300, should return 4. + assertEquals(4, counter.getHits(300)); + + // get hits at timestamp 301, should return 3. + assertEquals(3, counter.getHits(301)); + } +} From c386fbe8fcd237b695e9734ba29b01cfebbbd299 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Mon, 5 Aug 2019 15:28:00 +0100 Subject: [PATCH 127/164] find celebrity: done --- .../com/leetcode/arrays/FindTheCelebrity.java | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 src/main/java/com/leetcode/arrays/FindTheCelebrity.java diff --git a/src/main/java/com/leetcode/arrays/FindTheCelebrity.java b/src/main/java/com/leetcode/arrays/FindTheCelebrity.java new file mode 100644 index 00000000..1b15d996 --- /dev/null +++ b/src/main/java/com/leetcode/arrays/FindTheCelebrity.java @@ -0,0 +1,105 @@ +package com.leetcode.arrays; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Level: Medium + * Problem Link: https://leetcode.com/problems/find-the-celebrity/ + * Problem Description: + * Suppose you are at a party with n people (labeled from 0 to n - 1) and among them, there may exist one celebrity. + * The definition of a celebrity is that all the other n - 1 people know him/her but he/she does not know any of them. + * + * Now you want to find out who the celebrity is or verify that there is not one. The only thing you are allowed to do + * is to ask questions like: "Hi, A. Do you know B?" to get information of whether A knows B. You need to find out the + * celebrity (or verify there is not one) by asking as few questions as possible (in the asymptotic sense). + * + * You are given a helper function bool knows(a, b) which tells you whether A knows B. Implement a + * function int findCelebrity(n). There will be exactly one celebrity if he/she is in the party. Return the celebrity's + * label if there is a celebrity in the party. If there is no celebrity, return -1. + * + * Example 1: + * + * Input: graph = [ + * [1,1,0], + * [0,1,0], + * [1,1,1] + * ] + * Output: 1 + * Explanation: There are three persons labeled with 0, 1 and 2. graph[i][j] = 1 means person i knows person j, otherwise + * graph[i][j] = 0 means person i does not know person j. The celebrity is the person labeled as 1 because both 0 and 2 + * know him but 1 does not know anybody. + * + * + * Example 2: + * + * Input: graph = [ + * [1,0,1], + * [1,1,0], + * [0,1,1] + * ] + * Output: -1 + * Explanation: There is no celebrity. + * + * + * Note: The directed graph is represented as an adjacency matrix, which is an n x n matrix where a[i][j] = 1 means + * person i knows person j while a[i][j] = 0 means the contrary. Remember that you won't have direct access to the + * adjacency matrix. + * + * @author rampatra + * @since 2019-08-04 + */ +public class FindTheCelebrity { + + private int[][] knowsMatrix; + + FindTheCelebrity(int[][] knowsMatrix) { + this.knowsMatrix = knowsMatrix; + } + + public boolean knows(int a, int b) { + return knowsMatrix[a][b] == 1; + } + + /** + * Time Complexity: O(n) + * Space Complexity: O(1) + * Runtime: 6 ms. + * + * @param n + * @return + */ + public int findCelebrity(int n) { + int celebrityIndex = 0; + + for (int i = 1; i < n; i++) { + // if a person doesn't know another person then he maybe a celebrity + if (!knows(i, celebrityIndex)) { + celebrityIndex = i; + } + } + + for (int i = 0; i < n; i++) { + // verify whether the celebrity only knows himself and all other people know the celebrity + if ((knows(celebrityIndex, i) && i != celebrityIndex) || !knows(i, celebrityIndex)) { + return -1; + } + } + + return celebrityIndex; + } + + public static void main(String[] args) { + FindTheCelebrity findTheCelebrity = new FindTheCelebrity(new int[][]{ + {1, 1, 0}, + {0, 1, 0}, + {1, 1, 1}}); + + assertEquals(1, findTheCelebrity.findCelebrity(3)); + + findTheCelebrity = new FindTheCelebrity(new int[][]{ + {1, 0}, + {0, 1}}); + + assertEquals(-1, findTheCelebrity.findCelebrity(2)); + } +} From 7b99ea49d1c8c4a2754fe0a7218af68641cfe48e Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Wed, 7 Aug 2019 10:19:18 +0100 Subject: [PATCH 128/164] Graph Valid Tree: done --- .../com/leetcode/graphs/GraphValidTree.java | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 src/main/java/com/leetcode/graphs/GraphValidTree.java diff --git a/src/main/java/com/leetcode/graphs/GraphValidTree.java b/src/main/java/com/leetcode/graphs/GraphValidTree.java new file mode 100644 index 00000000..15950143 --- /dev/null +++ b/src/main/java/com/leetcode/graphs/GraphValidTree.java @@ -0,0 +1,131 @@ +package com.leetcode.graphs; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Level: Medium + * Problem Link: https://leetcode.com/problems/graph-valid-tree/ + * Problem Description: + * Given n nodes labeled from 0 to n-1 and a list of undirected edges (each edge is a pair of nodes), write a function + * to check whether these edges make up a valid tree. + *

+ * Example 1: + * Input: n = 5, and edges = [[0,1], [0,2], [0,3], [1,4]] + * Output: true + *

+ * Example 2: + * Input: n = 5, and edges = [[0,1], [1,2], [2,3], [1,3], [1,4]] + * Output: false + *

+ * Note: you can assume that no duplicate edges will appear in edges. Since all edges are undirected, [0,1] is the + * same as [1,0] and thus will not appear together in edges. + * + * @author rampatra + * @since 2019-08-05 + */ +public class GraphValidTree { + + /** + * + * @param n + * @param edges + * @return + */ + public static boolean isValidTree(int n, int[][] edges) { + List> adjacencyList = new ArrayList<>(n); + + for (int i = 0; i < n; i++) { + adjacencyList.add(new ArrayList<>()); + } + + for (int i = 0; i < edges.length; i++) { + adjacencyList.get(edges[i][0]).add(edges[i][1]); + } + + boolean[] visited = new boolean[n]; + + if (hasCycle(adjacencyList, 0, -1, visited)) { + return false; + } + + for (int i = 0; i < n; i++) { + if (!visited[i]) { + return false; + } + } + + return true; + } + + private static boolean hasCycle(List> adjacencyList, int node1, int exclude, boolean[] visited) { + visited[node1] = true; + + for (int i = 0; i < adjacencyList.get(node1).size(); i++) { + int node2 = adjacencyList.get(node1).get(i); + + if ((visited[node2] && exclude != node2) || (!visited[node2] && hasCycle(adjacencyList, node2, node1, visited))) { + return true; + } + } + + return false; + } + + + /** + * Union-find algorithm: We keep all connected nodes in one set in the union operation and in find operation we + * check whether two nodes belong to the same set. If yes then there's a cycle and if not then no cycle. + * + * Good articles on union-find: + * - https://www.hackerearth.com/practice/notes/disjoint-set-union-union-find/ + * - https://www.youtube.com/watch?v=wU6udHRIkcc + * + * @param n + * @param edges + * @return + */ + public static boolean isValidTreeUsingUnionFind(int n, int[][] edges) { + int[] roots = new int[n]; + + for (int i = 0; i < n; i++) { + roots[i] = i; + } + + for (int i = 0; i < edges.length; i++) { + // find operation + if (roots[edges[i][0]] == roots[edges[i][1]]) { + return false; + } + // union operation + roots[edges[i][1]] = findRoot(roots, roots[edges[i][0]]); // note: we can optimize this even further by + // considering size of each side and then join the side with smaller size to the one with a larger size (weighted union). + // We can use another array called size to keep count of the size or we can use the same root array with + // negative values, i.e, negative resembles that the node is pointing to itself and the number will represent + // the size. For example, roots = [-2, -1, -1, 0] means that node 3 is pointing to node 0 and node 0 is pointing + // to itself and is has 2 nodes under it including itself. + } + + return edges.length == n - 1; + } + + private static int findRoot(int[] roots, int node) { + while (roots[node] != node) { + node = roots[node]; + } + return node; + } + + public static void main(String[] args) { + assertTrue(isValidTree(5, new int[][]{{0, 1}, {0, 2}, {0, 3}, {1, 4}})); + assertFalse(isValidTree(5, new int[][]{{0, 1}, {1, 2}, {2, 3}, {1, 3}, {1, 4}})); + assertFalse(isValidTree(3, new int[][]{{0, 1}, {1, 2}, {2, 0}})); + + assertTrue(isValidTreeUsingUnionFind(5, new int[][]{{0, 1}, {0, 2}, {0, 3}, {1, 4}})); + assertFalse(isValidTreeUsingUnionFind(5, new int[][]{{0, 1}, {1, 2}, {2, 3}, {1, 3}, {1, 4}})); + assertFalse(isValidTreeUsingUnionFind(3, new int[][]{{0, 1}, {1, 2}, {2, 0}})); + } +} \ No newline at end of file From 5d20974750f7df8fd41a7d7bc8e6c91ecf675d7f Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Wed, 7 Aug 2019 20:48:03 +0100 Subject: [PATCH 129/164] No of Islands done --- .../com/leetcode/arrays/NumberOfIslands.java | 107 ++++++++++++++++++ .../leetcode/arrays/ValidTriangleNumber.java | 47 ++++++++ 2 files changed, 154 insertions(+) create mode 100644 src/main/java/com/leetcode/arrays/NumberOfIslands.java create mode 100644 src/main/java/com/leetcode/arrays/ValidTriangleNumber.java diff --git a/src/main/java/com/leetcode/arrays/NumberOfIslands.java b/src/main/java/com/leetcode/arrays/NumberOfIslands.java new file mode 100644 index 00000000..04ac6831 --- /dev/null +++ b/src/main/java/com/leetcode/arrays/NumberOfIslands.java @@ -0,0 +1,107 @@ +package com.leetcode.arrays; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Level: Medium + * Link: https://leetcode.com/problems/number-of-islands/ + * Description: + * Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surrounded by water + * and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid + * are all surrounded by water. + *

+ * Example 1: + * Input: + * 11110 + * 11010 + * 11000 + * 00000 + * Output: 1 + *

+ * Example 2: + * Input: + * 11000 + * 11000 + * 00100 + * 00011 + * Output: 3 + * + * @author rampatra + * @since 2019-08-07 + */ +public class NumberOfIslands { + + /** + * The idea is simple and straightforward. Once we encounter land ('1' in grid) we drown the island or change the + * neighboring '1's to '0's. Therefore, the number of '1's we encounter, we can say that we have that many islands. + *

+ * Time Complexity: O(n) + * Space Complexity: O(n) + * Runtime: 1 ms. + * + * @param grid + * @return + */ + public static int numIslands(char[][] grid) { + int count = 0; + + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + if (grid[i][j] == '1') { + drownTheIsland(grid, i, j); + count++; + } + } + } + + return count; + } + + private static void drownTheIsland(char[][] grid, int i, int j) { + if (i < 0 || j < 0 || i >= grid.length || j >= grid[0].length || grid[i][j] == '0') { + return; + } + + grid[i][j] = '0'; + + drownTheIsland(grid, i, j + 1); + drownTheIsland(grid, i, j - 1); + drownTheIsland(grid, i + 1, j); + drownTheIsland(grid, i - 1, j); + } + + public static void main(String[] args) { + assertEquals(1, numIslands(new char[][]{ + {'1', '1', '1', '1', '0'}, + {'1', '1', '0', '1', '0'}, + {'1', '1', '0', '0', '0'}, + {'0', '0', '0', '0', '0'} + })); + + assertEquals(2, numIslands(new char[][]{ + {'1', '1', '1', '1', '0'}, + {'1', '1', '0', '1', '0'}, + {'1', '1', '0', '0', '0'}, + {'0', '0', '0', '1', '0'} + })); + + assertEquals(1, numIslands(new char[][]{ + {'1', '1', '1', '1', '1'}, + {'1', '1', '1', '1', '1'}, + {'1', '1', '1', '1', '1'}, + {'1', '1', '1', '1', '1'} + })); + + assertEquals(1, numIslands(new char[][]{ + {'1'} + })); + + assertEquals(0, numIslands(new char[][]{ + {'0'} + })); + + assertEquals(0, numIslands(new char[][]{ + {} + })); + } +} \ No newline at end of file diff --git a/src/main/java/com/leetcode/arrays/ValidTriangleNumber.java b/src/main/java/com/leetcode/arrays/ValidTriangleNumber.java new file mode 100644 index 00000000..bab45ded --- /dev/null +++ b/src/main/java/com/leetcode/arrays/ValidTriangleNumber.java @@ -0,0 +1,47 @@ +package com.leetcode.arrays; + +import java.util.Arrays; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Level: Medium + * Problem Link: https://leetcode.com/problems/valid-triangle-number/ + * Problem Description: + * Given an array consists of non-negative integers, your task is to count the number of triplets chosen from the array + * that can make triangles if we take them as side lengths of a triangle. + *

+ * Example 1: + * Input: [2,2,3,4] + * Output: 3 + * Explanation: + * Valid combinations are: + * 2,3,4 (using the first 2) + * 2,3,4 (using the second 2) + * 2,2,3 + *

+ * Note: + * The length of the given array won't exceed 1000. + * The integers in the given array are in the range of [0, 1000]. + * + * @author rampatra + * @since 2019-08-07 + */ +public class ValidTriangleNumber { + + public static int triangleNumber(int[] nums) { + int l = 0; + int r = nums.length - 1; + int noOfTriangles = 0; + + Arrays.sort(nums); + + // todo + + return noOfTriangles; + } + + public static void main(String[] args) { + assertEquals(3, triangleNumber(new int[]{2, 2, 3, 4})); + } +} From 613bc46a82485155b2d3ccf4e7ca46c8fd78d699 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Fri, 9 Aug 2019 16:01:48 +0100 Subject: [PATCH 130/164] valid triangle done best meeting point brute force approach done --- .../leetcode/arrays/ValidTriangleNumber.java | 84 ++++++++++- .../com/leetcode/math/BestMeetingPoint.java | 141 ++++++++++++++++++ 2 files changed, 218 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/leetcode/math/BestMeetingPoint.java diff --git a/src/main/java/com/leetcode/arrays/ValidTriangleNumber.java b/src/main/java/com/leetcode/arrays/ValidTriangleNumber.java index bab45ded..cdbfb0c5 100644 --- a/src/main/java/com/leetcode/arrays/ValidTriangleNumber.java +++ b/src/main/java/com/leetcode/arrays/ValidTriangleNumber.java @@ -21,27 +21,97 @@ * 2,2,3 *

* Note: - * The length of the given array won't exceed 1000. - * The integers in the given array are in the range of [0, 1000]. + * - The length of the given array won't exceed 1000. + * - The integers in the given array are in the range of [0, 1000]. + * - Triangle Property: Sum of any 2 sides must be greater than the 3rd side. * * @author rampatra * @since 2019-08-07 */ public class ValidTriangleNumber { - public static int triangleNumber(int[] nums) { - int l = 0; - int r = nums.length - 1; + /** + * Time complexity : O(n^2 log n). In worst case, the inner loop will take n log n (binary search applied n times). + * Space complexity : O(log n). Sorting takes O(log n) space. + * Runtime: 13 ms. + * + * @param nums + * @return + */ + public static int triangleNumberUsingBinarySearch(int[] nums) { int noOfTriangles = 0; Arrays.sort(nums); - // todo + for (int i = 0; i < nums.length - 2; i++) { + int k = i + 2; + for (int j = i + 1; j < nums.length - 1; j++) { + k = binarySearch(nums, k, nums.length - 1, nums[i] + nums[j]); + if (k - j - 1 > 0) { + noOfTriangles += k - j - 1; + } + } + } + + return noOfTriangles; + } + + private static int binarySearch(int[] nums, int low, int high, int num) { + while (low <= high) { + int mid = (low + high) / 2; + if (nums[mid] < num) { + low = mid + 1; + } else { + high = mid - 1; + } + } + + return low; + } + + /** + * The concept is simple. For each pair (i,j), find the value of k such that nums[i] + nums[j] > nums[k] (as per + * triangle property). Once we find k then we can form k- j - 1 triangles. + * + * Time Complexity: O(n^2) Loop of k and j will be executed O(n^2) times in total, because, we do + * not reinitialize the value of k for a new value of j chosen(for the same i). Thus, the complexity + * will be O(n^2 + n^2) = O(n^2). + * Space Complexity: O(log n). Sorting takes O(log n) space. + * Runtime: 5 ms. + * + * @param nums + * @return + */ + public static int triangleNumber(int[] nums) { + int noOfTriangles = 0; + Arrays.sort(nums); + + for (int i = 0; i < nums.length - 2; i++) { + int k = i + 2; + for (int j = i + 1; j < nums.length - 1; j++) { + while (k < nums.length && nums[i] + nums[j] > nums[k]) { + k++; + } + if (k - j - 1 > 0) { + noOfTriangles += k - j - 1; + } + } + } return noOfTriangles; } public static void main(String[] args) { + assertEquals(0, triangleNumberUsingBinarySearch(new int[]{})); + assertEquals(0, triangleNumberUsingBinarySearch(new int[]{1})); + assertEquals(3, triangleNumberUsingBinarySearch(new int[]{2, 2, 3, 4})); + assertEquals(0, triangleNumberUsingBinarySearch(new int[]{0, 1, 0, 1})); + assertEquals(7, triangleNumberUsingBinarySearch(new int[]{1, 2, 3, 4, 5, 6})); + + assertEquals(0, triangleNumber(new int[]{})); + assertEquals(0, triangleNumber(new int[]{1})); assertEquals(3, triangleNumber(new int[]{2, 2, 3, 4})); + assertEquals(0, triangleNumber(new int[]{0, 1, 0, 1})); + assertEquals(7, triangleNumber(new int[]{1, 2, 3, 4, 5, 6})); } -} +} \ No newline at end of file diff --git a/src/main/java/com/leetcode/math/BestMeetingPoint.java b/src/main/java/com/leetcode/math/BestMeetingPoint.java new file mode 100644 index 00000000..84d96fe9 --- /dev/null +++ b/src/main/java/com/leetcode/math/BestMeetingPoint.java @@ -0,0 +1,141 @@ +package com.leetcode.math; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Level: Hard + * Link: https://leetcode.com/problems/best-meeting-point/ + * Description: + * A group of two or more people wants to meet and minimize the total travel distance. You are given a 2D grid + * of values 0 or 1, where each 1 marks the home of someone in the group. The distance is calculated using + * Manhattan Distance, where distance(p1, p2) = |p2.x - p1.x| + |p2.y - p1.y|. + * + * Example: + * + * Input: + * + * 1 - 0 - 0 - 0 - 1 + * | | | | | + * 0 - 0 - 0 - 0 - 0 + * | | | | | + * 0 - 0 - 1 - 0 - 0 + * + * Output: 6 + * + * Explanation: Given three people living at (0,0), (0,4), and (2,2): + * The point (0,2) is an ideal meeting point, as the total travel distance + * of 2+2+2=6 is minimal. So, return 6. + * + * @author rampatra + * @since 2019-08-07 + */ +public class BestMeetingPoint { + + /** + * Time Complexity: O(k * i * j) + * Space Complexity: O(1) + * where, + * k = no of homes + * i = rows in grid + * j = columns in grid + * + * So, if i = j = k then you can see that it has a O(n^3) time complexity. + * + * @param grid + * @return + */ + public static int minTotalDistanceBrutForce(int[][] grid) { + int minDistance = Integer.MAX_VALUE; + List> homeCoordinates = new ArrayList<>(); + + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + if (grid[i][j] == 1) { + homeCoordinates.add(Arrays.asList(i, j)); + } + } + } + + for (int i = 0; i < grid.length; i++) { + for (int j = 0; j < grid[0].length; j++) { + int distance = 0; + for (int k = 0; k < homeCoordinates.size(); k++) { + distance += Math.abs(homeCoordinates.get(k).get(0) - i) + Math.abs(homeCoordinates.get(k).get(1) - j); + } + minDistance = Math.min(minDistance, distance); + } + } + + return minDistance; + } + + public static int minTotalDistance(int[][] grid) { + return -1; // todo + } + + public static void main(String[] args) { + assertEquals(6, minTotalDistanceBrutForce(new int[][]{ + {1,0,0,0,1}, + {0,0,0,0,0}, + {0,0,1,0,0} + })); + + assertEquals(4, minTotalDistanceBrutForce(new int[][]{ + {1,0,0,0,1}, + {0,0,0,0,0}, + {0,0,0,0,0} + })); + + assertEquals(1, minTotalDistanceBrutForce(new int[][]{ + {1,1,0,0,0}, + {0,0,0,0,0}, + {0,0,0,0,0} + })); + + assertEquals(0, minTotalDistanceBrutForce(new int[][]{ + {1,0,0,0,0}, + {0,0,0,0,0}, + {0,0,0,0,0} + })); + + assertEquals(0, minTotalDistanceBrutForce(new int[][]{ + {0,0,0,0,0}, + {0,0,0,0,0}, + {0,0,0,0,0} + })); + + assertEquals(6, minTotalDistance(new int[][]{ + {1,0,0,0,1}, + {0,0,0,0,0}, + {0,0,1,0,0} + })); + + assertEquals(4, minTotalDistance(new int[][]{ + {1,0,0,0,1}, + {0,0,0,0,0}, + {0,0,0,0,0} + })); + + assertEquals(1, minTotalDistance(new int[][]{ + {1,1,0,0,0}, + {0,0,0,0,0}, + {0,0,0,0,0} + })); + + assertEquals(0, minTotalDistance(new int[][]{ + {1,0,0,0,0}, + {0,0,0,0,0}, + {0,0,0,0,0} + })); + + assertEquals(0, minTotalDistance(new int[][]{ + {0,0,0,0,0}, + {0,0,0,0,0}, + {0,0,0,0,0} + })); + } +} \ No newline at end of file From a4817fe188f23bb17d90d97dc9571d421da289f4 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Fri, 9 Aug 2019 17:13:33 +0100 Subject: [PATCH 131/164] Sparse matrix multiplication done --- .../arrays/SparseMatrixMultiplication.java | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 src/main/java/com/leetcode/arrays/SparseMatrixMultiplication.java diff --git a/src/main/java/com/leetcode/arrays/SparseMatrixMultiplication.java b/src/main/java/com/leetcode/arrays/SparseMatrixMultiplication.java new file mode 100644 index 00000000..78c884e4 --- /dev/null +++ b/src/main/java/com/leetcode/arrays/SparseMatrixMultiplication.java @@ -0,0 +1,87 @@ +package com.leetcode.arrays; + +import java.util.Arrays; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Level: Medium + * Link: https://leetcode.com/problems/sparse-matrix-multiplication/ + * Description: + * Given two sparse matrices A and B, return the result of AB. + * + * You may assume that A's column number is equal to B's row number. + * + * Example: + * + * Input: + * + * A = [ + * [ 1, 0, 0], + * [-1, 0, 3] + * ] + * + * B = [ + * [ 7, 0, 0 ], + * [ 0, 0, 0 ], + * [ 0, 0, 1 ] + * ] + * + * Output: + * + * | 1 0 0 | | 7 0 0 | | 7 0 0 | + * AB = | -1 0 3 | x | 0 0 0 | = | -7 0 3 | + * | 0 0 1 | + * + * @author rampatra + * @since 2019-08-09 + */ +public class SparseMatrixMultiplication { + + /** + * Time Complexity: O(Arow * Acol * Bcol) + * Space Complexity: O(Arow * Bcol) + * + * @param A + * @param B + * @return + */ + public static int[][] multiply(int[][] A, int[][] B) { + int[][] AB = new int[A.length][B[0].length]; + + for (int Bcol = 0; Bcol < B[0].length; Bcol++) { + for (int Arow = 0; Arow < A.length; Arow++) { + int sum = 0; + for (int Acol = 0; Acol < A[0].length; Acol++) { + sum += A[Arow][Acol] * B[Acol][Bcol]; + } + AB[Arow][Bcol] = sum; + } + } + + return AB; + } + + public static void main(String[] args) { + assertEquals(Arrays.deepToString(new int[][]{ + {7, 0, 0}, + {-7, 0, 3} + }), Arrays.deepToString(multiply(new int[][]{ + {1, 0, 0}, + {-1, 0, 3} + }, new int[][]{ + {7, 0, 0}, + {0, 0, 0}, + {0, 0, 1} + }))); + + assertEquals(Arrays.deepToString(new int[][]{ + {0} + }), Arrays.deepToString(multiply(new int[][]{ + {0, 1} + }, new int[][]{ + {1}, + {0} + }))); + } +} \ No newline at end of file From 24fe94684aa4b5a9cbf646e7ada6c9d708218802 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Fri, 9 Aug 2019 20:48:52 +0100 Subject: [PATCH 132/164] LongestSubstringWithKDistinctCharacters done --- ...ngestSubstringWithKDistinctCharacters.java | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 src/main/java/com/leetcode/maps/slidingwindow/LongestSubstringWithKDistinctCharacters.java diff --git a/src/main/java/com/leetcode/maps/slidingwindow/LongestSubstringWithKDistinctCharacters.java b/src/main/java/com/leetcode/maps/slidingwindow/LongestSubstringWithKDistinctCharacters.java new file mode 100644 index 00000000..58863c3d --- /dev/null +++ b/src/main/java/com/leetcode/maps/slidingwindow/LongestSubstringWithKDistinctCharacters.java @@ -0,0 +1,80 @@ +package com.leetcode.maps.slidingwindow; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Level: Hard + * Link: https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/ + * Description: + * Given a string, find the length of the longest substring T that contains at most k distinct characters. + *

+ * Example 1: + * Input: s = "eceba", k = 2 + * Output: 3 + * Explanation: T is "ece" which its length is 3. + *

+ * Example 2: + * Input: s = "aa", k = 1 + * Output: 2 + * Explanation: T is "aa" which its length is 2. + * + * @author rampatra + * @since 2019-08-09 + */ +public class LongestSubstringWithKDistinctCharacters { + + /** + * Time Complexity: O(n) + * Space Complexity: O(k), as we keep at most k characters in the hash table + * + * @param str + * @param k + * @return + */ + public static int lengthOfLongestSubstringKDistinct(String str, int k) { + int length = 0; + Map letterCountInWindow = new HashMap<>(); + + int i = 0; // start of window + int j = i; // end of window + + while (j < str.length()) { + char ch = str.charAt(j); + + letterCountInWindow.putIfAbsent(ch, 0); + letterCountInWindow.put(ch, letterCountInWindow.get(ch) + 1); + + // when number of distinct characters in the window exceeds k: + // - update length + // - remove the first character in the window or reduce its count if the window had more than one of this character + // - lastly, move the window forward + if (letterCountInWindow.keySet().size() > k) { + char firstChar = str.charAt(i); + int firstCharCount = letterCountInWindow.get(firstChar); + if (firstCharCount > 1) { + letterCountInWindow.put(firstChar, firstCharCount - 1); + } else { + letterCountInWindow.remove(firstChar); + } + length = Math.max(length, j - i); + i++; + } + j++; + } + + return length == 0 ? j - i : length; + } + + public static void main(String[] args) { + assertEquals(3, lengthOfLongestSubstringKDistinct("eceba", 2)); + assertEquals(7, lengthOfLongestSubstringKDistinct("eceeeeeba", 2)); + assertEquals(2, lengthOfLongestSubstringKDistinct("abcdef", 2)); + assertEquals(1, lengthOfLongestSubstringKDistinct("a", 1)); + assertEquals(2, lengthOfLongestSubstringKDistinct("aa", 1)); + assertEquals(3, lengthOfLongestSubstringKDistinct("aaa", 1)); + assertEquals(0, lengthOfLongestSubstringKDistinct("aa", 0)); + } +} From 5fd40fc97f4ad1673924c87fe08bc47cd594c528 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Fri, 9 Aug 2019 20:51:20 +0100 Subject: [PATCH 133/164] Minor improvement --- .../slidingwindow/LongestSubstringWithKDistinctCharacters.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/leetcode/maps/slidingwindow/LongestSubstringWithKDistinctCharacters.java b/src/main/java/com/leetcode/maps/slidingwindow/LongestSubstringWithKDistinctCharacters.java index 58863c3d..21cfab23 100644 --- a/src/main/java/com/leetcode/maps/slidingwindow/LongestSubstringWithKDistinctCharacters.java +++ b/src/main/java/com/leetcode/maps/slidingwindow/LongestSubstringWithKDistinctCharacters.java @@ -44,8 +44,7 @@ public static int lengthOfLongestSubstringKDistinct(String str, int k) { while (j < str.length()) { char ch = str.charAt(j); - letterCountInWindow.putIfAbsent(ch, 0); - letterCountInWindow.put(ch, letterCountInWindow.get(ch) + 1); + letterCountInWindow.put(ch, letterCountInWindow.getOrDefault(ch, 0) + 1); // when number of distinct characters in the window exceeds k: // - update length From 813a3c51feb1933b6a14b7ec301f738568abc4bb Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sun, 11 Aug 2019 08:11:58 +0100 Subject: [PATCH 134/164] Insert Delete GetRandom O(1): done --- .../design/InsertDeleteGetRandom.java | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 src/main/java/com/leetcode/design/InsertDeleteGetRandom.java diff --git a/src/main/java/com/leetcode/design/InsertDeleteGetRandom.java b/src/main/java/com/leetcode/design/InsertDeleteGetRandom.java new file mode 100644 index 00000000..a6c2f376 --- /dev/null +++ b/src/main/java/com/leetcode/design/InsertDeleteGetRandom.java @@ -0,0 +1,106 @@ +package com.leetcode.design; + +import java.util.*; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Level: Medium + * Link: https://leetcode.com/problems/insert-delete-getrandom-o1/ + * Description: + * Design a data structure that supports all following operations in average O(1) time. + * + * insert(val): Inserts an item val to the set if not already present. + * remove(val): Removes an item val from the set if present. + * getRandom: Returns a random element from current set of elements. Each element must have the same probability of + * being returned. + * + * Example: + * + * // Init an empty set. + * RandomizedSet randomSet = new RandomizedSet(); + * + * // Inserts 1 to the set. Returns true as 1 was inserted successfully. + * randomSet.insert(1); + * + * // Returns false as 2 does not exist in the set. + * randomSet.remove(2); + * + * // Inserts 2 to the set, returns true. Set now contains [1,2]. + * randomSet.insert(2); + * + * // getRandom should return either 1 or 2 randomly. + * randomSet.getRandom(); + * + * // Removes 1 from the set, returns true. Set now contains [2]. + * randomSet.remove(1); + * + * // 2 was already in the set, so return false. + * randomSet.insert(2); + * + * // Since 2 is the only number in the set, getRandom always return 2. + * randomSet.getRandom(); + * + * Runtime: 8 ms. + * + * @param s + * @param t + * @return + */ + public static boolean isIsomorphic(String s, String t) { + + Map sToTCharMap = new HashMap<>(); + Map tToSCharMap = new HashMap<>(); + + for (int i = 0; i < s.length(); i++) { + char chFromS = s.charAt(i); + char chFromT = t.charAt(i); + if (sToTCharMap.get(chFromS) == null && tToSCharMap.get(chFromT) == null) { + sToTCharMap.put(chFromS, chFromT); + tToSCharMap.put(chFromT, chFromS); + } + Character mappedChFromSToT = sToTCharMap.get(chFromS); + if (mappedChFromSToT == null || mappedChFromSToT != chFromT) { + return false; + } + } + + return true; + } + + /** + * Time Complexity: + * Space Complexity: + * Runtime: 3 ms. + * + * @param s + * @param t + * @return + */ + public static boolean isIsomorphicWithoutMaps(String s, String t) { + int[] charMap = new int[512]; + for (int i = 0; i < s.length(); i++) { + char chFromS = s.charAt(i); + char chFromT = t.charAt(i); + if (charMap[chFromS] != charMap[chFromT + 256]) { + return false; + } + charMap[chFromS] = charMap[chFromT + 256] = i + 1; + } + + return true; + } + + public static void main(String[] args) { + assertTrue(isIsomorphic("egg", "add")); + assertFalse(isIsomorphic("foo", "bar")); + assertTrue(isIsomorphic("paper", "title")); + assertFalse(isIsomorphic("ab", "aa")); + + assertTrue(isIsomorphicWithoutMaps("egg", "add")); + assertFalse(isIsomorphicWithoutMaps("foo", "bar")); + assertTrue(isIsomorphicWithoutMaps("paper", "title")); + assertFalse(isIsomorphicWithoutMaps("ab", "aa")); + } +} From b449afdc5e42d5e99ac120e6a18940211cb81afb Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sun, 11 Aug 2019 22:27:16 +0100 Subject: [PATCH 136/164] zigzag traversal: done --- .../BinaryTreeZigZagLevelOrderTraversal.java | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 src/main/java/com/leetcode/trees/BinaryTreeZigZagLevelOrderTraversal.java diff --git a/src/main/java/com/leetcode/trees/BinaryTreeZigZagLevelOrderTraversal.java b/src/main/java/com/leetcode/trees/BinaryTreeZigZagLevelOrderTraversal.java new file mode 100644 index 00000000..1a54d952 --- /dev/null +++ b/src/main/java/com/leetcode/trees/BinaryTreeZigZagLevelOrderTraversal.java @@ -0,0 +1,100 @@ +package com.leetcode.trees; + +import java.util.*; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Level: Medium + * Link: https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/ + * Description: + * 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). + * + * For example: + * Given binary tree [3,9,20,null,null,15,7], + * 3 + * / \ + * 9 20 + * / \ + * 15 7 + * return its zigzag level order traversal as: + * [ + * [3], + * [20,9], + * [15,7] + * ] + * + * @author rampatra + * @since 2019-08-11 + */ +public class BinaryTreeZigZagLevelOrderTraversal { + + /** + * Time Complexity: + * Space Complexity: + * Runtime: 1 ms. + * + * @param root + * @return + */ + public static List> zigzagLevelOrder(TreeNode root) { + + int levelNo = 0; + LinkedList currLevel = new LinkedList<>(); + List> levelOrderTraversal = new LinkedList<>(); + + if (root == null) { + return levelOrderTraversal; + } + + Queue queue = new LinkedList<>(); + queue.add(root); + queue.add(null); + + while (!queue.isEmpty()) { + + TreeNode treeNode = queue.poll(); + + if (treeNode == null) { + levelOrderTraversal.add(currLevel); + currLevel = new LinkedList<>(); + levelNo++; + + if (queue.size() > 0) { + queue.add(null); + } + } else { + if (levelNo % 2 == 0) { + currLevel.add(treeNode.val); + } else { + currLevel.add(0, treeNode.val); + } + if (treeNode.left != null) queue.add(treeNode.left); + if (treeNode.right != null) queue.add(treeNode.right); + } + } + + return levelOrderTraversal; + } + + public static void main(String[] args) { + /* + Binary Tree + + 1 + / \ + 2 3 + / \ + 4 5 + */ + TreeNode tree = new TreeNode(1); + tree.left = new TreeNode(2); + tree.right = new TreeNode(3); + tree.left.left = new TreeNode(4); + tree.left.right = new TreeNode(5); + + assertEquals("[[1], [3, 2], [4, 5]]", zigzagLevelOrder(tree).toString()); + assertEquals("[]", zigzagLevelOrder(null).toString()); + } +} From 869bc3099f0e51705adec71e345e69cb6452d26f Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Mon, 12 Aug 2019 10:44:50 +0100 Subject: [PATCH 137/164] flatten nestlist + minor refactorings: done --- .../recursion/FlattenNestListIterator.java | 69 +++++++++++++++++++ .../com/leetcode/recursion/NestedInteger.java | 46 +++++++++++++ .../NestedListWeightSum.java | 2 +- .../NestedListWeightSumII.java | 38 +--------- 4 files changed, 117 insertions(+), 38 deletions(-) create mode 100644 src/main/java/com/leetcode/recursion/FlattenNestListIterator.java create mode 100644 src/main/java/com/leetcode/recursion/NestedInteger.java rename src/main/java/com/leetcode/{arrays => recursion}/NestedListWeightSum.java (98%) rename src/main/java/com/leetcode/{arrays => recursion}/NestedListWeightSumII.java (78%) diff --git a/src/main/java/com/leetcode/recursion/FlattenNestListIterator.java b/src/main/java/com/leetcode/recursion/FlattenNestListIterator.java new file mode 100644 index 00000000..b443e954 --- /dev/null +++ b/src/main/java/com/leetcode/recursion/FlattenNestListIterator.java @@ -0,0 +1,69 @@ +package com.leetcode.recursion; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Level: Medium + * Link: https://leetcode.com/problems/flatten-nested-list-iterator/ + * Description: + * Given a nested list of integers, implement an iterator to flatten it. + * + * Each element is either an integer, or a list -- whose elements may also be integers or other lists. + * + * Example 1: + * Input: [[1,1],2,[1,1]] + * Output: [1,1,2,1,1] + * Explanation: By calling next repeatedly until hasNext returns false, + * the order of elements returned by next should be: [1,1,2,1,1]. + * + * Example 2: + * Input: [1,[4,[6]]] + * Output: [1,4,6] + * Explanation: By calling next repeatedly until hasNext returns false, + * the order of elements returned by next should be: [1,4,6]. + * + * Runtime: 2 ms. + * + * @author rampatra + * @since 2019-08-12 + */ +public class FlattenNestListIterator implements Iterator { + + private int index; + private List flattenedList; + + public FlattenNestListIterator(List nestedList) { + index = 0; + flattenedList = getFlattenedList(nestedList); + } + + private List getFlattenedList(List nestedList) { + List flattenedList = new ArrayList<>(); + + for (NestedInteger nestedInteger : nestedList) { + if (nestedInteger.isInteger()) { + flattenedList.add(nestedInteger.getInteger()); + } else { + flattenedList.addAll(getFlattenedList(nestedInteger.getList())); + } + } + + return flattenedList; + } + + @Override + public Integer next() { + return flattenedList.get(index++); + } + + @Override + public boolean hasNext() { + return index < flattenedList.size(); + } + + public static void main(String[] args) { + // TODO add some test cases + } +} \ No newline at end of file diff --git a/src/main/java/com/leetcode/recursion/NestedInteger.java b/src/main/java/com/leetcode/recursion/NestedInteger.java new file mode 100644 index 00000000..1bba817e --- /dev/null +++ b/src/main/java/com/leetcode/recursion/NestedInteger.java @@ -0,0 +1,46 @@ +package com.leetcode.recursion; + +import java.util.ArrayList; +import java.util.List; + +/** + * Class needed for various problems like {@link NestedListWeightSumII}, {@link FlattenNestListIterator}, etc. + * + * @author rampatra + * @since 2019-08-12 + */ +public class NestedInteger { + + private Integer integer; + private List list; + + public NestedInteger() { + this.list = new ArrayList<>(); + } + + public NestedInteger(int integer) { + this.integer = integer; + this.list = new ArrayList<>(); + } + + public boolean isInteger() { + return this.integer != null; + } + + public Integer getInteger() { + return integer; + } + + public void setInteger(Integer integer) { + this.integer = integer; + } + + public List getList() { + return list; + } + + public NestedInteger add(NestedInteger nestedInteger) { + this.list.add(nestedInteger); + return this; + } +} diff --git a/src/main/java/com/leetcode/arrays/NestedListWeightSum.java b/src/main/java/com/leetcode/recursion/NestedListWeightSum.java similarity index 98% rename from src/main/java/com/leetcode/arrays/NestedListWeightSum.java rename to src/main/java/com/leetcode/recursion/NestedListWeightSum.java index 4886c445..1079b29f 100644 --- a/src/main/java/com/leetcode/arrays/NestedListWeightSum.java +++ b/src/main/java/com/leetcode/recursion/NestedListWeightSum.java @@ -1,4 +1,4 @@ -package com.leetcode.arrays; +package com.leetcode.recursion; import static org.junit.jupiter.api.Assertions.assertEquals; diff --git a/src/main/java/com/leetcode/arrays/NestedListWeightSumII.java b/src/main/java/com/leetcode/recursion/NestedListWeightSumII.java similarity index 78% rename from src/main/java/com/leetcode/arrays/NestedListWeightSumII.java rename to src/main/java/com/leetcode/recursion/NestedListWeightSumII.java index 379c8f5e..eadd121b 100644 --- a/src/main/java/com/leetcode/arrays/NestedListWeightSumII.java +++ b/src/main/java/com/leetcode/recursion/NestedListWeightSumII.java @@ -1,4 +1,4 @@ -package com.leetcode.arrays; +package com.leetcode.recursion; import java.util.*; @@ -77,40 +77,4 @@ public static void main(String[] args) { assertEquals(17, nestedSum(Collections.singletonList(ni))); } -} - -class NestedInteger { - - private Integer integer; - private List list; - - public NestedInteger() { - this.list = new ArrayList<>(); - } - - public NestedInteger(int integer) { - this.integer = integer; - this.list = new ArrayList<>(); - } - - public boolean isInteger() { - return this.integer != null; - } - - public Integer getInteger() { - return integer; - } - - public void setInteger(Integer integer) { - this.integer = integer; - } - - public List getList() { - return list; - } - - public NestedInteger add(NestedInteger nestedInteger) { - this.list.add(nestedInteger); - return this; - } } \ No newline at end of file From 1eafcd907aeb420010ba5aea26105a319081e4ca Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Mon, 12 Aug 2019 21:45:52 +0100 Subject: [PATCH 138/164] ClosestBinarySearchTreeValue II: done --- .../trees/ClosestBinarySearchTreeValueII.java | 120 +++++++++++++++--- 1 file changed, 105 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValueII.java b/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValueII.java index 4f5cbe71..e583723a 100644 --- a/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValueII.java +++ b/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValueII.java @@ -1,27 +1,121 @@ package com.leetcode.trees; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; +import java.util.Stack; + import static org.junit.jupiter.api.Assertions.assertEquals; /** * Level: Hard * Problem Link: https://leetcode.com/problems/closest-binary-search-tree-value-ii/ * Problem Description: + * Given a non-empty binary search tree and a target value, find k values in the BST that are closest to the target. + * + * Note: + * - Given target value is a floating point. + * - You may assume k is always valid, that is: k ≤ total nodes. + * - You are guaranteed to have only one unique set of k values in the BST that are closest to the target. + * + * Example: + * Input: root = [4,2,5,1,3], target = 3.714286, and k = 2 * + * 4 + * / \ + * 2 5 + * / \ + * 1 3 + * + * Output: [4,3] + * + * Follow up: + * Assume that the BST is balanced, could you solve it in less than O(n) runtime (where n = total nodes)? * * @author rampatra * @since 2019-07-31 */ public class ClosestBinarySearchTreeValueII { + + /** + * The idea is simple. We do the inorder traversal and keep the values less than or equal to target in a stack and + * the values greater than target in a queue. And finally, we compare values from both stack and queue and take + * whichever is the closest to target value each time. + * + * Note: We can optimize it even further in terms of space. We can get rid of the stack and queue and just fill up + * the result list in the recursive inOrder call. Once the result list is of size k, we can compare and remove the + * farthest value and insert the closer value. See {@link ClosestBinarySearchTreeValueII#closestKValuesOptimized(TreeNode, double, int)}. + * + * @param root + * @param target + * @param k + * @return + */ + public static List closestKValues(TreeNode root, double target, int k) { + int count = 0; + List closestKValues = new LinkedList<>(); + + Stack predecessors = new Stack<>(); + Queue successors = new LinkedList<>(); + inOrder(root, predecessors, successors, target, k); + + while (count < k) { + if (predecessors.empty()) { + closestKValues.add(successors.poll()); + } else if (successors.isEmpty()) { + closestKValues.add(predecessors.pop()); + } else if (Math.abs(target - predecessors.peek()) < Math.abs(target - successors.peek())) { + closestKValues.add(predecessors.pop()); + } else { + closestKValues.add(successors.poll()); + } + count++; + } + + return closestKValues; + } + + private static void inOrder(TreeNode root, Stack predecessors, Queue successors, double target, int k) { + if (root == null || successors.size() == k) return; + inOrder(root.left, predecessors, successors, target, k); + if (root.val <= target) { + predecessors.add(root.val); + } else { + successors.add(root.val); + } + inOrder(root.right, predecessors, successors, target, k); + } + + /** - * @param node - * @param parentNode - * @param val - * @param diff + * This approach is similar to the above one but it doesn't use stack or queue. + * + * @param root + * @param target + * @param k * @return */ - public static TreeNode findNodeWithClosestValue(TreeNode node, TreeNode parentNode, int val, int diff) { - return null; + public static List closestKValuesOptimized(TreeNode root, double target, int k) { + LinkedList closestKValues = new LinkedList<>(); + inOrder(root, target, k, closestKValues); + return closestKValues; + } + + private static void inOrder(TreeNode root, double target, int k, LinkedList closestKValues) { + if (root == null) return; + + inOrder(root.left, target, k, closestKValues); + if (closestKValues.size() == k) { + //if size k, add current and remove head if it's closer to target, otherwise return + if (Math.abs(target - root.val) < Math.abs(target - closestKValues.peekFirst())) + closestKValues.removeFirst(); + else { + return; + } + } + closestKValues.add(root.val); + inOrder(root.right, target, k, closestKValues); } public static void main(String[] args) { @@ -46,13 +140,8 @@ public static void main(String[] args) { root.left.left.right = new TreeNode(6); root.right.right = new TreeNode(20); - assertEquals(13, findNodeWithClosestValue(root, root, 15, Integer.MAX_VALUE).val); - assertEquals(13, findNodeWithClosestValue(root, root, 13, Integer.MAX_VALUE).val); - assertEquals(9, findNodeWithClosestValue(root, root, 9, Integer.MAX_VALUE).val); - assertEquals(2, findNodeWithClosestValue(root, root, 2, Integer.MAX_VALUE).val); - assertEquals(2, findNodeWithClosestValue(root, root, 1, Integer.MAX_VALUE).val); - assertEquals(6, findNodeWithClosestValue(root, root, 6, Integer.MAX_VALUE).val); - assertEquals(13, findNodeWithClosestValue(root, root, 11, Integer.MAX_VALUE).val); // tie b/w 9 and 13 + assertEquals("[9, 8, 7, 6, 5]", closestKValues(root, 8.5, 5).toString()); + assertEquals("[5, 6, 7, 8, 9]", closestKValuesOptimized(root, 8.5, 5).toString()); /* BST looks like: @@ -67,10 +156,11 @@ public static void main(String[] args) { root.left = new TreeNode(7); root.right = new TreeNode(13); root.left.left = new TreeNode(5); - root.left.right = new TreeNode(8); root.right.left = new TreeNode(13); + root.left.right = new TreeNode(8); root.right.right = new TreeNode(20); - assertEquals(13, findNodeWithClosestValue(root, root, 15, Integer.MAX_VALUE).val); + assertEquals("[13, 13, 9, 20, 8]", closestKValues(root, 14, 5).toString()); + assertEquals("[8, 9, 13, 13, 20]", closestKValuesOptimized(root, 14, 5).toString()); } } From 062d4fc8507839d1b98e34c64160e685f68bc8ee Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Thu, 15 Aug 2019 13:17:19 +0100 Subject: [PATCH 139/164] Sliding Window Problems: done --- .../leetcode/arrays/ShortestWordDistance.java | 4 +- .../IsomorphicStrings.java | 2 +- .../RepeatedDnaSequence.java | 2 +- .../ShortestWordDistanceII.java | 2 +- .../{maps => hashtables}/TwoSumIII.java | 2 +- ...ngestSubstringWithKDistinctCharacters.java | 23 ++-- ...stSubstringWithoutRepeatingCharacters.java | 128 ++++++++++++++++++ .../slidingwindow/MinimumWindowSubstring.java | 104 ++++++++++++++ 8 files changed, 252 insertions(+), 15 deletions(-) rename src/main/java/com/leetcode/{maps => hashtables}/IsomorphicStrings.java (98%) rename src/main/java/com/leetcode/{maps => hashtables}/RepeatedDnaSequence.java (98%) rename src/main/java/com/leetcode/{maps => hashtables}/ShortestWordDistanceII.java (99%) rename src/main/java/com/leetcode/{maps => hashtables}/TwoSumIII.java (98%) rename src/main/java/com/leetcode/{maps => hashtables}/slidingwindow/LongestSubstringWithKDistinctCharacters.java (78%) create mode 100644 src/main/java/com/leetcode/hashtables/slidingwindow/LongestSubstringWithoutRepeatingCharacters.java create mode 100644 src/main/java/com/leetcode/hashtables/slidingwindow/MinimumWindowSubstring.java diff --git a/src/main/java/com/leetcode/arrays/ShortestWordDistance.java b/src/main/java/com/leetcode/arrays/ShortestWordDistance.java index 50b198cd..5cd0c821 100644 --- a/src/main/java/com/leetcode/arrays/ShortestWordDistance.java +++ b/src/main/java/com/leetcode/arrays/ShortestWordDistance.java @@ -1,5 +1,7 @@ package com.leetcode.arrays; +import com.leetcode.hashtables.ShortestWordDistanceII; + import static org.junit.jupiter.api.Assertions.assertEquals; /** @@ -16,7 +18,7 @@ * * Note: You may assume that word1 does not equal to word2, and word1 and word2 are both in the list. * - * Lastly, for a more complex variant, see {@link com.leetcode.maps.ShortestWordDistanceII}. + * Lastly, for a more complex variant, see {@link ShortestWordDistanceII}. * * @author rampatra * @since 2019-07-31 diff --git a/src/main/java/com/leetcode/maps/IsomorphicStrings.java b/src/main/java/com/leetcode/hashtables/IsomorphicStrings.java similarity index 98% rename from src/main/java/com/leetcode/maps/IsomorphicStrings.java rename to src/main/java/com/leetcode/hashtables/IsomorphicStrings.java index 78bc02bd..f9a7f4eb 100644 --- a/src/main/java/com/leetcode/maps/IsomorphicStrings.java +++ b/src/main/java/com/leetcode/hashtables/IsomorphicStrings.java @@ -1,4 +1,4 @@ -package com.leetcode.maps; +package com.leetcode.hashtables; import java.util.HashMap; import java.util.Map; diff --git a/src/main/java/com/leetcode/maps/RepeatedDnaSequence.java b/src/main/java/com/leetcode/hashtables/RepeatedDnaSequence.java similarity index 98% rename from src/main/java/com/leetcode/maps/RepeatedDnaSequence.java rename to src/main/java/com/leetcode/hashtables/RepeatedDnaSequence.java index a4eddb4a..7674273d 100644 --- a/src/main/java/com/leetcode/maps/RepeatedDnaSequence.java +++ b/src/main/java/com/leetcode/hashtables/RepeatedDnaSequence.java @@ -1,4 +1,4 @@ -package com.leetcode.maps; +package com.leetcode.hashtables; import java.util.*; diff --git a/src/main/java/com/leetcode/maps/ShortestWordDistanceII.java b/src/main/java/com/leetcode/hashtables/ShortestWordDistanceII.java similarity index 99% rename from src/main/java/com/leetcode/maps/ShortestWordDistanceII.java rename to src/main/java/com/leetcode/hashtables/ShortestWordDistanceII.java index ecb6c9b9..3932cebf 100644 --- a/src/main/java/com/leetcode/maps/ShortestWordDistanceII.java +++ b/src/main/java/com/leetcode/hashtables/ShortestWordDistanceII.java @@ -1,4 +1,4 @@ -package com.leetcode.maps; +package com.leetcode.hashtables; import java.util.ArrayList; import java.util.HashMap; diff --git a/src/main/java/com/leetcode/maps/TwoSumIII.java b/src/main/java/com/leetcode/hashtables/TwoSumIII.java similarity index 98% rename from src/main/java/com/leetcode/maps/TwoSumIII.java rename to src/main/java/com/leetcode/hashtables/TwoSumIII.java index 22f0748f..88916db0 100644 --- a/src/main/java/com/leetcode/maps/TwoSumIII.java +++ b/src/main/java/com/leetcode/hashtables/TwoSumIII.java @@ -1,4 +1,4 @@ -package com.leetcode.maps; +package com.leetcode.hashtables; import java.util.HashMap; import java.util.Map; diff --git a/src/main/java/com/leetcode/maps/slidingwindow/LongestSubstringWithKDistinctCharacters.java b/src/main/java/com/leetcode/hashtables/slidingwindow/LongestSubstringWithKDistinctCharacters.java similarity index 78% rename from src/main/java/com/leetcode/maps/slidingwindow/LongestSubstringWithKDistinctCharacters.java rename to src/main/java/com/leetcode/hashtables/slidingwindow/LongestSubstringWithKDistinctCharacters.java index 21cfab23..84a0773c 100644 --- a/src/main/java/com/leetcode/maps/slidingwindow/LongestSubstringWithKDistinctCharacters.java +++ b/src/main/java/com/leetcode/hashtables/slidingwindow/LongestSubstringWithKDistinctCharacters.java @@ -1,4 +1,4 @@ -package com.leetcode.maps.slidingwindow; +package com.leetcode.hashtables.slidingwindow; import java.util.HashMap; import java.util.Map; @@ -38,11 +38,11 @@ public static int lengthOfLongestSubstringKDistinct(String str, int k) { int length = 0; Map letterCountInWindow = new HashMap<>(); - int i = 0; // start of window - int j = i; // end of window + int left = 0; // start of window + int right = 0; // end of window - while (j < str.length()) { - char ch = str.charAt(j); + while (right < str.length()) { + char ch = str.charAt(right); letterCountInWindow.put(ch, letterCountInWindow.getOrDefault(ch, 0) + 1); @@ -51,20 +51,20 @@ public static int lengthOfLongestSubstringKDistinct(String str, int k) { // - remove the first character in the window or reduce its count if the window had more than one of this character // - lastly, move the window forward if (letterCountInWindow.keySet().size() > k) { - char firstChar = str.charAt(i); + char firstChar = str.charAt(left); int firstCharCount = letterCountInWindow.get(firstChar); if (firstCharCount > 1) { letterCountInWindow.put(firstChar, firstCharCount - 1); } else { letterCountInWindow.remove(firstChar); } - length = Math.max(length, j - i); - i++; + length = Math.max(length, right - left); + left++; } - j++; + right++; } - return length == 0 ? j - i : length; + return length == 0 ? right - left : length; } public static void main(String[] args) { @@ -75,5 +75,8 @@ public static void main(String[] args) { assertEquals(2, lengthOfLongestSubstringKDistinct("aa", 1)); assertEquals(3, lengthOfLongestSubstringKDistinct("aaa", 1)); assertEquals(0, lengthOfLongestSubstringKDistinct("aa", 0)); + assertEquals(3, lengthOfLongestSubstringKDistinct("aab", 2)); + assertEquals(8, lengthOfLongestSubstringKDistinct("abcabcbb", 3)); + assertEquals(5, lengthOfLongestSubstringKDistinct("pwwkew", 3)); } } diff --git a/src/main/java/com/leetcode/hashtables/slidingwindow/LongestSubstringWithoutRepeatingCharacters.java b/src/main/java/com/leetcode/hashtables/slidingwindow/LongestSubstringWithoutRepeatingCharacters.java new file mode 100644 index 00000000..93a940e4 --- /dev/null +++ b/src/main/java/com/leetcode/hashtables/slidingwindow/LongestSubstringWithoutRepeatingCharacters.java @@ -0,0 +1,128 @@ +package com.leetcode.hashtables.slidingwindow; + +import java.util.HashSet; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Level: Medium + * Link: https://leetcode.com/problems/longest-substring-without-repeating-characters/ + * Description: + * Given a string, find the length of the longest substring without repeating characters. + *

+ * Example 1: + * Input: "abcabcbb" + * Output: 3 + * Explanation: The answer is "abc", with the length of 3. + *

+ * Example 2: + * Input: "bbbbb" + * Output: 1 + * Explanation: The answer is "b", with the length of 1. + *

+ * Example 3: + * Input: "pwwkew" + * Output: 3 + * Explanation: The answer is "wke", with the length of 3. + * Note that the answer must be a substring, "pwke" is a subsequence and not a substring. + * + * @author rampatra + * @since 2019-08-15 + */ +public class LongestSubstringWithoutRepeatingCharacters { + + /** + * Sliding Window Approach (using map). + *

+ * Note: + * If we know that the charset is rather small, we can replace the Map with an integer array as direct access table. + *

+ * Commonly used tables are: + *

+ * int[26] for Letters 'a' - 'z' or 'A' - 'Z' + * int[128] for ASCII + * int[256] for Extended ASCII + *

+ * Runtime: 8 ms. + * + * @param s + * @return + */ + public static int lengthOfLongestSubstring(String s) { + int left = 0; + int right = 0; + int longestSubstringLen = 0; + Set charsInWindow = new HashSet<>(); + + + while (right < s.length()) { + + if (charsInWindow.contains(s.charAt(right))) { + while (s.charAt(left) != s.charAt(right)) { + longestSubstringLen = Math.max(longestSubstringLen, right - left); + charsInWindow.remove(s.charAt(left)); + left++; + } + left++; + } + + charsInWindow.add(s.charAt(right)); + right++; + } + + return Math.max(longestSubstringLen, right - left); + } + + /** + * Sliding Window Approach using int array. + * + * Runtime: 2 ms. + * + * @param s + * @return + */ + public static int lengthOfLongestSubstringNoMap(String s) { + int left = 0; + int right = 0; + int longestSubstringLen = 0; + int[] charsInWindow = new int[128]; + + // keep moving forward the right pointer and adding characters to the window + while (right < s.length()) { + + // once we encounter repeated characters, move the left pointer until the repeated character is removed + if (charsInWindow[s.charAt(right)] == 1) { + while (s.charAt(left) != s.charAt(right)) { + longestSubstringLen = Math.max(longestSubstringLen, right - left); + charsInWindow[s.charAt(left)] = 0; + left++; + } + left++; + } + + charsInWindow[s.charAt(right)] = 1; + right++; + } + + return Math.max(longestSubstringLen, right - left); + } + + public static void main(String[] args) { + assertEquals(0, lengthOfLongestSubstring("")); + assertEquals(1, lengthOfLongestSubstring(" ")); + assertEquals(1, lengthOfLongestSubstring("a")); + assertEquals(2, lengthOfLongestSubstring("aab")); + assertEquals(3, lengthOfLongestSubstring("abcabcbb")); + assertEquals(1, lengthOfLongestSubstring("bbbbb")); + assertEquals(3, lengthOfLongestSubstring("pwwkew")); + + assertEquals(0, lengthOfLongestSubstringNoMap("")); + assertEquals(1, lengthOfLongestSubstringNoMap(" ")); + assertEquals(1, lengthOfLongestSubstringNoMap("a")); + assertEquals(2, lengthOfLongestSubstringNoMap("aab")); + assertEquals(3, lengthOfLongestSubstringNoMap("abcabcbb")); + assertEquals(1, lengthOfLongestSubstringNoMap("bbbbb")); + assertEquals(3, lengthOfLongestSubstringNoMap("pwwkew")); + } +} \ No newline at end of file diff --git a/src/main/java/com/leetcode/hashtables/slidingwindow/MinimumWindowSubstring.java b/src/main/java/com/leetcode/hashtables/slidingwindow/MinimumWindowSubstring.java new file mode 100644 index 00000000..5414cdc1 --- /dev/null +++ b/src/main/java/com/leetcode/hashtables/slidingwindow/MinimumWindowSubstring.java @@ -0,0 +1,104 @@ +package com.leetcode.hashtables.slidingwindow; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Level: Hard + * Link: https://leetcode.com/problems/minimum-window-substring/ + * Description: + * Given a string S and a string T, find the minimum window in S which will contain all the characters in T in + * complexity O(n). + *

+ * Example: + *

+ * Input: S = "ADOBECODEBANC", T = "ABC" + * Output: "BANC" + *

+ * Note: + * - If there is no such window in S that covers all characters in T, return the empty string "". + * - If there is such window, you are guaranteed that there will always be only one unique minimum window in S. + * + * @author rampatra + * @since 2019-08-13 + */ +public class MinimumWindowSubstring { + + /** + * Sliding Window Approach (using map). + * + * Note: + * If we know that the charset is rather small, we can replace the Map with an integer array as direct access table. + * + * Commonly used tables are: + * + * int[26] for Letters 'a' - 'z' or 'A' - 'Z' + * int[128] for ASCII + * int[256] for Extended ASCII + * + * Runtime: 22 ms. + * + * @param s + * @param t + * @return + */ + public static String minWindow(String s, String t) { + + int left = 0; // start of window + int right = 0; // end of window + int begin = 0; + int windowSize = Integer.MAX_VALUE; + int charsInWindow = 0; // to check whether the window has all the characters in t with the required frequency + + // characters and their counts in t + Map dictT = new HashMap<>(); + for (int i = 0; i < t.length(); i++) { + char ch = t.charAt(i); + dictT.put(ch, dictT.getOrDefault(ch, 0) + 1); + } + + // characters and their counts in the window + Map dictWindow = new HashMap<>(); + + while (right < s.length()) { + char rightChar = s.charAt(right); + int rightCharCount; + dictWindow.put(rightChar, (rightCharCount = dictWindow.getOrDefault(rightChar, 0) + 1)); + + // once the window has a character in t with the required frequency, increment charsInWindow + if (dictT.get(rightChar) != null && dictT.get(rightChar).equals(rightCharCount)) { + charsInWindow++; + } + + // once the window has all characters in t with required frequency then shorten the window by moving the + // left window forward until the window no longer has all characters of t + while (left <= right && charsInWindow == dictT.size()) { + if (right - left < windowSize) { + windowSize = right - left + 1; + begin = left; + } + + char leftChar = s.charAt(left); + Integer leftCharCount = dictWindow.get(leftChar); + dictWindow.put(leftChar, leftCharCount - 1); + + if (dictT.get(leftChar) != null && leftCharCount - 1 < dictT.get(leftChar)) { + charsInWindow--; + } + left++; + } + right++; + } + + return windowSize == Integer.MAX_VALUE ? "" : s.substring(begin, begin + windowSize); + } + + public static void main(String[] args) { + assertEquals("BANC", minWindow("ADOBECODEBANC", "ABC")); + assertEquals("BAC", minWindow("ADOBECODEBAC", "ABC")); + assertEquals("ba", minWindow("bba", "ab")); + assertEquals("baca", minWindow("acbbaca", "aba")); + } +} \ No newline at end of file From 91d26d43c27f4cce4997282be650c0b697d6022a Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Thu, 15 Aug 2019 13:58:00 +0100 Subject: [PATCH 140/164] Minor fix --- .../LongestSubstringWithKDistinctCharacters.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/leetcode/hashtables/slidingwindow/LongestSubstringWithKDistinctCharacters.java b/src/main/java/com/leetcode/hashtables/slidingwindow/LongestSubstringWithKDistinctCharacters.java index 84a0773c..4b209b6e 100644 --- a/src/main/java/com/leetcode/hashtables/slidingwindow/LongestSubstringWithKDistinctCharacters.java +++ b/src/main/java/com/leetcode/hashtables/slidingwindow/LongestSubstringWithKDistinctCharacters.java @@ -48,7 +48,7 @@ public static int lengthOfLongestSubstringKDistinct(String str, int k) { // when number of distinct characters in the window exceeds k: // - update length - // - remove the first character in the window or reduce its count if the window had more than one of this character + // - remove the first character in the window or reduce its count if the window has more than one of this character // - lastly, move the window forward if (letterCountInWindow.keySet().size() > k) { char firstChar = str.charAt(left); @@ -64,17 +64,18 @@ public static int lengthOfLongestSubstringKDistinct(String str, int k) { right++; } - return length == 0 ? right - left : length; + return Math.max(length, right - left); } public static void main(String[] args) { assertEquals(3, lengthOfLongestSubstringKDistinct("eceba", 2)); assertEquals(7, lengthOfLongestSubstringKDistinct("eceeeeeba", 2)); + assertEquals(12, lengthOfLongestSubstringKDistinct("bbbeeeeebaaaaaaaaaaa", 2)); assertEquals(2, lengthOfLongestSubstringKDistinct("abcdef", 2)); assertEquals(1, lengthOfLongestSubstringKDistinct("a", 1)); + assertEquals(0, lengthOfLongestSubstringKDistinct("aa", 0)); assertEquals(2, lengthOfLongestSubstringKDistinct("aa", 1)); assertEquals(3, lengthOfLongestSubstringKDistinct("aaa", 1)); - assertEquals(0, lengthOfLongestSubstringKDistinct("aa", 0)); assertEquals(3, lengthOfLongestSubstringKDistinct("aab", 2)); assertEquals(8, lengthOfLongestSubstringKDistinct("abcabcbb", 3)); assertEquals(5, lengthOfLongestSubstringKDistinct("pwwkew", 3)); From 178347086db6101316231e454367a82366c8a214 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Thu, 15 Aug 2019 20:59:02 +0100 Subject: [PATCH 141/164] Word Ladder I: Done --- .../java/com/leetcode/graphs/WordLadder.java | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 src/main/java/com/leetcode/graphs/WordLadder.java diff --git a/src/main/java/com/leetcode/graphs/WordLadder.java b/src/main/java/com/leetcode/graphs/WordLadder.java new file mode 100644 index 00000000..78a76920 --- /dev/null +++ b/src/main/java/com/leetcode/graphs/WordLadder.java @@ -0,0 +1,109 @@ +package com.leetcode.graphs; + + +import javafx.util.Pair; + +import java.util.*; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Level: Medium + * Link: https://leetcode.com/problems/word-ladder/ + * Description: + * 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. + *

+ * Note: + * - Return 0 if there is no such transformation sequence. + * - All words have the same length. + * - All words contain only lowercase alphabetic characters. + * - You may assume no duplicates in the word list. + * - You may assume beginWord and endWord are non-empty and are not the same. + *

+ * Example 1: + * Input: + * beginWord = "hit", + * endWord = "cog", + * wordList = ["hot","dot","dog","lot","log","cog"] + *

+ * Output: 5 + *

+ * Explanation: As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog", + * return its length 5. + *

+ * Example 2: + * Input: + * beginWord = "hit" + * endWord = "cog" + * wordList = ["hot","dot","dog","lot","log"] + *

+ * Output: 0 + *

+ * Explanation: The endWord "cog" is not in wordList, therefore no possible transformation. + * + * @author rampatra + * @since 2019-08-15 + */ +public class WordLadder { + + /** + * Runtime: 78 ms. + * + * @param beginWord + * @param endWord + * @param wordList + * @return + */ + public static int ladderLength(String beginWord, String endWord, List wordList) { + int L = beginWord.length(); + Map> originalToTransformedWordMap = new HashMap<>(); + Queue> queue = new LinkedList<>(); + + wordList.forEach(word -> { + String transformedWord; + for (int i = 0; i < L; i++) { + transformedWord = word.substring(0, i) + "*" + word.substring(i + 1, L); + originalToTransformedWordMap.putIfAbsent(transformedWord, new HashSet<>()); + originalToTransformedWordMap.get(transformedWord).add(word); + } + } + ); + + Set visited = new HashSet<>(); + queue.add(new Pair<>(beginWord, 1)); + visited.add(beginWord); + + while (!queue.isEmpty()) { + Pair currPair = queue.poll(); + String word = currPair.getKey(); + Integer level = currPair.getValue(); + + if (word.equals(endWord)) { + return level; + } + + String transformedWord; + for (int i = 0; i < L; i++) { + transformedWord = word.substring(0, i) + "*" + word.substring(i + 1, L); + + for (String originalWord : originalToTransformedWordMap.getOrDefault(transformedWord, Collections.emptySet())) { + if (!visited.contains(originalWord)) { + queue.add(new Pair<>(originalWord, level + 1)); + visited.add(originalWord); + } + } + } + } + + return 0; + } + + public static void main(String[] args) { + assertEquals(5, ladderLength("hit", "cog", Arrays.asList("hot", "dot", "dog", "lot", "log", "cog"))); + assertEquals(0, ladderLength("hit", "cog", Arrays.asList("hot", "dot", "dog", "lot", "log"))); + } +} From d52dbe74aa77f76f1d3c1a29184293a9eeddaa38 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sat, 17 Aug 2019 13:06:15 +0100 Subject: [PATCH 142/164] word ladder done --- src/main/java/com/leetcode/design/AllOne.java | 125 ++++++++++++++ .../java/com/leetcode/graphs/WordLadder.java | 10 +- .../com/leetcode/graphs/WordLadderII.java | 152 ++++++++++++++++++ 3 files changed, 282 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/leetcode/design/AllOne.java create mode 100644 src/main/java/com/leetcode/graphs/WordLadderII.java diff --git a/src/main/java/com/leetcode/design/AllOne.java b/src/main/java/com/leetcode/design/AllOne.java new file mode 100644 index 00000000..51f771d7 --- /dev/null +++ b/src/main/java/com/leetcode/design/AllOne.java @@ -0,0 +1,125 @@ +package com.leetcode.design; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Level: Hard + * Link: https://leetcode.com/problems/all-oone-data-structure/ + * Description: + * Implement a data structure supporting the following operations: + * Inc(Key) - Inserts a new key with value 1. Or increments an existing key by 1. Key is guaranteed to be a non-empty + * string. + * Dec(Key) - If Key's value is 1, remove it from the data structure. Otherwise decrements an existing key by 1. If + * the key does not exist, this function does nothing. Key is guaranteed to be a non-empty string. + * GetMaxKey() - Returns one of the keys with maximal value. If no element exists, return an empty string "". + * GetMinKey() - Returns one of the keys with minimal value. If no element exists, return an empty string "". + *

+ * Challenge: Perform all these in O(1) time complexity. + * + * @author rampatra + * @since 2019-08-11 + */ +public class AllOne { + + + + Map keyToValMap; + Map> valToKeyMap; + + /** + * Initialize your data structure here. + */ + public AllOne() { + keyToValMap = new HashMap<>(); + valToKeyMap = new HashMap<>(); + } + + /** + * Inserts a new key with value 1. Or increments an existing key by 1. + */ + public void inc(String key) { + + } + + /** + * Decrements an existing key by 1. If Key's value is 1, remove it from the data structure. + */ + public void dec(String key) { + + } + + /** + * Returns one of the keys with maximal value. + */ + public String getMaxKey() { + return null; + } + + /** + * Returns one of the keys with Minimal value. + */ + public String getMinKey() { + return null; + } + + public static void main(String[] args) { + AllOne allOne = new AllOne(); + allOne.inc("r"); + allOne.inc("r"); + allOne.dec("r"); + allOne.inc("a"); + allOne.inc("b"); + allOne.inc("b"); + assertEquals("b", allOne.getMaxKey()); + assertEquals("a", allOne.getMinKey()); + + allOne = new AllOne(); + allOne.dec("hello"); + assertEquals("", allOne.getMaxKey()); + + allOne = new AllOne(); + allOne.inc("a"); + allOne.inc("b"); + allOne.inc("b"); + allOne.inc("b"); + allOne.inc("b"); + allOne.dec("b"); + allOne.dec("b"); + assertEquals("b", allOne.getMaxKey()); + assertEquals("a", allOne.getMinKey()); + + allOne = new AllOne(); + allOne.inc("hello"); + allOne.inc("hello"); + assertEquals("hello", allOne.getMaxKey()); + assertEquals("hello", allOne.getMinKey()); + allOne.inc("leet"); + assertEquals("hello", allOne.getMaxKey()); + assertEquals("leet", allOne.getMinKey()); + + allOne = new AllOne(); + allOne.inc("a"); + allOne.inc("b"); + allOne.inc("b"); + allOne.inc("c"); + allOne.inc("c"); + allOne.inc("c"); + allOne.dec("b"); + allOne.dec("b"); + assertEquals("a", allOne.getMinKey()); + allOne.dec("a"); + assertEquals("c", allOne.getMaxKey()); + //assertEquals("c", allOne.getMinKey()); + + allOne = new AllOne(); + allOne.inc("hello"); + allOne.dec("hello"); + assertEquals("", allOne.getMaxKey()); + assertEquals("", allOne.getMinKey()); + } +} \ No newline at end of file diff --git a/src/main/java/com/leetcode/graphs/WordLadder.java b/src/main/java/com/leetcode/graphs/WordLadder.java index 78a76920..979fb12e 100644 --- a/src/main/java/com/leetcode/graphs/WordLadder.java +++ b/src/main/java/com/leetcode/graphs/WordLadder.java @@ -51,7 +51,7 @@ public class WordLadder { /** - * Runtime: 78 ms. + * Runtime: 79 ms. * * @param beginWord * @param endWord @@ -60,15 +60,15 @@ public class WordLadder { */ public static int ladderLength(String beginWord, String endWord, List wordList) { int L = beginWord.length(); - Map> originalToTransformedWordMap = new HashMap<>(); + Map> transformedToOriginalWordMap = new HashMap<>(); Queue> queue = new LinkedList<>(); wordList.forEach(word -> { String transformedWord; for (int i = 0; i < L; i++) { transformedWord = word.substring(0, i) + "*" + word.substring(i + 1, L); - originalToTransformedWordMap.putIfAbsent(transformedWord, new HashSet<>()); - originalToTransformedWordMap.get(transformedWord).add(word); + transformedToOriginalWordMap.putIfAbsent(transformedWord, new HashSet<>()); + transformedToOriginalWordMap.get(transformedWord).add(word); } } ); @@ -90,7 +90,7 @@ public static int ladderLength(String beginWord, String endWord, List wo for (int i = 0; i < L; i++) { transformedWord = word.substring(0, i) + "*" + word.substring(i + 1, L); - for (String originalWord : originalToTransformedWordMap.getOrDefault(transformedWord, Collections.emptySet())) { + for (String originalWord : transformedToOriginalWordMap.getOrDefault(transformedWord, Collections.emptySet())) { if (!visited.contains(originalWord)) { queue.add(new Pair<>(originalWord, level + 1)); visited.add(originalWord); diff --git a/src/main/java/com/leetcode/graphs/WordLadderII.java b/src/main/java/com/leetcode/graphs/WordLadderII.java new file mode 100644 index 00000000..8265c259 --- /dev/null +++ b/src/main/java/com/leetcode/graphs/WordLadderII.java @@ -0,0 +1,152 @@ +package com.leetcode.graphs; + +import javafx.util.Pair; + +import java.util.*; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Level: Hard + * Link: https://leetcode.com/problems/word-ladder-ii/ + * Description: + * 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. + *

+ * Note: + * - Return an empty list if there is no such transformation sequence. + * - All words have the same length. + * - All words contain only lowercase alphabetic characters. + * - You may assume no duplicates in the word list. + * - You may assume beginWord and endWord are non-empty and are not the same. + *

+ * Example 1: + * Input: + * beginWord = "hit", + * endWord = "cog", + * wordList = ["hot","dot","dog","lot","log","cog"] + *

+ * Output: + * [ + * ["hit","hot","dot","dog","cog"], + * ["hit","hot","lot","log","cog"] + * ] + *

+ *

+ * Example 2: + * Input: + * beginWord = "hit" + * endWord = "cog" + * wordList = ["hot","dot","dog","lot","log"] + *

+ * Output: [] + * Explanation: The endWord "cog" is not in wordList, therefore no possible transformation. + * + * @author rampatra + * @since 2019-08-15 + */ +public class WordLadderII { + + /** + * The approach is same as {@link WordLadder}. We calculate the {@code minDistance} from start to end word and also + * keep a map of words and its adjacent words (i.e, with only character difference). After we are done calculating + * the {@code mindistance}, we perform a dfs on the map upto depth {@code minDistance} and if the last word at this + * depth is equal to the end word then we add all words to the result. + * + * @param beginWord + * @param endWord + * @param wordList + * @return + */ + public static List> findLadders(String beginWord, String endWord, List wordList) { + int L = beginWord.length(); + List> ladders = new LinkedList<>(); + Map> transformedToOriginalWordMap = new HashMap<>(); + Queue> queue = new LinkedList<>(); + + wordList.forEach(word -> { + String transformedWord; + for (int i = 0; i < L; i++) { + transformedWord = word.substring(0, i) + "*" + word.substring(i + 1, L); + transformedToOriginalWordMap.putIfAbsent(transformedWord, new HashSet<>()); + transformedToOriginalWordMap.get(transformedWord).add(word); + } + } + ); + + int minDistance = -1; + Set visited = new HashSet<>(); + queue.add(new Pair<>(beginWord, 1)); + visited.add(beginWord); + + HashMap> connectedNodes = new HashMap<>(); + + while (!queue.isEmpty()) { + Pair currPair = queue.poll(); + String word = currPair.getKey(); + Integer level = currPair.getValue(); + + if (word.equals(endWord) && minDistance == -1) { + minDistance = level - 1; + } + + String transformedWord; + for (int i = 0; i < L; i++) { + transformedWord = word.substring(0, i) + "*" + word.substring(i + 1, L); + + for (String originalWord : transformedToOriginalWordMap.getOrDefault(transformedWord, Collections.emptySet())) { + if (!visited.contains(originalWord)) { + queue.add(new Pair<>(originalWord, level + 1)); + visited.add(originalWord); + } + + if (!word.equals(originalWord)) { + connectedNodes.putIfAbsent(word, new HashSet<>()); + connectedNodes.get(word).add(originalWord); + } + } + } + } + + dfs(ladders, new LinkedHashSet<>(), connectedNodes, beginWord, endWord, 0, minDistance); + + return ladders; + } + + /** + * Perform dfs on the map which contains words and its adjacent words. + * + * @param ladders + * @param ladder + * @param connectedNodes + * @param startNode + * @param endNode + * @param distance + * @param minDistance + */ + private static void dfs(List> ladders, Set ladder, Map> connectedNodes, + String startNode, String endNode, int distance, int minDistance) { + if (distance == minDistance && startNode.equals(endNode)) { + ladder.add(endNode); + ladders.add(new ArrayList<>(ladder)); + return; + } else if (distance > minDistance) { + return; + } + + ladder.add(startNode); + for (String nextNode : connectedNodes.getOrDefault(startNode, new HashSet<>())) { + if (!ladder.contains(nextNode)) { + dfs(ladders, new LinkedHashSet<>(ladder), connectedNodes, nextNode, endNode, distance + 1, minDistance); + } + } + } + + public static void main(String[] args) { + assertEquals("[[hit, hot, lot, log, cog], [hit, hot, dot, dog, cog]]", findLadders("hit", "cog", Arrays.asList("hot", "dot", "dog", "lot", "log", "cog")).toString()); + // TODO Fix this test case System.out.println(findLadders("cet", "ism", Arrays.asList("kid", "tag", "pup", "ail", "tun", "woo", "erg", "luz", "brr", "gay", "sip", "kay", "per", "val", "mes", "ohs", "now", "boa", "cet", "pal", "bar", "die", "war", "hay", "eco", "pub", "lob", "rue", "fry", "lit", "rex", "jan", "cot", "bid", "ali", "pay", "col", "gum", "ger", "row", "won", "dan", "rum", "fad", "tut", "sag", "yip", "sui", "ark", "has", "zip", "fez", "own", "ump", "dis", "ads", "max", "jaw", "out", "btu", "ana", "gap", "cry", "led", "abe", "box", "ore", "pig", "fie", "toy", "fat", "cal", "lie", "noh", "sew", "ono", "tam", "flu", "mgm", "ply", "awe", "pry", "tit", "tie", "yet", "too", "tax", "jim", "san", "pan", "map", "ski", "ova", "wed", "non", "wac", "nut", "why", "bye", "lye", "oct", "old", "fin", "feb", "chi", "sap", "owl", "log", "tod", "dot", "bow", "fob", "for", "joe", "ivy", "fan", "age", "fax", "hip", "jib", "mel", "hus", "sob", "ifs", "tab", "ara", "dab", "jag", "jar", "arm", "lot", "tom", "sax", "tex", "yum", "pei", "wen", "wry", "ire", "irk", "far", "mew", "wit", "doe", "gas", "rte", "ian", "pot", "ask", "wag", "hag", "amy", "nag", "ron", "soy", "gin", "don", "tug", "fay", "vic", "boo", "nam", "ave", "buy", "sop", "but", "orb", "fen", "paw", "his", "sub", "bob", "yea", "oft", "inn", "rod", "yam", "pew", "web", "hod", "hun", "gyp", "wei", "wis", "rob", "gad", "pie", "mon", "dog", "bib", "rub", "ere", "dig", "era", "cat", "fox", "bee", "mod", "day", "apr", "vie", "nev", "jam", "pam", "new", "aye", "ani", "and", "ibm", "yap", "can", "pyx", "tar", "kin", "fog", "hum", "pip", "cup", "dye", "lyx", "jog", "nun", "par", "wan", "fey", "bus", "oak", "bad", "ats", "set", "qom", "vat", "eat", "pus", "rev", "axe", "ion", "six", "ila", "lao", "mom", "mas", "pro", "few", "opt", "poe", "art", "ash", "oar", "cap", "lop", "may", "shy", "rid", "bat", "sum", "rim", "fee", "bmw", "sky", "maj", "hue", "thy", "ava", "rap", "den", "fla", "auk", "cox", "ibo", "hey", "saw", "vim", "sec", "ltd", "you", "its", "tat", "dew", "eva", "tog", "ram", "let", "see", "zit", "maw", "nix", "ate", "gig", "rep", "owe", "ind", "hog", "eve", "sam", "zoo", "any", "dow", "cod", "bed", "vet", "ham", "sis", "hex", "via", "fir", "nod", "mao", "aug", "mum", "hoe", "bah", "hal", "keg", "hew", "zed", "tow", "gog", "ass", "dem", "who", "bet", "gos", "son", "ear", "spy", "kit", "boy", "due", "sen", "oaf", "mix", "hep", "fur", "ada", "bin", "nil", "mia", "ewe", "hit", "fix", "sad", "rib", "eye", "hop", "haw", "wax", "mid", "tad", "ken", "wad", "rye", "pap", "bog", "gut", "ito", "woe", "our", "ado", "sin", "mad", "ray", "hon", "roy", "dip", "hen", "iva", "lug", "asp", "hui", "yak", "bay", "poi", "yep", "bun", "try", "lad", "elm", "nat", "wyo", "gym", "dug", "toe", "dee", "wig", "sly", "rip", "geo", "cog", "pas", "zen", "odd", "nan", "lay", "pod", "fit", "hem", "joy", "bum", "rio", "yon", "dec", "leg", "put", "sue", "dim", "pet", "yaw", "nub", "bit", "bur", "sid", "sun", "oil", "red", "doc", "moe", "caw", "eel", "dix", "cub", "end", "gem", "off", "yew", "hug", "pop", "tub", "sgt", "lid", "pun", "ton", "sol", "din", "yup", "jab", "pea", "bug", "gag", "mil", "jig", "hub", "low", "did", "tin", "get", "gte", "sox", "lei", "mig", "fig", "lon", "use", "ban", "flo", "nov", "jut", "bag", "mir", "sty", "lap", "two", "ins", "con", "ant", "net", "tux", "ode", "stu", "mug", "cad", "nap", "gun", "fop", "tot", "sow", "sal", "sic", "ted", "wot", "del", "imp", "cob", "way", "ann", "tan", "mci", "job", "wet", "ism", "err", "him", "all", "pad", "hah", "hie", "aim", "ike", "jed", "ego", "mac", "baa", "min", "com", "ill", "was", "cab", "ago", "ina", "big", "ilk", "gal", "tap", "duh", "ola", "ran", "lab", "top", "gob", "hot", "ora", "tia", "kip", "han", "met", "hut", "she", "sac", "fed", "goo", "tee", "ell", "not", "act", "gil", "rut", "ala", "ape", "rig", "cid", "god", "duo", "lin", "aid", "gel", "awl", "lag", "elf", "liz", "ref", "aha", "fib", "oho", "tho", "her", "nor", "ace", "adz", "fun", "ned", "coo", "win", "tao", "coy", "van", "man", "pit", "guy", "foe", "hid", "mai", "sup", "jay", "hob", "mow", "jot", "are", "pol", "arc", "lax", "aft", "alb", "len", "air", "pug", "pox", "vow", "got", "meg", "zoe", "amp", "ale", "bud", "gee", "pin", "dun", "pat", "ten", "mob"))); + } +} From 3e95cdc9352111af0a408ae6b2c6b023c02001fa Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sat, 17 Aug 2019 19:31:05 +0100 Subject: [PATCH 143/164] IsomorphicStrings: done --- .../java/com/leetcode/graphs/WordLadder.java | 14 +- .../trees/SerializeDeserializeBinaryTree.java | 179 ++++++++++++++++++ 2 files changed, 192 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/leetcode/trees/SerializeDeserializeBinaryTree.java diff --git a/src/main/java/com/leetcode/graphs/WordLadder.java b/src/main/java/com/leetcode/graphs/WordLadder.java index 979fb12e..61e706ce 100644 --- a/src/main/java/com/leetcode/graphs/WordLadder.java +++ b/src/main/java/com/leetcode/graphs/WordLadder.java @@ -102,8 +102,20 @@ public static int ladderLength(String beginWord, String endWord, List wo return 0; } + /** + * TODO: Optimized both end BFS solution + * + * @param beginWord + * @param endWord + * @param wordList + * @return + */ + public static int ladderLengthOptimized(String beginWord, String endWord, List wordList) { + return -1; + } + public static void main(String[] args) { assertEquals(5, ladderLength("hit", "cog", Arrays.asList("hot", "dot", "dog", "lot", "log", "cog"))); assertEquals(0, ladderLength("hit", "cog", Arrays.asList("hot", "dot", "dog", "lot", "log"))); } -} +} \ No newline at end of file diff --git a/src/main/java/com/leetcode/trees/SerializeDeserializeBinaryTree.java b/src/main/java/com/leetcode/trees/SerializeDeserializeBinaryTree.java new file mode 100644 index 00000000..690de39d --- /dev/null +++ b/src/main/java/com/leetcode/trees/SerializeDeserializeBinaryTree.java @@ -0,0 +1,179 @@ +package com.leetcode.trees; + + +import java.util.LinkedList; +import java.util.Queue; + +/** + * Level: Hard + * Link: https://leetcode.com/problems/serialize-and-deserialize-binary-tree/ + * Description: + * Serialization is the process of converting a data structure or object into a sequence of bits so that it can be + * stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in + * the same or another computer environment. + * + * Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how your + * serialization/deserialization algorithm should work. You just need to ensure that a binary tree can be serialized + * to a string and this string can be deserialized to the original tree structure. + * + * Example: + * + * You may serialize the following tree: + * + * 1 + * / \ + * 2 3 + * / \ + * 4 5 + * + * as "[1,2,3,null,null,4,5]" + * + * Clarification: The above format is the same as how LeetCode serializes a binary tree. You do not necessarily need + * to follow this format, so please be creative and come up with different approaches yourself. + * + * Note: Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms + * should be stateless. + * + * @author rampatra + * @since 2019-08-17 + */ +public class SerializeDeserializeBinaryTree { + + /** + * Runtime: 31 ms. + * + * @param root + * @return + */ + public static String serialize(TreeNode root) { + if (root == null) { + return "[]"; + } + + StringBuilder sb = new StringBuilder(); + sb.append("["); + + Queue queue = new LinkedList<>(); + queue.add(root); + + while (!queue.isEmpty()) { + TreeNode node = queue.poll(); + + if (sb.length() > 1) { + sb.append(", "); + } + if (node == null) { + sb.append("null"); + continue; + } + + sb.append(node.val); + + queue.add(node.left); + queue.add(node.right); + } + + sb.append("]"); + return removeExtraNulls(sb.toString()); + } + + private static String removeExtraNulls(String data) { + int i = data.length() - 1; + while (!(data.charAt(i) >= 48 && data.charAt(i) <= 57)) { + i--; + } + return data.substring(0, i + 1) + "]"; + } + + /** + * + * @param data + * @return + */ + public static TreeNode deserialize(String data) { + data = data.substring(1, data.length() - 1); + + if (data.length() == 0) { + return null; + } + + String[] values = data.split(", "); + + TreeNode root = new TreeNode(Integer.parseInt(values[0])); + + Queue queue = new LinkedList<>(); + queue.add(root); + + for (int i = 0; i < values.length && !queue.isEmpty(); i += 2) { + TreeNode currNode = queue.poll(); + + if (i + 1 < values.length && !values[i + 1].equals("null")) { + TreeNode leftNode = new TreeNode(Integer.parseInt(values[i + 1])); + currNode.left = leftNode; + queue.add(leftNode); + } + + if (i + 2 < values.length && !values[i + 2].equals("null")) { + TreeNode rightNode = new TreeNode(Integer.parseInt(values[i + 2])); + currNode.right = rightNode; + queue.add(rightNode); + } + } + + return root; + } + + public static void main(String[] args) { + // TODO Convert the print statements to asserts + + System.out.println(serialize(new TreeNode(1))); + + /* + Binary Tree + + 1 + / \ + 2 3 + / \ + 4 5 + */ + TreeNode tree = new TreeNode(1); + tree.left = new TreeNode(2); + tree.right = new TreeNode(3); + tree.left.left = new TreeNode(4); + tree.left.right = new TreeNode(5); + + System.out.println(serialize(tree)); + + System.out.println(serialize(deserialize(serialize(tree)))); + + System.out.println(serialize(deserialize(serialize(null)))); + + TreeNode tree2 = new TreeNode(1); + tree2.right = new TreeNode(2); + tree2.right.right = new TreeNode(3); + tree2.right.right.right = new TreeNode(4); + tree2.right.right.right.right = new TreeNode(5); + tree2.right.right.right.right.right = new TreeNode(6); + tree2.right.right.right.right.right.right = new TreeNode(7); + tree2.right.right.right.right.right.right.right = new TreeNode(8); + + System.out.println(serialize(tree2)); + System.out.println(serialize(deserialize(serialize(tree2)))); + + System.out.println("---"); + + System.out.println(serialize(deserialize("[1, 2]"))); + System.out.println(serialize(deserialize("[1, 2, 3]"))); + System.out.println(serialize(deserialize("[3, 2, 4, 1]"))); + System.out.println(serialize(deserialize("[3, 2, 4, 1, 5, 6]"))); + System.out.println(serialize(deserialize("[1, 2, 3, null, null, 4, 5]"))); + System.out.println(serialize(deserialize("[5, 2, 3, null, null, 2, 4, 3, 1]"))); + + System.out.println(serialize(deserialize("[1, null, 2, null, 3, null, 4, null, 5]"))); + System.out.println(serialize(deserialize("[1, null, 2, null, 3, null, 4, null, 5, null, 6]"))); + System.out.println(serialize(deserialize("[1, null, 2, null, 3, null, 4, null, 5, null, 6, null, 7]"))); + System.out.println(serialize(deserialize("[1, null, 2, null, 3, null, 4, null, 5, null, 6, null, 7, null, 8]"))); + System.out.println(serialize(deserialize("[1, null, 2, null, 3, null, 4, null, 5, null, 6, null, 7, null, 8, null, 9]"))); + } +} \ No newline at end of file From dfe3fdd68432d226b17f424dd5343e5aca85e73e Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sun, 18 Aug 2019 00:16:35 +0100 Subject: [PATCH 144/164] Exclusive Time Functions: done --- .../stacks/ExclusiveTimeOfFunctions.java | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 src/main/java/com/leetcode/stacks/ExclusiveTimeOfFunctions.java diff --git a/src/main/java/com/leetcode/stacks/ExclusiveTimeOfFunctions.java b/src/main/java/com/leetcode/stacks/ExclusiveTimeOfFunctions.java new file mode 100644 index 00000000..169f41a2 --- /dev/null +++ b/src/main/java/com/leetcode/stacks/ExclusiveTimeOfFunctions.java @@ -0,0 +1,89 @@ +package com.leetcode.stacks; + +import javafx.util.Pair; + +import java.util.Arrays; +import java.util.List; +import java.util.Stack; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Level: Medium + * Link: https://leetcode.com/problems/exclusive-time-of-functions/ + * Description: + * On a single threaded CPU, we execute some functions. Each function has a unique id between 0 and N-1. + * + * We store logs in timestamp order that describe when a function is entered or exited. + * + * Each log is a string with this format: "{function_id}:{"start" | "end"}:{timestamp}". For example, "0:start:3" + * means the function with id 0 started at the beginning of timestamp 3. "1:end:2" means the function with id 1 ended + * at the end of timestamp 2. + * + * A function's exclusive time is the number of units of time spent in this function. Note that this does not include + * any recursive calls to child functions. + * + * The CPU is single threaded which means that only one function is being executed at a given time unit. + * + * Return the exclusive time of each function, sorted by their function id. + * + * Input: + * n = 2 + * logs = ["0:start:0","1:start:2","1:end:5","0:end:6"] + * Output: [3, 4] + * Explanation: + * Function 0 starts at the beginning of time 0, then it executes 2 units of time and reaches the end of time 1. + * Now function 1 starts at the beginning of time 2, executes 4 units of time and ends at time 5. + * Function 0 is running again at the beginning of time 6, and also ends at the end of time 6, thus executing for 1 unit of time. + * So function 0 spends 2 + 1 = 3 units of total time executing, and function 1 spends 4 units of total time executing. + * + * + * Note: + * -> 1 <= n <= 100 + * -> Two functions won't start or end at the same time. + * -> Functions will always log when they exit. + * + * @author rampatra + * @since 2019-08-17 + */ +public class ExclusiveTimeOfFunctions { + + /** + * Runtime: 18 ms. + * + * @param n + * @param logs + * @return + */ + public static int[] exclusiveTime(int n, List logs) { + int[] times = new int[n]; + Stack> stack = new Stack<>(); + + for (String log : logs) { + String[] l = log.split(":"); + int id = Integer.parseInt(l[0]); + String operation = l[1]; + int timestamp = Integer.parseInt(l[2]); + + if (operation.equals("start")) { + if (!stack.empty()) { + times[stack.peek().getKey()] += (timestamp - stack.peek().getValue() - 1); + } + stack.push(new Pair<>(id, timestamp)); + } else { + times[id] += timestamp - stack.pop().getValue() + 1; + if (!stack.isEmpty()) { + stack.push(new Pair<>(stack.pop().getKey(), timestamp)); + } + } + } + + return times; + } + + public static void main(String[] args) { + assertEquals("[4]", Arrays.toString(exclusiveTime(1, Arrays.asList("0:start:0", "0:start:1", "0:end:2", "0:end:3")))); + assertEquals("[6]", Arrays.toString(exclusiveTime(1, Arrays.asList("0:start:0", "0:start:1", "0:start:2", "0:end:3", "0:end:4", "0:end:5")))); + assertEquals("[3, 4]", Arrays.toString(exclusiveTime(2, Arrays.asList("0:start:0", "1:start:2", "1:end:5", "0:end:6")))); + } +} \ No newline at end of file From 4b89f45be4290f0cb429fb011e122c8942b23e3f Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sun, 18 Aug 2019 20:16:57 +0100 Subject: [PATCH 145/164] Max prod subarray: done --- .../MaximumProductSubArray.java | 62 +++++++++++++++++++ .../MaximumSubArray.java | 2 +- .../stacks/ExclusiveTimeOfFunctions.java | 4 +- 3 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/leetcode/dynamicprogramming/MaximumProductSubArray.java rename src/main/java/com/leetcode/{arrays => dynamicprogramming}/MaximumSubArray.java (98%) diff --git a/src/main/java/com/leetcode/dynamicprogramming/MaximumProductSubArray.java b/src/main/java/com/leetcode/dynamicprogramming/MaximumProductSubArray.java new file mode 100644 index 00000000..781cad13 --- /dev/null +++ b/src/main/java/com/leetcode/dynamicprogramming/MaximumProductSubArray.java @@ -0,0 +1,62 @@ +package com.leetcode.dynamicprogramming; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Level: Medium + * Link: https://leetcode.com/problems/maximum-product-subarray/ + * Description: + * Given an integer array nums, find the contiguous subarray within an array (containing at least one number) which + * has the largest product. + *

+ * Example 1: + * Input: [2,3,-2,4] + * Output: 6 + * Explanation: [2,3] has the largest product 6. + *

+ * Example 2: + * Input: [-2,0,-1] + * Output: 0 + * Explanation: The result cannot be 2, because [-2,-1] is not a subarray. + * + * @author rampatra + * @since 2019-08-18 + */ +public class MaximumProductSubArray { + + /** + * The approach is similar to {@link MaximumSubArray} where we update maxUntilIndex only if multiplying the current + * number to the product of of all numbers until index produces a larger product and if not make maxUntilIndex the + * current number. The only twist here is that we keep two such variables, one for max and one for min, and that's + * because the product of two negatives gives us a positive number. + *

+ * Runtime: 1 ms. + * + * @param nums + * @return + */ + public static int maxProduct(int[] nums) { + int maxProd = nums[0]; + int maxUntilIndex = nums[0]; + int minUntilIndex = nums[0]; + + for (int i = 1; i < nums.length; i++) { + if (nums[i] >= 0) { + maxUntilIndex = Math.max(nums[i], maxUntilIndex * nums[i]); + minUntilIndex = Math.min(nums[i], minUntilIndex * nums[i]); + } else { + int prevMaxUntilIndex = maxUntilIndex; + maxUntilIndex = Math.max(nums[i], minUntilIndex * nums[i]); // when current number is -ve then multiply with minUntilIndex to get the max as product of two negatives is a positive + minUntilIndex = Math.min(nums[i], prevMaxUntilIndex * nums[i]); + } + + maxProd = Math.max(maxProd, maxUntilIndex); + } + + return maxProd; + } + + public static void main(String[] args) { + assertEquals(24, maxProduct(new int[]{-2, 3, -4})); + } +} \ No newline at end of file diff --git a/src/main/java/com/leetcode/arrays/MaximumSubArray.java b/src/main/java/com/leetcode/dynamicprogramming/MaximumSubArray.java similarity index 98% rename from src/main/java/com/leetcode/arrays/MaximumSubArray.java rename to src/main/java/com/leetcode/dynamicprogramming/MaximumSubArray.java index f9a64a3f..90a28c93 100644 --- a/src/main/java/com/leetcode/arrays/MaximumSubArray.java +++ b/src/main/java/com/leetcode/dynamicprogramming/MaximumSubArray.java @@ -1,4 +1,4 @@ -package com.leetcode.arrays; +package com.leetcode.dynamicprogramming; /** * Level: Easy diff --git a/src/main/java/com/leetcode/stacks/ExclusiveTimeOfFunctions.java b/src/main/java/com/leetcode/stacks/ExclusiveTimeOfFunctions.java index 169f41a2..63c61dc2 100644 --- a/src/main/java/com/leetcode/stacks/ExclusiveTimeOfFunctions.java +++ b/src/main/java/com/leetcode/stacks/ExclusiveTimeOfFunctions.java @@ -66,13 +66,13 @@ public static int[] exclusiveTime(int n, List logs) { int timestamp = Integer.parseInt(l[2]); if (operation.equals("start")) { - if (!stack.empty()) { + if (!stack.empty()) { // if there are other processes started before, calculate their time until now times[stack.peek().getKey()] += (timestamp - stack.peek().getValue() - 1); } stack.push(new Pair<>(id, timestamp)); } else { times[id] += timestamp - stack.pop().getValue() + 1; - if (!stack.isEmpty()) { + if (!stack.isEmpty()) { // if there are other processes, make their start time to now stack.push(new Pair<>(stack.pop().getKey(), timestamp)); } } From b2aba3e6fcf22bf24ce6b8c3089a372bf7852063 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Sun, 18 Aug 2019 22:37:11 +0100 Subject: [PATCH 146/164] linked list cycle done --- .../linkedlists/LinkedListCycleII.java | 73 +++++++++++++++++++ .../linkedlists/DetectAndRemoveLoop.java | 25 ++++++- 2 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/leetcode/linkedlists/LinkedListCycleII.java diff --git a/src/main/java/com/leetcode/linkedlists/LinkedListCycleII.java b/src/main/java/com/leetcode/linkedlists/LinkedListCycleII.java new file mode 100644 index 00000000..d5fe0e50 --- /dev/null +++ b/src/main/java/com/leetcode/linkedlists/LinkedListCycleII.java @@ -0,0 +1,73 @@ +package com.leetcode.linkedlists; + +/** + * Level: Medium + * Link: https://leetcode.com/problems/linked-list-cycle-ii/ + * Description: + * Given a linked list, return the node where the cycle begins. If there is no cycle, return null. + * + * To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in + * the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list. + * + * Note: Do not modify the linked list. + * + * Example 1: + * + * Input: head = [3,2,0,-4], pos = 1 + * Output: tail connects to node index 1 + * Explanation: There is a cycle in the linked list, where tail connects to the second node. + * + * + * Example 2: + * + * Input: head = [1,2], pos = 0 + * Output: tail connects to node index 0 + * Explanation: There is a cycle in the linked list, where tail connects to the first node. + * + * + * Example 3: + * + * Input: head = [1], pos = -1 + * Output: no cycle + * Explanation: There is no cycle in the linked list. + * + * Follow-up: + * Can you solve it without using extra space? + * + * @author rampatra + * @since 2019-08-18 + */ +public class LinkedListCycleII { + + /** + * Runtime: 0 ms. + * + * @param head + * @return + */ + public Node detectCycle(Node head) { + Node slow = head; + Node fast = head; + + while (fast != null && fast.next != null) { + slow = slow.next; + fast = fast.next.next; + if (slow == fast) { + break; + } + } + + if (fast == null || fast.next == null) { + return null; + } else { + slow = head; + + while (slow != fast) { + slow = slow.next; + fast = fast.next; + } + + return slow; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/rampatra/linkedlists/DetectAndRemoveLoop.java b/src/main/java/com/rampatra/linkedlists/DetectAndRemoveLoop.java index ade19e90..5ad549d4 100644 --- a/src/main/java/com/rampatra/linkedlists/DetectAndRemoveLoop.java +++ b/src/main/java/com/rampatra/linkedlists/DetectAndRemoveLoop.java @@ -34,6 +34,11 @@ public class DetectAndRemoveLoop { * ii. Now, move both slow and fast pointer at same pace and where they meet is the starting point of the loop. * iii. Lastly, to remove the loop make the next of the node (before the starting point of loop) to null. * + * Proof for Floyd's Cycle Detection: Consider a cyclic list and imagine the slow and fast pointers are two runners + * racing around a circle track. The fast runner will eventually meet the slow runner. Why? Consider this case - + * The fast runner is just one step behind the slow runner. In the next iteration, they both increment one and two + * steps respectively and meet each other. + * * @param list * @param * @return {@code true} if loop exists {@code false} otherwise. @@ -58,7 +63,7 @@ public static > boolean detectAndRemoveLoop(SingleLinked while (true) { slow = slow.next; fast = fast.next; - if (slow.next == fast.next) { + if (slow == fast) { fast.next = null; break; } @@ -78,5 +83,23 @@ public static void main(String[] args) { linkedList.getNode(4).next = linkedList.getNode(2); System.out.println(detectAndRemoveLoop(linkedList)); linkedList.printList(); + + linkedList = new SingleLinkedList<>(); + linkedList.add(0); + linkedList.add(1); + linkedList.getNode(1).next = linkedList.getNode(0); + System.out.println(detectAndRemoveLoop(linkedList)); + linkedList.printList(); + + linkedList = new SingleLinkedList<>(); + linkedList.add(0); + System.out.println(detectAndRemoveLoop(linkedList)); + linkedList.printList(); + + linkedList = new SingleLinkedList<>(); + linkedList.add(0); + linkedList.getNode(0).next = linkedList.getNode(0); + System.out.println(detectAndRemoveLoop(linkedList)); + linkedList.printList(); } } \ No newline at end of file From d97139367d39f148b629dd818f3892739dc2ea76 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Mon, 19 Aug 2019 17:44:04 +0100 Subject: [PATCH 147/164] topk frequent elements --- .../heaps/KthLargestElementInArray.java | 143 ++++++++++++++++++ .../leetcode/heaps/TopKFrequentElements.java | 68 +++++++++ 2 files changed, 211 insertions(+) create mode 100644 src/main/java/com/leetcode/heaps/KthLargestElementInArray.java create mode 100644 src/main/java/com/leetcode/heaps/TopKFrequentElements.java diff --git a/src/main/java/com/leetcode/heaps/KthLargestElementInArray.java b/src/main/java/com/leetcode/heaps/KthLargestElementInArray.java new file mode 100644 index 00000000..2422de08 --- /dev/null +++ b/src/main/java/com/leetcode/heaps/KthLargestElementInArray.java @@ -0,0 +1,143 @@ +package com.leetcode.heaps; + +import com.rampatra.base.MaxHeap; + +import java.util.PriorityQueue; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Level: Medium + * Link: https://leetcode.com/problems/kth-largest-element-in-an-array/ + * Description: + * Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not + * the kth distinct element. + *

+ * Example 1: + * Input: [3,2,1,5,6,4] and k = 2 + * Output: 5 + *

+ * Example 2: + * Input: [3,2,3,1,2,4,5,5,6] and k = 4 + * Output: 4 + *

+ * Note: + * You may assume k is always valid, 1 ≤ k ≤ array's length. + * + * @author rampatra + * @since 2019-08-19 + */ +public class KthLargestElementInArray { + + /** + * Runtime: 1 ms. + * + * @param nums + * @param k + * @return + */ + public static int findKthLargest(int[] nums, int k) { + return heapSortUntilK(nums, k); + } + + /** + * In heapsort, after each iteration we have the max element at the end of the array. Ergo, if we run the algorithm + * k times then we would have our kth largest element. + * + * @param a + * @param k + * @return + */ + public static int heapSortUntilK(int[] a, int k) { + buildMaxHeap(a); + int count = 0; + + for (int i = a.length - 1; i > 0; i--) { + if (count++ == k) { + break; + } + swap(a, 0, i); + maxHeapify(a, 0, i); + } + + return a[a.length - k]; + } + + /** + * Makes the array {@param a} satisfy the max heap property starting from + * {@param index} till {@param end} position in array. + *

+ * See this {@link MaxHeap#maxHeapify} for a basic version of maxHeapify. + *

+ * Time complexity: O(log n). + * + * @param a + * @param index + * @param end + */ + public static void maxHeapify(int[] a, int index, int end) { + int largest = index; + int leftIndex = 2 * index + 1; + int rightIndex = 2 * index + 2; + + if (leftIndex < end && a[index] < a[leftIndex]) { + largest = leftIndex; + } + if (rightIndex < end && a[largest] < a[rightIndex]) { + largest = rightIndex; + } + + if (largest != index) { + swap(a, index, largest); + maxHeapify(a, largest, end); + } + } + + /** + * Converts array {@param a} in to a max heap. + *

+ * Time complexity: O(n) and is not O(n log n). + */ + private static void buildMaxHeap(int[] a) { + for (int i = a.length / 2 - 1; i >= 0; i--) { + maxHeapify(a, i, a.length); + } + } + + + /** + * When you poll() on a PriorityQueue the smallest number in the queue is removed. Based on this property, we can + * iterate over the entire array and in the end we would be left with the k largest element in the queue. + * + * @param nums + * @param k + * @return + */ + public static int findKthLargestUsingPriorityQueue(int[] nums, int k) { + PriorityQueue priorityQueue = new PriorityQueue<>(); + + for (int num : nums) { + priorityQueue.add(num); + + if (priorityQueue.size() > k) { + priorityQueue.poll(); + } + } + + return priorityQueue.isEmpty() ? -1 : priorityQueue.peek(); + } + + private static void swap(int[] a, int firstIndex, int secondIndex) { + a[firstIndex] = a[firstIndex] + a[secondIndex]; + a[secondIndex] = a[firstIndex] - a[secondIndex]; + a[firstIndex] = a[firstIndex] - a[secondIndex]; + } + + public static void main(String[] args) { + assertEquals(5, findKthLargest(new int[]{3, 2, 1, 5, 6, 4}, 2)); + assertEquals(3, findKthLargest(new int[]{3, 2, 1, 5, 6, 4}, 4)); + + assertEquals(5, findKthLargestUsingPriorityQueue(new int[]{3, 2, 1, 5, 6, 4}, 2)); + assertEquals(3, findKthLargestUsingPriorityQueue(new int[]{3, 2, 1, 5, 6, 4}, 4)); + } +} diff --git a/src/main/java/com/leetcode/heaps/TopKFrequentElements.java b/src/main/java/com/leetcode/heaps/TopKFrequentElements.java new file mode 100644 index 00000000..5a684325 --- /dev/null +++ b/src/main/java/com/leetcode/heaps/TopKFrequentElements.java @@ -0,0 +1,68 @@ +package com.leetcode.heaps; + +import javafx.util.Pair; + +import java.util.*; +import java.util.stream.Collectors; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Level: Medium + * Link: https://leetcode.com/problems/top-k-frequent-elements/ + * Description: + * Given a non-empty array of integers, return the k most frequent elements. + *

+ * Example 1: + * Input: nums = [1,1,1,2,2,3], k = 2 + * Output: [1,2] + *

+ * Example 2: + * Input: nums = [1], k = 1 + * Output: [1] + *

+ * Note: + * - You may assume k is always valid, 1 ≤ k ≤ number of unique elements. + * - Your algorithm's time complexity must be better than O(n log n), where n is the array's size. + * + * @author rampatra + * @since 2019-08-19 + */ +public class TopKFrequentElements { + + /** + * TODO: A faster approach without using Pair. + *

+ * Runtime: 51 ms. + * + * @param nums + * @param k + * @return + */ + public static List topKFrequent(int[] nums, int k) { + Map numCount = new HashMap<>(); + PriorityQueue> pq = new PriorityQueue<>(Comparator.comparing(Pair::getValue)); + + for (int num : nums) { + numCount.put(num, numCount.getOrDefault(num, 0) + 1); + } + + for (Map.Entry entry : numCount.entrySet()) { + pq.add(new Pair<>(entry.getKey(), entry.getValue())); + + if (pq.size() > k) { + pq.poll(); + } + } + + return pq.stream().map(Pair::getKey).collect(Collectors.toList()); + } + + public static void main(String[] args) { + assertEquals("[2, 1]", topKFrequent(new int[]{1, 1, 1, 2, 2, 3}, 2).toString()); + assertEquals("[0]", topKFrequent(new int[]{3, 0, 1, 0}, 1).toString()); + assertEquals("[1]", topKFrequent(new int[]{1}, 1).toString()); + assertEquals("[1, 2]", topKFrequent(new int[]{1, 2}, 2).toString()); + assertEquals("[2, -1]", topKFrequent(new int[]{4, 1, -1, 2, -1, 2, 3}, 2).toString()); + } +} From 788eb3dec3a1cdb96f25eecf650ccad766079d2c Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Mon, 19 Aug 2019 20:39:53 +0100 Subject: [PATCH 148/164] binary search questions: done --- .../binarysearch/SearchInsertPosition.java | 63 ++++++++++++++ .../SmallestLetterGreaterThanTarget.java | 87 +++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 src/main/java/com/leetcode/arrays/binarysearch/SearchInsertPosition.java create mode 100644 src/main/java/com/leetcode/arrays/binarysearch/SmallestLetterGreaterThanTarget.java diff --git a/src/main/java/com/leetcode/arrays/binarysearch/SearchInsertPosition.java b/src/main/java/com/leetcode/arrays/binarysearch/SearchInsertPosition.java new file mode 100644 index 00000000..ead76d2a --- /dev/null +++ b/src/main/java/com/leetcode/arrays/binarysearch/SearchInsertPosition.java @@ -0,0 +1,63 @@ +package com.leetcode.arrays.binarysearch; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Level: Easy + * Link: https://leetcode.com/problems/search-insert-position/ + * Description: + * Given a sorted array and a target value, return the index if the target is found. If not, return the index where it + * would be if it were inserted in order. + *

+ * You may assume no duplicates in the array. + *

+ * Example 1: + * Input: [1,3,5,6], 5 + * Output: 2 + *

+ * Example 2: + * Input: [1,3,5,6], 2 + * Output: 1 + *

+ * Example 3: + * Input: [1,3,5,6], 7 + * Output: 4 + *

+ * Example 4: + * Input: [1,3,5,6], 0 + * Output: 0 + * + * Similar question: {@link SmallestLetterGreaterThanTarget}. + * + * @author rampatra + * @since 2019-08-19 + */ +public class SearchInsertPosition { + + /** + * Runtime: 0 ms. + * + * @param nums + * @param target + * @return + */ + public static int searchInsert(int[] nums, int target) { + int low = 0; + int high = nums.length - 1; + while (low <= high) { + int mid = low + (high - low) / 2; + if (nums[mid] == target) { + return mid; + } else if (nums[mid] < target) { + low = mid + 1; + } else { + high = mid - 1; + } + } + return low; + } + + public static void main(String[] args) { + assertEquals(2, searchInsert(new int[]{1, 2}, 3)); + } +} \ No newline at end of file diff --git a/src/main/java/com/leetcode/arrays/binarysearch/SmallestLetterGreaterThanTarget.java b/src/main/java/com/leetcode/arrays/binarysearch/SmallestLetterGreaterThanTarget.java new file mode 100644 index 00000000..e44dc339 --- /dev/null +++ b/src/main/java/com/leetcode/arrays/binarysearch/SmallestLetterGreaterThanTarget.java @@ -0,0 +1,87 @@ +package com.leetcode.arrays.binarysearch; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Level: Easy + * Link: https://leetcode.com/problems/find-smallest-letter-greater-than-target/ + * Description: + * Given a list of sorted characters letters containing only lowercase letters, and given a target letter target, find + * the smallest element in the list that is larger than the given target. + * + * Letters also wrap around. For example, if the target is target = 'z' and letters = ['a', 'b'], the answer is 'a'. + * + * Examples: + * + * Input: + * letters = ["c", "f", "j"] + * target = "a" + * Output: "c" + * + * Input: + * letters = ["c", "f", "j"] + * target = "c" + * Output: "f" + * + * Input: + * letters = ["c", "f", "j"] + * target = "d" + * Output: "f" + * + * Input: + * letters = ["c", "f", "j"] + * target = "g" + * Output: "j" + * + * Input: + * letters = ["c", "f", "j"] + * target = "j" + * Output: "c" + * + * Input: + * letters = ["c", "f", "j"] + * target = "k" + * Output: "c" + * + * Note: + * - letters has a length in range [2, 10000]. + * - letters consists of lowercase letters, and contains at least 2 unique letters. + * - target is a lowercase letter. + * + * @author rampatra + * @since 2019-08-19 + */ +public class SmallestLetterGreaterThanTarget { + + /** + * Runtime: 0 ms. + * + * @param letters + * @param target + * @return + */ + public static char nextGreatestLetter(char[] letters, char target) { + int low = 0, hi = letters.length - 1; + while (low <= hi) { + int mid = low + (hi - low) / 2; + if (letters[mid] <= target) { + low = mid + 1; + } else { + hi = mid - 1; + } + } + return letters[low % letters.length]; + } + + public static void main(String[] args) { + assertEquals('a', nextGreatestLetter(new char[]{'a'}, 'z')); + assertEquals('b', nextGreatestLetter(new char[]{'a', 'b'}, 'a')); + assertEquals('b', nextGreatestLetter(new char[]{'a', 'b', 'c'}, 'a')); + assertEquals('a', nextGreatestLetter(new char[]{'a', 'b', 'c'}, 'z')); + assertEquals('c', nextGreatestLetter(new char[]{'c', 'f', 'j'}, 'a')); + assertEquals('f', nextGreatestLetter(new char[]{'c', 'f', 'j'}, 'c')); + assertEquals('f', nextGreatestLetter(new char[]{'c', 'f', 'j'}, 'd')); + assertEquals('b', nextGreatestLetter(new char[]{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'l', + 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}, 'a')); + } +} \ No newline at end of file From 04350de4f583a9d61ea953251dc99f952d12605a Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Tue, 20 Aug 2019 13:30:39 +0100 Subject: [PATCH 149/164] pow x^n : done --- .../leetcode/arrays/binarysearch/PowXN.java | 85 +++++++++++++++++++ .../leetcode/strings/AnagramsInString.java | 2 +- 2 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/leetcode/arrays/binarysearch/PowXN.java diff --git a/src/main/java/com/leetcode/arrays/binarysearch/PowXN.java b/src/main/java/com/leetcode/arrays/binarysearch/PowXN.java new file mode 100644 index 00000000..b2a305a2 --- /dev/null +++ b/src/main/java/com/leetcode/arrays/binarysearch/PowXN.java @@ -0,0 +1,85 @@ +package com.leetcode.arrays.binarysearch; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Level: Medium + * Link: https://leetcode.com/problems/powx-n/ + * Description: + * Implement pow(x, n), which calculates x raised to the power n (x^n). + *

+ * Example 1: + * Input: 2.00000, 10 + * Output: 1024.00000 + *

+ * Example 2: + * Input: 2.10000, 3 + * Output: 9.26100 + *

+ * Example 3: + * Input: 2.00000, -2 + * Output: 0.25000 + * Explanation: 2^-2 = 1/22 = 1/4 = 0.25 + *

+ * Note: + * -100.0 < x < 100.0 + * n is a 32-bit signed integer, within the range [−231, 231 − 1] + * + * @author rampatra + * @since 2019-08-19 + */ +public class PowXN { + + /** + * In this approach we iterate n times and keep multiplying x with x. + * Runtime: Time limit exceeded. + * + * @param x + * @param n + * @return + */ + public static double myPowNaive(double x, int n) { + if (n == 0) { + return 1; + } + double res = x; + int absN = Math.abs(n); + for (int i = 1; i < absN; i++) { + res *= x; + } + return n < 0 ? 1 / res : res; + } + + + /** + * In this approach, we iterate log n times. We omit half of n each time. When n is odd, we store whatever product + * we have calculated so far in the final result. + *

+ * Runtime: 1 ms. + * + * @param x + * @param n + * @return + */ + public static double myPow(double x, int n) { + double res = 1; + long absN = Math.abs((long) n); + + while (absN > 0) { + if (absN % 2 == 1) res *= x; // store whatever we have calculated so far in the final result + x *= x; + absN /= 2; + } + return n < 0 ? 1 / res : res; + } + + public static void main(String[] args) { + assertEquals(1024.0, myPowNaive(2.0, 10)); + assertEquals(0.25, myPowNaive(2.0, -2)); + assertEquals(0.0, myPowNaive(0.00001, 2147483647)); + + assertEquals(1024.0, myPow(2.0, 10)); + assertEquals(0.25, myPow(2.0, -2)); + assertEquals(0.0, myPow(0.00001, 2147483647)); + } +} diff --git a/src/main/java/com/leetcode/strings/AnagramsInString.java b/src/main/java/com/leetcode/strings/AnagramsInString.java index afdb3f9f..444fcca4 100644 --- a/src/main/java/com/leetcode/strings/AnagramsInString.java +++ b/src/main/java/com/leetcode/strings/AnagramsInString.java @@ -55,7 +55,7 @@ private static List findAllAnagramsInTextNaive(String text, String patt * where, * n = length of text or number of characters in text *

- * Runtime: 7 ms on leetcode. + * Runtime: 6 ms. * * @param text * @param pattern From a718d3dec8eefec356c3912f210959456cf3e12c Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Tue, 20 Aug 2019 14:08:56 +0100 Subject: [PATCH 150/164] sqrt x: done --- .../leetcode/arrays/binarysearch/PowXN.java | 2 +- .../binarysearch/SearchInsertPosition.java | 3 +- .../leetcode/arrays/binarysearch/SqrtX.java | 62 +++++++++++++++++++ .../leetcode/strings/AnagramsInString.java | 34 +++++++++- 4 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/leetcode/arrays/binarysearch/SqrtX.java diff --git a/src/main/java/com/leetcode/arrays/binarysearch/PowXN.java b/src/main/java/com/leetcode/arrays/binarysearch/PowXN.java index b2a305a2..3591c50e 100644 --- a/src/main/java/com/leetcode/arrays/binarysearch/PowXN.java +++ b/src/main/java/com/leetcode/arrays/binarysearch/PowXN.java @@ -63,7 +63,7 @@ public static double myPowNaive(double x, int n) { */ public static double myPow(double x, int n) { double res = 1; - long absN = Math.abs((long) n); + long absN = Math.abs((long) n); // used a long so that `absN / 2` doesn't overflow while (absN > 0) { if (absN % 2 == 1) res *= x; // store whatever we have calculated so far in the final result diff --git a/src/main/java/com/leetcode/arrays/binarysearch/SearchInsertPosition.java b/src/main/java/com/leetcode/arrays/binarysearch/SearchInsertPosition.java index ead76d2a..2f13214a 100644 --- a/src/main/java/com/leetcode/arrays/binarysearch/SearchInsertPosition.java +++ b/src/main/java/com/leetcode/arrays/binarysearch/SearchInsertPosition.java @@ -26,7 +26,7 @@ * Example 4: * Input: [1,3,5,6], 0 * Output: 0 - * + *

* Similar question: {@link SmallestLetterGreaterThanTarget}. * * @author rampatra @@ -59,5 +59,6 @@ public static int searchInsert(int[] nums, int target) { public static void main(String[] args) { assertEquals(2, searchInsert(new int[]{1, 2}, 3)); + assertEquals(1, searchInsert(new int[]{1, 3, 5, 6}, 2)); } } \ No newline at end of file diff --git a/src/main/java/com/leetcode/arrays/binarysearch/SqrtX.java b/src/main/java/com/leetcode/arrays/binarysearch/SqrtX.java new file mode 100644 index 00000000..0dde1308 --- /dev/null +++ b/src/main/java/com/leetcode/arrays/binarysearch/SqrtX.java @@ -0,0 +1,62 @@ +package com.leetcode.arrays.binarysearch; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Level: Easy + * Link: https://leetcode.com/problems/sqrtx/ + * Description: + * Implement int sqrt(int x). + * + * Compute and return the square root of x, where x is guaranteed to be a non-negative integer. + * + * Since the return type is an integer, the decimal digits are truncated and only the integer part + * of the result is returned. + * + * Example 1: + * Input: 4 + * Output: 2 + * + * Example 2: + * Input: 8 + * Output: 2 + * Explanation: The square root of 8 is 2.82842..., and since + * the decimal part is truncated, 2 is returned. + * + * @author rampatra + * @since 2019-08-19 + */ +public class SqrtX { + + /** + * Runtime: 1 ms. + * + * @param x + * @return + */ + public static int mySqrt(int x) { + if (x == 0 || x == 1) { + return x; + } + long low = 1; + long high = x / 2; + + while (low <= high) { + long mid = low + (high - low) / 2; + if (mid * mid == x) { + return (int) mid; + } else if (mid * mid < x) { + low = mid + 1; + } else { + high = mid - 1; + } + } + return (int) high; + } + + public static void main(String[] args) { + assertEquals(2, mySqrt(8)); + assertEquals(3, mySqrt(9)); + assertEquals(46339, mySqrt(2147395599)); + } +} \ No newline at end of file diff --git a/src/main/java/com/leetcode/strings/AnagramsInString.java b/src/main/java/com/leetcode/strings/AnagramsInString.java index 444fcca4..12e7d766 100644 --- a/src/main/java/com/leetcode/strings/AnagramsInString.java +++ b/src/main/java/com/leetcode/strings/AnagramsInString.java @@ -5,8 +5,40 @@ import java.util.List; /** - * Level: Easy + * Level: Medium * Problem: https://leetcode.com/problems/find-all-anagrams-in-a-string/ + * Description: + * Given a string s and a non-empty string p, find all the start indices of p's anagrams in s. + * + * Strings consists of lowercase English letters only and the length of both strings s and p will not be larger + * than 20,100. + * + * The order of output does not matter. + * + * Example 1: + * + * Input: + * s: "cbaebabacd" p: "abc" + * + * Output: + * [0, 6] + * + * Explanation: + * The substring with start index = 0 is "cba", which is an anagram of "abc". + * The substring with start index = 6 is "bac", which is an anagram of "abc". + * + * Example 2: + * + * Input: + * s: "abab" p: "ab" + * + * Output: + * [0, 1, 2] + * + * Explanation: + * The substring with start index = 0 is "ab", which is an anagram of "ab". + * The substring with start index = 1 is "ba", which is an anagram of "ab". + * The substring with start index = 2 is "ab", which is an anagram of "ab". * * @author rampatra * @since 2019-04-13 From 9a10dadd404b2d0b441e43304223fa0bca5eb8d6 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Tue, 20 Aug 2019 21:10:06 +0100 Subject: [PATCH 151/164] lfu cache: 90% done --- .../java/com/leetcode/design/LFUCache.java | 127 ++++++++++++++++++ .../com/rampatra/linkedlists/LRUCache.java | 16 ++- 2 files changed, 136 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/leetcode/design/LFUCache.java diff --git a/src/main/java/com/leetcode/design/LFUCache.java b/src/main/java/com/leetcode/design/LFUCache.java new file mode 100644 index 00000000..0a3e9b8e --- /dev/null +++ b/src/main/java/com/leetcode/design/LFUCache.java @@ -0,0 +1,127 @@ +package com.leetcode.design; + +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Level: Hard + * Link: https://leetcode.com/problems/lfu-cache/ + * Description: + * Design and implement a data structure for Least Frequently Used (LFU) cache. It should support the following + * operations: get and put. + * + * get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1. + * put(key, value) - Set or insert the value if the key is not already present. When the cache reaches its capacity, it + * should invalidate the least frequently used item before inserting a new item. For the purpose of this problem, when + * there is a tie (i.e., two or more keys that have the same frequency), the least recently used key would be evicted. + * + * Follow up: + * Could you do both operations in O(1) time complexity? + * + * Note: + * - + * + * @author rampatra + * @since 2019-08-20 + */ +public class LFUCache { + + private int minCount = 0; + private int capacity; + private Map keyValueMap; + private Map keyCountMap; + private Map> countKeysMap; + + + public LFUCache(int capacity) { + this.capacity = capacity; + keyValueMap = new HashMap<>(); + keyCountMap = new HashMap<>(); + countKeysMap = new HashMap<>(); + } + + + public int get(int key) { + Integer val = keyValueMap.get(key); + if (val == null) { + return -1; + } + + int prevCount = keyCountMap.get(key); + countKeysMap.getOrDefault(prevCount, new LinkedHashSet<>()).remove(key); + countKeysMap.putIfAbsent(prevCount + 1, new LinkedHashSet<>()); + countKeysMap.get(prevCount + 1).add(key); + + if (prevCount == minCount && countKeysMap.get(prevCount).size() == 0) { + minCount++; + } + + return val; + } + + + public void put(int key, int value) { + if (capacity <= 0) { + return; + } + + if (!keyValueMap.containsKey(key) && keyCountMap.size() == capacity) { + int keyToEvict = countKeysMap.get(minCount).iterator().next(); + countKeysMap.get(minCount).remove(keyToEvict); + keyValueMap.remove(keyToEvict); + keyCountMap.remove(keyToEvict); + } + + keyValueMap.put(key, value); + int prevCount = keyCountMap.getOrDefault(key, 0); + keyCountMap.put(key, 1); + + countKeysMap.getOrDefault(prevCount, new LinkedHashSet<>()).remove(key); + countKeysMap.putIfAbsent(1, new LinkedHashSet<>()); + countKeysMap.get(1).add(key); + + minCount = 1; + } + + + public static void main(String[] args) { + LFUCache lfuCache = new LFUCache(2); + lfuCache.put(2, 2); + lfuCache.put(3, 3); + lfuCache.put(4, 4); + assertEquals(-1, lfuCache.get(2)); + assertEquals(3, lfuCache.get(3)); + lfuCache.put(5, 5); + assertEquals(-1, lfuCache.get(4)); + + lfuCache = new LFUCache(2); + lfuCache.put(3, 1); + lfuCache.put(2, 1); + lfuCache.put(2, 2); + lfuCache.put(4, 4); + assertEquals(-1, lfuCache.get(3)); + assertEquals(2, lfuCache.get(2)); + + lfuCache = new LFUCache(2); + lfuCache.put(2, 1); + lfuCache.put(2, 2); + assertEquals(2, lfuCache.get(2)); + lfuCache.put(1, 1); + lfuCache.put(4, 4); + assertEquals(2, lfuCache.get(2)); + + lfuCache = new LFUCache(2); + assertEquals(-1, lfuCache.get(2)); + lfuCache.put(2, 6); + assertEquals(-1, lfuCache.get(1)); + lfuCache.put(1, 1); + lfuCache.put(1, 2); + assertEquals(2, lfuCache.get(1)); + assertEquals(6, lfuCache.get(2)); + + // todo fix some test cases https://leetcode.com/submissions/detail/253376947/ + } +} \ No newline at end of file diff --git a/src/main/java/com/rampatra/linkedlists/LRUCache.java b/src/main/java/com/rampatra/linkedlists/LRUCache.java index 5a8d12f1..ed046035 100644 --- a/src/main/java/com/rampatra/linkedlists/LRUCache.java +++ b/src/main/java/com/rampatra/linkedlists/LRUCache.java @@ -2,6 +2,7 @@ import java.util.Iterator; import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.Map; /** @@ -20,7 +21,7 @@ */ public class LRUCache { - LinkedHashMap linkedHashMap; + private LinkedHashMap linkedHashMap; // initialize cache LRUCache(final int size) { @@ -37,7 +38,7 @@ V add(E key, V value) { } V get(E key) { - return linkedHashMap.get(key); + return linkedHashMap.get(key); } private void print() { @@ -52,12 +53,13 @@ public static void main(String[] args) { cache.add(1, 1); cache.add(2, 2); cache.add(3, 3); + cache.print(); // initial cache contents + + cache.add(4, 4); // should remove 1 as it was accessed last cache.print(); - if (cache.get(4) == null) { - cache.add(4, 4); - } - cache.print(); - cache.add(5, 5); + + cache.get(2); + cache.add(5, 5); // should remove 3 as 2 was recently accessed cache.print(); } } From 27a92f7a20c771a41facd1aedc5f96061d16cb7a Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Tue, 20 Aug 2019 21:38:36 +0100 Subject: [PATCH 152/164] lru cache: done --- .../java/com/leetcode/design/LFUCache.java | 2 +- .../java/com/leetcode/design/LRUCache.java | 61 +++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/leetcode/design/LRUCache.java diff --git a/src/main/java/com/leetcode/design/LFUCache.java b/src/main/java/com/leetcode/design/LFUCache.java index 0a3e9b8e..595b5a52 100644 --- a/src/main/java/com/leetcode/design/LFUCache.java +++ b/src/main/java/com/leetcode/design/LFUCache.java @@ -22,7 +22,7 @@ * Could you do both operations in O(1) time complexity? * * Note: - * - + * - When setting a key which is already present, reset its frequency/count to 1. * * @author rampatra * @since 2019-08-20 diff --git a/src/main/java/com/leetcode/design/LRUCache.java b/src/main/java/com/leetcode/design/LRUCache.java new file mode 100644 index 00000000..162889f2 --- /dev/null +++ b/src/main/java/com/leetcode/design/LRUCache.java @@ -0,0 +1,61 @@ +package com.leetcode.design; + +import java.util.LinkedHashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Level: Medium + * Link: https://leetcode.com/problems/lru-cache/ + * Description: + * Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following + * operations: get and put. + * + * get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1. + * put(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it + * should invalidate the least recently used item before inserting a new item. + * + * The cache is initialized with a positive capacity. + * + * Follow up: + * Could you do both operations in O(1) time complexity? + * + * Runtime: 54 ms. + * + * @author rampatra + * @since 2019-08-20 + */ +public class LRUCache { + + private LinkedHashMap cache; + + public LRUCache(int capacity) { + this.cache = new LinkedHashMap(capacity, 0.75f, true) { + @Override + protected boolean removeEldestEntry(Map.Entry eldest) { + return size() > capacity; + } + }; + } + + public int get(int key) { + Integer val = cache.get(key); + return val == null ? -1 : val; + } + + public void put(int key, int value) { + cache.put(key, value); + } + + public static void main(String[] args) { + LRUCache cache = new LRUCache(2); + cache.put(1,1); + cache.put(2,2); + cache.put(1,1); + cache.put(3,3); + assertEquals(1, cache.get(1)); + assertEquals(-1, cache.get(2)); + assertEquals(3, cache.get(3)); + } +} \ No newline at end of file From 142a8495ff206f860a0c1ab9a91773a4d8fac439 Mon Sep 17 00:00:00 2001 From: Ram Patra Date: Wed, 21 Aug 2019 13:59:15 +0100 Subject: [PATCH 153/164] minor refactorings --- .../treesandgraphs/FirstCommonAncestor.java | 5 +++- .../com/leetcode/arrays/BuySellStocks.java | 22 +++++++++++++++++- .../com/leetcode/arrays/BuySellStocksII.java | 4 ++-- .../com/leetcode/arrays/MergeSortedArray.java | 15 +++++++++++- .../java/com/leetcode/arrays/RotateArray.java | 23 ++++++++++++++++++- 5 files changed, 63 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/ctci/treesandgraphs/FirstCommonAncestor.java b/src/main/java/com/ctci/treesandgraphs/FirstCommonAncestor.java index f1fc5293..38977be3 100644 --- a/src/main/java/com/ctci/treesandgraphs/FirstCommonAncestor.java +++ b/src/main/java/com/ctci/treesandgraphs/FirstCommonAncestor.java @@ -5,6 +5,9 @@ * tree. Avoid storing additional nodes in a data structure. Also, for this question, the tree node * does NOT have access to its parent node. NOTE: This is not necessarily a binary search tree. * + * First Common Ancestor or the Least/Lowest Common Ancestor of two nodes is a node which is the + * closest to both of the nodes. + * * @author rampatra * @since 2019-02-24 */ @@ -18,7 +21,7 @@ public class FirstCommonAncestor { * - Returns null, if neither p nor q are in root's subtree. * - Else, returns the common ancestor of p and q. *

- * See {@link com.rampatra.trees.LeastCommonAncestorInBT} for a simpler version. + * See {@link com.rampatra.trees.LeastCommonAncestorInBT} for a better answer. * * @param root * @param a diff --git a/src/main/java/com/leetcode/arrays/BuySellStocks.java b/src/main/java/com/leetcode/arrays/BuySellStocks.java index d94c3296..4d4ba02b 100644 --- a/src/main/java/com/leetcode/arrays/BuySellStocks.java +++ b/src/main/java/com/leetcode/arrays/BuySellStocks.java @@ -2,7 +2,27 @@ /** * Level: Easy - * Problem: https://leetcode.com/problems/best-time-to-buy-and-sell-stock/ + * Link: https://leetcode.com/problems/best-time-to-buy-and-sell-stock/ + * Description: + * 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 (i.e., buy one and sell one share of the stock), + * design an algorithm to find the maximum profit. + * + * Note that you cannot sell a stock before you buy one. + * + * Example 1: + * + * Input: [7,1,5,3,6,4] + * Output: 5 + * Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 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 + * Explanation: In this case, no transaction is done, i.e. max profit = 0. * * @author rampatra * @since 2019-04-23 diff --git a/src/main/java/com/leetcode/arrays/BuySellStocksII.java b/src/main/java/com/leetcode/arrays/BuySellStocksII.java index 47966b48..d215246e 100644 --- a/src/main/java/com/leetcode/arrays/BuySellStocksII.java +++ b/src/main/java/com/leetcode/arrays/BuySellStocksII.java @@ -2,8 +2,8 @@ /** * Level: Easy - * Problem Link: https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/ - * Problem Description: + * Link: https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/ + * Description: * 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 diff --git a/src/main/java/com/leetcode/arrays/MergeSortedArray.java b/src/main/java/com/leetcode/arrays/MergeSortedArray.java index 09cd730d..975db8ec 100644 --- a/src/main/java/com/leetcode/arrays/MergeSortedArray.java +++ b/src/main/java/com/leetcode/arrays/MergeSortedArray.java @@ -4,7 +4,20 @@ /** * Level: Easy - * Problem Link: https://leetcode.com/problems/merge-sorted-array/ + * Link: https://leetcode.com/problems/merge-sorted-array/ + * Description: + * Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. + * + * Note: + * The number of elements initialized in nums1 and nums2 are m and n respectively. + * You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold + * additional elements from nums2. + * + * Example: + * Input: + * nums1 = [1,2,3,0,0,0], m = 3 + * nums2 = [2,5,6], n = 3 + * Output: [1,2,2,3,5,6] * * @author rampatra * @since 2019-04-26 diff --git a/src/main/java/com/leetcode/arrays/RotateArray.java b/src/main/java/com/leetcode/arrays/RotateArray.java index e4f6de33..91475160 100644 --- a/src/main/java/com/leetcode/arrays/RotateArray.java +++ b/src/main/java/com/leetcode/arrays/RotateArray.java @@ -4,7 +4,28 @@ /** * Level: Easy - * Problem: https://leetcode.com/problems/rotate-array/ + * Link: https://leetcode.com/problems/rotate-array/ + * Description: + * Given an array, rotate the array to the right by k steps, where k is non-negative. + * + * Example 1: + * Input: [1,2,3,4,5,6,7] and k = 3 + * Output: [5,6,7,1,2,3,4] + * Explanation: + * rotate 1 steps to the right: [7,1,2,3,4,5,6] + * rotate 2 steps to the right: [6,7,1,2,3,4,5] + * rotate 3 steps to the right: [5,6,7,1,2,3,4] + * + * Example 2: + * Input: [-1,-100,3,99] and k = 2 + * Output: [3,99,-1,-100] + * Explanation: + * rotate 1 steps to the right: [99,-1,-100,3] + * rotate 2 steps to the right: [3,99,-1,-100] + * + * Note: + * Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem. + * Could you do it in-place with O(1) extra space? * * @author rampatra * @since 2019-04-20 From 497e46319c0bbab7f106d8a03bf47f357dcfa29b Mon Sep 17 00:00:00 2001 From: Ram <2862724+rampatra@users.noreply.github.com> Date: Thu, 16 Jul 2020 09:09:21 +0100 Subject: [PATCH 154/164] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 989a3224..58fe8ecb 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ The repo consists of solutions to numerous problems using different data structu contains solutions to HackerRank problems which I have solved so far and questions from Cracking the Coding Interview Book _(6th Edition)_. -You can also refer to my [Java Notes](http://java.ramswaroop.me) for a quick refresh on the Java concepts. +You can also refer to my [Java Notes](http://blog.rampatra.com/category/java) for a quick refresh on the Java concepts. ## Contents From 9d705a5a9818ecb5c23b475791826896dba74d2b Mon Sep 17 00:00:00 2001 From: Ram <2862724+rampatra@users.noreply.github.com> Date: Sat, 20 Feb 2021 08:38:49 +0000 Subject: [PATCH 155/164] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 58fe8ecb..06b6d7b6 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ The repo consists of solutions to numerous problems using different data structu contains solutions to HackerRank problems which I have solved so far and questions from Cracking the Coding Interview Book _(6th Edition)_. -You can also refer to my [Java Notes](http://blog.rampatra.com/category/java) for a quick refresh on the Java concepts. +You can also refer to my [Java Notes](http://blog.rampatra.com/category/java) for a quick refresh on the Java concepts. Lastly, feel free to connect with me on [Twitter](https://twitter.com/ram__patra) for any queries or concerns. All the best! ## Contents From 8423f8164cd1ea0acd729d3725b7e70efc0f1e4e Mon Sep 17 00:00:00 2001 From: Ram <2862724+rampatra@users.noreply.github.com> Date: Mon, 28 Mar 2022 20:34:56 +0100 Subject: [PATCH 156/164] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 06b6d7b6..e6ae9ca8 100644 --- a/README.md +++ b/README.md @@ -50,3 +50,5 @@ IntelliJ IDEA 2018.1.4 (Ultimate Edition) MacBook Pro 2.5 GHz Intel Core i7 16 GB 1600 MHz DDR3 + +_P.S. If my open-source project(s) benefitted you in some way or the other, a follow on [Twitter](https://twitter.com/ram__patra) would be greatly appreciated 🙇‍♂️._ From 7550901537074d35adb0eef09138383c9e162fd0 Mon Sep 17 00:00:00 2001 From: Ram <2862724+rampatra@users.noreply.github.com> Date: Mon, 28 Mar 2022 20:40:27 +0100 Subject: [PATCH 157/164] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index e6ae9ca8..0bf98d9d 100644 --- a/README.md +++ b/README.md @@ -51,4 +51,6 @@ MacBook Pro 2.5 GHz Intel Core i7 16 GB 1600 MHz DDR3 +--- + _P.S. If my open-source project(s) benefitted you in some way or the other, a follow on [Twitter](https://twitter.com/ram__patra) would be greatly appreciated 🙇‍♂️._ From 82ae2fd7fc1f364a67e716d7f70ba6289f2357e6 Mon Sep 17 00:00:00 2001 From: Ram <2862724+rampatra@users.noreply.github.com> Date: Sun, 19 Jun 2022 12:42:01 +0100 Subject: [PATCH 158/164] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0bf98d9d..7be895d1 100644 --- a/README.md +++ b/README.md @@ -53,4 +53,4 @@ MacBook Pro --- -_P.S. If my open-source project(s) benefitted you in some way or the other, a follow on [Twitter](https://twitter.com/ram__patra) would be greatly appreciated 🙇‍♂️._ +_P.S. For any queries or concerns, [Twitter](https://twitter.com/ram__patra) is the best place to reach out to me. I'll try my best to help._ From 87c869ba97e5c18ff111ce5394323b872be5a3b9 Mon Sep 17 00:00:00 2001 From: Ram <2862724+rampatra@users.noreply.github.com> Date: Sun, 19 Jun 2022 12:49:02 +0100 Subject: [PATCH 159/164] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7be895d1..ce82e09f 100644 --- a/README.md +++ b/README.md @@ -53,4 +53,4 @@ MacBook Pro --- -_P.S. For any queries or concerns, [Twitter](https://twitter.com/ram__patra) is the best place to reach out to me. I'll try my best to help._ +_P.S. For any queries or concerns, you can reach out to me on [Twitter](https://twitter.com/ram__patra). I'll try my best to help 🙏._ From db15c1e0450c801aa3ee56e0d930fa3e33e3fb62 Mon Sep 17 00:00:00 2001 From: Ram <2862724+rampatra@users.noreply.github.com> Date: Sat, 6 Aug 2022 12:54:42 +0100 Subject: [PATCH 160/164] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ce82e09f..57f6c1b7 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ The repo consists of solutions to numerous problems using different data structu contains solutions to HackerRank problems which I have solved so far and questions from Cracking the Coding Interview Book _(6th Edition)_. -You can also refer to my [Java Notes](http://blog.rampatra.com/category/java) for a quick refresh on the Java concepts. Lastly, feel free to connect with me on [Twitter](https://twitter.com/ram__patra) for any queries or concerns. All the best! +You can also refer to my [Java Notes](http://blog.rampatra.com/category/java) for a quick refresh on the Java concepts or if you want a break from coding then can read about my [interview experiences](https://blog.rampatra.com/category/interview/) at various companies. Lastly, feel free to connect with me on [Twitter](https://twitter.com/ram__patra) for any queries or concerns. All the best! ## Contents From 957d03bfde64f6a2a0a2ba7334d6e2a3ff2a43e9 Mon Sep 17 00:00:00 2001 From: Ram <2862724+rampatra@users.noreply.github.com> Date: Wed, 12 Oct 2022 10:50:00 +0100 Subject: [PATCH 161/164] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 57f6c1b7..b1bbc14c 100644 --- a/README.md +++ b/README.md @@ -53,4 +53,4 @@ MacBook Pro --- -_P.S. For any queries or concerns, you can reach out to me on [Twitter](https://twitter.com/ram__patra). I'll try my best to help 🙏._ +_P.S. For any queries or concerns, you can reach out to me on [Twitter](https://twitter.com/ram__patra). I'll try my best to help 🙏. And, if you're keen to know what I'm currently working on then check out [Presentify](https://presentify.compzets.com)._ From 615e19b8ee550d117308e5df0fc790731710ffa4 Mon Sep 17 00:00:00 2001 From: Ram <2862724+rampatra@users.noreply.github.com> Date: Wed, 17 Jul 2024 19:37:56 +0100 Subject: [PATCH 162/164] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b1bbc14c..07ebdb73 100644 --- a/README.md +++ b/README.md @@ -53,4 +53,4 @@ MacBook Pro --- -_P.S. For any queries or concerns, you can reach out to me on [Twitter](https://twitter.com/ram__patra). I'll try my best to help 🙏. And, if you're keen to know what I'm currently working on then check out [Presentify](https://presentify.compzets.com)._ +_P.S. For any queries or concerns, you can reach out to me on [Twitter](https://twitter.com/ram__patra). I'll try my best to help 🙏. And, if you're keen to know what I'm currently working on then check out [Presentify](https://presentifyapp.com), or [ToDoBar](https://todobarapp.com/)._ From 7eadd472a3578984626c4d31fec840ecead6fd28 Mon Sep 17 00:00:00 2001 From: Ram <2862724+rampatra@users.noreply.github.com> Date: Wed, 18 Dec 2024 16:12:11 +0000 Subject: [PATCH 163/164] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 07ebdb73..195f3c39 100644 --- a/README.md +++ b/README.md @@ -53,4 +53,4 @@ MacBook Pro --- -_P.S. For any queries or concerns, you can reach out to me on [Twitter](https://twitter.com/ram__patra). I'll try my best to help 🙏. And, if you're keen to know what I'm currently working on then check out [Presentify](https://presentifyapp.com), or [ToDoBar](https://todobarapp.com/)._ +_P.S. For any queries or concerns, you can reach out to me on [Twitter](https://twitter.com/rampatra_). I'll try my best to help 🙏. And, if you're keen to know what I'm currently working on then check out [Presentify](https://presentifyapp.com), [FaceScreen](https://facescreenapp.com/), or [ToDoBar](https://todobarapp.com/)._ From c23f98b7f70ab7ca613c34672eeaca8b38c7c43b Mon Sep 17 00:00:00 2001 From: Ram <2862724+rampatra@users.noreply.github.com> Date: Mon, 7 Apr 2025 15:38:06 +0100 Subject: [PATCH 164/164] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 195f3c39..33b68334 100644 --- a/README.md +++ b/README.md @@ -53,4 +53,4 @@ MacBook Pro --- -_P.S. For any queries or concerns, you can reach out to me on [Twitter](https://twitter.com/rampatra_). I'll try my best to help 🙏. And, if you're keen to know what I'm currently working on then check out [Presentify](https://presentifyapp.com), [FaceScreen](https://facescreenapp.com/), or [ToDoBar](https://todobarapp.com/)._ +_P.S. For any queries or concerns, you can reach out to me on [Twitter](https://twitter.com/rampatra_). I'll try my best to help 🙏. And, if you're keen to know what I'm currently working on then check out [Presentify](https://presentifyapp.com), [FaceScreen](https://facescreenapp.com/), [ToDoBar](https://todobarapp.com/), [SimpleFill](https://simplefillapp.com/), and [Apps.Deals](https://www.apps.deals)._