+ * 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/ctci/bitmanipulation/FlipBitToWin.java b/src/main/java/com/ctci/bitmanipulation/FlipBitToWin.java new file mode 100644 index 00000000..4424f7ab --- /dev/null +++ b/src/main/java/com/ctci/bitmanipulation/FlipBitToWin.java @@ -0,0 +1,53 @@ +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)); + } +} 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/bitmanipulation/NextNumber.java b/src/main/java/com/ctci/bitmanipulation/NextNumber.java new file mode 100644 index 00000000..ec817c13 --- /dev/null +++ b/src/main/java/com/ctci/bitmanipulation/NextNumber.java @@ -0,0 +1,124 @@ +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 rightmostNonTrailingZero = 0; + int noOfZeros = 0; + int noOfOnes = 0; + int temp = n; + + /* Count the number of zeros and ones until the rightmost non-trailing zero + For example, see below: + + n = 10110110011110 + ^ + */ + while ((temp & 1) == 0 && temp != 0) { + noOfZeros++; + temp >>>= 1; + } + + while ((temp & 1) == 1 && temp != 0) { + noOfOnes++; + temp >>>= 1; + } + + if (noOfZeros + noOfOnes == 31 || noOfZeros + noOfOnes == 0) { + return -1; + } + + /* 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 = 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) + ^ + */ + 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 rightmostNonTrailingOne = 0; + int noOfZeros = 0; + int noOfOnes = 0; + int temp = n; + + while ((temp & 1) == 1 && temp != 0) { + noOfOnes++; + temp >>>= 1; + } + + if (temp == 0) { + return -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; + } + + 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/bitmanipulation/PairwiseSwap.java b/src/main/java/com/ctci/bitmanipulation/PairwiseSwap.java new file mode 100644 index 00000000..a1219d47 --- /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(0x55555555)); + System.out.println(Integer.toBinaryString(0xaaaaaaaa)); + } +} \ No newline at end of file diff --git a/src/main/java/com/ctci/linkedlists/DeleteMiddleNode.java b/src/main/java/com/ctci/linkedlists/DeleteMiddleNode.java new file mode 100644 index 00000000..c4b4052e --- /dev/null +++ b/src/main/java/com/ctci/linkedlists/DeleteMiddleNode.java @@ -0,0 +1,65 @@ +package com.ctci.linkedlists; + +/** + * @author rampatra + * @since 2019-01-27 + */ +public class DeleteMiddleNode { + + /** + * Implement an algorithm to delete a node in the middle (i.e., any node but the first and last node, not + * necessarily the exact middle) of a singly linked list, given only access to that node. + *
+ * EXAMPLE + * Input: the node c from the linked list a->b->c->d->e->f + * Result: nothing is returned, but the new linked list looks like a->b->d->e->f + * + * @param middle the node to be deleted + */ + private static void deleteMiddleNode(Node middle) { + if (middle == null || middle.next == null) { + return; + } + // copy the data from the next node over to the middle node, and then to delete the next node + Node next = middle.next; + middle.val = next.val; + middle.next = next.next; + } + + public static void main(String[] args) { + Node l1 = new Node(1); + l1.next = new Node(2); + l1.next.next = new Node(3); + l1.next.next.next = new Node(4); + l1.next.next.next.next = new Node(5); + l1.next.next.next.next.next = new Node(6); + l1.print(); + deleteMiddleNode(l1.next.next); + l1.print(); + + System.out.println("----"); + + l1 = new Node(1); + l1.next = new Node(2); + l1.next.next = new Node(3); + l1.print(); + deleteMiddleNode(l1.next); + l1.print(); + + System.out.println("----"); + + l1 = new Node(1); + l1.next = new Node(3); + l1.print(); + deleteMiddleNode(l1); + l1.print(); + + System.out.println("----"); + + l1 = new Node(1); + l1.next = new Node(3); + l1.print(); + deleteMiddleNode(l1.next); + l1.print(); + } +} diff --git a/src/main/java/com/ctci/linkedlists/Intersection.java b/src/main/java/com/ctci/linkedlists/Intersection.java new file mode 100644 index 00000000..4665fe43 --- /dev/null +++ b/src/main/java/com/ctci/linkedlists/Intersection.java @@ -0,0 +1,104 @@ +package com.ctci.linkedlists; + +/** + * @author rampatra + * @since 2019-02-02 + */ +public class Intersection { + + /** + * Given two (singly) linked lists, determine if the two lists intersect. Return the intersecting node. Note that + * the intersection is defined based on reference, not value. That is, if the kth node of the first linked list is + * the exact same node (by reference) as the jth node of the second linked list, then they are intersecting. + * + * @param n1 + * @param n2 + * @return the intersecting node, {@code null} otherwise. + */ + private static Node findIntersectingNode(Node n1, Node n2) { + Node curr1 = n1; + Node curr2 = n2; + int len1 = 1; + int len2 = 1; + + /* Calculate the length of both linked lists */ + while (curr1 != null && curr1.next != null) { + len1++; + curr1 = curr1.next; + } + while (curr2 != null && curr2.next != null) { + len2++; + curr2 = curr2.next; + } + + // if different tail nodes, they don't intersect + if (curr1 != curr2) { + return null; + } + + curr1 = n1; + curr2 = n2; + + /* Get rid of the extra nodes from the longer list */ + if (len1 > len2) { + for (int i = 0; i < len1 - len2; i++) { + curr1 = curr1.next; + } + } + if (len2 > len1) { + for (int i = 0; i < len2 - len1; i++) { + curr2 = curr2.next; + } + } + + // move both pointers until you have a collision + while (curr1 != curr2) { + curr1 = curr1.next; + curr2 = curr2.next; + } + + // return either + return curr1; + } + + public static void main(String[] args) { + Node l1 = new Node(1); + l1.next = new Node(2); + l1.next.next = new Node(3); + l1.next.next.next = new Node(4); + l1.next.next.next.next = new Node(5); + l1.next.next.next.next.next = new Node(5); + Node l2 = new Node(1); + l2.next = new Node(4); + l2.next.next = new Node(2); + l2.next.next.next = new Node(3); + l2.next.next.next.next = l1.next.next.next; + 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; + 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); + l1.next = new Node(2); + l1.next.next = new Node(3); + l1.next.next.next = new Node(4); + l1.next.next.next.next = new Node(5); + l1.next.next.next.next.next = new Node(5); + l2 = new Node(1); + l2.next = new Node(4); + l2.next.next = new Node(2); + l2.next.next.next = new Node(3); + 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 new file mode 100644 index 00000000..8fff3f9d --- /dev/null +++ b/src/main/java/com/ctci/linkedlists/KthToLastElement.java @@ -0,0 +1,88 @@ +package com.ctci.linkedlists; + +/** + * @author rampatra + * @since 21/11/2018 + */ +public class KthToLastElement { + + /** + * Finds the kth node from the end in a linked list. + * + * @param head is the reference to the head of the linked list + * @param k is the position of element from the end + * @return the Kth node from the end + */ + private static Node getKthToLastElement(Node head, int k) { + Node slow = head; + Node fast = head; + int i = 0; + + // forward the fast reference k times + while (i < k) { + if (fast == null) return null; // k is out of bounds + fast = fast.next; + i++; + } + + while (fast != null) { + slow = slow.next; + fast = fast.next; + } + return slow; + } + + /** + * This approach is recursive and it just prints the kth to last node instead + * of returning the node. + * + * @param head starting node of the linklist + * @param k kth to last node to print + * @return the index of the kth to last node + */ + private static int printKthToLastElement(Node head, int k) { + if (head == null) { + return 0; + } + int index = printKthToLastElement(head.next, k) + 1; + if (index == k) { + System.out.println(head.val); + } + return index; + } + + public static void main(String[] args) { + Node l1 = new Node(1); + l1.next = new Node(6); + l1.next.next = new Node(3); + l1.next.next.next = new Node(4); + l1.next.next.next.next = new Node(5); + l1.next.next.next.next.next = new Node(7); + 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); + + Node l2 = new Node(1); + l2.next = new Node(6); + l2.next.next = new Node(2); + l2.next.next.next = new Node(3); + l2.next.next.next.next = new Node(4); + l2.next.next.next.next.next = new Node(7); + l2.print(); + System.out.println("k=1: " + getKthToLastElement(l2, 1).val); + System.out.print("k=1: "); + printKthToLastElement(l2, 1); + + Node l3 = new Node(1); + l3.next = new Node(6); + l3.next.next = new Node(3); + l3.next.next.next = new Node(3); + l3.next.next.next.next = new Node(4); + l3.next.next.next.next.next = new Node(7); + 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/LoopDetection.java b/src/main/java/com/ctci/linkedlists/LoopDetection.java new file mode 100644 index 00000000..d0a9a110 --- /dev/null +++ b/src/main/java/com/ctci/linkedlists/LoopDetection.java @@ -0,0 +1,67 @@ +package com.ctci.linkedlists; + +/** + * @author rampatra + * @since 2019-02-03 + */ +public class LoopDetection { + + /** + * Given a circular linked list, implement an algorithm that returns the node at the beginning of the loop. + * DEFINITION + * Circular linked list: A (corrupt) linked list in which a node's next pointer points to an earlier node, so + * as to make a loop in the linked list. + * 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.
+ */
+ private static Node findLoopStartNode(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;
+ }
+ }
+
+ /* Error check - no meeting point, and therefore no loop */
+ if (fast == null || fast.next == null) {
+ return null;
+ }
+
+ /* Move slow to Head. Keep fast at Meeting Point. Each are k steps from the
+ * Loop Start. If they move at the same pace, they must meet at Loop Start. */
+ slow = head;
+ while (slow != fast) {
+ slow = slow.next;
+ fast = fast.next;
+ }
+
+ /* You can return either as now both point to the start of the loop */
+ return fast;
+ }
+
+ public static void main(String[] args) {
+ /*
+ * 1 -> 2 -> 3 -> 4 -> 5 -> 6
+ * ^ |
+ * |_________|
+ */
+ Node l1 = new Node(1);
+ l1.next = new Node(2);
+ l1.next.next = new Node(3);
+ l1.next.next.next = new Node(4);
+ l1.next.next.next.next = new Node(5);
+ l1.next.next.next.next.next = new Node(6);
+ 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/ctci/linkedlists/Node.java b/src/main/java/com/ctci/linkedlists/Node.java
new file mode 100644
index 00000000..5c0d1ec3
--- /dev/null
+++ b/src/main/java/com/ctci/linkedlists/Node.java
@@ -0,0 +1,23 @@
+package com.ctci.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);
+ }
+}
diff --git a/src/main/java/com/ctci/linkedlists/Palindrome.java b/src/main/java/com/ctci/linkedlists/Palindrome.java
new file mode 100644
index 00000000..57bb184d
--- /dev/null
+++ b/src/main/java/com/ctci/linkedlists/Palindrome.java
@@ -0,0 +1,107 @@
+package com.ctci.linkedlists;
+
+import java.util.Stack;
+
+/**
+ * @author rampatra
+ * @since 2019-02-02
+ */
+public class Palindrome {
+
+ /**
+ * Checks whether a Linked List is palindrome by using a stack.
+ *
+ * @param head starting node of the linked list.
+ * @return {@code true} if linked list palindrome, {@code false} otherwise.
+ */
+ private static boolean isPalindrome(Node head) {
+ Node curr = head;
+ Stack
+ * EXAMPLE:
+ * Input: 3 -> 5 -> 8 -> 5 -> 10 -> 2 -> 1 [partition=5]
+ * Output: 3 -> 1 -> 2 -> 10 -> 5 -> 5 -> 8
+ *
+ * @author rampatra
+ * @since 2019-01-28
+ */
+public class Partition {
+
+ private static Node partition(Node head, int x) {
+ Node leftPartitionHead = null;
+ Node leftPartitionCurr = null;
+ Node rightPartitionHead = null;
+ Node rightPartitionCurr = null;
+ Node curr = head;
+
+ while (curr != null) {
+ if (curr.val < x) {
+ if (leftPartitionHead == null) {
+ leftPartitionHead = curr;
+ leftPartitionCurr = curr;
+ } else {
+ leftPartitionCurr.next = curr;
+ leftPartitionCurr = leftPartitionCurr.next;
+ }
+ } else {
+ if (rightPartitionHead == null) {
+ rightPartitionHead = curr;
+ rightPartitionCurr = curr;
+ } else {
+ rightPartitionCurr.next = curr;
+ rightPartitionCurr = rightPartitionCurr.next;
+ }
+ }
+ curr = curr.next;
+ }
+
+ if (leftPartitionCurr != null) leftPartitionCurr.next = rightPartitionHead;
+ if (rightPartitionCurr != null) rightPartitionCurr.next = null;
+
+ return leftPartitionHead;
+ }
+
+ public static void main(String[] args) {
+ Node l1 = new Node(3);
+ l1.next = new Node(5);
+ l1.next.next = new Node(8);
+ l1.next.next.next = new Node(5);
+ 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);
+ l1.print();
+ l1.print();
+
+ System.out.println("----");
+
+ l1 = new Node(1);
+ l1.next = new Node(2);
+ l1.next.next = new Node(3);
+ l1.print();
+ l1.print();
+
+ System.out.println("----");
+
+ l1 = new Node(3);
+ l1.next = new Node(2);
+ l1.next.next = new Node(1);
+ l1.print();
+ l1.print();
+
+ System.out.println("----");
+
+ l1 = new Node(1);
+ l1.print();
+ l1.print();
+
+ System.out.println("----");
+
+ l1 = null;
+ 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
new file mode 100644
index 00000000..31029188
--- /dev/null
+++ b/src/main/java/com/ctci/linkedlists/RemoveDuplicates.java
@@ -0,0 +1,88 @@
+package com.ctci.linkedlists;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author rampatra
+ * @since 21/11/2018
+ */
+public class RemoveDuplicates {
+
+ /**
+ * Removes duplicates in an unsorted linked list by using additional memory
+ * and two references.
+ *
+ * If asked not to use any additional memory then you can
+ * loop through the list for each node and check for repeated elements but bear
+ * in mind that the time complexity of this would be O(n^2) where n is the number
+ * of nodes in the linked list.
+ *
+ * @param head reference to the head of the linked list
+ */
+ private static void removeDuplicatesFromUnsortedList(Node head) {
+ Set
+ * EXAMPLE
+ * Input: (7-> 1 -> 6) + (5 -> 9 -> 2).That is, 617 + 295.
+ * Output: 2 -> 1 -> 9. That is, 912.
+ *
+ * @param num1
+ * @param num2
+ * @return
+ */
+ private static Node sumLists(Node num1, Node num2) {
+ int carry = 0;
+ int sum;
+ Node sumList = null, curr = null;
+ while (num1 != null || num2 != null) {
+ sum = ((num1 == null) ? 0 : num1.val) + ((num2 == null) ? 0 : num2.val) + carry;
+ carry = sum / 10;
+ if (sumList == null) {
+ sumList = new Node(sum % 10);
+ curr = sumList;
+ } else {
+ curr.next = new Node(sum % 10);
+ curr = curr.next;
+ }
+ if (num1 != null) num1 = num1.next;
+ if (num2 != null) num2 = num2.next;
+ }
+ if (carry != 0) {
+ curr.next = new Node(carry);
+ }
+ return sumList;
+ }
+
+ // TODO: After doing reverseListRecursive
+ private static Node sumListsWithMostSignificantDigitAtHead(Node n1, Node n2) {
+ return null;
+ }
+
+ public static void main(String[] args) {
+ Node l1 = new Node(9);
+ l1.next = new Node(9);
+ l1.next.next = new Node(9);
+
+ Node l2 = new Node(9);
+ l2.next = new Node(9);
+ l2.next.next = new Node(9);
+
+ l1.print();
+ l2.print();
+ sumLists(l1, l2).print();
+ System.out.println("-----------");
+
+ l1 = new Node(9);
+ l1.next = new Node(9);
+
+ l2 = new Node(9);
+ l2.next = new Node(9);
+ l2.next.next = new Node(9);
+
+ l1.print();
+ l2.print();
+ sumLists(l1, l2).print();
+ System.out.println("-----------");
+
+ l1 = null;
+ l2 = new Node(9);
+ l2.next = new Node(9);
+ l2.next.next = new Node(8);
+
+ l1.print();
+ l2.print();
+ sumLists(l1, l2).print();
+ }
+}
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/ctci/stacksandqueues/QueueViaStacks.java b/src/main/java/com/ctci/stacksandqueues/QueueViaStacks.java
new file mode 100644
index 00000000..271fd8e4
--- /dev/null
+++ b/src/main/java/com/ctci/stacksandqueues/QueueViaStacks.java
@@ -0,0 +1,61 @@
+package com.ctci.stacksandqueues;
+
+import java.util.NoSuchElementException;
+import java.util.Stack;
+
+/**
+ * Implement a queue using two stacks. No other data structures to be used.
+ *
+ * @author rampatra
+ * @since 2019-02-06
+ */
+public class QueueViaStacks
+ * See {@link com.rampatra.trees.LeastCommonAncestorInBT} for a better answer.
+ *
+ * @param root
+ * @param a
+ * @param b
+ * @return the least common ancestor node
+ */
+ private static TreeNode findFCA(TreeNode root, TreeNode a, TreeNode b) {
+ if (root == null) { // validation
+ return null;
+ }
+ if (root == a && root == b) { // optimization
+ return root;
+ }
+
+ TreeNode left = findFCA(root.left, a, b);
+ if (left != null && left != a && left != b) {
+ return left;
+ }
+
+ TreeNode right = findFCA(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("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/FirstCommonAncestorWithParentAccess.java b/src/main/java/com/ctci/treesandgraphs/FirstCommonAncestorWithParentAccess.java
new file mode 100644
index 00000000..5aa453cf
--- /dev/null
+++ b/src/main/java/com/ctci/treesandgraphs/FirstCommonAncestorWithParentAccess.java
@@ -0,0 +1,115 @@
+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 FirstCommonAncestorWithParentAccess {
+
+ /**
+ * 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, 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;
+
+ // 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("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/ctci/treesandgraphs/GraphNode.java b/src/main/java/com/ctci/treesandgraphs/GraphNode.java
new file mode 100644
index 00000000..573cccf3
--- /dev/null
+++ b/src/main/java/com/ctci/treesandgraphs/GraphNode.java
@@ -0,0 +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
+ * Time Complexity: O(n) as we touch all the nodes in the tree.
+ * Space Complexity: O(n) as we use a list to store all the elements in the tree. If we
+ * had used just a instance/class variable, the space complexity would have been O(log n)
+ * as there can be up to O(log n) recursive calls as we may recurse up to the depth of
+ * the tree. Note, the tree has to balanced though.
+ *
+ * @param node
+ * @param values
+ * @return
+ */
+ private static boolean isBST(TreeNode node, List
+ * Time Complexity: O(n) as we touch all the nodes in the tree.
+ * Space Complexity: O(log n) as there are up to O(log n) recursive calls on the stack
+ * as we may recurse up to the depth fo the tree. Note, the tree has to be balanced though.
+ *
+ * @param node
+ * @param min
+ * @param max
+ * @return
+ */
+ private static boolean isBSTApproach2(TreeNode node, int min, int max) {
+ if (node == null) return true;
+
+ if (node.val < min || node.val > max) {
+ return false;
+ }
+
+ return isBSTApproach2(node.left, min, node.val) && isBSTApproach2(node.right, node.val + 1, max);
+ }
+
+ public static void main(String[] args) {
+ TreeNode treeRoot = new TreeNode(1);
+ treeRoot.left = new TreeNode(2);
+ treeRoot.right = new TreeNode(3);
+ System.out.println("Is BST Approach 1: " + isBST(treeRoot));
+ System.out.println("Is BST Approach 2: " + isBSTApproach2(treeRoot));
+
+ treeRoot = new TreeNode(2);
+ treeRoot.left = new TreeNode(1);
+ treeRoot.right = new TreeNode(3);
+ System.out.println("Is BST Approach 1: " + isBST(treeRoot));
+ System.out.println("Is BST Approach 2: " + isBSTApproach2(treeRoot));
+
+ 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);
+ treeRoot.right.left.right = new TreeNode(7);
+ System.out.println("Is BST Approach 1: " + isBST(treeRoot));
+ System.out.println("Is BST Approach 2: " + isBSTApproach2(treeRoot));
+ }
+}
\ No newline at end of file
diff --git a/src/com/hackerrank/algorithms/arraysandsorting/InsertionSort1.java b/src/main/java/com/hackerrank/algorithms/arraysandsorting/InsertionSort1.java
similarity index 98%
rename from src/com/hackerrank/algorithms/arraysandsorting/InsertionSort1.java
rename to src/main/java/com/hackerrank/algorithms/arraysandsorting/InsertionSort1.java
index 7dadb554..6fd03542 100644
--- a/src/com/hackerrank/algorithms/arraysandsorting/InsertionSort1.java
+++ b/src/main/java/com/hackerrank/algorithms/arraysandsorting/InsertionSort1.java
@@ -4,7 +4,7 @@
/**
* Created by IntelliJ IDEA.
- * User: ramswaroop
+ * User: rampatra
* Date: 3/1/15
* Time: 8:58 PM
* To change this template go to Preferences | IDE Settings | File and Code Templates
diff --git a/src/com/hackerrank/algorithms/arraysandsorting/InsertionSort2.java b/src/main/java/com/hackerrank/algorithms/arraysandsorting/InsertionSort2.java
similarity index 98%
rename from src/com/hackerrank/algorithms/arraysandsorting/InsertionSort2.java
rename to src/main/java/com/hackerrank/algorithms/arraysandsorting/InsertionSort2.java
index 93ee48a3..cd710eb9 100644
--- a/src/com/hackerrank/algorithms/arraysandsorting/InsertionSort2.java
+++ b/src/main/java/com/hackerrank/algorithms/arraysandsorting/InsertionSort2.java
@@ -4,7 +4,7 @@
/**
* Created by IntelliJ IDEA.
- * User: ramswaroop
+ * User: rampatra
* Date: 3/1/15
* Time: 9:42 PM
* To change this template go to Preferences | IDE Settings | File and Code Templates
diff --git a/src/com/hackerrank/algorithms/arraysandsorting/IntroTutorial.java b/src/main/java/com/hackerrank/algorithms/arraysandsorting/IntroTutorial.java
similarity index 93%
rename from src/com/hackerrank/algorithms/arraysandsorting/IntroTutorial.java
rename to src/main/java/com/hackerrank/algorithms/arraysandsorting/IntroTutorial.java
index aac8e479..aeb8ea5f 100644
--- a/src/com/hackerrank/algorithms/arraysandsorting/IntroTutorial.java
+++ b/src/main/java/com/hackerrank/algorithms/arraysandsorting/IntroTutorial.java
@@ -5,7 +5,7 @@
/**
* Created by IntelliJ IDEA.
- * User: ramswaroop
+ * User: rampatra
* Date: 3/1/15
* Time: 3:38 PM
* To change this template go to Preferences | IDE Settings | File and Code Templates
@@ -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/com/hackerrank/algorithms/arraysandsorting/LoopInvariant.java b/src/main/java/com/hackerrank/algorithms/arraysandsorting/LoopInvariant.java
similarity index 98%
rename from src/com/hackerrank/algorithms/arraysandsorting/LoopInvariant.java
rename to src/main/java/com/hackerrank/algorithms/arraysandsorting/LoopInvariant.java
index 2b8613e9..dd12ee7e 100644
--- a/src/com/hackerrank/algorithms/arraysandsorting/LoopInvariant.java
+++ b/src/main/java/com/hackerrank/algorithms/arraysandsorting/LoopInvariant.java
@@ -4,7 +4,7 @@
/**
* Created by IntelliJ IDEA.
- * User: ramswaroop
+ * User: rampatra
* Date: 3/2/15
* Time: 3:26 PM
* To change this template go to Preferences | IDE Settings | File and Code Templates
diff --git a/src/com/hackerrank/algorithms/arraysandsorting/QuickSort1.java b/src/main/java/com/hackerrank/algorithms/arraysandsorting/QuickSort1.java
similarity index 98%
rename from src/com/hackerrank/algorithms/arraysandsorting/QuickSort1.java
rename to src/main/java/com/hackerrank/algorithms/arraysandsorting/QuickSort1.java
index 7e14ca9b..0753f812 100644
--- a/src/com/hackerrank/algorithms/arraysandsorting/QuickSort1.java
+++ b/src/main/java/com/hackerrank/algorithms/arraysandsorting/QuickSort1.java
@@ -4,7 +4,7 @@
/**
* Created by IntelliJ IDEA.
- * User: ramswaroop
+ * User: rampatra
* Date: 3/2/15
* Time: 5:13 PM
* To change this template go to Preferences | IDE Settings | File and Code Templates
diff --git a/src/com/hackerrank/algorithms/arraysandsorting/QuickSort2.java b/src/main/java/com/hackerrank/algorithms/arraysandsorting/QuickSort2.java
similarity index 98%
rename from src/com/hackerrank/algorithms/arraysandsorting/QuickSort2.java
rename to src/main/java/com/hackerrank/algorithms/arraysandsorting/QuickSort2.java
index a366da37..b9b1dcba 100644
--- a/src/com/hackerrank/algorithms/arraysandsorting/QuickSort2.java
+++ b/src/main/java/com/hackerrank/algorithms/arraysandsorting/QuickSort2.java
@@ -4,7 +4,7 @@
/**
* Created by IntelliJ IDEA.
- * User: ramswaroop
+ * User: rampatra
* Date: 3/3/15
* Time: 1:05 PM
* To change this template go to Preferences | IDE Settings | File and Code Templates
diff --git a/src/com/hackerrank/algorithms/arraysandsorting/RunningTime.java b/src/main/java/com/hackerrank/algorithms/arraysandsorting/RunningTime.java
similarity index 98%
rename from src/com/hackerrank/algorithms/arraysandsorting/RunningTime.java
rename to src/main/java/com/hackerrank/algorithms/arraysandsorting/RunningTime.java
index 36a55877..27a0bd77 100644
--- a/src/com/hackerrank/algorithms/arraysandsorting/RunningTime.java
+++ b/src/main/java/com/hackerrank/algorithms/arraysandsorting/RunningTime.java
@@ -4,7 +4,7 @@
/**
* Created by IntelliJ IDEA.
- * User: ramswaroop
+ * User: rampatra
* Date: 3/2/15
* Time: 5:02 PM
* To change this template go to Preferences | IDE Settings | File and Code Templates
diff --git a/src/main/java/com/hackerrank/algorithms/implementation/CavityMap.java b/src/main/java/com/hackerrank/algorithms/implementation/CavityMap.java
new file mode 100644
index 00000000..0bc4a052
--- /dev/null
+++ b/src/main/java/com/hackerrank/algorithms/implementation/CavityMap.java
@@ -0,0 +1,30 @@
+package com.hackerrank.algorithms.implementation;
+
+import java.util.Scanner;
+
+/**
+ * Created by rampatra on 08/05/2016.
+ */
+public class CavityMap {
+ public static void main(String[] args) {
+ Scanner in = new Scanner(System.in);
+ int n = in.nextInt();
+ String grid[] = new String[n];
+ for (int grid_i = 0; grid_i < n; grid_i++) {
+ grid[grid_i] = in.next();
+ }
+ for (int i = 1; i < n - 1; i++) {
+ for (int j = 1; j < n - 1; j++) {
+ if (Character.getNumericValue(grid[i].charAt(j)) > Character.getNumericValue(grid[i].charAt(j - 1))
+ && Character.getNumericValue(grid[i].charAt(j)) > Character.getNumericValue(grid[i].charAt(j + 1))
+ && Character.getNumericValue(grid[i].charAt(j)) > Character.getNumericValue(grid[i - 1].charAt(j))
+ && Character.getNumericValue(grid[i].charAt(j)) > Character.getNumericValue(grid[i + 1].charAt(j))) {
+ grid[i] = grid[i].substring(0, j) + "X" + grid[i].substring(j + 1);
+ }
+ }
+ }
+ for (int grid_i = 0; grid_i < n; grid_i++) {
+ System.out.println(grid[grid_i]);
+ }
+ }
+}
diff --git a/src/main/java/com/hackerrank/algorithms/implementation/ExtraLongFactorials.java b/src/main/java/com/hackerrank/algorithms/implementation/ExtraLongFactorials.java
new file mode 100644
index 00000000..230a18aa
--- /dev/null
+++ b/src/main/java/com/hackerrank/algorithms/implementation/ExtraLongFactorials.java
@@ -0,0 +1,19 @@
+package com.hackerrank.algorithms.implementation;
+
+import java.math.BigInteger;
+import java.util.Scanner;
+
+/**
+ * Created by rampatra on 29/05/2016.
+ */
+public class ExtraLongFactorials {
+ public static void main(String[] args) {
+ Scanner in = new Scanner(System.in);
+ int n = in.nextInt();
+ BigInteger res = BigInteger.ONE;
+ for (int i = n; i > 0; i--) {
+ res = res.multiply(BigInteger.valueOf(i));
+ }
+ System.out.println(res);
+ }
+}
diff --git a/src/main/java/com/hackerrank/algorithms/implementation/GridSearch.java b/src/main/java/com/hackerrank/algorithms/implementation/GridSearch.java
new file mode 100644
index 00000000..a317913c
--- /dev/null
+++ b/src/main/java/com/hackerrank/algorithms/implementation/GridSearch.java
@@ -0,0 +1,68 @@
+package com.hackerrank.algorithms.implementation;
+
+import java.util.Scanner;
+
+/**
+ * Created by rampatra on 02/05/2016.
+ */
+public class GridSearch {
+
+ public static void main(String[] args) {
+ Scanner in = new Scanner(System.in);
+ int t = in.nextInt();
+ for (int a0 = 0; a0 < t; a0++) {
+ int R = in.nextInt();
+ int C = in.nextInt();
+ String G[] = new String[R];
+ for (int G_i = 0; G_i < R; G_i++) {
+ G[G_i] = in.next();
+ }
+ int r = in.nextInt();
+ int c = in.nextInt();
+ String P[] = new String[r];
+ for (int P_i = 0; P_i < r; P_i++) {
+ P[P_i] = in.next();
+ }
+
+ // create 2D array for grid
+ int grid[][] = new int[R][C];
+ for (int i = 0; i < R; i++) {
+ for (int j = 0; j < C; j++) {
+ grid[i][j] = Character.getNumericValue(G[i].charAt(j));
+ }
+ }
+
+ // create 2D array for pattern to be searched in grid
+ int pattern[][] = new int[r][c];
+ for (int i = 0; i < r; i++) {
+ for (int j = 0; j < c; j++) {
+ pattern[i][j] = Character.getNumericValue(P[i].charAt(j));
+ }
+ }
+
+ // search logic
+ outerLoop:
+ for (int G_i = 0; G_i < R; G_i++) {
+ for (int G_j = 0; G_j < C; G_j++) {
+ innerLoop:
+ for (int P_i = 0; P_i < r && G_i + P_i < R; P_i++) {
+ for (int P_j = 0; P_j < c && G_j + P_j < C; P_j++) {
+ if (grid[G_i + P_i][G_j + P_j] != pattern[P_i][P_j]) {
+ break innerLoop;
+ } else if (P_i == r - 1 && P_j == c - 1) {
+ System.out.println("YES");
+ break outerLoop;
+ }
+ }
+
+ }
+ if (R - G_i < r) { // no. of rows left in grid less than no. of rows in pattern
+ System.out.println("NO");
+ break outerLoop;
+ }
+ }
+ }
+ }
+ }
+}
+
diff --git a/src/main/java/com/hackerrank/algorithms/implementation/TheTimeInWords.java b/src/main/java/com/hackerrank/algorithms/implementation/TheTimeInWords.java
new file mode 100644
index 00000000..4915014b
--- /dev/null
+++ b/src/main/java/com/hackerrank/algorithms/implementation/TheTimeInWords.java
@@ -0,0 +1,38 @@
+package com.hackerrank.algorithms.implementation;
+
+import java.util.Scanner;
+
+/**
+ * Created by rampatra on 29/05/2016.
+ */
+public class TheTimeInWords {
+ public static void main(String[] args) {
+ Scanner in = new Scanner(System.in);
+ int h = in.nextInt();
+ int m = in.nextInt();
+ String timeInWords;
+ String[] words = {"", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten",
+ "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen",
+ "nineteen", "twenty", "twenty one", "twenty two", "twenty three", "twenty four", "twenty five", "twenty six",
+ "twenty seven", "twenty eight", "twenty nine"};
+
+ if (m == 0) {
+ timeInWords = words[h] + " o' clock";
+ } else if (m == 1) {
+ timeInWords = words[m] + " minute past " + words[h];
+ } else if (m == 15) {
+ timeInWords = "quarter past " + words[h];
+ } else if (m < 30) {
+ timeInWords = words[m] + " minutes past " + words[h];
+ } else if (m == 30) {
+ timeInWords = "half past " + words[h];
+ } else if (m == 45) {
+ timeInWords = "quarter to " + words[(h == 12) ? h - 11 : h + 1];
+ } else if (60 - m == 1) {
+ timeInWords = words[60 - m] + " minute to " + words[(h == 12) ? h - 11 : h + 1];
+ } else {
+ timeInWords = words[60 - m] + " minutes to " + words[(h == 12) ? h - 11 : h + 1];
+ }
+ System.out.println(timeInWords);
+ }
+}
diff --git a/src/main/java/com/hackerrank/algorithms/recursion/RecursiveDigitSum.java b/src/main/java/com/hackerrank/algorithms/recursion/RecursiveDigitSum.java
new file mode 100644
index 00000000..cd9cae21
--- /dev/null
+++ b/src/main/java/com/hackerrank/algorithms/recursion/RecursiveDigitSum.java
@@ -0,0 +1,60 @@
+package com.hackerrank.algorithms.recursion;
+
+import java.io.BufferedWriter;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Scanner;
+
+/**
+ * Recursive Digit Sum Problem.
+ *
+ * @link https://www.hackerrank.com/challenges/recursive-digit-sum/problem
+ * @author rpatra16
+ * @since 06/11/2018
+ */
+public class RecursiveDigitSum {
+
+ /**
+ * Finds the recursive digit sum of n.
+ *
+ * @param n number
+ * @param k the number would be repeated k times
+ * @return recursive sum of the digits
+ */
+ private static int superDigit(String n, int k) {
+ if (n.length() == 1 && k == 0) {
+ return Integer.parseInt(n);
+ }
+
+ Long sum = 0L;
+ char[] num = n.toCharArray();
+ for (int i = 0; i < num.length; i++) {
+ sum += Long.parseLong(String.valueOf(num[i]));
+ }
+
+ if (k != 0) sum *= k;
+
+ return superDigit(sum.toString(), 0);
+ }
+
+ private static final Scanner scanner = new Scanner(System.in);
+
+ public static void main(String[] args) throws IOException {
+ BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(System.getenv("OUTPUT_PATH")));
+
+ String[] nk = scanner.nextLine().split(" ");
+
+ String n = nk[0];
+
+ int k = Integer.parseInt(nk[1]);
+
+ int result = superDigit(n, k);
+
+ bufferedWriter.write(String.valueOf(result));
+ bufferedWriter.newLine();
+
+ bufferedWriter.close();
+
+ scanner.close();
+ }
+}
diff --git a/src/com/hackerrank/algorithms/strings/AlternatingCharacters.java b/src/main/java/com/hackerrank/algorithms/strings/AlternatingCharacters.java
similarity index 95%
rename from src/com/hackerrank/algorithms/strings/AlternatingCharacters.java
rename to src/main/java/com/hackerrank/algorithms/strings/AlternatingCharacters.java
index 823f1e61..c81f5c22 100644
--- a/src/com/hackerrank/algorithms/strings/AlternatingCharacters.java
+++ b/src/main/java/com/hackerrank/algorithms/strings/AlternatingCharacters.java
@@ -5,8 +5,8 @@
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 10/22/15
+ * @author rampatra
+ * @since 10/22/15
* @time: 9:24 AM
*/
public class AlternatingCharacters {
diff --git a/src/main/java/com/hackerrank/algorithms/strings/MakingAnagrams.java b/src/main/java/com/hackerrank/algorithms/strings/MakingAnagrams.java
new file mode 100644
index 00000000..b218c04e
--- /dev/null
+++ b/src/main/java/com/hackerrank/algorithms/strings/MakingAnagrams.java
@@ -0,0 +1,53 @@
+package com.hackerrank.algorithms.strings;
+
+import java.util.Arrays;
+
+/**
+ * @author rampatra
+ * @version 28/09/2016
+ */
+public class MakingAnagrams {
+
+ /**
+ * Find number of characters to be deleted to make {@param a}
+ * and {@param b} anagrams.
+ * See: https://www.hackerrank.com/challenges/making-anagrams
+ *
+ * @param a
+ * @param b
+ * @return
+ */
+ public static int makeAnagrams(String a, String b) {
+
+ int i = 0, j = 0, c = 0;
+ char[] s1 = a.toCharArray();
+ char[] s2 = b.toCharArray();
+ Arrays.sort(s1);
+ Arrays.sort(s2);
+
+ while (i < s1.length || j < s2.length) {
+ if (i >= s1.length) {
+ c++;
+ j++;
+ } else if (j >= s2.length) {
+ c++;
+ i++;
+ } else if (s1[i] < s2[j]) {
+ c++;
+ i++;
+ } else if (s1[i] > s2[j]) {
+ c++;
+ j++;
+ } else {
+ i++;
+ j++;
+ }
+ }
+
+ return c;
+ }
+
+ public static void main(String[] args) {
+ System.out.println(makeAnagrams("abc", "cde"));
+ }
+}
diff --git a/src/com/hackerrank/algorithms/strings/PalindromeIndex.java b/src/main/java/com/hackerrank/algorithms/strings/PalindromeIndex.java
similarity index 95%
rename from src/com/hackerrank/algorithms/strings/PalindromeIndex.java
rename to src/main/java/com/hackerrank/algorithms/strings/PalindromeIndex.java
index b9d76784..294c4dd2 100644
--- a/src/com/hackerrank/algorithms/strings/PalindromeIndex.java
+++ b/src/main/java/com/hackerrank/algorithms/strings/PalindromeIndex.java
@@ -4,7 +4,7 @@
/**
* Created by IntelliJ IDEA.
- * User: ramswaroop
+ * User: rampatra
* Date: 3/18/15
* Time: 12:27 PM
* To change this template go to Preferences | IDE Settings | File and Code Templates
@@ -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/com/hackerrank/algorithms/strings/Pangram.java b/src/main/java/com/hackerrank/algorithms/strings/Pangram.java
similarity index 95%
rename from src/com/hackerrank/algorithms/strings/Pangram.java
rename to src/main/java/com/hackerrank/algorithms/strings/Pangram.java
index 27fffa88..fa98b4fd 100644
--- a/src/com/hackerrank/algorithms/strings/Pangram.java
+++ b/src/main/java/com/hackerrank/algorithms/strings/Pangram.java
@@ -5,8 +5,8 @@
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 10/22/15
+ * @author rampatra
+ * @since 10/22/15
* @time: 8:47 AM
*/
public class Pangram {
diff --git a/src/com/hackerrank/algorithms/strings/TwoStrings.java b/src/main/java/com/hackerrank/algorithms/strings/TwoStrings.java
similarity index 92%
rename from src/com/hackerrank/algorithms/strings/TwoStrings.java
rename to src/main/java/com/hackerrank/algorithms/strings/TwoStrings.java
index f2b0ea1f..779a148b 100644
--- a/src/com/hackerrank/algorithms/strings/TwoStrings.java
+++ b/src/main/java/com/hackerrank/algorithms/strings/TwoStrings.java
@@ -5,8 +5,8 @@
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 10/22/15
+ * @author rampatra
+ * @since 10/22/15
* @time: 10:08 AM
*/
public class TwoStrings {
@@ -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/com/hackerrank/algorithms/warmup/FlippingBits.java b/src/main/java/com/hackerrank/algorithms/warmup/FlippingBits.java
similarity index 91%
rename from src/com/hackerrank/algorithms/warmup/FlippingBits.java
rename to src/main/java/com/hackerrank/algorithms/warmup/FlippingBits.java
index 9db5f21c..e335efe1 100644
--- a/src/com/hackerrank/algorithms/warmup/FlippingBits.java
+++ b/src/main/java/com/hackerrank/algorithms/warmup/FlippingBits.java
@@ -1,10 +1,10 @@
-package me.ramswaroop.algorithms.warmup;
+package com.hackerrank.algorithms.warmup;
import java.util.Scanner;
/**
* Created by IntelliJ IDEA.
- * User: ramswaroop
+ * User: rampatra
* Date: 2/28/15
* Time: 12:41 PM
* To change this template go to Preferences | IDE Settings | File and Code Templates
diff --git a/src/com/hackerrank/algorithms/warmup/LonelyInteger.java b/src/main/java/com/hackerrank/algorithms/warmup/LonelyInteger.java
similarity index 95%
rename from src/com/hackerrank/algorithms/warmup/LonelyInteger.java
rename to src/main/java/com/hackerrank/algorithms/warmup/LonelyInteger.java
index b60b695c..666b3fa0 100644
--- a/src/com/hackerrank/algorithms/warmup/LonelyInteger.java
+++ b/src/main/java/com/hackerrank/algorithms/warmup/LonelyInteger.java
@@ -1,4 +1,4 @@
-package me.ramswaroop.algorithms.warmup;
+package com.hackerrank.algorithms.warmup;
import java.util.HashMap;
import java.util.Map;
@@ -6,7 +6,7 @@
/**
* Created by IntelliJ IDEA.
- * User: ramswaroop
+ * User: rampatra
* Date: 2/28/15
* Time: 12:16 PM
* To change this template go to Preferences | IDE Settings | File and Code Templates
diff --git a/src/com/hackerrank/algorithms/warmup/LoveLetterMystery.java b/src/main/java/com/hackerrank/algorithms/warmup/LoveLetterMystery.java
similarity index 89%
rename from src/com/hackerrank/algorithms/warmup/LoveLetterMystery.java
rename to src/main/java/com/hackerrank/algorithms/warmup/LoveLetterMystery.java
index b0588dfd..8855498c 100644
--- a/src/com/hackerrank/algorithms/warmup/LoveLetterMystery.java
+++ b/src/main/java/com/hackerrank/algorithms/warmup/LoveLetterMystery.java
@@ -1,10 +1,10 @@
-package me.ramswaroop.algorithms.warmup;
+package com.hackerrank.algorithms.warmup;
import java.util.Scanner;
/**
* Created by IntelliJ IDEA.
- * User: ramswaroop
+ * User: rampatra
* Date: 3/17/15
* Time: 3:22 PM
* To change this template go to Preferences | IDE Settings | File and Code Templates
@@ -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/com/hackerrank/algorithms/warmup/MaximizingXor.java b/src/main/java/com/hackerrank/algorithms/warmup/MaximizingXor.java
similarity index 92%
rename from src/com/hackerrank/algorithms/warmup/MaximizingXor.java
rename to src/main/java/com/hackerrank/algorithms/warmup/MaximizingXor.java
index 78865aa2..2b0cc0ab 100644
--- a/src/com/hackerrank/algorithms/warmup/MaximizingXor.java
+++ b/src/main/java/com/hackerrank/algorithms/warmup/MaximizingXor.java
@@ -1,11 +1,11 @@
-package me.ramswaroop.algorithms.warmup;
+package com.hackerrank.algorithms.warmup;
import java.util.Scanner;
import java.util.TreeSet;
/**
* Created by IntelliJ IDEA.
- * User: ramswaroop
+ * User: rampatra
* Date: 3/7/15
* Time: 11:07 AM
* To change this template go to Preferences | IDE Settings | File and Code Templates
diff --git a/src/com/hackerrank/algorithms/warmup/UtopianTree.java b/src/main/java/com/hackerrank/algorithms/warmup/UtopianTree.java
similarity index 87%
rename from src/com/hackerrank/algorithms/warmup/UtopianTree.java
rename to src/main/java/com/hackerrank/algorithms/warmup/UtopianTree.java
index ca0d5556..43e455c2 100644
--- a/src/com/hackerrank/algorithms/warmup/UtopianTree.java
+++ b/src/main/java/com/hackerrank/algorithms/warmup/UtopianTree.java
@@ -1,10 +1,10 @@
-package me.ramswaroop.algorithms.warmup;
+package com.hackerrank.algorithms.warmup;
import java.util.Scanner;
/**
* Created by IntelliJ IDEA.
- * User: ramswaroop
+ * User: rampatra
* Date: 3/1/15
* Time: 3:07 PM
* To change this template go to Preferences | IDE Settings | File and Code Templates
@@ -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/com/hackerrank/bitmanipulation/CounterGame.java b/src/main/java/com/hackerrank/bitmanipulation/CounterGame.java
similarity index 91%
rename from src/com/hackerrank/bitmanipulation/CounterGame.java
rename to src/main/java/com/hackerrank/bitmanipulation/CounterGame.java
index e5ede2a2..b2a03e21 100644
--- a/src/com/hackerrank/bitmanipulation/CounterGame.java
+++ b/src/main/java/com/hackerrank/bitmanipulation/CounterGame.java
@@ -1,4 +1,4 @@
-package me.ramswaroop.bitmanipulation;
+package com.hackerrank.bitmanipulation;
import java.math.BigInteger;
import java.util.Scanner;
@@ -6,8 +6,8 @@
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 6/24/15
+ * @author rampatra
+ * @since 6/24/15
* @time: 12:03 PM
*/
public class CounterGame {
@@ -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/com/hackerrank/bitmanipulation/Solution.java b/src/main/java/com/hackerrank/bitmanipulation/Solution.java
similarity index 68%
rename from src/com/hackerrank/bitmanipulation/Solution.java
rename to src/main/java/com/hackerrank/bitmanipulation/Solution.java
index 84bbebd9..d07b9f37 100644
--- a/src/com/hackerrank/bitmanipulation/Solution.java
+++ b/src/main/java/com/hackerrank/bitmanipulation/Solution.java
@@ -1,4 +1,4 @@
-package me.ramswaroop.bitmanipulation;
+package com.hackerrank.bitmanipulation;
import java.io.BufferedReader;
import java.io.IOException;
@@ -7,49 +7,53 @@
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 6/24/15
+ * @author rampatra
+ * @since 6/24/15
* @time: 10:25 PM
*/
public class Solution {
private final static byte BITS;
private final static long[] BIT_COUNT_TO_BIT;
+
static {
BITS = 32;
- BIT_COUNT_TO_BIT = new long[BITS+1];
+ BIT_COUNT_TO_BIT = new long[BITS + 1];
BIT_COUNT_TO_BIT[0] = 1;
- for(byte i = 1; i <= BITS; i++){
- BIT_COUNT_TO_BIT[i] = ((BIT_COUNT_TO_BIT[i-1] - 1L) << 1) + (1L << (i-1)) + 1L;
+ for (byte i = 1; i <= BITS; i++) {
+ BIT_COUNT_TO_BIT[i] = ((BIT_COUNT_TO_BIT[i - 1] - 1L) << 1) + (1L << (i - 1)) + 1L;
}
}
+
public static void main(String[] args) throws IOException {
StringBuffer sb = new StringBuffer();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
- for(short T = Short.parseShort(br.readLine()); T > 0; T--){
+ for (short T = Short.parseShort(br.readLine()); T > 0; T--) {
String[] temp = br.readLine().split(" ");
int A = Integer.parseInt(temp[0]);
int B = Integer.parseInt(temp[1]);
long bits = bitCountToNum(B) - bitCountToNum(A) + getHammingWeight(A);
- bits += (A < 0 && B >= 0) ? BIT_COUNT_TO_BIT[BITS] - 1L: 0;
+ bits += (A < 0 && B >= 0) ? BIT_COUNT_TO_BIT[BITS] - 1L : 0;
sb.append(bits + "\n");
}
System.out.print(sb);
}
+
//Bit count in number
- private static int getHammingWeight(int n){
+ private static int getHammingWeight(int n) {
byte count = 0;
- while(n != 0){
+ while (n != 0) {
count++;
- n &= n-1;
+ n &= n - 1;
}
return count;
}
+
//Bit count to number, inclusive
- private static long bitCountToNum(int n){
+ private static long bitCountToNum(int n) {
long count = 0;
- for(byte b = BITS; n != 0;){
+ for (byte b = BITS; n != 0; ) {
int x = 1 << --b;
- if((n & x) != 0){
+ if ((n & x) != 0) {
n &= ~x;
count += BIT_COUNT_TO_BIT[b] + n;
}
diff --git a/src/com/hackerrank/bitmanipulation/TwosCompliment.java b/src/main/java/com/hackerrank/bitmanipulation/TwosCompliment.java
similarity index 85%
rename from src/com/hackerrank/bitmanipulation/TwosCompliment.java
rename to src/main/java/com/hackerrank/bitmanipulation/TwosCompliment.java
index 1f379cd2..0bfdc29f 100644
--- a/src/com/hackerrank/bitmanipulation/TwosCompliment.java
+++ b/src/main/java/com/hackerrank/bitmanipulation/TwosCompliment.java
@@ -1,12 +1,12 @@
-package me.ramswaroop.bitmanipulation;
+package com.hackerrank.bitmanipulation;
import java.util.Scanner;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 6/24/15
+ * @author rampatra
+ * @since 6/24/15
* @time: 10:25 PM
*/
public class TwosCompliment {
@@ -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/contests/SwappingInAnArray.java b/src/main/java/com/hackerrank/contests/SwappingInAnArray.java
new file mode 100644
index 00000000..d21866d8
--- /dev/null
+++ b/src/main/java/com/hackerrank/contests/SwappingInAnArray.java
@@ -0,0 +1,75 @@
+package com.hackerrank.contests;
+
+import java.io.BufferedWriter;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Scanner;
+
+/**
+ * @author rpatra16
+ * @since 04/11/2018
+ */
+public class SwappingInAnArray {
+
+ /**
+ * The problem asks if we can sort the array with only one swap.
+ *
+ * @param a array to sort
+ * @return 0 if already sorted, 1 if it can be sorted with one swap, -1 otherwise
+ */
+ static int swapToSort(int[] a) {
+ int swaps = 0;
+ for (int i=0; i < a.length-1; i++) {
+ int swapIndex = i;
+ for (int j = i + 1; j < a.length; j++) {
+ if (a[i] > a[j]) {
+ swapIndex = j;
+ }
+ }
+ if (swapIndex != i) {
+ swap(a, i, swapIndex);
+ swaps++;
+ i--;
+ }
+ }
+ if (swaps > 1) {
+ return -1;
+ } else {
+ return swaps;
+ }
+ }
+
+ private static void swap(int[] a, int i, int j) {
+ int temp = a[i];
+ a[i] = a[j];
+ a[j] = temp;
+ }
+
+ private static final Scanner scanner = new Scanner(System.in);
+
+ public static void main(String[] args) throws IOException {
+ BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(System.getenv("OUTPUT_PATH")));
+
+ int n = scanner.nextInt();
+ scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");
+
+ int[] a = new int[n];
+
+ String[] aItems = scanner.nextLine().split(" ");
+ scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");
+
+ for (int i = 0; i < n; i++) {
+ int aItem = Integer.parseInt(aItems[i]);
+ a[i] = aItem;
+ }
+
+ int result = swapToSort(a);
+
+ bufferedWriter.write(String.valueOf(result));
+ bufferedWriter.newLine();
+
+ bufferedWriter.close();
+
+ scanner.close();
+ }
+}
diff --git a/src/main/java/com/hackerrank/interviewpreparation/arrays/DS2DArrayProblem.java b/src/main/java/com/hackerrank/interviewpreparation/arrays/DS2DArrayProblem.java
new file mode 100644
index 00000000..ba7a2fe6
--- /dev/null
+++ b/src/main/java/com/hackerrank/interviewpreparation/arrays/DS2DArrayProblem.java
@@ -0,0 +1,55 @@
+package com.hackerrank.interviewpreparation.arrays;
+
+import java.io.BufferedWriter;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Scanner;
+
+/**
+ * @author rpatra16
+ * @since 31/10/2018
+ */
+public class DS2DArrayProblem {
+
+ private static final Scanner scanner = new Scanner(System.in);
+
+ private static int hourglassSum(int[][] arr) {
+ int maxSum = Integer.MIN_VALUE;
+ int hourglassSum;
+ for (int i = 0; i < arr.length - 2; i++) {
+ for (int j = 0; j < arr[0].length - 2; j++) {
+ hourglassSum = arr[i][j] + arr[i][j + 1] + arr[i][j + 2] + arr[i + 1][j + 1] +
+ arr[i + 2][j] + arr[i + 2][j + 1] + arr[i + 2][j + 2];
+ if (hourglassSum > maxSum) {
+ maxSum = hourglassSum;
+ }
+ }
+ }
+ return maxSum;
+ }
+
+ public static void main(String[] args) throws IOException {
+ BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(System.getenv("OUTPUT_PATH")));
+
+ int[][] arr = new int[6][6];
+
+ for (int i = 0; i < 6; i++) {
+ String[] arrRowItems = scanner.nextLine().split(" ");
+ scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");
+
+ for (int j = 0; j < 6; j++) {
+ int arrItem = Integer.parseInt(arrRowItems[j]);
+ arr[i][j] = arrItem;
+ }
+ }
+
+ int result = hourglassSum(arr);
+
+ bufferedWriter.write(String.valueOf(result));
+ bufferedWriter.newLine();
+
+ bufferedWriter.close();
+
+ scanner.close();
+ }
+}
diff --git a/src/main/java/com/hackerrank/interviewpreparation/arrays/NewYearChaos.java b/src/main/java/com/hackerrank/interviewpreparation/arrays/NewYearChaos.java
new file mode 100644
index 00000000..a065be9d
--- /dev/null
+++ b/src/main/java/com/hackerrank/interviewpreparation/arrays/NewYearChaos.java
@@ -0,0 +1,56 @@
+package com.hackerrank.interviewpreparation.arrays;
+
+import java.util.Scanner;
+
+/**
+ * @author rpatra16
+ * @since 02/11/2018
+ */
+public class NewYearChaos {
+
+ /**
+ * To solve this question, we just need to count the number of persons
+ * that overtake a particular person.
+ *
+ * @param q the queue
+ */
+ private static void minimumBribes(int[] q) {
+ int bribes = 0;
+ for (int i = q.length - 1; i >= 0; i--) {
+ if (q[i] - i - 1 > 2) {
+ System.out.println("Too chaotic");
+ return;
+ }
+ for (int j = Math.max(0, q[i] - 2); j < i; j++) {
+ if (q[j] > q[i]) bribes++;
+ }
+ }
+ System.out.println(bribes);
+ }
+
+ private static final Scanner scanner = new Scanner(System.in);
+
+ public static void main(String[] args) {
+ int t = scanner.nextInt();
+ scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");
+
+ for (int tItr = 0; tItr < t; tItr++) {
+ int n = scanner.nextInt();
+ scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");
+
+ int[] q = new int[n];
+
+ String[] qItems = scanner.nextLine().split(" ");
+ scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");
+
+ for (int i = 0; i < n; i++) {
+ int qItem = Integer.parseInt(qItems[i]);
+ q[i] = qItem;
+ }
+
+ minimumBribes(q);
+ }
+
+ scanner.close();
+ }
+}
diff --git a/src/main/java/com/hackerrank/interviewpreparation/greedyalgorithmns/LuckBalance.java b/src/main/java/com/hackerrank/interviewpreparation/greedyalgorithmns/LuckBalance.java
new file mode 100644
index 00000000..3cf74165
--- /dev/null
+++ b/src/main/java/com/hackerrank/interviewpreparation/greedyalgorithmns/LuckBalance.java
@@ -0,0 +1,77 @@
+package com.hackerrank.interviewpreparation.greedyalgorithmns;
+
+import java.io.BufferedWriter;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Scanner;
+
+/**
+ * @author rpatra16
+ * @since 04/11/2018
+ */
+public class LuckBalance {
+
+ /**
+ * For the full question, please see: https://www.hackerrank.com/challenges/luck-balance/
+ *
+ * @param k
+ * @param contests
+ * @return
+ */
+ private static int luckBalance(int k, int[][] contests) {
+ int lucks = 0;
+ List
+ * 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
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..d215246e
--- /dev/null
+++ b/src/main/java/com/leetcode/arrays/BuySellStocksII.java
@@ -0,0 +1,94 @@
+package com.leetcode.arrays;
+
+/**
+ * Level: Easy
+ * 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
+ * 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/CanPlaceFlowers.java b/src/main/java/com/leetcode/arrays/CanPlaceFlowers.java
new file mode 100644
index 00000000..916499ac
--- /dev/null
+++ b/src/main/java/com/leetcode/arrays/CanPlaceFlowers.java
@@ -0,0 +1,68 @@
+package com.leetcode.arrays;
+
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.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
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));
+ }
+}
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..52155f19
--- /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/MajorityElement.java b/src/main/java/com/leetcode/arrays/MajorityElement.java
new file mode 100644
index 00000000..2ccdd116
--- /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 = 1;
+ int majElem = nums[0];
+
+ for (int i = 1; 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}));
+ }
+}
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..58f56ebc
--- /dev/null
+++ b/src/main/java/com/leetcode/arrays/MergeIntervals.java
@@ -0,0 +1,78 @@
+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.
+ *
+ * Companies: LinkedIn
+ * Related: {@link InsertInterval}.
+ *
+ * @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
+ * 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/PascalsTriangle.java b/src/main/java/com/leetcode/arrays/PascalsTriangle.java
new file mode 100644
index 00000000..5f32d69f
--- /dev/null
+++ b/src/main/java/com/leetcode/arrays/PascalsTriangle.java
@@ -0,0 +1,53 @@
+package com.leetcode.arrays;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Level: Easy
+ * 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
+ * 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.
+ *
+ * NOTE: It doesn't matter what you leave beyond the returned length.
+ *
+ * @author rampatra
+ * @since 2019-04-24
+ */
+public class RemoveDuplicates {
+
+ /**
+ * This removes the duplicates from the array in-place.
+ *
+ * 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
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..91475160
--- /dev/null
+++ b/src/main/java/com/leetcode/arrays/RotateArray.java
@@ -0,0 +1,93 @@
+package com.leetcode.arrays;
+
+import java.util.Arrays;
+
+/**
+ * Level: Easy
+ * 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
+ */
+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/arrays/ShortestWordDistance.java b/src/main/java/com/leetcode/arrays/ShortestWordDistance.java
new file mode 100644
index 00000000..5cd0c821
--- /dev/null
+++ b/src/main/java/com/leetcode/arrays/ShortestWordDistance.java
@@ -0,0 +1,71 @@
+package com.leetcode.arrays;
+
+import com.leetcode.hashtables.ShortestWordDistanceII;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * Level: Easy
+ * 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.
+ *
+ * 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 ShortestWordDistanceII}.
+ *
+ * @author rampatra
+ * @since 2019-07-31
+ */
+public class ShortestWordDistance {
+
+ /**
+ * Time Complexity:
+ * Space Complexity:
+ * Runtime: 1 ms.
+ *
+ * @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)) {
+ indexWord1 = i;
+ } else if (words[i].equals(word2)) {
+ 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"},
+ "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"},
+ "makes", "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/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
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..cdbfb0c5
--- /dev/null
+++ b/src/main/java/com/leetcode/arrays/ValidTriangleNumber.java
@@ -0,0 +1,117 @@
+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].
+ * - Triangle Property: Sum of any 2 sides must be greater than the 3rd side.
+ *
+ * @author rampatra
+ * @since 2019-08-07
+ */
+public class ValidTriangleNumber {
+
+ /**
+ * 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);
+
+ 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/arrays/binarysearch/PowXN.java b/src/main/java/com/leetcode/arrays/binarysearch/PowXN.java
new file mode 100644
index 00000000..3591c50e
--- /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); // 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
+ 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/arrays/binarysearch/SearchInsertPosition.java b/src/main/java/com/leetcode/arrays/binarysearch/SearchInsertPosition.java
new file mode 100644
index 00000000..2f13214a
--- /dev/null
+++ b/src/main/java/com/leetcode/arrays/binarysearch/SearchInsertPosition.java
@@ -0,0 +1,64 @@
+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));
+ 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/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
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/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
+ * 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/dynamicprogramming/MaximumSubArray.java b/src/main/java/com/leetcode/dynamicprogramming/MaximumSubArray.java
new file mode 100644
index 00000000..90a28c93
--- /dev/null
+++ b/src/main/java/com/leetcode/dynamicprogramming/MaximumSubArray.java
@@ -0,0 +1,104 @@
+package com.leetcode.dynamicprogramming;
+
+/**
+ * Level: Easy
+ * Problem Link: https://leetcode.com/problems/maximum-subarray
+ *
+ * @author rampatra
+ * @since 2019-04-26
+ */
+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/dynamicprogramming/PaintHouse.java b/src/main/java/com/leetcode/dynamicprogramming/PaintHouse.java
new file mode 100644
index 00000000..5692b0d8
--- /dev/null
+++ b/src/main/java/com/leetcode/dynamicprogramming/PaintHouse.java
@@ -0,0 +1,52 @@
+package com.leetcode.dynamicprogramming;
+
+/**
+ * Level: Easy
+ * 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
+ * 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 {
+
+ /**
+ * 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
+ */
+ 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..431ce612
--- /dev/null
+++ b/src/main/java/com/leetcode/dynamicprogramming/PaintHouseII.java
@@ -0,0 +1,120 @@
+package com.leetcode.dynamicprogramming;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * Level: Hard
+ * 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.
+ * 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}}));
+ }
+}
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
+ * 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: 79 ms.
+ *
+ * @param beginWord
+ * @param endWord
+ * @param wordList
+ * @return
+ */
+ public static int ladderLength(String beginWord, String endWord, List
+ * 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
+ * Time Complexity:
+ * Space Complexity:
+ * Runtime: 38 ms.
+ *
+ * @param s
+ * @return
+ */
+ public static List
+ * Examples:
+ * Assume that words = ["practice", "makes", "perfect", "coding", "makes"].
+ *
+ * Input1: word1 = “coding”, word2 = “practice”
+ * Output1: 3
+ *
+ * Input2: word1 = "makes", word2 = "coding"
+ * Output2: 1
+ *
+ * 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 {
+
+ private String[] words;
+ private Map
+ * 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
+ * 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
+ * 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
+ * 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
+ * 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.
+ *
+ * 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
+ * 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
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
+ * 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 NestedListWeightSum {
+
+ /**
+ * 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);
+ }
+
+ 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/recursion/NestedListWeightSumII.java b/src/main/java/com/leetcode/recursion/NestedListWeightSumII.java
new file mode 100644
index 00000000..eadd121b
--- /dev/null
+++ b/src/main/java/com/leetcode/recursion/NestedListWeightSumII.java
@@ -0,0 +1,80 @@
+package com.leetcode.recursion;
+
+import java.util.*;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * Level: Medium
+ * 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.
+ *
+ * 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 {
+
+ /**
+ * Time Complexity:
+ * Space Complexity:
+ * Runtime: 1 ms.
+ *
+ * @param nestedList
+ * @return
+ */
+ public static int nestedSum(List
+ * 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
+ * Runtime: 6 ms.
+ *
+ * @param text
+ * @param pattern
+ * @return
+ */
+ private static List
+ * Runtime: 1 ms.
+ *
+ * @param strs
+ * @return
+ */
+ public static String longestCommonPrefix(String[] strs) {
+ if (strs == null || strs.length == 0) return "";
+
+ int row;
+ 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, 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)) {
+ return strs[row].substring(0, col);
+ }
+ }
+ }
+
+ return strs[0];
+ }
+
+ 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"}));
+ }
+}
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..c6b66fb0
--- /dev/null
+++ b/src/main/java/com/leetcode/strings/RansomNote.java
@@ -0,0 +1,40 @@
+package com.leetcode.strings;
+
+/**
+ * Level: Easy
+ * 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"));
+ }
+}
\ 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..4a5aabd4
--- /dev/null
+++ b/src/main/java/com/leetcode/strings/ReverseStringII.java
@@ -0,0 +1,46 @@
+package com.leetcode.strings;
+
+/**
+ * Level: Easy
+ * 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();
+ for (int i = 0; i < len; i += 2 * k) {
+ reverse(chars, i, Math.min(len, i + 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));
+ }
+}
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..25518cac
--- /dev/null
+++ b/src/main/java/com/leetcode/strings/ReverseVowels.java
@@ -0,0 +1,66 @@
+package com.leetcode.strings;
+
+/**
+ * Level: Easy
+ * 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/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("", ""));
+ }
+}
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
new file mode 100644
index 00000000..da155710
--- /dev/null
+++ b/src/main/java/com/leetcode/strings/UniqueCharacterInString.java
@@ -0,0 +1,38 @@
+package com.leetcode.strings;
+
+/**
+ * Level: Easy
+ * Problem: https://leetcode.com/problems/first-unique-character-in-a-string/
+ *
+ * @author rampatra
+ * @since 2019-04-16
+ */
+public class UniqueCharacterInString {
+
+ /**
+ * 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.
+ */
+ 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"));
+ }
+}
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..451849b6
--- /dev/null
+++ b/src/main/java/com/leetcode/strings/ValidPalindrome.java
@@ -0,0 +1,59 @@
+package com.leetcode.strings;
+
+/**
+ * Level: Easy
+ * Problem: https://leetcode.com/problems/valid-palindrome/
+ *
+ * @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
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
+ * 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
+ */
+public class ClosestBinarySearchTreeValue {
+
+ /**
+ * Runtime: 0 ms.
+ *
+ * @param root
+ * @param target
+ * @return
+ */
+ public static int closestValue(TreeNode root, double target) {
+ if (root == null) return -1;
+
+ 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 closestValue(node.left, closestNode, val);
+ } else {
+ return closestValue(node.right, closestNode, 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.right = new TreeNode(6);
+ root.left.left.left = new TreeNode(2);
+ root.right.right = new TreeNode(20);
+
+ 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:
+
+ 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, closestValue(root, 15));
+
+ /*
+ BST looks like:
+
+ 1500000000
+ /
+ /
+ /
+ 1400000000
+ */
+ root = new TreeNode(1500000000);
+ root.left = new TreeNode(1400000000);
+
+ assertEquals(1400000000, closestValue(root, -1500000000.0));
+ }
+}
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..e583723a
--- /dev/null
+++ b/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValueII.java
@@ -0,0 +1,166 @@
+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
* TODO: Not tested.
*/
public class CelebrityProblem {
@@ -44,7 +44,7 @@ public static boolean haveAcquaintance(int[][] peoples, int a, int b) {
* - Push the remained person onto stack.
* - Repeat step 2 and 3 until only one person remains in the stack.
* - Check the remained person in stack does not have acquaintance with anyone else.
- *
+ *
* @param peoples
* @return
*/
@@ -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/me/ramswaroop/arrays/ConsecutiveElements.java b/src/main/java/com/rampatra/arrays/ConsecutiveElements.java
similarity index 94%
rename from src/me/ramswaroop/arrays/ConsecutiveElements.java
rename to src/main/java/com/rampatra/arrays/ConsecutiveElements.java
index 4cd92231..f8dc151e 100644
--- a/src/me/ramswaroop/arrays/ConsecutiveElements.java
+++ b/src/main/java/com/rampatra/arrays/ConsecutiveElements.java
@@ -1,10 +1,10 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 8/28/15
+ * @author rampatra
+ * @since 8/28/15
* @time: 10:32 AM
*/
public class ConsecutiveElements {
@@ -62,7 +62,7 @@ public static boolean areConsecutiveElements(int[] a) {
}
/**
- * This approach is similar to {@link me.ramswaroop.arrays.ConsecutiveElements#areConsecutiveElements(int[])} but
+ * This approach is similar to {@link ConsecutiveElements#areConsecutiveElements(int[])} but
* requires O(1) auxiliary space instead of O(n). But the only con of this method is that it modifies the original
* input array {@param a}.
*
@@ -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
new file mode 100644
index 00000000..3023dc3c
--- /dev/null
+++ b/src/main/java/com/rampatra/arrays/CountDivisors.java
@@ -0,0 +1,35 @@
+package com.rampatra.arrays;
+
+/**
+ * @author rampatra
+ * @since 31/05/2016
+ */
+public class CountDivisors {
+
+ /**
+ * 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
+ */
+ 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
+
+ if (begin % n == 0) { // "begin" is inclusive; if divisible by n then
+ --a; // remove 1 from "a"
+ }
+ return b - a; // return integers in range
+ }
+
+ public static void main(String[] args) {
+ 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/me/ramswaroop/arrays/CountSmallerElementsOnRHS.java b/src/main/java/com/rampatra/arrays/CountSmallerElementsOnRHS.java
similarity index 83%
rename from src/me/ramswaroop/arrays/CountSmallerElementsOnRHS.java
rename to src/main/java/com/rampatra/arrays/CountSmallerElementsOnRHS.java
index 295b50ec..413234ec 100644
--- a/src/me/ramswaroop/arrays/CountSmallerElementsOnRHS.java
+++ b/src/main/java/com/rampatra/arrays/CountSmallerElementsOnRHS.java
@@ -1,12 +1,12 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
import java.util.Arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 9/19/15
+ * @author rampatra
+ * @since 9/19/15
* @time: 11:33 PM
*/
public class CountSmallerElementsOnRHS {
@@ -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/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
* Explanation: In merge() if a[i] > b[j] then all elements in array a starting
* from i are greater than b[j] which equals to the number of inversions for
* the two sub-arrays.
@@ -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/me/ramswaroop/arrays/KLargestElements.java b/src/main/java/com/rampatra/arrays/KLargestElements.java
similarity index 88%
rename from src/me/ramswaroop/arrays/KLargestElements.java
rename to src/main/java/com/rampatra/arrays/KLargestElements.java
index aa173187..87546e7d 100644
--- a/src/me/ramswaroop/arrays/KLargestElements.java
+++ b/src/main/java/com/rampatra/arrays/KLargestElements.java
@@ -1,31 +1,31 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
-import me.ramswaroop.common.MinHeap;
+import com.rampatra.base.MinHeap;
import java.util.Arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 8/3/15
+ * @author rampatra
+ * @since 8/3/15
* @time: 3:47 PM
*/
public class KLargestElements {
/**
* Finds {@param k} largest elements in array {@param a}.
- *
+ *
* Algorithm:
* 1) Build a Min Heap MH of the first k elements (arr[0] to arr[k-1]) of the given array. This takes O(k) time.
- *
+ *
* 2) For each element, after the kth element (arr[k] to arr[n-1]), compare it with root of MH.
* ……a) If the element is greater than the root then make it root and call buildHeap for MH
* ……b) Else ignore it.
* This step takes (n-k) * O(k) time.
- *
+ *
* 3) Finally, MH has k largest elements and root of the MH is the kth largest element.
- *
+ *
* Therefore, the total time complexity of the above algorithm is: O(k) + (n-k) * O(k).
*
* @param a
@@ -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/me/ramswaroop/arrays/KthLargestElement.java b/src/main/java/com/rampatra/arrays/KthLargestElement.java
similarity index 73%
rename from src/me/ramswaroop/arrays/KthLargestElement.java
rename to src/main/java/com/rampatra/arrays/KthLargestElement.java
index 62c771b2..65ca77c7 100644
--- a/src/me/ramswaroop/arrays/KthLargestElement.java
+++ b/src/main/java/com/rampatra/arrays/KthLargestElement.java
@@ -1,15 +1,15 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
-import me.ramswaroop.arrays.sorting.MergeSort;
-import me.ramswaroop.common.MaxHeap;
+import com.rampatra.sorting.MergeSort;
+import com.rampatra.base.MaxHeap;
import java.util.Arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 8/1/15
+ * @author rampatra
+ * @since 8/1/15
* @time: 11:26 PM
*/
public class KthLargestElement {
@@ -44,7 +44,7 @@ public static int getKthLargestElement(int[] a, int k) {
maxHeap.buildMaxHeap();
while (true) {
if (k == 1) break;
-
+
maxHeap.extractMax();
k--;
}
@@ -52,13 +52,7 @@ public static int getKthLargestElement(int[] a, int k) {
return maxHeap.findMax();
}
- 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 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/me/ramswaroop/arrays/LargestProductContiguousSubArray.java b/src/main/java/com/rampatra/arrays/LargestProductContiguousSubArray.java
similarity index 79%
rename from src/me/ramswaroop/arrays/LargestProductContiguousSubArray.java
rename to src/main/java/com/rampatra/arrays/LargestProductContiguousSubArray.java
index 367c5541..c7afb19b 100644
--- a/src/me/ramswaroop/arrays/LargestProductContiguousSubArray.java
+++ b/src/main/java/com/rampatra/arrays/LargestProductContiguousSubArray.java
@@ -1,16 +1,15 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 5/28/15
+ * @author rampatra
+ * @since 5/28/15
* @time: 12:44 PM
*/
public class LargestProductContiguousSubArray {
/**
- *
* @param a
* @return
*/
@@ -18,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/me/ramswaroop/arrays/LargestSumContiguousSubArray.java b/src/main/java/com/rampatra/arrays/LargestSumContiguousSubArray.java
similarity index 94%
rename from src/me/ramswaroop/arrays/LargestSumContiguousSubArray.java
rename to src/main/java/com/rampatra/arrays/LargestSumContiguousSubArray.java
index 14266935..8b34d9ef 100644
--- a/src/me/ramswaroop/arrays/LargestSumContiguousSubArray.java
+++ b/src/main/java/com/rampatra/arrays/LargestSumContiguousSubArray.java
@@ -1,10 +1,10 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 5/28/15
+ * @author rampatra
+ * @since 5/28/15
* @time: 12:44 PM
*/
public class LargestSumContiguousSubArray {
@@ -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/me/ramswaroop/arrays/LeadersInArray.java b/src/main/java/com/rampatra/arrays/LeadersInArray.java
similarity index 90%
rename from src/me/ramswaroop/arrays/LeadersInArray.java
rename to src/main/java/com/rampatra/arrays/LeadersInArray.java
index 837da57c..c2075751 100644
--- a/src/me/ramswaroop/arrays/LeadersInArray.java
+++ b/src/main/java/com/rampatra/arrays/LeadersInArray.java
@@ -1,12 +1,12 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
import java.util.Arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 7/29/15
+ * @author rampatra
+ * @since 7/29/15
* @time: 12:06 PM
*/
public class LeadersInArray {
@@ -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/me/ramswaroop/arrays/LongestBitonicSubArray.java b/src/main/java/com/rampatra/arrays/LongestBitonicSubArray.java
similarity index 94%
rename from src/me/ramswaroop/arrays/LongestBitonicSubArray.java
rename to src/main/java/com/rampatra/arrays/LongestBitonicSubArray.java
index e804b8fa..dc3caafb 100644
--- a/src/me/ramswaroop/arrays/LongestBitonicSubArray.java
+++ b/src/main/java/com/rampatra/arrays/LongestBitonicSubArray.java
@@ -1,10 +1,10 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 9/18/15
+ * @author rampatra
+ * @since 9/18/15
* @time: 5:10 PM
*/
public class LongestBitonicSubArray {
@@ -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/LongestConsecutiveSubsequence.java b/src/main/java/com/rampatra/arrays/LongestConsecutiveSubsequence.java
new file mode 100644
index 00000000..8e6a99f8
--- /dev/null
+++ b/src/main/java/com/rampatra/arrays/LongestConsecutiveSubsequence.java
@@ -0,0 +1,80 @@
+package com.rampatra.arrays;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author rampatra
+ * @since 25/11/2018
+ */
+public class LongestConsecutiveSubsequence {
+
+ /**
+ * 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};
+ * Output: 4
+ * The subsequence {1, 3, 4, 2} is the longest subsequence
+ * of consecutive elements
+ *
+ * Input: arr[] = {36, 41, 56, 35, 44, 33, 34, 92, 43, 32, 42}
+ * 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 non-repeating integers
+ * @return the length of the longest consecutive subsequence
+ */
+ private static int findLengthOfLongestConsecutiveSubsequence(int[] arr) {
+ int longestSubseqCount = 0;
+ int subseqCount;
+ int currElem;
+ // add all numbers to a set to have O(1) time complexity for searching elements
+ Set
* Time complexity: O(n)
* Auxiliary Space: O(k)
- *
+ *
* @param a
* @param k
* @return
@@ -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/me/ramswaroop/arrays/MaxIndexDiff.java b/src/main/java/com/rampatra/arrays/MaxIndexDiff.java
similarity index 94%
rename from src/me/ramswaroop/arrays/MaxIndexDiff.java
rename to src/main/java/com/rampatra/arrays/MaxIndexDiff.java
index 03c7ea5d..9eb982c4 100644
--- a/src/me/ramswaroop/arrays/MaxIndexDiff.java
+++ b/src/main/java/com/rampatra/arrays/MaxIndexDiff.java
@@ -1,10 +1,10 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 9/1/15
+ * @author rampatra
+ * @since 9/1/15
* @time: 10:21 PM
*/
public class MaxIndexDiff {
@@ -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/me/ramswaroop/arrays/MaxMinWithMinComparisons.java b/src/main/java/com/rampatra/arrays/MaxMinWithMinComparisons.java
similarity index 92%
rename from src/me/ramswaroop/arrays/MaxMinWithMinComparisons.java
rename to src/main/java/com/rampatra/arrays/MaxMinWithMinComparisons.java
index 7aaf304d..23e3e99d 100644
--- a/src/me/ramswaroop/arrays/MaxMinWithMinComparisons.java
+++ b/src/main/java/com/rampatra/arrays/MaxMinWithMinComparisons.java
@@ -1,12 +1,12 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
import java.util.Arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 7/31/15
+ * @author rampatra
+ * @since 7/31/15
* @time: 3:16 PM
*/
public class MaxMinWithMinComparisons {
@@ -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/MaxSpan.java b/src/main/java/com/rampatra/arrays/MaxSpan.java
new file mode 100644
index 00000000..7db17c18
--- /dev/null
+++ b/src/main/java/com/rampatra/arrays/MaxSpan.java
@@ -0,0 +1,45 @@
+package com.rampatra.arrays;
+
+import com.sun.tools.javac.util.Assert;
+
+/**
+ * Consider the leftmost and rightmost appearances of some value in an array. We'll say that the "span" is the
+ * number of elements between the two inclusive. A single value has a span of 1. Returns the largest span found
+ * in the given array.
+ *
+ * Examples:
+ * maxSpan([1, 2, 1, 1, 3]) → 4
+ * maxSpan([1, 4, 2, 1, 4, 1, 4]) → 6
+ * maxSpan([1, 4, 2, 1, 4, 4, 4]) → 6
+ *
+ * Level: Easy
+ *
+ * @author rampatra
+ * @link https://codingbat.com/prob/p189576
+ * @since 2019-01-23
+ */
+public class MaxSpan {
+
+ public static int maxSpan(int[] nums) {
+ if (nums.length == 0) return 0;
+ int largestSpan = 1;
+ for (int i = 0; i < nums.length; i++) {
+ for (int j = nums.length - 1; j > i; j--) {
+ if (nums[i] == nums[j]) {
+ if (j - i + 1 > largestSpan) {
+ largestSpan = j - i + 1;
+ }
+ }
+ }
+ }
+ return largestSpan;
+ }
+
+ public static void main(String[] args) {
+ Assert.check(maxSpan(new int[]{1, 2, 1, 1, 3}) == 4);
+ Assert.check(maxSpan(new int[]{1, 4, 2, 1, 4, 1, 4}) == 6);
+ Assert.check(maxSpan(new int[]{1, 4, 2, 1, 4, 4, 4}) == 6);
+ Assert.check(maxSpan(new int[]{1}) == 1);
+ Assert.check(maxSpan(new int[]{}) == 0);
+ }
+}
diff --git a/src/me/ramswaroop/arrays/MaximumSizeSquareSubMatrix.java b/src/main/java/com/rampatra/arrays/MaximumSizeSquareSubMatrix.java
similarity index 95%
rename from src/me/ramswaroop/arrays/MaximumSizeSquareSubMatrix.java
rename to src/main/java/com/rampatra/arrays/MaximumSizeSquareSubMatrix.java
index 251a6fc9..0c9c4419 100644
--- a/src/me/ramswaroop/arrays/MaximumSizeSquareSubMatrix.java
+++ b/src/main/java/com/rampatra/arrays/MaximumSizeSquareSubMatrix.java
@@ -1,10 +1,10 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 8/4/15
+ * @author rampatra
+ * @since 8/4/15
* @time: 11:48 PM
*/
public class MaximumSizeSquareSubMatrix {
@@ -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/me/ramswaroop/arrays/MaximumSumNonAdjacentSubsequence.java b/src/main/java/com/rampatra/arrays/MaximumSumNonAdjacentSubSequence.java
similarity index 86%
rename from src/me/ramswaroop/arrays/MaximumSumNonAdjacentSubsequence.java
rename to src/main/java/com/rampatra/arrays/MaximumSumNonAdjacentSubSequence.java
index d5b68b1b..9734aa29 100644
--- a/src/me/ramswaroop/arrays/MaximumSumNonAdjacentSubsequence.java
+++ b/src/main/java/com/rampatra/arrays/MaximumSumNonAdjacentSubSequence.java
@@ -1,10 +1,10 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 7/29/15
+ * @author rampatra
+ * @since 7/29/15
* @time: 9:18 AM
*/
public class MaximumSumNonAdjacentSubSequence {
@@ -17,7 +17,7 @@ public class MaximumSumNonAdjacentSubSequence {
* Example:
* 1) 3 2 7 10 should return 13 (sum of 3 and 10)
* 2) 3 2 5 10 7 should return 15 (sum of 3, 5 and 7).
- *
+ *
* Here we maintain 2 variables incl and excl which is max sum till now (satisfying the constraint)
* including the current element and excluding the current element respectively.
*
@@ -26,7 +26,7 @@ public class MaximumSumNonAdjacentSubSequence {
*/
public static int maximumSumNonAdjacentSubSequence(int[] a) {
int incl = a[0], excl = 0, prevIncl = incl; // incl is max sum including the current element
- // and excl is max sum excluding the current element
+ // and excl is max sum excluding the current element
for (int i = 1; i < a.length; i++) {
incl = excl + a[i]; // because we have to exclude the previous element if we consider the current element
excl = Math.max(prevIncl, excl); // we are excluding the current element so we can consider the previous element or dont
@@ -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/me/ramswaroop/arrays/MedianOfStream.java b/src/main/java/com/rampatra/arrays/MedianOfStream.java
similarity index 92%
rename from src/me/ramswaroop/arrays/MedianOfStream.java
rename to src/main/java/com/rampatra/arrays/MedianOfStream.java
index d92a002c..47781bc0 100644
--- a/src/me/ramswaroop/arrays/MedianOfStream.java
+++ b/src/main/java/com/rampatra/arrays/MedianOfStream.java
@@ -1,13 +1,13 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
-import me.ramswaroop.common.MaxHeap;
-import me.ramswaroop.common.MinHeap;
+import com.rampatra.base.MaxHeap;
+import com.rampatra.base.MinHeap;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 9/12/15
+ * @author rampatra
+ * @since 9/12/15
* @time: 11:19 PM
*/
public class MedianOfStream {
@@ -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/me/ramswaroop/arrays/MedianOfTwoSortedArrays.java b/src/main/java/com/rampatra/arrays/MedianOfTwoSortedArrays.java
similarity index 96%
rename from src/me/ramswaroop/arrays/MedianOfTwoSortedArrays.java
rename to src/main/java/com/rampatra/arrays/MedianOfTwoSortedArrays.java
index 24995176..d64ec757 100644
--- a/src/me/ramswaroop/arrays/MedianOfTwoSortedArrays.java
+++ b/src/main/java/com/rampatra/arrays/MedianOfTwoSortedArrays.java
@@ -1,12 +1,12 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
import java.util.Arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 7/27/15
+ * @author rampatra
+ * @since 7/27/15
* @time: 5:50 PM
*/
public class MedianOfTwoSortedArrays {
@@ -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/me/ramswaroop/arrays/MergeArrayOfNintoArrayOfMplusN.java b/src/main/java/com/rampatra/arrays/MergeArrayOfNIntoArrayOfMPlusN.java
similarity index 93%
rename from src/me/ramswaroop/arrays/MergeArrayOfNintoArrayOfMplusN.java
rename to src/main/java/com/rampatra/arrays/MergeArrayOfNIntoArrayOfMPlusN.java
index 51c1b72a..e95c653a 100644
--- a/src/me/ramswaroop/arrays/MergeArrayOfNintoArrayOfMplusN.java
+++ b/src/main/java/com/rampatra/arrays/MergeArrayOfNIntoArrayOfMPlusN.java
@@ -1,12 +1,12 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
import java.util.Arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 7/27/15
+ * @author rampatra
+ * @since 7/27/15
* @time: 12:15 PM
*/
public class MergeArrayOfNIntoArrayOfMPlusN {
@@ -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/me/ramswaroop/arrays/MinimumDistanceBetweenTwoNos.java b/src/main/java/com/rampatra/arrays/MinimumDistanceBetweenTwoNos.java
similarity index 94%
rename from src/me/ramswaroop/arrays/MinimumDistanceBetweenTwoNos.java
rename to src/main/java/com/rampatra/arrays/MinimumDistanceBetweenTwoNos.java
index 560ab591..48edc1a9 100644
--- a/src/me/ramswaroop/arrays/MinimumDistanceBetweenTwoNos.java
+++ b/src/main/java/com/rampatra/arrays/MinimumDistanceBetweenTwoNos.java
@@ -1,10 +1,10 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 9/6/15
+ * @author rampatra
+ * @since 9/6/15
* @time: 10:53 PM
*/
public class MinimumDistanceBetweenTwoNos {
@@ -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/me/ramswaroop/arrays/MissingAndRepeatingElements.java b/src/main/java/com/rampatra/arrays/MissingAndRepeatingElements.java
similarity index 92%
rename from src/me/ramswaroop/arrays/MissingAndRepeatingElements.java
rename to src/main/java/com/rampatra/arrays/MissingAndRepeatingElements.java
index a5b8a32f..5fe08bf2 100644
--- a/src/me/ramswaroop/arrays/MissingAndRepeatingElements.java
+++ b/src/main/java/com/rampatra/arrays/MissingAndRepeatingElements.java
@@ -1,12 +1,12 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
import java.util.Arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 9/7/15
+ * @author rampatra
+ * @since 9/7/15
* @time: 10:54 AM
*/
public class MissingAndRepeatingElements {
@@ -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/me/ramswaroop/arrays/MissingNumber.java b/src/main/java/com/rampatra/arrays/MissingNumber.java
similarity index 92%
rename from src/me/ramswaroop/arrays/MissingNumber.java
rename to src/main/java/com/rampatra/arrays/MissingNumber.java
index 504263f2..6691f6db 100644
--- a/src/me/ramswaroop/arrays/MissingNumber.java
+++ b/src/main/java/com/rampatra/arrays/MissingNumber.java
@@ -1,10 +1,10 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 5/28/15
+ * @author rampatra
+ * @since 5/28/15
* @time: 4:34 PM
*/
@@ -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/me/ramswaroop/arrays/NextGreaterElement.java b/src/main/java/com/rampatra/arrays/NextGreaterElement.java
similarity index 90%
rename from src/me/ramswaroop/arrays/NextGreaterElement.java
rename to src/main/java/com/rampatra/arrays/NextGreaterElement.java
index 3039fb0a..96c568f1 100644
--- a/src/me/ramswaroop/arrays/NextGreaterElement.java
+++ b/src/main/java/com/rampatra/arrays/NextGreaterElement.java
@@ -1,13 +1,13 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
-import me.ramswaroop.common.LinkedStack;
-import me.ramswaroop.common.Stack;
+import com.rampatra.base.LinkedStack;
+import com.rampatra.base.Stack;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 8/26/15
+ * @author rampatra
+ * @since 8/26/15
* @time: 12:35 PM
*/
public class NextGreaterElement {
@@ -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/me/ramswaroop/arrays/NextLargerNumber.java b/src/main/java/com/rampatra/arrays/NextLargerNumber.java
similarity index 93%
rename from src/me/ramswaroop/arrays/NextLargerNumber.java
rename to src/main/java/com/rampatra/arrays/NextLargerNumber.java
index e937577a..00e00b78 100644
--- a/src/me/ramswaroop/arrays/NextLargerNumber.java
+++ b/src/main/java/com/rampatra/arrays/NextLargerNumber.java
@@ -1,12 +1,12 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
-import me.ramswaroop.arrays.sorting.QuickSort;
+import com.rampatra.sorting.QuickSort;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 10/30/15
+ * @author rampatra
+ * @since 10/30/15
* @time: 11:01 AM
* @see: http://www.geeksforgeeks.org/find-next-greater-number-set-digits/
*/
@@ -44,7 +44,7 @@ public static int findNextLargerNumber(Integer n) {
// digits are already in descending order, so return
if (i <= 0) return -1;
-
+
// find index of smallest no. greater than a[i-1]
minIndex = i;
int j = len - 1;
@@ -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/NthSmallestNumber.java b/src/main/java/com/rampatra/arrays/NthSmallestNumber.java
new file mode 100644
index 00000000..8f7fbaf1
--- /dev/null
+++ b/src/main/java/com/rampatra/arrays/NthSmallestNumber.java
@@ -0,0 +1,61 @@
+package com.rampatra.arrays;
+
+/**
+ * A Google Interview Question. For a simpler version of this question see {@link SmallestAndSecondSmallest}.
+ *
+ * @author rampatra
+ * @since 2019-02-01
+ */
+public class NthSmallestNumber {
+
+ /**
+ * Given an unsorted array of integers, find the nth smallest integer in the array in most optimized way possible.
+ *
+ * Approach: Similar to Quick Sort where in every iteration, we choose a pivot element and shift all lesser integers
+ * to left and higher integers to the right. After doing this we compare the pivot index with n and recursively call
+ * the method accordingly. See {@link com.rampatra.sorting.QuickSort}.
+ *
+ * @param arr the input unsorted array of integers
+ * @param n nth smallest integer to find
+ * @param start the start index in the array to search (inclusive)
+ * @param end the last index in the array to search (inclusive)
+ * @return the nth smallest integer, {@code -1} if invalid input
+ */
+ private static int findNthSmallestNumber(int[] arr, int n, int start, int end) {
+ if (arr.length == 0 || arr.length < n) {
+ return -1;
+ }
+ int temp;
+ int lastBigger = start;
+ for (int i = start; i < end; i++) {
+ if (arr[i] < arr[end]) {
+ temp = arr[i];
+ arr[i] = arr[lastBigger];
+ arr[lastBigger] = temp;
+ lastBigger++;
+ }
+ }
+ temp = arr[lastBigger];
+ arr[lastBigger] = arr[end];
+ arr[end] = temp;
+
+ if (lastBigger + 1 < n) {
+ return findNthSmallestNumber(arr, n, lastBigger + 1, end);
+ } else if (lastBigger + 1 > n) {
+ return findNthSmallestNumber(arr, n, start, lastBigger - 1);
+ } else {
+ return arr[lastBigger];
+ }
+ }
+
+ public static void main(String[] args) {
+ System.out.println(findNthSmallestNumber(new int[]{}, 3, 0, 5));
+ System.out.println(findNthSmallestNumber(new int[]{0, 1}, 3, 0, 1));
+ System.out.println(findNthSmallestNumber(new int[]{0, 1}, 2, 0, 1));
+ System.out.println(findNthSmallestNumber(new int[]{1, 0}, 2, 0, 1));
+ System.out.println(findNthSmallestNumber(new int[]{2, 3, 5, 10, 9, 4}, 3, 0, 5));
+ System.out.println(findNthSmallestNumber(new int[]{2, 3, 4, 10, 9, 4}, 3, 0, 5));
+ System.out.println(findNthSmallestNumber(new int[]{4, 4, 4, 4, 4, 4}, 3, 0, 5));
+ System.out.println(findNthSmallestNumber(new int[]{4, 8, 1, 9, 10, 2, 7, 3, 2, 6}, 3, 0, 9)); // TODO: doesn't work with duplicates currently
+ }
+}
diff --git a/src/me/ramswaroop/arrays/NumberOccurringOddTimes.java b/src/main/java/com/rampatra/arrays/NumberOccurringOddTimes.java
similarity index 74%
rename from src/me/ramswaroop/arrays/NumberOccurringOddTimes.java
rename to src/main/java/com/rampatra/arrays/NumberOccurringOddTimes.java
index 71902bb0..81656dd1 100644
--- a/src/me/ramswaroop/arrays/NumberOccurringOddTimes.java
+++ b/src/main/java/com/rampatra/arrays/NumberOccurringOddTimes.java
@@ -1,19 +1,21 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 5/20/15
+ * @author rampatra
+ * @since 5/20/15
* @time: 11:09 PM
*/
+import com.rampatra.bits.TwoNonRepeatingElements;
+
/**
* Given an array of positive integers. All numbers occur
* even number of times except one number which occurs odd
* number of times. Find the number in O(n) time & constant space.
- *
- * See {@link me.ramswaroop.bits.TwoNonRepeatingElements} for a more
+ *
+ * See {@link TwoNonRepeatingElements} for a more
* complex problem which is solved in a similar approach.
*/
public class NumberOccurringOddTimes {
@@ -26,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/me/ramswaroop/arrays/OccurrencesInSortedArray.java b/src/main/java/com/rampatra/arrays/OccurrencesInSortedArray.java
similarity index 95%
rename from src/me/ramswaroop/arrays/OccurrencesInSortedArray.java
rename to src/main/java/com/rampatra/arrays/OccurrencesInSortedArray.java
index d4af1859..fea37847 100644
--- a/src/me/ramswaroop/arrays/OccurrencesInSortedArray.java
+++ b/src/main/java/com/rampatra/arrays/OccurrencesInSortedArray.java
@@ -1,10 +1,10 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 8/31/15
+ * @author rampatra
+ * @since 8/31/15
* @time: 2:52 PM
*/
public class OccurrencesInSortedArray {
@@ -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/me/ramswaroop/arrays/PairDiff.java b/src/main/java/com/rampatra/arrays/PairDiff.java
similarity index 90%
rename from src/me/ramswaroop/arrays/PairDiff.java
rename to src/main/java/com/rampatra/arrays/PairDiff.java
index 670d1656..8fce2367 100644
--- a/src/me/ramswaroop/arrays/PairDiff.java
+++ b/src/main/java/com/rampatra/arrays/PairDiff.java
@@ -1,10 +1,10 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 5/18/15
+ * @author rampatra
+ * @since 5/18/15
* @time: 10:24 PM
*/
@@ -15,7 +15,7 @@
/**
* Given an array ar[] of n numbers and another number x, determine whether
* or not there exists two elements in ar[] whose difference is exactly x.
- * This problem is similar to {@link me.ramswaroop.arrays.PairSum}.
+ * This problem is similar to {@link PairSum}.
*/
public class PairDiff {
@@ -63,7 +63,7 @@ static boolean pairDiff(int ar[], int x, Map
* In the above procedure, we are computing random number for each of the indexes greater than k
* thereby giving all items an equal probability.
- *
+ *
* NOTE: When {@param k} is small enough we can use a simpler method as follows:
* Create an array reservoir[] of maximum size k. One by one randomly select an
* item from stream[0..n-1]. If the selected item is not previously selected, then
@@ -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/me/ramswaroop/arrays/ReverseArray.java b/src/main/java/com/rampatra/arrays/ReverseArray.java
similarity index 90%
rename from src/me/ramswaroop/arrays/ReverseArray.java
rename to src/main/java/com/rampatra/arrays/ReverseArray.java
index eb9fabdc..64550c58 100644
--- a/src/me/ramswaroop/arrays/ReverseArray.java
+++ b/src/main/java/com/rampatra/arrays/ReverseArray.java
@@ -1,12 +1,12 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
import java.util.Arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 7/27/15
+ * @author rampatra
+ * @since 7/27/15
* @time: 8:40 PM
*/
public class ReverseArray {
@@ -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/me/ramswaroop/arrays/RotateArray.java b/src/main/java/com/rampatra/arrays/RotateArray.java
similarity index 90%
rename from src/me/ramswaroop/arrays/RotateArray.java
rename to src/main/java/com/rampatra/arrays/RotateArray.java
index 57a168bb..f720dcf6 100644
--- a/src/me/ramswaroop/arrays/RotateArray.java
+++ b/src/main/java/com/rampatra/arrays/RotateArray.java
@@ -1,12 +1,12 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
import java.util.Arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 7/28/15
+ * @author rampatra
+ * @since 7/28/15
* @time: 10:53 AM
*/
public class RotateArray {
@@ -46,10 +46,10 @@ public static void rotateNaiveApproach(int[] a, int k) {
* Reverse B, we get ArBr = [2, 1, 7, 6, 5, 4, 3]
* Reverse all, we get (ArBr)r = [3, 4, 5, 6, 7, 1, 2]
* NOTE: Ar = Reverse of A
+ * See: http://www.geeksforgeeks.org/program-for-array-rotation-continued-reversal-algorithm/
*
* @param a
* @param k
- * @see: http://www.geeksforgeeks.org/program-for-array-rotation-continued-reversal-algorithm/
*/
public static void rotateReversal(int[] a, int k) {
ReverseArray.reverseRecursive(a, 0, k - 1);
@@ -59,10 +59,10 @@ public static void rotateReversal(int[] a, int k) {
/**
* Juggling algorithm for array rotation.
+ * See: http://www.geeksforgeeks.org/array-rotation/
*
* @param a
* @param k
- * @see: http://www.geeksforgeeks.org/array-rotation/
*/
public static void rotateGCD(int[] a, int k) {
int gcd = gcd(a.length, k), temp, i, j, p;
@@ -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/me/ramswaroop/arrays/RotateMatrixBy90Degrees.java b/src/main/java/com/rampatra/arrays/RotateMatrixBy90Degrees.java
similarity index 92%
rename from src/me/ramswaroop/arrays/RotateMatrixBy90Degrees.java
rename to src/main/java/com/rampatra/arrays/RotateMatrixBy90Degrees.java
index 9d81e9d8..ccff75ca 100644
--- a/src/me/ramswaroop/arrays/RotateMatrixBy90Degrees.java
+++ b/src/main/java/com/rampatra/arrays/RotateMatrixBy90Degrees.java
@@ -1,10 +1,10 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 8/22/15
+ * @author rampatra
+ * @since 8/22/15
* @time: 4:03 PM
*/
public class RotateMatrixBy90Degrees {
@@ -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/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/me/ramswaroop/arrays/SearchInSorted2DArray.java b/src/main/java/com/rampatra/arrays/SearchInSorted2DArray.java
similarity index 97%
rename from src/me/ramswaroop/arrays/SearchInSorted2DArray.java
rename to src/main/java/com/rampatra/arrays/SearchInSorted2DArray.java
index aa02619a..8ab14269 100644
--- a/src/me/ramswaroop/arrays/SearchInSorted2DArray.java
+++ b/src/main/java/com/rampatra/arrays/SearchInSorted2DArray.java
@@ -1,12 +1,12 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
import java.util.Arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 8/23/15
+ * @author rampatra
+ * @since 8/23/15
* @time: 10:31 PM
*/
public class SearchInSorted2DArray {
@@ -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/me/ramswaroop/arrays/Segregate0s1sAnd2s.java b/src/main/java/com/rampatra/arrays/Segregate0s1sAnd2s.java
similarity index 92%
rename from src/me/ramswaroop/arrays/Segregate0s1sAnd2s.java
rename to src/main/java/com/rampatra/arrays/Segregate0s1sAnd2s.java
index e0e767c5..e64929f8 100644
--- a/src/me/ramswaroop/arrays/Segregate0s1sAnd2s.java
+++ b/src/main/java/com/rampatra/arrays/Segregate0s1sAnd2s.java
@@ -1,26 +1,26 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
import java.util.Arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 8/18/15
+ * @author rampatra
+ * @since 8/18/15
* @time: 8:38 PM
*/
public class Segregate0s1sAnd2s {
/**
- * Segregates an array {@param a} consisting of only 0s, 1s and 2s. Based on
+ * Segregates an array {@param a} consisting of only 0s, 1s and 2s. Based on
* Dutch National Flag (DNF) problem {@see: http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Sort/Flag/}.
- *
+ *
* @param a
*/
public static void segregate0s1sAnd2s(int[] a) {
// assume low points to 0 and mid to 1 and high to 2
int low = 0, mid = 0, high = a.length - 1;
-
+
while (mid <= high) {
switch (a[mid]) {
case 0: // mid points to 0 but it should point to 1 so swap it with low
@@ -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/me/ramswaroop/arrays/Segregate0sAnd1s.java b/src/main/java/com/rampatra/arrays/Segregate0sAnd1s.java
similarity index 85%
rename from src/me/ramswaroop/arrays/Segregate0sAnd1s.java
rename to src/main/java/com/rampatra/arrays/Segregate0sAnd1s.java
index 2e0f4e06..e5f9634a 100644
--- a/src/me/ramswaroop/arrays/Segregate0sAnd1s.java
+++ b/src/main/java/com/rampatra/arrays/Segregate0sAnd1s.java
@@ -1,12 +1,12 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
import java.util.Arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 7/31/15
+ * @author rampatra
+ * @since 7/31/15
* @time: 5:13 PM
*/
public class Segregate0sAnd1s {
@@ -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/me/ramswaroop/arrays/SegregateEvenAndOddNos.java b/src/main/java/com/rampatra/arrays/SegregateEvenAndOddNos.java
similarity index 86%
rename from src/me/ramswaroop/arrays/SegregateEvenAndOddNos.java
rename to src/main/java/com/rampatra/arrays/SegregateEvenAndOddNos.java
index aa79fd4a..8cdaf6b6 100644
--- a/src/me/ramswaroop/arrays/SegregateEvenAndOddNos.java
+++ b/src/main/java/com/rampatra/arrays/SegregateEvenAndOddNos.java
@@ -1,12 +1,12 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
import java.util.Arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 7/31/15
+ * @author rampatra
+ * @since 7/31/15
* @time: 5:13 PM
*/
public class SegregateEvenAndOddNos {
@@ -15,7 +15,7 @@ public class SegregateEvenAndOddNos {
* Segregate even and odd numbers by traversing the
* array {@param a} only once.
*
* Algorithm:
* 1) Create an auxiliary array smaller[0..n-1]. smaller[i] should store the index of a number which is smaller than arr[i] and is on left side of arr[i]. smaller[i] should contain -1 if there is no such element.
* 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,14 +47,14 @@ 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;
}
}
}
- 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/me/ramswaroop/arrays/SubArrayOfSum.java b/src/main/java/com/rampatra/arrays/SubArrayOfSum.java
similarity index 92%
rename from src/me/ramswaroop/arrays/SubArrayOfSum.java
rename to src/main/java/com/rampatra/arrays/SubArrayOfSum.java
index 78ded53f..4e4f5c2e 100644
--- a/src/me/ramswaroop/arrays/SubArrayOfSum.java
+++ b/src/main/java/com/rampatra/arrays/SubArrayOfSum.java
@@ -1,10 +1,10 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 9/27/15
+ * @author rampatra
+ * @since 9/27/15
* @time: 7:32 PM
*/
public class SubArrayOfSum {
@@ -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/me/ramswaroop/arrays/SubsetOfArray.java b/src/main/java/com/rampatra/arrays/SubsetOfArray.java
similarity index 89%
rename from src/me/ramswaroop/arrays/SubsetOfArray.java
rename to src/main/java/com/rampatra/arrays/SubsetOfArray.java
index 47e3154f..21d5ff2c 100644
--- a/src/me/ramswaroop/arrays/SubsetOfArray.java
+++ b/src/main/java/com/rampatra/arrays/SubsetOfArray.java
@@ -1,12 +1,12 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
-import me.ramswaroop.arrays.sorting.QuickSort;
+import com.rampatra.sorting.QuickSort;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 9/4/15
+ * @author rampatra
+ * @since 9/4/15
* @time: 11:28 PM
*/
public class SubsetOfArray {
@@ -17,7 +17,7 @@ public class SubsetOfArray {
* Explanation: The below method uses sorting + merge method of merge sort. Time
* complexity is O(mlogm + nlogn) where m and n are lengths of array a and b resp.
* You could also have used sorting + binary search but this fails when array
- * {@param b} has repeating elements for example, a={1,4,2} and b={1,4,4,2}. Time
+ * {@param b} has repeating elements for example, a={1,4,2} and b={1,4,4,2}. Time
* complexity would be O(mlogm + nlogm).
*
* @param a
@@ -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/me/ramswaroop/arrays/SymmetricDifference.java b/src/main/java/com/rampatra/arrays/SymmetricDifference.java
similarity index 93%
rename from src/me/ramswaroop/arrays/SymmetricDifference.java
rename to src/main/java/com/rampatra/arrays/SymmetricDifference.java
index dcd7fa98..9ae00478 100644
--- a/src/me/ramswaroop/arrays/SymmetricDifference.java
+++ b/src/main/java/com/rampatra/arrays/SymmetricDifference.java
@@ -1,12 +1,12 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
import java.util.Arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 10/20/15
+ * @author rampatra
+ * @since 10/20/15
* @time: 11:34 PM
*/
public class SymmetricDifference {
@@ -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/me/ramswaroop/arrays/TripletOfSum.java b/src/main/java/com/rampatra/arrays/TripletOfSum.java
similarity index 87%
rename from src/me/ramswaroop/arrays/TripletOfSum.java
rename to src/main/java/com/rampatra/arrays/TripletOfSum.java
index 087cb343..91d47649 100644
--- a/src/me/ramswaroop/arrays/TripletOfSum.java
+++ b/src/main/java/com/rampatra/arrays/TripletOfSum.java
@@ -1,14 +1,14 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
-import me.ramswaroop.arrays.sorting.QuickSort;
+import com.rampatra.sorting.QuickSort;
import java.util.Arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 9/28/15
+ * @author rampatra
+ * @since 9/28/15
* @time: 10:39 PM
*/
public class TripletOfSum {
@@ -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/me/ramswaroop/arrays/TwoElementsSumClosestToZero.java b/src/main/java/com/rampatra/arrays/TwoElementsSumClosestToZero.java
similarity index 87%
rename from src/me/ramswaroop/arrays/TwoElementsSumClosestToZero.java
rename to src/main/java/com/rampatra/arrays/TwoElementsSumClosestToZero.java
index db1eb771..e41a0f92 100644
--- a/src/me/ramswaroop/arrays/TwoElementsSumClosestToZero.java
+++ b/src/main/java/com/rampatra/arrays/TwoElementsSumClosestToZero.java
@@ -1,14 +1,14 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
-import me.ramswaroop.arrays.sorting.QuickSort;
+import com.rampatra.sorting.QuickSort;
import java.util.Arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 7/30/15
+ * @author rampatra
+ * @since 7/30/15
* @time: 5:44 PM
*/
public class TwoElementsSumClosestToZero {
@@ -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/me/ramswaroop/arrays/TwoRepeatingElements.java b/src/main/java/com/rampatra/arrays/TwoRepeatingElements.java
similarity index 91%
rename from src/me/ramswaroop/arrays/TwoRepeatingElements.java
rename to src/main/java/com/rampatra/arrays/TwoRepeatingElements.java
index c1c9a4ae..a943a532 100644
--- a/src/me/ramswaroop/arrays/TwoRepeatingElements.java
+++ b/src/main/java/com/rampatra/arrays/TwoRepeatingElements.java
@@ -1,19 +1,21 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
+
+import com.rampatra.bits.TwoNonRepeatingElements;
import java.util.Arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 8/17/15
+ * @author rampatra
+ * @since 8/17/15
* @time: 7:23 PM
*/
public class TwoRepeatingElements {
/**
* Finds the 2 repeating elements in an array {@param a} of 1 to n elements and n+2 length. This is
- * similar to {@link me.ramswaroop.bits.TwoNonRepeatingElements}.
+ * similar to {@link TwoNonRepeatingElements}.
*
+ * Similar to {@link DuplicatesInArray#findDuplicatesInArray(int[])}.
+ *
* @param a
* @return
*/
@@ -86,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/me/ramswaroop/arrays/TwoStacksInOneArray.java b/src/main/java/com/rampatra/arrays/TwoStacksInOneArray.java
similarity index 95%
rename from src/me/ramswaroop/arrays/TwoStacksInOneArray.java
rename to src/main/java/com/rampatra/arrays/TwoStacksInOneArray.java
index f0e626a8..b4e83806 100644
--- a/src/me/ramswaroop/arrays/TwoStacksInOneArray.java
+++ b/src/main/java/com/rampatra/arrays/TwoStacksInOneArray.java
@@ -1,18 +1,18 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
import java.util.Arrays;
/**
* Created by IntelliJ IDEA.
- *
+ *
* Implement two stacks using a single array with efficient use of space.
* We could do this by dividing the array into two equal halves or storing stack
* elements alternatively in the array but that wouldn't utilize the space fully.
* So we stored stack1's elements at one end of the array and stack2's elements at
* the other end.
*
- * @author: ramswaroop
- * @date: 9/21/15
+ * @author rampatra
+ * @since 9/21/15
* @time: 6:18 PM
*/
public class TwoStacksInOneArray {
@@ -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/me/ramswaroop/arrays/UnsortedSubArray.java b/src/main/java/com/rampatra/arrays/UnsortedSubArray.java
similarity index 95%
rename from src/me/ramswaroop/arrays/UnsortedSubArray.java
rename to src/main/java/com/rampatra/arrays/UnsortedSubArray.java
index ab24d03d..36aa4e12 100644
--- a/src/me/ramswaroop/arrays/UnsortedSubArray.java
+++ b/src/main/java/com/rampatra/arrays/UnsortedSubArray.java
@@ -1,12 +1,12 @@
-package me.ramswaroop.arrays;
+package com.rampatra.arrays;
import java.util.Arrays;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 8/20/15
+ * @author rampatra
+ * @since 8/20/15
* @time: 10:31 AM
*/
public class UnsortedSubArray {
@@ -40,7 +40,7 @@ public static int[] getUnsortedSubArray(int[] a) {
int[] unsortedArray;
// 1(a)
- for (int i = 0; i < a.length-1; i++) {
+ for (int i = 0; i < a.length - 1; i++) {
if (a[i] > a[i + 1]) {
start = i;
break;
@@ -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/me/ramswaroop/backtracking/KnightTour.java b/src/main/java/com/rampatra/backtracking/KnightTour.java
similarity index 94%
rename from src/me/ramswaroop/backtracking/KnightTour.java
rename to src/main/java/com/rampatra/backtracking/KnightTour.java
index 0d82b0b7..64b58918 100644
--- a/src/me/ramswaroop/backtracking/KnightTour.java
+++ b/src/main/java/com/rampatra/backtracking/KnightTour.java
@@ -1,4 +1,4 @@
-package me.ramswaroop.backtracking;
+package com.rampatra.backtracking;
/**
* Created by IntelliJ IDEA.
@@ -7,11 +7,11 @@
* once. If the knight ends on a square that is one knight's move from the beginning square (so that it could tour the
* board again immediately, following the same path), the tour is closed, otherwise it is open.
*
- * @author: ramswaroop
- * @date: 10/15/15
+ * @author rampatra
+ * @since 10/15/15
* @time: 11:56 PM
* @see: https://en.wikipedia.org/wiki/Knight%27s_tour
- * @see: me.ramswaroop.backtracking.RatInAMaze for a simpler version of this problem
+ * @see: RatInAMaze for a simpler version of this problem
*/
public class KnightTour {
@@ -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/me/ramswaroop/backtracking/RatInAMaze.java b/src/main/java/com/rampatra/backtracking/RatInAMaze.java
similarity index 95%
rename from src/me/ramswaroop/backtracking/RatInAMaze.java
rename to src/main/java/com/rampatra/backtracking/RatInAMaze.java
index 09aaf096..bb8ea749 100644
--- a/src/me/ramswaroop/backtracking/RatInAMaze.java
+++ b/src/main/java/com/rampatra/backtracking/RatInAMaze.java
@@ -1,10 +1,10 @@
-package me.ramswaroop.backtracking;
+package com.rampatra.backtracking;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 10/18/15
+ * @author rampatra
+ * @since 10/18/15
* @time: 10:39 AM
*/
public class RatInAMaze {
@@ -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/me/ramswaroop/common/AVLTree.java b/src/main/java/com/rampatra/base/AVLTree.java
similarity index 64%
rename from src/me/ramswaroop/common/AVLTree.java
rename to src/main/java/com/rampatra/base/AVLTree.java
index b995d78f..61999cd0 100644
--- a/src/me/ramswaroop/common/AVLTree.java
+++ b/src/main/java/com/rampatra/base/AVLTree.java
@@ -1,10 +1,10 @@
-package me.ramswaroop.common;
+package com.rampatra.base;
/**
* Created by IntelliJ IDEA.
*
- * @author: ramswaroop
- * @date: 4/25/15
+ * @author rampatra
+ * @since 4/25/15
* @time: 10:25 AM
*/
public class AVLTree
+ * 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
+ * Time complexity: O(h^2) where, h is the height of the tree
*/
public void breadthFirstTraversal() {
- // assuming level starts at zero
- for (int level = 0; level < height(root); level++) {
+ int height = height(root);
+ // assuming level starts at one
+ for (int level = 1; level <= height + 1; level++) {
printLevel(root, level);
}
}
@@ -122,9 +137,9 @@ public void printLevel(BinaryNode
+ * Time complexity: O(log n) where 'n' is total no. of
* elements in heap or O(h) where 'h' is the height of
* heap.
- *
+ *
* @param elem
*/
public void insert(int elem) {
diff --git a/src/me/ramswaroop/common/MinHeap.java b/src/main/java/com/rampatra/base/MinHeap.java
similarity index 87%
rename from src/me/ramswaroop/common/MinHeap.java
rename to src/main/java/com/rampatra/base/MinHeap.java
index be1f3312..6e7b7df1 100644
--- a/src/me/ramswaroop/common/MinHeap.java
+++ b/src/main/java/com/rampatra/base/MinHeap.java
@@ -1,10 +1,8 @@
-package me.ramswaroop.common;
+package com.rampatra.base;
import java.util.Arrays;
/**
- * Created by IntelliJ IDEA.
- * > listOfDepths(TreeNode root) {
+ List
> listOfDepths = new ArrayList<>();
+ List
> listOfDepths(TreeNode node, int depth, List
> listOfDepths) {
+ if (node == null) return null;
+
+ List
> listOfDepths) {
+ for (int i = 0; i < listOfDepths.size(); i++) {
+ System.out.print("Depth " + i + ": ");
+ listOfDepths.get(i).forEach(node -> System.out.print("->" + node.val));
+ System.out.println();
+ }
+ }
+
+ public static void main(String[] args) {
+ TreeNode treeRoot = new TreeNode(1);
+ treeRoot.left = new TreeNode(2);
+ treeRoot.right = new TreeNode(3);
+ treeRoot.left.left = new TreeNode(4);
+ treeRoot.left.right = new TreeNode(5);
+ treeRoot.right.left = new TreeNode(6);
+ treeRoot.right.right = new TreeNode(7);
+
+ printAllDepths(listOfDepths(treeRoot));
+ System.out.println("-----");
+ printAllDepths(listOfDepths(treeRoot, 0, new ArrayList<>()));
+ }
+}
diff --git a/src/main/java/com/ctci/treesandgraphs/MinimalTree.java b/src/main/java/com/ctci/treesandgraphs/MinimalTree.java
new file mode 100644
index 00000000..4d18faf7
--- /dev/null
+++ b/src/main/java/com/ctci/treesandgraphs/MinimalTree.java
@@ -0,0 +1,43 @@
+package com.ctci.treesandgraphs;
+
+/**
+ * Given a sorted (increasing order) array with unique integer elements, write
+ * an algorithm to create a binary search tree with minimal height.
+ *
+ * @author rampatra
+ * @since 2019-02-15
+ */
+public class MinimalTree {
+
+ private static TreeNode constructBSTWithMinimalHeight(int[] arr, int start, int end) {
+ if (start > end) return null;
+
+ int mid = (start + end) / 2;
+ TreeNode root = new TreeNode(arr[mid]);
+ root.left = constructBSTWithMinimalHeight(arr, start, mid - 1);
+ root.right = constructBSTWithMinimalHeight(arr, mid + 1, end);
+ return root;
+ }
+
+ private static void inOrderTraversal(TreeNode node) {
+ if (node == null) return;
+
+ inOrderTraversal(node.left);
+ System.out.print("->" + node.val);
+ inOrderTraversal(node.right);
+ }
+
+ public static void main(String[] args) {
+ TreeNode root = constructBSTWithMinimalHeight(new int[]{1, 2, 3, 4, 5, 6, 7}, 0, 6);
+ inOrderTraversal(root);
+ System.out.println();
+ root = constructBSTWithMinimalHeight(new int[]{1, 2, 3, 4, 5, 6, 7, 8}, 0, 7);
+ inOrderTraversal(root);
+ System.out.println();
+ root = constructBSTWithMinimalHeight(new int[]{1, 2}, 0, 1);
+ inOrderTraversal(root);
+ System.out.println();
+ root = constructBSTWithMinimalHeight(new int[]{1}, 0, 0);
+ inOrderTraversal(root);
+ }
+}
\ 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
new file mode 100644
index 00000000..b849b8c8
--- /dev/null
+++ b/src/main/java/com/ctci/treesandgraphs/RouteBetweenNodes.java
@@ -0,0 +1,94 @@
+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 {
+
+ class Graph {
+
+ private final Map
> generatePascalsTriangle(int numRows) {
+ List
> pascalsTriangle = new ArrayList<>();
+
+ if (numRows == 0) return pascalsTriangle;
+
+ 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
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..61e706ce
--- /dev/null
+++ b/src/main/java/com/leetcode/graphs/WordLadder.java
@@ -0,0 +1,121 @@
+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:
+ *
> findLadders(String beginWord, String endWord, List
> ladders = new LinkedList<>();
+ Map
> ladders, Set
> 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
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/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.
+ *
> zigzagLevelOrder(TreeNode root) {
+
+ int levelNo = 0;
+ LinkedList
> levelOrderTraversal = new LinkedList<>();
+
+ if (root == null) {
+ return levelOrderTraversal;
+ }
+
+ Queue
> 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.val);
+
+ 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/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