diff --git a/README.md b/README.md index 989a3224..419e7c6a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +#To read a.doc files download intellij plugin asciidoc. + # Algorithms and Data Structures in Java The repo consists of solutions to numerous problems using different data structures and algorithms, all coded in Java. It also @@ -8,32 +10,32 @@ You can also refer to my [Java Notes](http://java.ramswaroop.me) for a quick ref ## Contents -1. [Basic Practice](/src/main/java/com/rampatra/): - 1. [Arrays](/src/main/java/com/rampatra/arrays) - 2. [Backtracking](/src/main/java/com/rampatra/backtracking) - 3. [Bits](/src/main/java/com/rampatra/bits) - 4. [Blockchain Demo](/src/main/java/com/rampatra/blockchain) - 5. [Dynamic Programming](/src/main/java/com/rampatra/dynamicprogramming) - 6. [Graphs](/src/main/java/com/rampatra/graphs) - 7. [Java 8](/src/main/java/com/rampatra/java8) - 8. [Linked Lists](/src/main/java/com/rampatra/linkedlists) - 9. [Miscellaneous](/src/main/java/com/rampatra/misc) - 10. [Permutations](/src/main/java/com/rampatra/permutations) - 11. [Searching](/src/main/java/com/rampatra/searching) - 12. [Sorting](/src/main/java/com/rampatra/sorting) - 13. [Stacks](/src/main/java/com/rampatra/stacks) - 14. [Strings](/src/main/java/com/rampatra/strings) - 15. [Threads](/src/main/java/com/rampatra/threads) - 16. [Trees](/src/main/java/com/rampatra/trees) -2. [Cracking the Coding Interview](/src/main/java/com/ctci): - 1. [Arrays and Strings](/src/main/java/com/ctci/arraysandstrings) - 2. [Linked Lists](/src/main/java/com/ctci/linkedlists) - 3. [Stacks and Queues](/src/main/java/com/ctci/stacksandqueues) - 4. [Trees and Graphs](/src/main/java/com/ctci/treesandgraphs) - 5. [Bit Manipulation](/src/main/java/com/ctci/bitmanipulation) - 6. [Recursion and DP](/src/main/java/com/ctci/recursionanddp) -3. [LeetCode](/src/main/java/com/leetcode). -4. [HackerRank](/src/main/java/com/hackerrank). +1. [Basic Practice](/com/backup/rampatra/): + 1. [Arrays](/com/backup/rampatra/arrays) + 2. [Backtracking](/com/backup/rampatra/backtracking) + 3. [Bits](/com/backup/rampatra/bits) + 4. [Blockchain Demo](/com/backup/rampatra/blockchain) + 5. [Dynamic Programming](/com/backup/rampatra/dynamicprogramming) + 6. [Graphs](/com/backup/rampatra/graphs) + 7. [Java 8](/com/backup/rampatra/java8) + 8. [Linked Lists](/com/backup/rampatra/linkedlists) + 9. [Miscellaneous](/com/backup/rampatra/misc) + 10. [Permutations](/com/backup/rampatra/permutations) + 11. [Searching](/com/backup/rampatra/searching) + 12. [Sorting](/com/backup/rampatra/sorting) + 13. [Stacks](/com/backup/rampatra/stacks) + 14. [Strings](/com/backup/rampatra/strings) + 15. [Threads](/com/backup/rampatra/threads) + 16. [Trees](/com/backup/rampatra/trees) +2. [Cracking the Coding Interview](/com/backup/ctci): + 1. [Arrays and Strings](/com/backup/ctci/arraysandstrings) + 2. [Linked Lists](/com/backup/ctci/linkedlists) + 3. [Stacks and Queues](/com/backup/ctci/stacksandqueues) + 4. [Trees and Graphs](/com/backup/ctci/treesandgraphs) + 5. [Bit Manipulation](/com/backup/ctci/bitmanipulation) + 6. [Recursion and DP](/com/backup/ctci/recursionanddp) +3. [LeetCode](/com/backup/leetcode). +4. [HackerRank](/com/backup/hackerrank). ## Environment diff --git a/src/main/images/GetMinimumFromStackInConstantTime.png b/src/main/images/GetMinimumFromStackInConstantTime.png new file mode 100644 index 00000000..84f69450 Binary files /dev/null and b/src/main/images/GetMinimumFromStackInConstantTime.png differ diff --git a/src/main/images/KDistanceFromGivenNode.png b/src/main/images/KDistanceFromGivenNode.png new file mode 100644 index 00000000..666aa3fe Binary files /dev/null and b/src/main/images/KDistanceFromGivenNode.png differ diff --git a/src/main/images/KDistanceFromGivenNode1.png b/src/main/images/KDistanceFromGivenNode1.png new file mode 100644 index 00000000..11db8c62 Binary files /dev/null and b/src/main/images/KDistanceFromGivenNode1.png differ diff --git a/src/main/images/KDistanceFromGivenNode2.png b/src/main/images/KDistanceFromGivenNode2.png new file mode 100644 index 00000000..b84a4183 Binary files /dev/null and b/src/main/images/KDistanceFromGivenNode2.png differ diff --git a/src/main/images/KDistanceFromGivenNode3.png b/src/main/images/KDistanceFromGivenNode3.png new file mode 100644 index 00000000..a8a1860f Binary files /dev/null and b/src/main/images/KDistanceFromGivenNode3.png differ diff --git a/src/main/images/KDistanceFromGivenNode4.png b/src/main/images/KDistanceFromGivenNode4.png new file mode 100644 index 00000000..ee9cfaf6 Binary files /dev/null and b/src/main/images/KDistanceFromGivenNode4.png differ diff --git a/src/main/images/KDistanceFromGivenNode5.png b/src/main/images/KDistanceFromGivenNode5.png new file mode 100644 index 00000000..7b4113fe Binary files /dev/null and b/src/main/images/KDistanceFromGivenNode5.png differ diff --git a/src/main/images/KDistanceFromGivenNode6.png b/src/main/images/KDistanceFromGivenNode6.png new file mode 100644 index 00000000..49899fbf Binary files /dev/null and b/src/main/images/KDistanceFromGivenNode6.png differ diff --git a/src/main/images/LRUCache.png b/src/main/images/LRUCache.png new file mode 100644 index 00000000..4cff11f0 Binary files /dev/null and b/src/main/images/LRUCache.png differ diff --git a/src/main/images/MinimumPlatforms_Greedy.png b/src/main/images/MinimumPlatforms_Greedy.png new file mode 100644 index 00000000..d8011ffe Binary files /dev/null and b/src/main/images/MinimumPlatforms_Greedy.png differ diff --git a/src/main/images/ProntNodesAtKdistanceFromRoot.png b/src/main/images/ProntNodesAtKdistanceFromRoot.png new file mode 100644 index 00000000..988cd5a0 Binary files /dev/null and b/src/main/images/ProntNodesAtKdistanceFromRoot.png differ diff --git a/src/main/images/SearchInRotatedSortedArray.png b/src/main/images/SearchInRotatedSortedArray.png new file mode 100644 index 00000000..59573dd6 Binary files /dev/null and b/src/main/images/SearchInRotatedSortedArray.png differ diff --git a/src/main/images/TopViewOfBinaryTree.png b/src/main/images/TopViewOfBinaryTree.png new file mode 100644 index 00000000..fd267261 Binary files /dev/null and b/src/main/images/TopViewOfBinaryTree.png differ diff --git a/src/main/images/WildCardMatching.png b/src/main/images/WildCardMatching.png new file mode 100644 index 00000000..c54017ba Binary files /dev/null and b/src/main/images/WildCardMatching.png differ diff --git a/src/main/images/class.png b/src/main/images/class.png new file mode 100644 index 00000000..19b59c06 Binary files /dev/null and b/src/main/images/class.png differ diff --git a/src/main/images/classdia.png b/src/main/images/classdia.png new file mode 100644 index 00000000..bcdfeb36 Binary files /dev/null and b/src/main/images/classdia.png differ diff --git a/src/main/images/solidPrinciple.png b/src/main/images/solidPrinciple.png new file mode 100644 index 00000000..4edf7f4c Binary files /dev/null and b/src/main/images/solidPrinciple.png differ diff --git a/src/main/images/spring_actuator.png b/src/main/images/spring_actuator.png new file mode 100644 index 00000000..fc075f82 Binary files /dev/null and b/src/main/images/spring_actuator.png differ diff --git a/src/main/images/spring_annotations.png b/src/main/images/spring_annotations.png new file mode 100644 index 00000000..43ee3964 Binary files /dev/null and b/src/main/images/spring_annotations.png differ diff --git a/src/main/images/spring_annotations_1.png b/src/main/images/spring_annotations_1.png new file mode 100644 index 00000000..db3da33f Binary files /dev/null and b/src/main/images/spring_annotations_1.png differ diff --git a/src/main/images/spring_beans.png b/src/main/images/spring_beans.png new file mode 100644 index 00000000..bd9ac3b7 Binary files /dev/null and b/src/main/images/spring_beans.png differ diff --git a/src/main/images/uml.png b/src/main/images/uml.png new file mode 100644 index 00000000..68e0f205 Binary files /dev/null and b/src/main/images/uml.png differ diff --git a/src/main/java/com/arrays/FindMissingNumber.adoc b/src/main/java/com/arrays/FindMissingNumber.adoc new file mode 100644 index 00000000..5e41a642 --- /dev/null +++ b/src/main/java/com/arrays/FindMissingNumber.adoc @@ -0,0 +1,8 @@ + he bitwise method evaluates the binary representation of the values of the two inputs. For each bit in the binary representation, a Boolean Exclusive Or is performed. In the Boolean evaluation, if one of the input values for the bit is true and the other is false, the output is one for the bit; if both input values are true or if both are false, the output is zero for the bit. When one or both input values are NoData, the bitwise expression outputs NoData. +For example, the input values for a particular cell location on two rasters are 5 and 3. The Boolean Exclusive Or is performed, producing a new binary value. When the value of this number is printed as a decimal integer, its base10 value is assigned to the output. The example below is of an 8-bit integer. + +Value Binary representation +Input 1 5 00000101 +Input 2 3 00000011 +(Bitwise XOr) +Output 6 00000110 diff --git a/src/main/java/com/arrays/FindMissingNumber.java b/src/main/java/com/arrays/FindMissingNumber.java new file mode 100644 index 00000000..8b5edb69 --- /dev/null +++ b/src/main/java/com/arrays/FindMissingNumber.java @@ -0,0 +1,83 @@ +package com.arrays; + +import java.time.Duration; +import java.time.Instant; + +/** + * Input: arr[] = {1, 2, 4, 6, 3, 7, 8} + * Output: 5 + * Explanation: The missing number from 1 to 8 is 5 + *

+ * Input: arr[] = {1, 2, 3, 5} + * Output: 4 + * Explanation: The missing number from 1 to 5 is 4 + *

+ * Approach: + * XOR has certain properties + * Assume a1 ^ a2 ^ a3 ^ …^ an = a and a1 ^ a2 ^ a3 ^ …^ an-1 = b + * Then a ^ b = an + * Using this property, the missing element can be found. Calculate XOR of all the natural number from 1 to n and store it as a. + * Now calculate XOR of all the elements of the array and store it as b. + * The missing number will be a ^ b. + * ^ is XOR operator. + *

+ * Algorithm: + * Create two variables a = 0 and b = 0 + * Run a loop from 1 to n with i as counter. + * For every index update a as a = a ^ i + * Now traverse the array from start to end. + * For every index update b as b = b ^ array[i] + * Print the missing number as a ^ b. + *

+ * Compelxity Analysis: + * Time Complexity: O(n). + * Only one traversal of array is needed. + * Space Complexity: O(1). + * No extra space is needed + *

+ * Bitwise operations are incredibly simple and thus usually faster than arithmetic operations. + */ + +public class FindMissingNumber { + + public static long missingNumber(int[] nums, int n) { + System.out.println("time start"); + + long naturalNumberXOR = 1; + long arrayXOR = nums[0]; + + for (int i = 2; i <= n + 1; i++) { + naturalNumberXOR = naturalNumberXOR ^ i; + } + + for (int i = 1; i < nums.length; i++) { + arrayXOR = arrayXOR ^ nums[i]; + } + System.out.println("time end"); + return naturalNumberXOR ^ arrayXOR; + + + } + + + public static long missingNumberUsingSUm(int[] nums, int n) { + System.out.println("time start"); + long naturalNumberSum = 1; + long arraySum = nums[0]; + + naturalNumberSum = (n * (n + 1)) / 2; //Summation formula GUass's formula + + + for (int i = 1; i < nums.length; i++) { + arraySum = arraySum + nums[i]; + } + System.out.println("time end"); + return naturalNumberSum - arraySum; + + } + + public static void main(String args[]) { + int[] nums = {1, 2, 3, 4, 5, 7, 8, 9, 10}; + System.out.println("Missing Number:" + missingNumberUsingSUm(nums, 10)); + } +} diff --git a/src/main/java/com/arrays/InversionCountInArray_MergeSort.html b/src/main/java/com/arrays/InversionCountInArray_MergeSort.html new file mode 100644 index 00000000..f516ebb8 --- /dev/null +++ b/src/main/java/com/arrays/InversionCountInArray_MergeSort.html @@ -0,0 +1,2475 @@ + + + + + + + + + + + + + + + + + + + + + + +Count Inversions in an array | Set 1 (Using Merge Sort) - GeeksforGeeks + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ + +
+
+
menu
+ +
+
+
+ +
+
+ +
+ +
+ + +
+ + +
+ + + + + +
+ +
+
+
+
+
+

Count Inversions in an array | Set 1 (Using Merge Sort)

+ +
+ +
+
+

Inversion Count for an array indicates – how far (or close) the array is from being sorted. If array is already sorted then inversion count is 0. If array is sorted in reverse order that inversion count is the maximum.
+Formally speaking, two elements a[i] and a[j] form an inversion if a[i] > a[j] and i < j

+

Example:

+
+Input: arr[] = {8, 4, 2, 1}
+Output: 6
+
+Explanation: Given array has six inversions:
+(8,4), (4,2),(8,2), (8,1), (4,1), (2,1).
+
+
+Input: arr[] = {3, 1, 2}
+Output: 2
+
+Explanation: Given array has two inversions:
+(3, 1), (3, 2) 
+
+ +

 
+METHOD 1 (Simple)



+
    +
  • Approach :Traverse through the array and for every index find the number of smaller elements on its right side of the array. This can be done using a nested loop. Sum up the counts for all index in the array and print the sum.
  • +
  • Algorithm : +
      +
    1. Traverse through the array from start to end
    2. +
    3. For every element find the count of elements smaller than the current number upto that index using another loop.
    4. +
    5. Sum up the count of inversion for every index.
    6. +
    7. Print the count of inversions.
    8. +
    +
  • +
  • +Implementation:
    +
    +

    C++

    +
    +

    +
    +
    +
    +
    +
    + filter_none

    +
    +

    edit
    + close

    +
    +

    play_arrow

    +
    +

    link
    + brightness_4
    + code +

    +

    +

    +

    +
    +
    + + + + + + +
    +
    +
    // C++ program to Count Inversions
    +
    // in an array
    +
    #include <bits/stdc++.h>
    +
    using namespace std;
    +
      
    +
    int getInvCount(int arr[], int n)
    +
    {
    +
        int inv_count = 0;
    +
        for (int i = 0; i < n - 1; i++)
    +
            for (int j = i + 1; j < n; j++)
    +
                if (arr[i] > arr[j])
    +
                    inv_count++;
    +
      
    +
        return inv_count;
    +
    }
    +
      
    +
    // Driver Code
    +
    int main()
    +
    {
    +
        int arr[] = { 1, 20, 6, 4, 5 };
    +
        int n = sizeof(arr) / sizeof(arr[0]);
    +
        cout << " Number of inversions are "
    +
             << getInvCount(arr, n);
    +
        return 0;
    +
    }
    +
      
    +
    // This code is contributed
    +
    // by Akanksha Rai
    +
    +
    +
    +
    +

    +
    +
    + chevron_right

    +
    
    +

    + +

    + +

    C

    +
    + +
    +
    +
    +
    +
    + filter_none

    +
    +

    edit
    + close

    +
    +

    play_arrow

    +
    +

    link
    + brightness_4
    + code +

    +

    +

    +

    +
    +
    + + + + + + +
    +
    +
    // C program to Count
    +
    // Inversions in an array
    +
    #include <stdio.h>
    +
    int getInvCount(int arr[], int n)
    +
    {
    +
        int inv_count = 0;
    +
        for (int i = 0; i < n - 1; i++)
    +
            for (int j = i + 1; j < n; j++)
    +
                if (arr[i] > arr[j])
    +
                    inv_count++;
    +
      
    +
        return inv_count;
    +
    }
    +
      
    +
    /* Driver program to test above functions */
    +
    int main()
    +
    {
    +
        int arr[] = { 1, 20, 6, 4, 5 };
    +
        int n = sizeof(arr) / sizeof(arr[0]);
    +
        printf(" Number of inversions are %d \n", getInvCount(arr, n));
    +
        return 0;
    +
    }
    +
    +
    +
    +
    +

    +
    +
    + chevron_right

    +
    
    +

    + +

    + +

    Java

    +
    + +
    +
    +
    +
    +
    + filter_none

    +
    +

    edit
    + close

    +
    +

    play_arrow

    +
    +

    link
    + brightness_4
    + code +

    +

    +

    +

    +
    +
    + + + + + + +
    +
    +
    // Java program to count
    +
    // inversions in an array
    +
    class Test {
    +
        static int arr[] = new int[] { 1, 20, 6, 4, 5 };
    +
      
    +
        static int getInvCount(int n)
    +
        {
    +
            int inv_count = 0;
    +
            for (int i = 0; i < n - 1; i++)
    +
                for (int j = i + 1; j < n; j++)
    +
                    if (arr[i] > arr[j])
    +
                        inv_count++;
    +
      
    +
            return inv_count;
    +
        }
    +
      
    +
        // Driver method to test the above function
    +
        public static void main(String[] args)
    +
        {
    +
            System.out.println("Number of inversions are "
    +
                               + getInvCount(arr.length));
    +
        }
    +
    }
    +
    +
    +
    +
    +

    +
    +
    + chevron_right

    +
    
    +

    + +

    + +

    Python3

    +
    + +
    +
    +
    +
    +
    + filter_none

    +
    +

    edit
    + close

    +
    +

    play_arrow

    +
    +

    link
    + brightness_4
    + code +

    +

    +

    +

    +
    +
    + + + + + + +
    +
    +
    # Python3 program to count 
    +
    # inversions in an array
    +
      
    +
    def getInvCount(arr, n):
    +
      
    +
        inv_count = 0
    +
        for i in range(n):
    +
            for j in range(i + 1, n):
    +
                if (arr[i] > arr[j]):
    +
                    inv_count += 1
    +
      
    +
        return inv_count
    +
      
    +
    # Driver Code
    +
    arr = [1, 20, 6, 4, 5]
    +
    n = len(arr)
    +
    print("Number of inversions are",
    +
                  getInvCount(arr, n))
    +
      
    +
    # This code is contributed by Smitha Dinesh Semwal
    +
    +
    +
    +
    +

    +
    +
    + chevron_right

    +
    
    +

    + +

    + +

    C#

    +
    + +
    +
    +
    +
    +
    + filter_none

    +
    +

    edit
    + close

    +
    +

    play_arrow

    +
    +

    link
    + brightness_4
    + code +

    +

    +

    +

    +
    +
    + + + + + + +
    +
    +
    // C# program to count inversions
    +
    // in an array
    +
    using System;
    +
    using System.Collections.Generic;
    +
      
    +
    class GFG {
    +
      
    +
        static int[] arr = new int[] { 1, 20, 6, 4, 5 };
    +
      
    +
        static int getInvCount(int n)
    +
        {
    +
            int inv_count = 0;
    +
      
    +
            for (int i = 0; i < n - 1; i++)
    +
                for (int j = i + 1; j < n; j++)
    +
                    if (arr[i] > arr[j])
    +
                        inv_count++;
    +
      
    +
            return inv_count;
    +
        }
    +
      
    +
        // Driver code
    +
        public static void Main()
    +
        {
    +
            Console.WriteLine("Number of "
    +
                              + "inversions are "
    +
                              + getInvCount(arr.Length));
    +
        }
    +
    }
    +
      
    +
    // This code is contributed by Sam007
    +
    +
    +
    +
    +

    +
    +
    + chevron_right

    +
    
    +

    + +

    + +

    PHP

    +
    + +
    +
    +
    +
    +
    + filter_none

    +
    +

    edit
    + close

    +
    +

    play_arrow

    +
    +

    link
    + brightness_4
    + code +

    +

    +

    +

    +
    +
    + + + + + + +
    +
    +
    <?php 
    +
    // PHP program to Count Inversions
    +
    // in an array
    +
      
    +
    function getInvCount(&$arr, $n)
    +
    {
    +
        $inv_count = 0;
    +
        for ($i = 0; $i < $n - 1; $i++)
    +
            for ($j = $i + 1; $j < $n; $j++)
    +
                if ($arr[$i] > $arr[$j])
    +
                    $inv_count++;
    +
      
    +
        return $inv_count;
    +
    }
    +
      
    +
    // Driver Code
    +
    $arr = array(1, 20, 6, 4, 5 );
    +
    $n = sizeof($arr);
    +
    echo "Number of inversions are "
    +
               getInvCount($arr, $n);
    +
      
    +
    // This code is contributed by ita_c
    +
    ?>
    +
    +
    +
    +
    +

    +
    +
    + chevron_right

    +
    
    +

    + +

    +


    +Output:

    +
    Number of inversions are 5
    +
  • +

    +
  • Complexity Analysis: +
      +
    • Time Complexity: O(n^2), Two nested loops are needed to traverse the array from start to end so the Time complexity is O(n^2)
    • +
    • Space Compelxity:O(1), No extra space is required.
    • +
    +
  • +
+

METHOD 2(Enhance Merge Sort)

+
    +
  • Approach:
    +Suppose the number of inversions in the left half and right half of the array (let be inv1 and inv2), what kinds of inversions are not accounted for in Inv1 + Inv2? The answer is – the inversions that need to be counted during the merge step. Therefore, to get a number of inversions, that needs to be added a number of inversions in the left subarray, right subarray and merge().

    +

    inv_count1
    +How to get number of inversions in merge()?
    +In merge process, let i is used for indexing left sub-array and j for right sub-array. At any step in merge(), if a[i] is greater than a[j], then there are (mid – i) inversions. because left and right subarrays are sorted, so all the remaining elements in left-subarray (a[i+1], a[i+2] … a[mid]) will be greater than a[j]

    +

    inv_count2

    +

    The complete picture:
    +inv_count3

  • +
  • Algorithm: +
      +
    1. The idea is similar to merge sort, divide the array into two equal or almost equal halves in each step until the base case is reached.
    2. +
    3. Create a function merge that counts the number of inversions when two halves of the array are merged, create two indices i and j, i is the index for first half and j is an index of the second half. if a[i] is greater than a[j], then there are (mid – i) inversions. because left and right subarrays are sorted, so all the remaining elements in left-subarray (a[i+1], a[i+2] … a[mid]) will be greater than a[j].
    4. +
    5. Create a recursive function to divide the array into halves and find the answer by summing the number of inversions is the first half, number of inversion in the second half and the number of inversions by merging the two.
    6. +
    7. The base case of recursion is when there is only one element in the given half.
    8. +
    9. Print the answer
    10. +
    +
  • +
  • +Implementation:
    +
    +

    C++

    +
    +

    +
    +
    +
    +
    +
    + filter_none

    +
    +

    edit
    + close

    +
    +

    play_arrow

    +
    +

    link
    + brightness_4
    + code +

    +

    +

    +

    +
    +
    + + + + + + +
    +
    +
    // C++ program to Count
    +
    // Inversions in an array
    +
    // using Merge Sort
    +
    #include <bits/stdc++.h>
    +
    using namespace std;
    +
      
    +
    int _mergeSort(int arr[], int temp[], int left, int right);
    +
    int merge(int arr[], int temp[], int left, int mid, int right);
    +
      
    +
    /* This function sorts the input array and returns the 
    +
    number of inversions in the array */
    +
    int mergeSort(int arr[], int array_size)
    +
    {
    +
        int temp[array_size];
    +
        return _mergeSort(arr, temp, 0, array_size - 1);
    +
    }
    +
      
    +
    /* An auxiliary recursive function that sorts the input array and 
    +
    returns the number of inversions in the array. */
    +
    int _mergeSort(int arr[], int temp[], int left, int right)
    +
    {
    +
        int mid, inv_count = 0;
    +
        if (right > left) {
    +
            /* Divide the array into two parts and 
    +
            call _mergeSortAndCountInv() 
    +
            for each of the parts */
    +
            mid = (right + left) / 2;
    +
      
    +
            /* Inversion count will be sum of 
    +
            inversions in left-part, right-part 
    +
            and number of inversions in merging */
    +
            inv_count += _mergeSort(arr, temp, left, mid);
    +
            inv_count += _mergeSort(arr, temp, mid + 1, right);
    +
      
    +
            /*Merge the two parts*/
    +
            inv_count += merge(arr, temp, left, mid + 1, right);
    +
        }
    +
        return inv_count;
    +
    }
    +
      
    +
    /* This funt merges two sorted arrays 
    +
    and returns inversion count in the arrays.*/
    +
    int merge(int arr[], int temp[], int left,
    +
              int mid, int right)
    +
    {
    +
        int i, j, k;
    +
        int inv_count = 0;
    +
      
    +
        i = left; /* i is index for left subarray*/
    +
        j = mid; /* j is index for right subarray*/
    +
        k = left; /* k is index for resultant merged subarray*/
    +
        while ((i <= mid - 1) && (j <= right)) {
    +
            if (arr[i] <= arr[j]) {
    +
                temp[k++] = arr[i++];
    +
            }
    +
            else {
    +
                temp[k++] = arr[j++];
    +
      
    +
                /* this is tricky -- see above 
    +
                explanation/diagram for merge()*/
    +
                inv_count = inv_count + (mid - i);
    +
            }
    +
        }
    +
      
    +
        /* Copy the remaining elements of left subarray 
    +
    (if there are any) to temp*/
    +
        while (i <= mid - 1)
    +
            temp[k++] = arr[i++];
    +
      
    +
        /* Copy the remaining elements of right subarray 
    +
    (if there are any) to temp*/
    +
        while (j <= right)
    +
            temp[k++] = arr[j++];
    +
      
    +
        /*Copy back the merged elements to original array*/
    +
        for (i = left; i <= right; i++)
    +
            arr[i] = temp[i];
    +
      
    +
        return inv_count;
    +
    }
    +
      
    +
    // Driver code
    +
    int main()
    +
    {
    +
        int arr[] = { 1, 20, 6, 4, 5 };
    +
        int n = sizeof(arr) / sizeof(arr[0]);
    +
        int ans = mergeSort(arr, n);
    +
        cout << " Number of inversions are " << ans;
    +
        return 0;
    +
    }
    +
      
    +
    // This is code is contributed by rathbhupendra
    +
    +
    +
    +
    +

    +
    +
    + chevron_right

    +
    
    +

    + +

    + +

    C

    +
    + +
    +
    +
    +
    +
    + filter_none

    +
    +

    edit
    + close

    +
    +

    play_arrow

    +
    +

    link
    + brightness_4
    + code +

    +

    +

    +

    +
    +
    + + + + + + +
    +
    +
    // C program to Count
    +
    // Inversions in an array
    +
    // using Merge Sort
    +
    #include <stdio.h>
    +
      
    +
    int _mergeSort(int arr[], int temp[], int left, int right);
    +
    int merge(int arr[], int temp[], int left, int mid, int right);
    +
      
    +
    /* This function sorts the input array and returns the
    +
       number of inversions in the array */
    +
    int mergeSort(int arr[], int array_size)
    +
    {
    +
        int* temp = (int*)malloc(sizeof(int) * array_size);
    +
        return _mergeSort(arr, temp, 0, array_size - 1);
    +
    }
    +
      
    +
    /* An auxiliary recursive function that sorts the input array and
    +
      returns the number of inversions in the array. */
    +
    int _mergeSort(int arr[], int temp[], int left, int right)
    +
    {
    +
        int mid, inv_count = 0;
    +
        if (right > left) {
    +
            /* Divide the array into two parts and call _mergeSortAndCountInv()
    +
           for each of the parts */
    +
            mid = (right + left) / 2;
    +
      
    +
            /* Inversion count will be the sum of inversions in left-part, right-part
    +
          and number of inversions in merging */
    +
            inv_count += _mergeSort(arr, temp, left, mid);
    +
            inv_count += _mergeSort(arr, temp, mid + 1, right);
    +
      
    +
            /*Merge the two parts*/
    +
            inv_count += merge(arr, temp, left, mid + 1, right);
    +
        }
    +
        return inv_count;
    +
    }
    +
      
    +
    /* This funt merges two sorted arrays and returns inversion count in
    +
       the arrays.*/
    +
    int merge(int arr[], int temp[], int left, int mid, int right)
    +
    {
    +
        int i, j, k;
    +
        int inv_count = 0;
    +
      
    +
        i = left; /* i is index for left subarray*/
    +
        j = mid; /* j is index for right subarray*/
    +
        k = left; /* k is index for resultant merged subarray*/
    +
        while ((i <= mid - 1) && (j <= right)) {
    +
            if (arr[i] <= arr[j]) {
    +
                temp[k++] = arr[i++];
    +
            }
    +
            else {
    +
                temp[k++] = arr[j++];
    +
      
    +
                /*this is tricky -- see above explanation/diagram for merge()*/
    +
                inv_count = inv_count + (mid - i);
    +
            }
    +
        }
    +
      
    +
        /* Copy the remaining elements of left subarray
    +
       (if there are any) to temp*/
    +
        while (i <= mid - 1)
    +
            temp[k++] = arr[i++];
    +
      
    +
        /* Copy the remaining elements of right subarray
    +
       (if there are any) to temp*/
    +
        while (j <= right)
    +
            temp[k++] = arr[j++];
    +
      
    +
        /*Copy back the merged elements to original array*/
    +
        for (i = left; i <= right; i++)
    +
            arr[i] = temp[i];
    +
      
    +
        return inv_count;
    +
    }
    +
      
    +
    /* Driver program to test above functions */
    +
    int main(int argv, char** args)
    +
    {
    +
        int arr[] = { 1, 20, 6, 4, 5 };
    +
        printf(" Number of inversions are %d \n", mergeSort(arr, 5));
    +
        getchar();
    +
        return 0;
    +
    }
    +
    +
    +
    +
    +

    +
    +
    + chevron_right

    +
    
    +

    + +

    + +

    Java

    +
    + +
    +
    +
    +
    +
    + filter_none

    +
    +

    edit
    + close

    +
    +

    play_arrow

    +
    +

    link
    + brightness_4
    + code +

    +

    +

    +

    +
    +
    + + + + + + +
    +
    +
    // Java implementation of the approach
    +
    import java.util.Arrays;
    +
      
    +
    public class GFG {
    +
      
    +
        // Function to count the number of inversions
    +
        // during the merge process
    +
        private static int mergeAndCount(int[] arr, int l, int m, int r)
    +
        {
    +
      
    +
            // Left subarray
    +
            int[] left = Arrays.copyOfRange(arr, l, m + 1);
    +
      
    +
            // Right subarray
    +
            int[] right = Arrays.copyOfRange(arr, m + 1, r + 1);
    +
      
    +
            int i = 0, j = 0, k = l, swaps = 0;
    +
      
    +
            while (i < left.length && j < right.length) {
    +
                if (left[i] <= right[j])
    +
                    arr[k++] = left[i++];
    +
                else {
    +
                    arr[k++] = right[j++];
    +
                    swaps += (m + 1) - (l + i);
    +
                }
    +
            }
    +
      
    +
            // Fill from the rest of the left subarray
    +
            while (i < left.length)
    +
                arr[k++] = left[i++];
    +
      
    +
            // Fill from the rest of the right subarray
    +
            while (j < right.length)
    +
                arr[k++] = right[j++];
    +
      
    +
            return swaps;
    +
        }
    +
      
    +
        // Merge sort function
    +
        private static int mergeSortAndCount(int[] arr, int l, int r)
    +
        {
    +
      
    +
            // Keeps track of the inversion count at a
    +
            // particular node of the recursion tree
    +
            int count = 0;
    +
      
    +
            if (l < r) {
    +
                int m = (l + r) / 2;
    +
      
    +
                // Total inversion count = left subarray count
    +
                // + right subarray count + merge count
    +
      
    +
                // Left subarray count
    +
                count += mergeSortAndCount(arr, l, m);
    +
      
    +
                // Right subarray count
    +
                count += mergeSortAndCount(arr, m + 1, r);
    +
      
    +
                // Merge count
    +
                count += mergeAndCount(arr, l, m, r);
    +
            }
    +
      
    +
            return count;
    +
        }
    +
      
    +
        // Driver code
    +
        public static void main(String[] args)
    +
        {
    +
            int[] arr = { 1, 20, 6, 4, 5 };
    +
      
    +
            System.out.println(mergeSortAndCount(arr, 0, arr.length - 1));
    +
        }
    +
    }
    +
      
    +
    // This code is contributed by Pradip Basak
    +
    +
    +
    +
    +

    +
    +
    + chevron_right

    +
    
    +

    + +

    + +

    Python3

    +
    + +
    +
    +
    +
    +
    + filter_none

    +
    +

    edit
    + close

    +
    +

    play_arrow

    +
    +

    link
    + brightness_4
    + code +

    +

    +

    +

    +
    +
    + + + + + + +
    +
    +
    # Python 3 program to count inversions in an array
    +
      
    +
    # Function to Use Inversion Count
    +
    def mergeSort(arr, n):
    +
        # A temp_arr is created to store
    +
        # sorted array in merge function
    +
        temp_arr = [0]*n
    +
        return _mergeSort(arr, temp_arr, 0, n-1)
    +
      
    +
    # This Function will use MergeSort to count inversions
    +
      
    +
    def _mergeSort(arr, temp_arr, left, right):
    +
      
    +
        # A variable inv_count is used to store
    +
        # inversion counts in each recursive call
    +
      
    +
        inv_count = 0
    +
      
    +
        # We will make a recursive call if and only if
    +
        # we have more than one elements
    +
      
    +
        if left < right:
    +
      
    +
            # mid is calculated to divide the array into two subarrays
    +
            # Floor division is must in case of python
    +
      
    +
            mid = (left + right)//2
    +
      
    +
            # It will calculate inversion counts in the left subarray
    +
      
    +
            inv_count += _mergeSort(arr, temp_arr, left, mid)
    +
      
    +
            # It will calculate inversion counts in right subarray
    +
      
    +
            inv_count += _mergeSort(arr, temp_arr, mid + 1, right)
    +
      
    +
            # It will merge two subarrays in a sorted subarray
    +
      
    +
            inv_count += merge(arr, temp_arr, left, mid, right)
    +
        return inv_count
    +
      
    +
    # This function will merge two subarrays in a single sorted subarray
    +
    def merge(arr, temp_arr, left, mid, right):
    +
        i = left     # Starting index of left subarray
    +
        j = mid + 1 # Starting index of right subarray
    +
        k = left     # Starting index of to be sorted subarray
    +
        inv_count = 0
    +
      
    +
        # Conditions are checked to make sure that i and j don't exceed their
    +
        # subarray limits.
    +
      
    +
        while i <= mid and j <= right:
    +
      
    +
            # There will be no inversion if arr[i] <= arr[j]
    +
      
    +
            if arr[i] <= arr[j]:
    +
                temp_arr[k] = arr[i]
    +
                k += 1
    +
                i += 1
    +
            else:
    +
                # Inversion will occur.
    +
                temp_arr[k] = arr[j]
    +
                inv_count += (mid-i + 1)
    +
                k += 1
    +
                j += 1
    +
      
    +
        # Copy the remaining elements of left subarray into temporary array
    +
        while i <= mid:
    +
            temp_arr[k] = arr[i]
    +
            k += 1
    +
            i += 1
    +
      
    +
        # Copy the remaining elements of right subarray into temporary array
    +
        while j <= right:
    +
            temp_arr[k] = arr[j]
    +
            k += 1
    +
            j += 1
    +
      
    +
        # Copy the sorted subarray into Original array
    +
        for loop_var in range(left, right + 1):
    +
            arr[loop_var] = temp_arr[loop_var]
    +
              
    +
        return inv_count
    +
      
    +
    # Driver Code
    +
    # Given array is
    +
    arr = [1, 20, 6, 4, 5]
    +
    n = len(arr)
    +
    result = mergeSort(arr, n)
    +
    print("Number of inversions are", result)
    +
      
    +
    # This code is contributed by ankush_953
    +
    +
    +
    +
    +

    +
    +
    + chevron_right

    +
    
    +

    + +

    + +

    C#

    +
    + +
    +
    +
    +
    +
    + filter_none

    +
    +

    edit
    + close

    +
    +

    play_arrow

    +
    +

    link
    + brightness_4
    + code +

    +

    +

    +

    +
    +
    + + + + + + +
    +
    +
    // C# implementation of counting the
    +
    // inversion using merge sort
    +
      
    +
    using System;
    +
    public class Test {
    +
      
    +
        /* This method sorts the input array and returns the
    +
           number of inversions in the array */
    +
        static int mergeSort(int[] arr, int array_size)
    +
        {
    +
            int[] temp = new int[array_size];
    +
            return _mergeSort(arr, temp, 0, array_size - 1);
    +
        }
    +
      
    +
        /* An auxiliary recursive method that sorts the input array and
    +
          returns the number of inversions in the array. */
    +
        static int _mergeSort(int[] arr, int[] temp, int left, int right)
    +
        {
    +
            int mid, inv_count = 0;
    +
            if (right > left) {
    +
                /* Divide the array into two parts and call _mergeSortAndCountInv()
    +
               for each of the parts */
    +
                mid = (right + left) / 2;
    +
      
    +
                /* Inversion count will be the sum of inversions in left-part, right-part
    +
              and number of inversions in merging */
    +
                inv_count += _mergeSort(arr, temp, left, mid);
    +
                inv_count += _mergeSort(arr, temp, mid + 1, right);
    +
      
    +
                /*Merge the two parts*/
    +
                inv_count += merge(arr, temp, left, mid + 1, right);
    +
            }
    +
            return inv_count;
    +
        }
    +
      
    +
        /* This method merges two sorted arrays and returns inversion count in
    +
           the arrays.*/
    +
        static int merge(int[] arr, int[] temp, int left, int mid, int right)
    +
        {
    +
            int i, j, k;
    +
            int inv_count = 0;
    +
      
    +
            i = left; /* i is index for left subarray*/
    +
            j = mid; /* j is index for right subarray*/
    +
            k = left; /* k is index for resultant merged subarray*/
    +
            while ((i <= mid - 1) && (j <= right)) {
    +
                if (arr[i] <= arr[j]) {
    +
                    temp[k++] = arr[i++];
    +
                }
    +
                else {
    +
                    temp[k++] = arr[j++];
    +
      
    +
                    /*this is tricky -- see above explanation/diagram for merge()*/
    +
                    inv_count = inv_count + (mid - i);
    +
                }
    +
            }
    +
      
    +
            /* Copy the remaining elements of left subarray
    +
           (if there are any) to temp*/
    +
            while (i <= mid - 1)
    +
                temp[k++] = arr[i++];
    +
      
    +
            /* Copy the remaining elements of right subarray
    +
           (if there are any) to temp*/
    +
            while (j <= right)
    +
                temp[k++] = arr[j++];
    +
      
    +
            /*Copy back the merged elements to original array*/
    +
            for (i = left; i <= right; i++)
    +
                arr[i] = temp[i];
    +
      
    +
            return inv_count;
    +
        }
    +
      
    +
        // Driver method to test the above function
    +
        public static void Main()
    +
        {
    +
            int[] arr = new int[] { 1, 20, 6, 4, 5 };
    +
            Console.Write("Number of inversions are " + mergeSort(arr, 5));
    +
        }
    +
    }
    +
    // This code is contributed by Rajput-Ji
    +
    +
    +
    +
    +

    +
    +
    + chevron_right

    +
    
    +

    + +

    +


    +Output:

    +
    Number of inversions are 5
    +
  • +
  • Complexity Analysis: +
      +
    • Time Complexity: O(n log n), The algorithm used is divide and conquer, So in each level one full array traversal is needed and there are log n levels so the time complexity is O(n log n).
    • +
    • Space Compelxity:O(1), No extra space is required.
    • +
    +
  • +
+

Note that above code modifies (or sorts) the input array. If we want to count only inversions then we need to create a copy of original array and call mergeSort() on copy.

+

+

You may like to see.
+Count inversions in an array | Set 2 (Using Self-Balancing BST)
+Counting Inversions using Set in C++ STL
+Count inversions in an array | Set 3 (Using BIT)

+


+References:

+http://www.cs.umd.edu/class/fall2009/cmsc451/lectures/Lec08-inversions.pdf
+http://www.cp.eng.chula.ac.th/~piak/teaching/algo/algo2008/count-inv.htm

+

Please write comments if you find any bug in the above program/algorithm or other ways to solve the same problem.

+


+
+ My Personal Notes + arrow_drop_up +
+
+ +
+ + +
+
+

+ + +
+ + + + + + + + + + + +
+

+ + + + +

+ +
+
+ +
+ +
+ +
+
+ + + +
+ +
+
+
+ +
+ +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/arrays/InversionCountInArray_MergeSort.java b/src/main/java/com/arrays/InversionCountInArray_MergeSort.java new file mode 100644 index 00000000..f108c436 --- /dev/null +++ b/src/main/java/com/arrays/InversionCountInArray_MergeSort.java @@ -0,0 +1,87 @@ +package com.arrays; + +import java.util.Arrays; + +/** + * Inversion Count : For an array, inversion count indicates how far (or close) the array is from being sorted. + * If array is already sorted then inversion count is 0. If array is sorted in reverse order that inversion count is the maximum. + * Formally, two elements a[i] and a[j] form an inversion if a[i] > a[j] and i < j. + *

+ *

+ * Algorithm: + * The idea is similar to merge sort, divide the array into two equal or almost equal halves in each step until the base case is reached. + * Create a function merge that counts the number of inversions when two halves of the array are merged, + * create two indices i and j, i is the index for first half and j is an index of the second half. + * if a[i] is greater than a[j], then there are (mid – i) inversions. because left and right subarrays are sorted, so all the remaining elements in left-subarray (a[i+1], a[i+2] … a[mid]) will be greater than a[j]. + * Create a recursive function to divide the array into halves and find the answer by summing the number of inversions is the first half, number of inversion in the second half and the number of inversions by merging the two. + * The base case of recursion is when there is only one element in the given half. + * Print the answer + *

+ *

+ * Complexity Analysis: + * Time Complexity: O(n log n), The algorithm used is divide and conquer, + * So in each level one full array traversal is needed and there are log n levels so the time complexity is O(n log n). + * Space Compelxity:O(1), No extra space is required. + */ +public class InversionCountInArray_MergeSort { + + // Merge two sorted subarrays arr[low .. mid] and arr[mid + 1 .. high] + public static int merge(int[] arr, int start, int mid, int end) { + // Left subarray + int[] left = Arrays.copyOfRange(arr, start, mid + 1); + + // Right subarray + int[] right = Arrays.copyOfRange(arr, mid + 1, end + 1); + + int leftCursor = 0, rightCursor = 0, current = start, swaps = 0; + + while (leftCursor < left.length && rightCursor < right.length) { + if (left[leftCursor] <= right[rightCursor]) + arr[current++] = left[leftCursor++]; + else { + arr[current++] = right[rightCursor++]; + swaps += mid + 1 - leftCursor; /**important*/ + } + } + + // Fill from the rest of the left subarray + while (leftCursor < left.length) + arr[current++] = left[leftCursor++]; + + // Fill from the rest of the right subarray + while (rightCursor < right.length) + arr[current++] = right[rightCursor++]; + + return swaps; + } + + // Sort array arr [low..high] using auxiliary array aux[] + public static int mergeSort(int[] arr, int low, int high) { + // Base case + if (high == low) { // if run size == 1 + return 0; + } + + // find mid point + int mid = (low + high) / 2; + int inversionCount = 0; + + // recursively split runs into two halves until run size == 1, + // then merge them and return back up the call chain + + inversionCount += mergeSort(arr, low, mid); // split / merge left half + inversionCount += mergeSort(arr, mid + 1, high); // split / merge right half + inversionCount += merge(arr, low, mid, high); // merge the two half runs + + return inversionCount; + } + + public static void main(String[] args) { + int[] arr = {1, 9, 6, 4, 5}; + int[] aux = Arrays.copyOf(arr, arr.length); + + // get inversion count by performing merge sort on arr + System.out.println("Inversion count is " + + mergeSort(arr, 0, arr.length - 1)); + } +} diff --git a/src/main/java/com/arrays/LongestConsecutiveSubsequence.java b/src/main/java/com/arrays/LongestConsecutiveSubsequence.java new file mode 100644 index 00000000..2a8f17cd --- /dev/null +++ b/src/main/java/com/arrays/LongestConsecutiveSubsequence.java @@ -0,0 +1,61 @@ +package com.arrays; + +import java.util.HashSet; + +/** + * Given an unsorted array of integers, + * find the length of the longest consecutive elements sequence. + * + * For example, given [100, 4, 200, 1, 3, 2], + * the longest consecutive elements sequence should be [1, 2, 3, 4]. Its length is 4. + * + * Because it requires O(n) complexity, + * we can not solve the problem by sorting the array first. Sorting takes at least O(nlogn) time. + * + * We can use a HashSet to add and remove elements. + * The add, remove and contains methods have constant time complexity O(1). + */ +public class LongestConsecutiveSubsequence { + + public static int longestConsecutive(int[] nums) { + + /** Add all the elements of array to Set */ + HashSet set = new HashSet<>(); + for (int num : nums) + set.add(num); + + int result = 0; + + /** Iterate over each element in array */ + for (int num : nums) { + int count = 1; + + /** calculate previous element to current element to see if present in set */ + int down = num - 1; + while (set.contains(down)) { + set.remove(down); + down--; + count++; + } + + /** calculate next element to current element to see if present in set */ + int up = num + 1; + while (set.contains(up)) { + set.remove(up); + up++; + count++; + } + + /** update the result if current counter is bigger than result */ + result = Math.max(result, count); + } + + return result; + } + + public static void main(String args[]) { + int nums[] = {1, 5, 4, 100, 200, 2, 3}; + int result = longestConsecutive(nums); + System.out.println("longestConsecutive : " + result); + } +} diff --git a/src/main/java/com/arrays/MaxSumSubArray_KadaneAlgo_DynamicProgram.html b/src/main/java/com/arrays/MaxSumSubArray_KadaneAlgo_DynamicProgram.html new file mode 100644 index 00000000..3eab7092 --- /dev/null +++ b/src/main/java/com/arrays/MaxSumSubArray_KadaneAlgo_DynamicProgram.html @@ -0,0 +1,2919 @@ + + + + + + + + + + +Kadane's Algorithm in Java. | JavaByPatel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ + +
+
+
+ +
+
+
+ + +
+ +
+
+
+
+
+
+ +
+ + +
+ + +
+ +
+
+

+Kadane's Algorithm in Java. +

+ +
+
+
+
+
+
+

+Kadane's Algorithm in Java to find Largest Sum Contiguous Subarray.
+

+Kadane's Algorithm in Java. Kadane's Algorithm to solve maximum sum subarray problem.
+
+The maximum subarray problem is the task of finding the contiguous subarray within a one-dimensional array of numbers which has the largest sum.
+
+
+
+Lets see what is expected output from given input,
 

+Case 1:
        Input:
            {3, -1, -1, -1, -1, -1, 2, 0, 0, 0}
        Output:
            start index :0
            End index :0
            Sum :3
           
Case 2:   
        Input:      
            {-1, 3, -5, 4, 6, -1, 2, -7, 13, -3}
        Output:      
            start index :3
            End index :8
            Sum :17

Case 3:
        Input:  
            {-2,-3,4,-1,-2,1,5,-3}
        Output:
            start index :2
            End index :6
            Sum :7

Case 4:
        Input:  
            {-1,3,-5,4,6,-1,2,-7,13,-3}
        Output:
            start index :3
            End index :8
            Sum :17

Case 5:
        Input:  
            {-1}
        Output:
            start index :0
            End index :0
            Sum :-1

Case 6:
        Input:  
            {-6,-2,-3,-4,-1,-5,-5}
        Output:
            start index :4
            End index :4
            Sum :-1

+ 
+

+Algorithm: How to find maximum subarray sequence?

+
+
+ 0 element Array
+        If there is no element present in array then we can say that,
+        in this case, startIndex = -1, endIndex = -1 and
+        maxSum = -1 (or any other suitable notation for no element present) +
+
+
+ + + + + + +
+
+
+1 element Array
+        If array is having only one element, then that single element is the highest in array
+        as that is the only element present in array,
+        in this case, startIndex = 0, endIndex = 0 and maxSum = arr[0];
+
+Now, lets look for array having length greater than 1.
+        Before iterating the array, we first check array length and if it is greater then 0,
+        then only proceed else return startIndex = -1, endIndex = -1 and maxSum = -1.
+
+        Lets take one variable for storing sum and initialize it to 0;
+        int tempSum = 0;
+      
+        Lets start a loop from 0 to length of array,
+        we will pick the first element of array and check,       +
+
+        tempSum = tempSum + array[i];
+        If tempSum is less then 0,
+        It means there is no point in including or considering this element in maximum
+        sum sub array search as including this element will bring the tempSum to less then 0,
+        So ignore the element and go ahead for searching next element.
+
+        If tempSum is greater then 0,
+        It means there is a chance that including or considering this element can lead to
+        maximum sum sub array, as including this element is not bringing tempSum to less then 0,
+        So consider this element and go ahead for searching next element.
+
+        However, considering this element is not guaranteed to form a maximum sub array
+        as it can decrease the total sum which is not less then 0.
+       
+        Eg: if the array is {4, -2}
+        So initially, when considering element at position 0.
+        we will get tempSum = 4 and it is greater then 0, so we are including it,
+
+        Now lets see element at position 1, we will get tempSum = 2 (4 + -2 = -2),
+        In this case tempSum = 2, which is not less then 0, so should we consider this????
+        we should consider this and give a try because chances are there that we may get
+        higher element at next position(Eg array: {4, -2, 4})
+        but in our case we don't have element at position 2, so what to do in this case,
+
+        So what we will do is we will take 2 variables,
+        1. maxSumTillNow, which will store max sum till now encountered.
+        2. tempSum, which will store max sum till now encountered and also take risk of
+        adding next element which may or may not increase the maxSumTillNow.
+
+        Lets try to map this variables in our example,
+        In 1st iteration, for arr[0]
+        maxSumTillNow=4
+        tempSum=4
+
+        In 2nd iteration, for arr[1]
+        maxSumTillNow=4
+        tempSum=2
+
+        So our maxSumTillNow will reflect the maximum sub array sum.
+        +
+
+
+Lets see example {4, -2, 6},
+
+        In 1st iteration, for arr[0]
+        maxSumTillNow=4
+        tempSum=4
+
+        In 2nd iteration, for arr[1]
+        maxSumTillNow=4
+        tempSum=2
+
+        In 3rd iteration, for arr[2]
+        maxSumTillNow=4
+        tempSum=8
+
+        In this case, our tempSum is greater then maxSumTillNow and maxSumTillNow is stale,
+        so what we will do in this situation is,
+        when tempSum > maxSumTillNow, then we will re initialize maxSumTillNow = tempSum;
+        and maxSumTillNow gets updated.
+        Now when maxSumTillNow gets updated, obviously we have to update
+        startIndex and endIndex as new element get added to maxSumTillNow.
+
+        So by looking at this example, do we need to update start index when we include element 6?
+        Lets see example from start {4, -2, 6},
+
+        In 1st iteration, for arr[0]
+        maxSumTillNow=4
+        tempSum=4
+        startIndex = 0
+        endIndex = 0
+
+        In 2nd iteration, for arr[1]
+        maxSumTillNow=4
+        tempSum=2
+        startIndex = 0
+        endIndex = 0
+
+        In 3rd iteration, for arr[2]
+        maxSumTillNow=8
+            (in this case tempSum > maxSumTillNow, so maxSumTillNow is updated to
+             value of tempSum)
+        tempSum=8
+        startIndex = 0
+        endIndex = 2
+
+        We can see from above example, when our tempSum > maxSumTillNow,
+        we are including a new element in our chain, so our chain start element will remain same,
+        that is we don't need to update start index at this point but we need to update endIndex to
+        index position of new element added.
+
+        So when we will update startIndex then????
+       
+
+
+Let see one more example {4, -2, 6, -10, 8, 1},
+
+        In 1st iteration, for arr[0]
+        maxSumTillNow=4
+        tempSum=4
+        startIndex = 0
+        endIndex = 0
+
+        In 2nd iteration, for arr[1]
+        maxSumTillNow=4
+        tempSum=2
+        startIndex = 0
+        endIndex = 0
+
+        In 3rd iteration, for arr[2]
+        maxSumTillNow=8
+        tempSum=8
+        startIndex = 0
+        endIndex = 2
+
+        In 4th iteration, for arr[3]
+        maxSumTillNow=8
+        tempSum=-2
+        startIndex = ?
+        endIndex = ?
+
+        Now, when we encounter that our result was going good and next element when checked
        is making tempSum to -2 that is tempSum < 0,

+        So in this case it is sure including this element(-10) in chain before this element(4, -2, 6)
        will make the result negative, so not include this element in consideration and simply ignore
        this element and keep our variables as it is without modification.

+
+        So our variables will be,
+
+        maxSumTillNow=8
+        tempSum=-2
+        startIndex = 0
+        endIndex = 2
+       
+        we can see from this, that there forms 2 chain,
+        one chain is before -10 that is (4, -2, 6) and
+        one chain is after -10 that is (8, 1)
+
+        and -10 when included with before chain or after chain will surely decrease the result.
+        Now question is which chain contains maximum sub array sum, before -10 or after -10?
+
+        Till now we have seen before chain and we got maxSumTillNow=8 and variables as,
+        maxSumTillNow=8
+        startIndex = 0
+        endIndex = 2
+
+        Now, we will start exploring after chain, so before exploring after chain,
+        we have to reset variable tempSum to 0 as we are starting the things again.
+
+        So when tempSum<0, we will reset tempSum to 0.
+        Also, keeping existing startIndex = 0 and endIndex = 2 intact, we need to explore next chain.
+        
+        So we have to take one more variable as tempStartIndex.
+        tempStartIndex holds new start index of new chain that we are going to explore.
+        
+        When we found that new chain sum is greater then chain we already explored,
        at that time we will update startIndex to tempStartIndex.

+
+        Also, when we observe tempSum<0, at that time we will initialize
        tempStartIndex = i(currentIndex) + 1,

+        because next max chain we can get, can be formed excluding current element and start from 
+        next index.
+
+        In 5th iteration, for arr[4]
        maxSumTillNow=8
        tempSum=8(from -2, reseted to 0 and now included element 8)
        startIndex = 0
        endIndex = 2
        tempStartIndex = 4

        In 6th iteration, for arr[5]
        maxSumTillNow=8
        tempSum=9

        we can see in this step,
        tempSum>maxSumTillNow, so we have to update maxSumTillNow as we got new chain

+        starting from tempStartIndex and ending at i(curent index)
        

+        So we will update variable startIndex to tempStartIndex value as that is the starting
        place where we started exploring new chain.
        also, we will update variable endIndex to i(current index of loop).
        also, we will update variable maxSumTillNow to tempSum.

        So the new variables are,
        maxSumTillNow=9
        tempSum=9
        startIndex = 4
        endIndex = 5
        tempStartIndex = 4

+
+
+

+Program to find the largest sum contiguous subarray in Java

+In this program, instead of using 3 variables that we are interested in
+maxSumTillNow, startIndex. and endIndex, we are using result array whose,
+result[0] will represent startIndex,
+result[1] will represent endIndex,
+result[2] will represent maxSumTillNow
+
+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package algo.kadane;
 
public class MaximumSubArray {
 
 public static void main(String[] args) {
 
  int[] arr = {-1,3,-5,4,6,-1,2,-7,13,-3};
 
  int[] result = findMaxSumIndex(arr);
  System.out.println("start index :"+result[0]);
  System.out.println("End index :"+result[1]);
  System.out.println("Sum :"+result[2]);
 
 }
 
 private static int[] findMaxSumIndex(int[] arr){
  int[] result = new int[3];
  int maxSumTillNow = Integer.MIN_VALUE;
 
  int tempStartIndex = 0;
  int tempSum = 0;
 
  for (int i = 0; i < arr.length; i++) {
   tempSum = tempSum + arr[i];
 
   if(tempSum > maxSumTillNow){
    maxSumTillNow = tempSum;
    result[0] = tempStartIndex;
    result[1] = i;
    result[2] = maxSumTillNow;
   }
 
   if(tempSum<0){
    tempSum = 0;
    tempStartIndex = i + 1;
   }
  }
  return result;
 }
}
+

+Time Complexity:

+
+The runtime complexity of Kadane's algorithm is O(n) as we are iterating the array containing n elements only once.
+
+
+
+Enjoy !!!!
+
+
+
+If you find any issue in post or face any error while implementing, Please comment.
+ +
+ +
+
+
+ + + + +
+
+
+ +
+ +
+ + + +
+ +
+ + +
+
+ +Newer Post + + +Older Post + +Home +
+
+
+
+
+ + +
+ +
+
+ + + + +
+ + + + + + + + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/arrays/MaxSumSubArray_KadaneAlgo_DynamicProgram.java b/src/main/java/com/arrays/MaxSumSubArray_KadaneAlgo_DynamicProgram.java new file mode 100644 index 00000000..33616ef3 --- /dev/null +++ b/src/main/java/com/arrays/MaxSumSubArray_KadaneAlgo_DynamicProgram.java @@ -0,0 +1,58 @@ +package com.arrays; +/** + +Dynamic programming solves a problem by dividing it into smaller subproblems. This is very similar to the divide-and-conquer algorithm solving technique. + The major difference, however, is that dynamic programming solves a subproblem only once. +It then stores the result of this subproblem and later reuses this result to solve other related subproblems. This process is known as memoization. + +Dynamic programming builds solutions from the bottom up by breaking each problem down into smaller, +problems that you solve first. Recursion also breaks problems down into subproblems but does this from +the top down. +One advantage of dynamic programming over recursion is that it prevents possible duplicate solutions of the same subproblem, +which uses less CPUs and generally makes your code run faster. + +Complexity of finding largest sum subarray in an array is O(N) in time and O(1) in space. + + */ + +public class MaxSumSubArray_KadaneAlgo_DynamicProgram { + + public static void main(String[] args) { + + int[] arr = {-1, -3, -5, -4, -1, -1, -2, -7, -3, -3}; + + int[] result = findMaxSumIndex(arr); + System.out.println("start index :" + result[0]); + System.out.println("End index :" + result[1]); + System.out.println("Sum :" + result[2]); + + } + + private static int[] findMaxSumIndex(int[] arr) { + int[] result = new int[3]; + int maxSumTillNow = Integer.MIN_VALUE; + + int tempStartIndex = 0; + int tempSum = 0; + + for (int i = 0; i < arr.length; i++) { + tempSum = tempSum + arr[i]; + + if (tempSum > maxSumTillNow) { + maxSumTillNow = tempSum; + result[0] = tempStartIndex; + result[1] = i; + result[2] = maxSumTillNow; + } + + //Important Condition to reset + if (tempSum < 0) { + tempSum = 0; + tempStartIndex = i + 1; + } + } + return result; + } +} + + diff --git a/src/main/java/com/arrays/MaxSumWithoutAdjacents.java b/src/main/java/com/arrays/MaxSumWithoutAdjacents.java new file mode 100644 index 00000000..fef6a98c --- /dev/null +++ b/src/main/java/com/arrays/MaxSumWithoutAdjacents.java @@ -0,0 +1,36 @@ +package com.arrays; + +/** + * + * Complexity Analysis: + * Time Complexity: O(n), Only one traversal of original array is needed. So the time complexity is O(n). + * + * Question + * Stickler the thief wants to loot money from a society having n houses in a single line. + * Rule 1 - never loot two consecutive houses. + * he wants to maximize the amount he loots. + * find the maximum money he can get if he strictly follows the rule. + * + */ +public class MaxSumWithoutAdjacents { + + public static void main(String[] args) { + + int[] input = {3, 2, 5, 10, 7}; + int counter = 0; + int evenSum = 0; + int oddSum = 0; + + while (counter != input.length) { + + if (counter % 2 == 0) { + evenSum += input[counter]; + } else { + oddSum += input[counter]; + } + counter++; + } + int max = Integer.max(evenSum, oddSum); + System.out.println(max); + } +} \ No newline at end of file diff --git a/src/main/java/com/arrays/MinimumPlatforms_Greedy.adoc b/src/main/java/com/arrays/MinimumPlatforms_Greedy.adoc new file mode 100644 index 00000000..335696c6 --- /dev/null +++ b/src/main/java/com/arrays/MinimumPlatforms_Greedy.adoc @@ -0,0 +1 @@ +image::../../../images/MinimumPlatforms_Greedy.png[] \ No newline at end of file diff --git a/src/main/java/com/arrays/MinimumPlatforms_Greedy.java b/src/main/java/com/arrays/MinimumPlatforms_Greedy.java new file mode 100644 index 00000000..d48cc404 --- /dev/null +++ b/src/main/java/com/arrays/MinimumPlatforms_Greedy.java @@ -0,0 +1,87 @@ +package com.arrays; + +import java.util.Arrays; + +/** + * Write a program to find the minimum number of platforms needed in a railway station. + *

+ * The arrival and departure time of several trains are provided. + * Two disparate arrays are given: one with all the arrival times and another with the departure time in 24 hours clock. + * Write a program to find the minimum number of platforms needed in a given railway station. + *

+ * Solution: + *

+ * Clue: The minimum number of platforms is nothing but the maximum number of trains that rest in the given railway station + * from the time limit between the arrival of the first train to the departure of the last train. + * Input: arr[] = {9:00, 9:40, 9:50, 11:00, 15:00, 18:00} + * dep[] = {9:10, 12:00, 11:20, 11:30, 19:00, 20:00} + * Output: 3 + * There are at-most three trains at a time (time between 9:40 to 11:00) + *

+ * Sort the timing values given in both the arrays and later check the count of trains at every given time of arrival and departure. + * The maximum number of trains in the process is taken as the output. + *

+ * arr[] = {9:00, 9:40, 9:50, 11:00, 15:00, 18:00} + * dep[] = {9:10, 12:00, 11:20, 11:30, 19:00, 20:00} + *

+ * Time complexity is O(n + nlog n). n = traverse the array of n elements + nlogn (for sorting the array) + * Space Complexity: O(1). + * As no extra space is required. + *

+ * dynamic programming is used to conserve memory. + */ +public class MinimumPlatforms_Greedy { + + // Returns minimum number of platforms required + static int findPlatform(int arr[], int dep[], int n) { + + //Edge case for input. + if (arr.length==0){ + return 0; + } + if(dep.length==0){ + return arr.length; + } + + /**important*/ + // Sort arrival and departure arrays + Arrays.sort(arr); + Arrays.sort(dep); + + // max_platforms_so_far indicates number of platforms needed at a time + int max_platforms_so_far = 1, needed_platforms = 1; + int i = 1, j = 0; + + // Similar to merge in merge sort to process all events in sorted order + while (i < n && j < n) { /** end the loop when any one iterator completes any one array.*/ + // If next event in sorted order is arrival, + // increment count of platforms needed + if (arr[i] <= dep[j]) { /**means one more train came before any train could depart so increment the max_platfroms */ + max_platforms_so_far++; + i++; + + // Update result if needed + if (max_platforms_so_far > needed_platforms) + needed_platforms = max_platforms_so_far; + } + + // Else decrement count of platforms needed + else { + max_platforms_so_far--; + j++; + } + } + + return needed_platforms; + } + + // Driver program to test methods of graph class + public static void main(String[] args) { + int arr[] = {900, 940, 950, 1100, 1500, 1800}; + int dep[] = {910, 1200, 1120, 1130, 1900, 2000}; + int n = arr.length; + System.out.println("Minimum Number of Platforms Required = " + + findPlatform(arr, dep, n)); + } +} + diff --git a/src/main/java/com/arrays/SearchInRotatedSortedArray_BitonicArray.adoc b/src/main/java/com/arrays/SearchInRotatedSortedArray_BitonicArray.adoc new file mode 100644 index 00000000..f91316d1 --- /dev/null +++ b/src/main/java/com/arrays/SearchInRotatedSortedArray_BitonicArray.adoc @@ -0,0 +1 @@ +image::../../../images/SearchInRotatedSortedArray.png[] \ No newline at end of file diff --git a/src/main/java/com/arrays/SearchInRotatedSortedArray_BitonicArray.java b/src/main/java/com/arrays/SearchInRotatedSortedArray_BitonicArray.java new file mode 100644 index 00000000..f107e2ae --- /dev/null +++ b/src/main/java/com/arrays/SearchInRotatedSortedArray_BitonicArray.java @@ -0,0 +1,49 @@ +package com.arrays; + +/** + * An array is called Bitonic if it is comprises of an increasing sequence of integers followed immediately + * by a decreasing sequence of integers. + * Given a bitonic array A of N distinct integers. Find a element X in it. + *

+ * You may assume no duplicate exists in the array. + */ +public class SearchInRotatedSortedArray_BitonicArray { + + public static int search(int[] nums, int target) { + int left = 0; + int right = nums.length - 1; + + while (left <= right) { + + int mid = (left + right) / 2; + if (target == nums[mid]) + return mid; + + /** update left and right + left will always move forward and right will always shrink*/ + if (nums[left] <= nums[mid]) { /** first half = left -> mid */ + if (nums[left] <= target && target < nums[mid]) { /** target is between left and mid so means left at right position and need + to update right as right will always shrink/move backward it will be mid-1 */ + right = mid - 1; + } else { + left = mid + 1; + } + } else { /** second half = mid -> right */ + if (nums[mid] < target && target <= nums[right]) { /** target is between mid and right so means right is at correct position and need + to update left as left will always move forward it will be mid+1 */ + left = mid + 1; + } else { + right = mid - 1; + } + } + + } + + return -1; + } + + public static void main(String args[]) { + int[] arr = {4, 5, 6, 7, 0, 1, 2}; + System.out.println("Element found at index : " + search(arr, 7)); + } +} diff --git a/src/main/java/com/arrays/SortArrayOf0s1s2s_DutchNationalFlagAlgo.html b/src/main/java/com/arrays/SortArrayOf0s1s2s_DutchNationalFlagAlgo.html new file mode 100644 index 00000000..3dc6ebd2 --- /dev/null +++ b/src/main/java/com/arrays/SortArrayOf0s1s2s_DutchNationalFlagAlgo.html @@ -0,0 +1,552 @@ + + + + + + + +dutch flag problem Archives | Algorithms and Me + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+
+ + + + +
+ +
+
+ + + + + +
+
+ +

Dutch National Flag Problem

+ + + +
+

Dutch National Flag Problem

+

Given an array with 0s,1s and 2s, sort array in increasing order. Another way to phrase this problem is sort balls with three different colors : red, blue and white, where balls of each color are placed together. This is typically know as Dutch national flag problem and algorithm to solve it is called Dutch national flag problem. Example:
+ A = [0,1,0,1,1,2,0,2,0,1]
+Output = [0,0,0,0,1,1,1,1,2,2]
+

+ A = [R,B,B,W,B,R,W,B,B]
+Output = [R,R,W,W,B,B,B,B]
+

+This problem can be asked as design question, as let’s say you have to design a robot. All this robot does is : it see three empty buckets and a bucket full of colored balls (red, blue and white). Design an instruction set for this robot that it fill each empty buckets with one color. It’s the same problem as Dutch National Flag problem.

+

Count to sort an array of 0s,1s and 2s
+We have already seen a similar problem before as Segregate 0s and 1s in an array. We explored how to count elements and re-write them again on to the array.

+

Let’s apply the same method for this problem. Take an array of three integers, index store corresponding count for that number. E.g count[0] stores count of 0 and count[1] stores count of 1. Scan through the array and count each element. At last, re-write those numbers back on to array starting from index 0, according to their count. For example, if there are 4 zeros, then starting from 0 indexes, write 4 zeros, followed by 1s and then by 2.

+

Complexity of counting method is O(n), notice that we scan array twice, first time for counts and second time for writing on array.

+

Dutch national flag problem : algorithm

+
    +
  1. Start with three pointers : reader, low and high.
  2. +
  3. reader and low are initialized as 0 and high is initialized as last element of array as size-1.
  4. +
  5. reader will be used to scan the array while low and high will be used to swap elements to their desired positions.
  6. +
  7. Starting with current position of reader, follow below steps, keep in mind we need 0 at start of array +
      +
    1. If element at index reader is 0, swap element at reader with element at low and increment low and reader by 1.
    2. +
    3. If element at reader is 1, do not swap and increment reader by 1.
    4. +
    5. If element at reader is 2, swap element at reader with element at high and decrease high by 1
    6. +
    +
  8. +
+

Actually, three pointers divide array into four parts.  Red, white, unknown and Blue. Every element is taken from unknown part and put into its right place. So all three other parts expand while unknown part shrinks.

+

Let’s take an example and see how dutch national flag algorithm works.

+

First step, initialize reader, low and high.

+

dutch national flag problem

+

Element at reader is 0, hence swap element at reader and low,also increment reader and low.

+

dutch national flag algorithm

+

Follow the same step, check element at reader again, it’s 1, hence, just move reader by one.

+

dutch national flag problem

+

Element at reader is now 2, swap element at reader with element at high and decrease high by 1.

+

dutch national flag problem

+

Element at reader is 1, just increment reader.

+

+

Element at reader is now 2, swap element at reader with element at high and decrease high by 1.

+

Dutch national flag algorithm explanation

+

Element at reader is 1, just increment reader.

+

dutch national flag problem

+

Element at reader is 1, just increment reader.

+

Dutch national flag algorithm explanation

+

Element at reader 0, hence swap element at reader and low,also increment reader and low.

+

dutch national flag problem

+

Element at reader 0, hence swap element at reader and low,also increment reader and low.

+

Dutch national flag algorithm explanation

+

Element at reader is now 2, swap element at reader with element at high and decrease high by 1.

+

dutch national flag problem

+

Here, high becomes less than reader, we can stop as array is already sorted.

+

Dutch national flag problem implementation

+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package com.company;
 
/**
 * Created by sangar on 5.1.18.
 */
public class DutchNationalFlag {
 
    public static void swap(int[] input, int i, int j){
        int temp =  input[i];
        input[i] = input[j];
        input[j] = temp;
    }
 
    public static void dutchNationalFalgAlgorithm(int [] input){
 
        //initialize all variables
        int reader = 0;
        int low = 0;
        int high = input.length - 1;
 
        while(reader <= high){
            /*
              input always holds a permutation of the
              original data with input(0..(lo-1)) =0,
              input(lo..(reader-1))=1, input(reader..hi) is
              untouched, and input((hi+1)..(input.length-1)) = 2
            */
            if(input[reader] == 0){
                /*When element at reader is 0, swap
                element at reader with element at index
                low and increment reader and low*/
                swap(input, reader, low);
                reader++;
                low++;
            }
            else if(input[reader] == 1){
                /* if element at reader is just
                increment reader by 1 */
                reader++;
            }
            else if(input[reader] == 2){
                /* If element at reader is 2, swap
                 element at reader with element at
                 high and decrease high by 1 */
                swap(input, reader, high);
                high--;
            }
            else{
               System.out.println("Bad input");
               break;
            }
        }
 
    }
    public static void main(String[] args) {
        int[] input = {2,2,1,1,0,0,0,1,1,2};
 
        dutchNationalFalgAlgorithm(input);
 
        for(int i=0; i<input.length; i++){
            System.out.print(" " + input[i]);
        }
    }
}
+

Complexity of Dutch National Flag algorithm is O(n), however, we scan the array only once.

+

Please share if you have some suggestions or comments. Sharing is caring.

+
+ + +
+ +
+
+ + + + +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + + + +
Feedback
Help us improve by sharing your feedback. Thank you for sharing your feedback with us!

How would you rate your experience?

Hate
Dislike
Neutral
Like
Love
Select an element on the page.

Enter your email address if you would like to receive a follow up.

Thank you for sharing your feedback with us!

Select an element on the page.
\ No newline at end of file diff --git a/src/main/java/com/arrays/SortArrayOf0s1s2s_DutchNationalFlagAlgo.java b/src/main/java/com/arrays/SortArrayOf0s1s2s_DutchNationalFlagAlgo.java new file mode 100644 index 00000000..2bbfee7a --- /dev/null +++ b/src/main/java/com/arrays/SortArrayOf0s1s2s_DutchNationalFlagAlgo.java @@ -0,0 +1,101 @@ +package com.arrays; + +/** +Dutch National Flag Algorithm, or 3-way Partitioning + +Sort an array of 0s, 1s and 2s +Given an array A[] consisting 0s, 1s and 2s. +The task is to write a function that sorts the given array. +The functions should put all 0s first, then all 1s and all 2s in last. +https://www.geeksforgeeks.org/sort-an-array-of-0s-1s-and-2s/ + +Examples: + +Input: {0, 1, 2, 0, 1, 2} +Output: {0, 0, 1, 1, 2, 2} + +Input: {0, 1, 1, 0, 1, 2, 1, 2, 0, 0, 0, 1} +Output: {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2} + +Simplest Solution +Count the number of 0’s, 1’s and 2’s. After Counting, put all 0’s first, then 1’s and lastly 2’s in the array. +We traverse the array two times. Time complexity will be O(n). + + Dutch national flag problem : algorithm + Start with three pointers : reader, low and high. + reader and low are initialized as 0 and high is initialized as last element of array as size-1. + reader will be used to scan the array while low and high will be used to swap elements to their desired positions. + Starting with current position of reader, follow below steps, keep in mind we need 0 at start of array + If element at index reader is 0, swap element at reader with element at low and increment low and reader by 1. + If element at reader is 1, do not swap and increment reader by 1. + If element at reader is 2, swap element at reader with element at high and decrease high by 1 + + Actually, three pointers divide array into four parts. Red, white, unknown and Blue. + Every element is taken from unknown part and put into its right place. + So all three other parts expand while unknown part shrinks. + +Best Solution +https://algorithmsandme.com/dutch-national-flag-problem/ +*/ + + +public class SortArrayOf0s1s2s_DutchNationalFlagAlgo { + + public static void swap(int[] input, int i, int j){ + int temp = input[i]; + input[i] = input[j]; + input[j] = temp; + } + + public static void dutchNationalFalgAlgorithm(int [] input){ + + //initialize all variables + int reader = 0; + int low = 0; + int high = input.length - 1; + + while(reader <= high){ + /* + input always holds a permutation of the + original data with input(0..(lo-1)) =0, + input(lo..(reader-1))=1, input(reader..hi) is + untouched, and input((hi+1)..(input.length-1)) = 2 + */ + if(input[reader] == 0){ + /*When element at reader is 0, swap + element at reader with element at index + low and increment reader and low*/ + swap(input, reader, low); + reader++; + low++; + } + else if(input[reader] == 1){ + /* if element at reader is just + increment reader by 1 */ + reader++; + } + else if(input[reader] == 2){ + /* If element at reader is 2, swap + element at reader with element at + high and decrease high by 1 */ + swap(input, reader, high); + high--; + } + else{ + System.out.println("Bad input"); + break; + } + } + + } + public static void main(String[] args) { + int[] input = {2,2,1,1,0,0,0,1,1,2}; + + dutchNationalFalgAlgorithm(input); + + for(int i=0; i prices[i - 1]) + maxprofit += prices[i] - prices[i - 1]; + } + return maxprofit; + } + + public static void main (String args[]){ + int[] price = {100,60,120,110,90,200}; + int maxProfit= maxProfit(price); + System.out.println(maxProfit); + + } +} diff --git a/src/main/java/com/arrays/TripletSumInArray_Sorting_TwoPointerAlgo.java b/src/main/java/com/arrays/TripletSumInArray_Sorting_TwoPointerAlgo.java new file mode 100644 index 00000000..2316ea20 --- /dev/null +++ b/src/main/java/com/arrays/TripletSumInArray_Sorting_TwoPointerAlgo.java @@ -0,0 +1,66 @@ +package com.arrays; + +import java.util.Arrays; + +/** + * This method uses the method of Sorting and Two-pointer Technique to solve the above problem. + * This execution will involve O(n2)) time complexity and O(1) space complexity. + */ + + +/** + * 1. Sort all element of array + * 2. Run loop from i=0 to n-2. + * Initialize two index variables l=i+1 and r=n-1 + * 4. while (l < r) + * Check sum of arr[i], arr[l], arr[r] is + * given sum or not if sum is 'sum', then print + * the triplet and do l++ and r--. + * 5. If sum is less than given sum then l++ + * 6. If sum is greater than given sum then r-- + * 7. If not exist in array then print not found. + */ + +/** + * Complexity Analysis: + * Time Complexity: O(n2). + * Use of a nested loop (one for iterating , other for two-pointer technique) brings the time complexity to O(n2). + * Auxiliary Space: O(1). + * As no use of additional data structure is used. + */ + +public class TripletSumInArray_Sorting_TwoPointerAlgo { + + public static void find_all_triplets(int[] arr, int sum) { + + /**sort array elements*/ + Arrays.sort(arr); /**important*/ + + int n = arr.length; + int left; + int right; + for (int i = 0; i < n - 2; i++) { + left = i + 1; //cursor starting from front + right = n - 1; // cursor starting from end + while (left < right) { + int tempSum = arr[i] + arr[left] + arr[right]; + if (tempSum == sum) { + System.out.println("triplet:{" + arr[i] + "," + arr[left] + "," + arr[right] + "}"); + left++; + right--; + } else if (tempSum < sum) { + left++; + } else { + right--; + } + } + } + } + + + public static void main(String args[]) { + int arr[] = {1, 7, 4, 3, 4, 5, 2}; + int sum = 9; + find_all_triplets(arr, sum); + } +} diff --git a/src/main/java/com/arrays/WildCardMatching.adoc b/src/main/java/com/arrays/WildCardMatching.adoc new file mode 100644 index 00000000..fe1b513e --- /dev/null +++ b/src/main/java/com/arrays/WildCardMatching.adoc @@ -0,0 +1 @@ +image::../../../images/WildCardMatching.png[] \ No newline at end of file diff --git a/src/main/java/com/arrays/WildCardMatching.html b/src/main/java/com/arrays/WildCardMatching.html new file mode 100644 index 00000000..2f834ef3 --- /dev/null +++ b/src/main/java/com/arrays/WildCardMatching.html @@ -0,0 +1,109 @@ + Wildcard Matching in C++ - ProDeveloperTutorial.com + \ No newline at end of file diff --git a/src/main/java/com/arrays/WildCardMatching.java b/src/main/java/com/arrays/WildCardMatching.java new file mode 100644 index 00000000..b12d780b --- /dev/null +++ b/src/main/java/com/arrays/WildCardMatching.java @@ -0,0 +1,75 @@ +package com.arrays; + +/** + * '?' Matches any single character. + * '*' Matches any sequence of characters (including the empty sequence). + *

+ * Input: + * s = "cb" + * p = "?a" + * Output: false + * Explanation: '?' matches 'c', but the second letter is 'a', which does not match 'b'. + *

+ * Time complexity of above solution is O(m x n). Auxiliary space used is also O(m x n). + * where m = length of pattern + * n = length of String + */ + +public class WildCardMatching { + + public boolean isMatch(String s, String p) { + char[] str = s.toCharArray(); + char[] pattern = p.toCharArray(); + + //replace multiple * with one * + //e.g a**b***c --> a*b*c + int writeIndex = 0; + boolean isFirst = true; + for (int i = 0; i < pattern.length; i++) { + if (pattern[i] == '*') { + if (isFirst) { + pattern[writeIndex++] = pattern[i]; + isFirst = false; + } + } else { + pattern[writeIndex++] = pattern[i]; + isFirst = true; + } + } + + boolean T[][] = new boolean[str.length + 1][pattern.length + 1]; + + if (writeIndex > 0 && pattern[0] == '*') { + T[0][1] = true; + } + + // base case + T[0][0] = true; + + /** + * Rules + * 1) if the value at boolean_array[i][j] is a matching character or a “?”. + * boolean_array[i][j] = boolean_array[i-1][j-1] (means diagonal) + * + * 2) if the value at at boolean_array[i][j] is “*”. + * boolean_array[i][j] = boolean_array[i][j-1] || boolean_array[i-1][j] (means one one left or one on top whichever is true) + */ + + for (int i = 1; i <= str.length; i++) { + for (int j = 1; j <= pattern.length; j++) + if (pattern[j - 1] == '?' || str[i - 1] == pattern[j - 1]) { + T[i][j] = T[i - 1][j - 1]; //diagonal + } else if (pattern[j - 1] == '*') { + T[i][j] = T[i - 1][j] || T[i][j - 1]; + } + } + + return T[str.length][pattern.length]; + } + + + public static void main(String args[]) { + WildCardMatching wcm = new WildCardMatching(); + System.out.println(wcm.isMatch("xbylmz", "x?y*z")); + } +} diff --git a/src/main/java/com/ctci/arraysandstrings/CheckPermutation.java b/src/main/java/com/ctci/arraysandstrings/CheckPermutation.java deleted file mode 100644 index dbf7c795..00000000 --- a/src/main/java/com/ctci/arraysandstrings/CheckPermutation.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.ctci.arraysandstrings; - -import java.util.Arrays; - -/** - * @author rampatra - * @since 19/11/2018 - */ -public class CheckPermutation { - - /** - * Checks if {@code s1} is a permutation of {@code s2}. - * - * @param s1 - * @param s2 - * @return - */ - private static boolean isOnePermutationOfOther(String s1, String s2) { - if (s1.length() != s2.length()) { - return false; - } - - char[] c1 = s1.toCharArray(); - char[] c2 = s2.toCharArray(); - Arrays.sort(c1); - Arrays.sort(c2); - - return Arrays.equals(c1, c2); - } - - /** - * Checks if {@code s1} is a permutation of {@code s2}. - * - * @param s1 - * @param s2 - * @return - */ - private static boolean isOnePermutationOfOtherGivenThatStringsContainOnlyAscii(String s1, String s2) { - if (s1.length() != s2.length()) { - return false; - } - - int[] chars = new int[128]; // assuming strings contain only ASCII characters - - for (int i = 0; i < s1.length(); i++) { - chars[s1.charAt(i)]++; - } - - for (int i = 0; i < s2.length(); i++) { - chars[s2.charAt(i)]--; - if (chars[s2.charAt(i)] < 0) { - return false; - } - } - return true; - } - - public static void main(String[] args) { - System.out.println(isOnePermutationOfOther("ram", "mar")); - System.out.println(isOnePermutationOfOther("rama", "mar")); - System.out.println(isOnePermutationOfOther("rama", "marA")); - System.out.println("-------"); - System.out.println(isOnePermutationOfOtherGivenThatStringsContainOnlyAscii("ram", "mar")); - System.out.println(isOnePermutationOfOtherGivenThatStringsContainOnlyAscii("rama", "mar")); - System.out.println(isOnePermutationOfOtherGivenThatStringsContainOnlyAscii("rama", "marA")); - } -} diff --git a/src/main/java/com/ctci/arraysandstrings/IsUnique.java b/src/main/java/com/ctci/arraysandstrings/IsUnique.java deleted file mode 100644 index 895d16b3..00000000 --- a/src/main/java/com/ctci/arraysandstrings/IsUnique.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.ctci.arraysandstrings; - -/** - * @author rampatra - * @since 18/11/2018 - */ -public class IsUnique { - - private static boolean hasAllUniqueCharacters(String str) { - if (str == null || str.length() > 128) return false; - - boolean[] charSet = new boolean[128]; // assuming the string contains only ASCII characters - for (int i = 0; i < str.length(); i++) { - int charVal = str.charAt(i); - if (charSet[charVal]) { - return false; - } - charSet[charVal] = true; - } - return true; - } - - private static boolean hasAllUniqueCharactersWhenStringContainsAllLowercase(String s) { - int checker = 0; - for (int i = 0; i < s.length(); i++) { - int charValue = s.charAt(i) - 'a'; - if ((checker & (1 << charValue)) > 0) { - return false; - } - checker |= (1 << charValue); - } - return true; - } - - public static void main(String[] args) { - String s = "ram"; - System.out.println(hasAllUniqueCharacters(s)); - s = "rama"; - System.out.println(hasAllUniqueCharacters(s)); - s = "ramA"; - System.out.println(hasAllUniqueCharacters(s)); - System.out.println("-------"); - s = "ram"; - System.out.println(hasAllUniqueCharactersWhenStringContainsAllLowercase(s)); - s = "rama"; - System.out.println(hasAllUniqueCharactersWhenStringContainsAllLowercase(s)); - // not working as the input contains different cases - s = "ramA"; - System.out.println(hasAllUniqueCharactersWhenStringContainsAllLowercase(s)); - } -} diff --git a/src/main/java/com/ctci/arraysandstrings/OneAway.java b/src/main/java/com/ctci/arraysandstrings/OneAway.java deleted file mode 100644 index f5345ed7..00000000 --- a/src/main/java/com/ctci/arraysandstrings/OneAway.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.ctci.arraysandstrings; - -/** - * @author rampatra - * @since 24/11/2018 - */ -public class OneAway { - - /** - * Checks if two strings are only one edit away, that is, by inserting, deleting, or editing - * at max one character in {@code s1} it becomes same as {@code s2}. - * - * @param s1 - * @param s2 - * @return - */ - private static boolean isOneEditAway(String s1, String s2) { - if (s1.length() == s2.length()) { - return isOneCharacterDiffAtMax(s1, s2); - } else if (s1.length() < s2.length()) { - return checkForMaxOneInsertOrDeleteInS1(s1, s2); - } else { - return checkForMaxOneInsertOrDeleteInS1(s1, s2); - } - } - - private static boolean isOneCharacterDiffAtMax(String s1, String s2) { - boolean foundDiff = false; - for (int i = 0; i < s1.length(); i++) { - if (s1.charAt(i) != s2.charAt(i)) { - if (foundDiff) { - return false; // means we already found a difference earlier - } - foundDiff = true; - } - } - return true; - } - - private static boolean checkForMaxOneInsertOrDeleteInS1(String s1, String s2) { - int i = 0; - int j = 0; - int s1Len = s1.length(); - int s2Len = s2.length(); - if (Math.abs(s1Len - s2Len) > 1) return false; - - while (i < s1Len && j < s2Len) { - if (s1.charAt(i) != s2.charAt(j)) { - if (s1Len > s2Len) { - i++; - } else { - j++; - } - continue; - } - i++; - j++; - } - return Math.abs(i - j) <= 1; // check whether difference in two strings is not more than 1 - } - - public static void main(String[] args) { - System.out.println("pale, ple: " + isOneEditAway("pale", "ple")); - System.out.println("pales,pale: " + isOneEditAway("pales", "pale")); - System.out.println("pale, bale: " + isOneEditAway("pale", "bale")); - System.out.println("pale, bake: " + isOneEditAway("pale", "bake")); - System.out.println("ram, rama: " + isOneEditAway("ram", "rama")); - System.out.println("ram, ramaaaaaaa: " + isOneEditAway("ram", "ramaaaaaaa")); - } -} diff --git a/src/main/java/com/ctci/arraysandstrings/PalindromePermutation.java b/src/main/java/com/ctci/arraysandstrings/PalindromePermutation.java deleted file mode 100644 index 0ab21095..00000000 --- a/src/main/java/com/ctci/arraysandstrings/PalindromePermutation.java +++ /dev/null @@ -1,103 +0,0 @@ -package com.ctci.arraysandstrings; - -import java.util.HashMap; -import java.util.Map; - -/** - * @author rampatra - * @since 21/11/2018 - */ -public class PalindromePermutation { - - /** - * This method exploits the fact that a palindrome will contain at most - * one character with odd counts. All other characters should be of even - * counts. - * - * @param str input string - * @return {@code true} if {@code str} is a permutation of a palindrome - */ - private static boolean isPermutationOfPalindrome(String str) { - Map charCounts = new HashMap<>(); - Integer freq; - int oddCounts = 0; // keep count of odds so that we don't have to loop through the hashmap the second time - for (int i = 0; i < str.length(); i++) { - char c = str.charAt(i); - if (c != 32) { - freq = charCounts.get(c) == null ? 0 : charCounts.get(c); - if ((freq + 1) % 2 == 1) { - oddCounts++; - } else { - oddCounts--; - } - charCounts.put(c, freq + 1); - } - } - return oddCounts <= 1; - } - - - /** - * This approach sets a bit in a number based on the character in the string and - * then un-sets the bit if it sees the character again. Finally, checks if the - * bitVector has at most one bit set only. - * - * @param str input string - * @return {@code true} if {@code str} is a permutation of a palindrome - */ - private static boolean isPermutationOfPalindromeViaBits(String str) { - int bitVector = 0; - int index; - - for (int i = 0; i < str.length(); i++) { - index = getIndex(str.charAt(i)); - if (index != -1) { - bitVector = toggleBitAt(bitVector, index); - } - } - return (bitVector & (bitVector - 1)) == 0; - } - - /** - * Calculates the index to set the bit according to the character {@code c}. - * - * @param c - * @return the index to set the bit as per the character {@code c} - */ - private static int getIndex(char c) { - char a = 'a'; - char z = 'z'; - - // assuming string contains only lowercase characters - if (c < a || c > z) { - return -1; - } - - return c - a; - } - - /** - * Toggles the bit at index {@code index} in {@code bitVector}. - * - * @param bitVector - * @param index - * @return the resulting {@code bitVector} after toggling the bit - */ - private static int toggleBitAt(int bitVector, int index) { - return bitVector ^ (1 << index); - } - - public static void main(String[] args) { - System.out.println(isPermutationOfPalindrome("tactc oapapa")); - System.out.println(isPermutationOfPalindrome("maam")); - System.out.println(isPermutationOfPalindrome("maa m")); - System.out.println(isPermutationOfPalindrome("rammmar")); - System.out.println(isPermutationOfPalindrome("rammmara")); - System.out.println("---------"); - System.out.println(isPermutationOfPalindromeViaBits("tactc oapapa")); - System.out.println(isPermutationOfPalindromeViaBits("maam")); - System.out.println(isPermutationOfPalindromeViaBits("maa m")); - System.out.println(isPermutationOfPalindromeViaBits("rammmar")); - System.out.println(isPermutationOfPalindromeViaBits("rammmara")); - } -} diff --git a/src/main/java/com/ctci/arraysandstrings/RotateMatrix.java b/src/main/java/com/ctci/arraysandstrings/RotateMatrix.java deleted file mode 100644 index de43c56b..00000000 --- a/src/main/java/com/ctci/arraysandstrings/RotateMatrix.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.ctci.arraysandstrings; - -/** - * @author rampatra - * @since 2019-01-20 - */ -public class RotateMatrix { - - public static void rotateImage(int[][] pixels) { - - } - - public static void main(String[] args) { - - } -} diff --git a/src/main/java/com/ctci/arraysandstrings/StringCompression.java b/src/main/java/com/ctci/arraysandstrings/StringCompression.java deleted file mode 100644 index 5c2df955..00000000 --- a/src/main/java/com/ctci/arraysandstrings/StringCompression.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.ctci.arraysandstrings; - -/** - * @author rampatra - * @since 24/11/2018 - */ -public class StringCompression { - - /** - * Compresses the string {@code s} such that a string {@code aabccccaaa} becomes {@code a2b1c4a3}. - * Also, if the compressed string is not shorter than the original, returns the original string. - * - * @param str input string containing only a-z characters, both cases - * @return which ever is the shorter string - */ - private static String compressString(String str) { - StringBuilder compressedSb = new StringBuilder(); - int countConsecutive = 0; - for (int i = 0; i < str.length(); i++) { - countConsecutive++; - - /* If next character is different than current, append this char to result. */ - if (i + 1 >= str.length() || str.charAt(i) != str.charAt(i + 1)) { - compressedSb.append(str.charAt(i)); - compressedSb.append(countConsecutive); - countConsecutive = 0; - } - } - return compressedSb.length() < str.length() ? compressedSb.toString() : str; - } - - public static void main(String[] args) { - System.out.println("aabccccaaa: " + compressString("aabccccaaa")); - System.out.println("aabccccAAAA: " + compressString("aabccccAAAA")); - System.out.println("abcd: " + compressString("abcd")); - System.out.println("a: " + compressString("a")); - System.out.println("aabcccccccccccccccccccccccccaaa: " + compressString("aabcccccccccccccccccccccccccaaa")); - } -} diff --git a/src/main/java/com/ctci/arraysandstrings/StringRotation.java b/src/main/java/com/ctci/arraysandstrings/StringRotation.java deleted file mode 100644 index 0c03e94f..00000000 --- a/src/main/java/com/ctci/arraysandstrings/StringRotation.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.ctci.arraysandstrings; - -/** - * Assume you have a method isSubString which checks if one word is a substring of another. Given two - * strings, S1 and S2, write code to check if S2 is a rotation of S1 using only one call to isSubString - * (e.g., "waterbottle" is a rotation of" erbottlewat"). - * - * @author rampatra - * @since 2019-01-22 - */ -public class StringRotation { - - private static boolean isStringRotation(String s1, String s2) { - if (s1.length() != s2.length()) { - return false; - } - s2 = s2 + s2; - return isSubString(s1, s2); - } - - /** - * Given method in question. - * - * @param s1 first string - * @param s2 second string - * @return {@code true} if s1 is a substring of s2 or else {@code false} - */ - private static boolean isSubString(String s1, String s2) { - return s2.contains(s1); - } - - public static void main(String[] args) { - System.out.println(isStringRotation("waterbottle", "erbottlewat")); // true - System.out.println(isStringRotation("rampatra", "atraramp")); // true - System.out.println(isStringRotation("rampatra", "arampata")); // false - System.out.println(isStringRotation("rampatra", "arampat")); // false - System.out.println(isStringRotation("", "")); // true - } -} diff --git a/src/main/java/com/ctci/arraysandstrings/URLify.java b/src/main/java/com/ctci/arraysandstrings/URLify.java deleted file mode 100644 index 712829ac..00000000 --- a/src/main/java/com/ctci/arraysandstrings/URLify.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.ctci.arraysandstrings; - -/** - * @author rampatra - * @since 19/11/2018 - */ -public class URLify { - - /** - * We space encode the string such that all spaces in the string are replaced with '%20'. The string {@code str} - * contains extra spaces to accommodate the extra characters. - * - * @param str string with spaces - * @return string with spaces replaced with %20 - */ - private static String urlify(String str) { - char[] chars = str.toCharArray(); - int curr = chars.length - 1; // we will start backwards so that we don't have to worry about characters we overwrite - int insertIndex = curr; - - // move the curr pointer to the last character which isn't a space - while (chars[curr] == 32) { - curr--; - } - - while (curr >= 0) { - if (chars[curr] == 32) { - chars[insertIndex--] = '0'; - chars[insertIndex--] = '2'; - chars[insertIndex--] = '%'; - } else { - chars[insertIndex--] = chars[curr]; - } - curr--; - } - return String.valueOf(chars); - } - - public static void main(String[] args) { - System.out.println(urlify("Mr John Smith ")); - System.out.println(urlify("Mr Ram Patra ")); - } -} diff --git a/src/main/java/com/ctci/arraysandstrings/ZeroMatrix.java b/src/main/java/com/ctci/arraysandstrings/ZeroMatrix.java deleted file mode 100644 index f73d8760..00000000 --- a/src/main/java/com/ctci/arraysandstrings/ZeroMatrix.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.ctci.arraysandstrings; - -import java.util.ArrayList; -import java.util.List; - -/** - * Write an algorithm such that if an element in an MxN matrix is 0, its entire row - * and column are set to 0. - * - * @author rampatra - * @since 2019-01-20 - */ -public class ZeroMatrix { - - private static void zeroMatrix(int[][] matrix) { - // keep count of which rows and columns have a number zero - List rowsToZero = new ArrayList<>(); - List colsToZero = new ArrayList<>(); - - for (int i = 0; i < matrix.length; i++) { - for (int j = 0; j < matrix[0].length; j++) { - if (matrix[i][j] == 0) { - rowsToZero.add(i); - colsToZero.add(j); - } - } - } - - makeRowColumnZero(matrix, rowsToZero, colsToZero); - } - - private static void makeRowColumnZero(int[][] matrix, List rows, List cols) { - for (int row : rows) { - // make entire row zero - for (int c = 0; c < matrix[0].length; c++) { - matrix[row][c] = 0; - } - } - for (int col : cols) { - // make entire column zero - for (int r = 0; r < matrix.length; r++) { - matrix[r][col] = 0; - } - } - } - - private static void printMatrix(int[][] matrix) { - for (int i = 0; i < matrix.length; i++) { - for (int j = 0; j < matrix[0].length; j++) { - System.out.print(matrix[i][j]); - if (j + 1 >= matrix[0].length) { - System.out.println(); - } - } - } - } - - public static void main(String[] args) { - int[][] m = new int[][]{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}}; - printMatrix(m); - zeroMatrix(m); - System.out.println("---"); - printMatrix(m); - System.out.println("---"); - m = new int[][]{{1, 0, 2}, {3, 4, 5}, {6, 7, 8}}; - printMatrix(m); - zeroMatrix(m); - System.out.println("---"); - printMatrix(m); - System.out.println("---"); - m = new int[][]{{1, 2, 0}, {3, 4, 5}, {6, 7, 8}}; - printMatrix(m); - zeroMatrix(m); - System.out.println("---"); - printMatrix(m); - System.out.println("---"); - } -} diff --git a/src/main/java/com/ctci/bitmanipulation/BinaryToString.java b/src/main/java/com/ctci/bitmanipulation/BinaryToString.java deleted file mode 100644 index 895c354a..00000000 --- a/src/main/java/com/ctci/bitmanipulation/BinaryToString.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.ctci.bitmanipulation; - -/** - * @author rampatra - * @since 2019-03-16 - */ -public class BinaryToString { - - /** - * Given a real number between 0 and 1 (e.g., 0.72) that is passed in as a double, print the binary representation. - * If the number cannot be represented accurately in binary with at most 32 characters, print "ERROR." - * - * @param realNum a real number between 0 and 1 (for ex. 0.75) - * @return binary string of the real number - * @see how to convert decimal fraction to binary - */ - private static String decimalFractionToBinaryString(double realNum) { - if (realNum <= 0 || realNum >= 1) { - return "ERROR"; - } - - int binaryBit; - StringBuilder sb = new StringBuilder(); - sb.append("0."); - - while (realNum > 0) { - if (sb.length() == 32) { - return "ERROR"; - } - realNum = realNum * 2; - // the binary bit is the whole number part (left to the decimal) - binaryBit = (int) realNum; - // we only have to take the part after the decimal (right to the decimal) for the next iteration - if (binaryBit == 1) { - realNum -= 1; - } - sb.append(binaryBit); - } - return sb.toString(); - } - - public static void main(String[] args) { - System.out.println(decimalFractionToBinaryString(0.625)); - System.out.println(decimalFractionToBinaryString(0.75)); - System.out.println(decimalFractionToBinaryString(0.72)); - System.out.println(decimalFractionToBinaryString(0.10)); - } -} diff --git a/src/main/java/com/ctci/bitmanipulation/Conversion.java b/src/main/java/com/ctci/bitmanipulation/Conversion.java deleted file mode 100644 index 5a4c7575..00000000 --- a/src/main/java/com/ctci/bitmanipulation/Conversion.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.ctci.bitmanipulation; - -/** - * @author rampatra - * @since 2019-03-17 - */ -public class Conversion { - - /** - * Write a function to determine the number of bits you would need to flip to convert - * integer A to integer B. - * Example: - * Input: 29 (or: 11101), 15 (or: 01111) - * Output: 2 - * - * @param a - * @param b - * @return the number of bits to flip - */ - private static int getNoOfBitsToFlipToConvertAToB(int a, int b) { - return countSetBits(a ^ b); - } - - private static int countSetBits(int n) { - int count = 0; - while (n > 0) { - if ((n & 1) == 1) { - count++; - } - n >>>= 1; - } - return count; - } - - /** - * In this approach, we first take the xor of both the integers (which sets the bits at positions where the bits - * in a and b are different). We then unset the least significant bit in each iteration (c & (c - 1)) and count the - * number of iterations to find the bits to flip. - * - * @param a - * @param b - * @return the number of bits to flip - */ - private static int getNoOfBitsToFlipToConvertAToBWithoutRightShift(int a, int b) { - int count = 0; - for (int c = a ^ b; c != 0; c = c & (c - 1)) { - count++; - } - return count; - } - - public static void main(String[] args) { - System.out.println(getNoOfBitsToFlipToConvertAToB(5, 7)); - System.out.println(getNoOfBitsToFlipToConvertAToB(5, 5)); - System.out.println(getNoOfBitsToFlipToConvertAToB(29, 15)); - - System.out.println("---"); - - System.out.println(getNoOfBitsToFlipToConvertAToBWithoutRightShift(5, 7)); - System.out.println(getNoOfBitsToFlipToConvertAToBWithoutRightShift(5, 5)); - System.out.println(getNoOfBitsToFlipToConvertAToBWithoutRightShift(29, 15)); - } -} \ No newline at end of file diff --git a/src/main/java/com/ctci/bitmanipulation/Debugger.java b/src/main/java/com/ctci/bitmanipulation/Debugger.java deleted file mode 100644 index 6782036b..00000000 --- a/src/main/java/com/ctci/bitmanipulation/Debugger.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.ctci.bitmanipulation; - -/** - * @author rampatra - * @since 2019-03-17 - */ -public class Debugger { - - /** - * If after un-setting the least significant bit in n, it becomes 0 then it implies that it has only set bit. This - * can also imply that n is a power of 2. - * - * @param n input integer - * @return {@code true} if n has only set bit, {@code false} otherwise. - */ - private static boolean hasOneSetBit(int n) { - // edge case - if (n == 0) { - return false; - } - return (n & (n - 1)) == 0; // (n & (n - 1)) un-sets the least significant bit - } - - public static void main(String[] args) { - System.out.println(hasOneSetBit(0)); - System.out.println(hasOneSetBit(2)); - System.out.println(hasOneSetBit(16)); - System.out.println(hasOneSetBit(10)); - } -} diff --git a/src/main/java/com/ctci/bitmanipulation/DrawLine.java b/src/main/java/com/ctci/bitmanipulation/DrawLine.java deleted file mode 100644 index 3eb2be0c..00000000 --- a/src/main/java/com/ctci/bitmanipulation/DrawLine.java +++ /dev/null @@ -1,109 +0,0 @@ -package com.ctci.bitmanipulation; - -import java.util.Arrays; - -/** - * @author rampatra - * @since 2019-03-21 - */ -public class DrawLine { - - /** - * A monochrome screen is stored as a single array of bytes, allowing eight consecutive pixels to be stored - * in one byte. The screen has width w, where w is divisible by 8 (that is, no byte will be split across rows). - * The height of the screen, of course, can be derived from the length of the array and the width. Implement a - * function that draws a horizontal line from (xl, y) to ( x2, y). - *

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

- * Approach: - * First, find the numbers in which all bits has to be set. Next, find the starting number and apply the mask - * created from the starting offset. Do the same with the ending number. - * - * @param screen - * @param width - * @param x1 - * @param x2 - * @param y - */ - private static void drawLine(byte[] screen, int width, int x1, int x2, int y) { - int startOffset = x1 % 8; - int startFullByte = x1 / 8; - if (startOffset != 0) { - startFullByte++; - } - int endOffset = x2 % 8; - int endFullByte = x2 / 8; - if (endOffset != 7) { - endFullByte--; - } - - // all bits have to be set in in-between numbers - for (int i = startFullByte; i <= endFullByte; i++) { - screen[width / 8 * y + i] |= (byte) 0xff; - } - - /* 0xff is an integer literal which is like 000...11111111 (32 bits) but when we - cast it to a byte, we get rid of the initial 24 bits */ - byte startByteMask = (byte) (0xff >> startOffset); - byte endByteMask = (byte) ~(0xff >> endOffset + 1); - - if (x1 / 8 == x2 / 8) { // if starting and ending both lie in the same byte - screen[width / 8 * y + (x1 / 8)] |= (startByteMask & endByteMask); - } else { - screen[width / 8 * y + (startFullByte - 1)] |= startByteMask; // only specific bits set in the starting number - screen[width / 8 * y + (endFullByte + 1)] |= endByteMask; // only specific bits set in the ending number - } - } - - public static void main(String[] args) { - /* - Consider the below screen with width 32 as an example: - - byte[] screen = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; - - This screen has a width of 32 so you can assume the screen would be looking like: - - 9 10 11 12 - 5 6 7 8 - 1 2 3 4 - - x-axis is 5-20 (5th position to 20th position) - y-axis is 1 - - which means our line would lie in numbers 5, 6, and 7 - - so if you visualize these numbers in bits, it would be like: - - 00000101 00000110 00000111 - ^ ^ - and after drawing the line, the bits would become: - - 00000111 11111111 11111111 - - and in the output we would see: - - 7, -1, -1 instead of 5, 6, 7 - */ - byte[] screen = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; - System.out.println("Input: " + Arrays.toString(screen)); - drawLine(screen, 32, 5, 20, 1); - System.out.println("Output: " + Arrays.toString(screen)); - System.out.println("---"); - screen = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; - System.out.println("Input: " + Arrays.toString(screen)); - drawLine(screen, 32, 0, 5, 1); - System.out.println("Output: " + Arrays.toString(screen)); - System.out.println("---"); - screen = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; - System.out.println("Input: " + Arrays.toString(screen)); - drawLine(screen, 32, 3, 7, 1); - System.out.println("Output: " + Arrays.toString(screen)); - System.out.println("---"); - screen = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; - System.out.println("Input: " + Arrays.toString(screen)); - drawLine(screen, 16, 0, 7, 0); - System.out.println("Output: " + Arrays.toString(screen)); - } -} \ No newline at end of file diff --git a/src/main/java/com/ctci/bitmanipulation/FlipBitToWin.java b/src/main/java/com/ctci/bitmanipulation/FlipBitToWin.java deleted file mode 100644 index 4424f7ab..00000000 --- a/src/main/java/com/ctci/bitmanipulation/FlipBitToWin.java +++ /dev/null @@ -1,53 +0,0 @@ -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 deleted file mode 100644 index 3230d86f..00000000 --- a/src/main/java/com/ctci/bitmanipulation/Insertion.java +++ /dev/null @@ -1,49 +0,0 @@ -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 deleted file mode 100644 index ec817c13..00000000 --- a/src/main/java/com/ctci/bitmanipulation/NextNumber.java +++ /dev/null @@ -1,124 +0,0 @@ -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 deleted file mode 100644 index a1219d47..00000000 --- a/src/main/java/com/ctci/bitmanipulation/PairwiseSwap.java +++ /dev/null @@ -1,40 +0,0 @@ -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 deleted file mode 100644 index c4b4052e..00000000 --- a/src/main/java/com/ctci/linkedlists/DeleteMiddleNode.java +++ /dev/null @@ -1,65 +0,0 @@ -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 deleted file mode 100644 index 4665fe43..00000000 --- a/src/main/java/com/ctci/linkedlists/Intersection.java +++ /dev/null @@ -1,104 +0,0 @@ -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 deleted file mode 100644 index 8fff3f9d..00000000 --- a/src/main/java/com/ctci/linkedlists/KthToLastElement.java +++ /dev/null @@ -1,88 +0,0 @@ -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 deleted file mode 100644 index d0a9a110..00000000 --- a/src/main/java/com/ctci/linkedlists/LoopDetection.java +++ /dev/null @@ -1,67 +0,0 @@ -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 deleted file mode 100644 index 5c0d1ec3..00000000 --- a/src/main/java/com/ctci/linkedlists/Node.java +++ /dev/null @@ -1,23 +0,0 @@ -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 deleted file mode 100644 index 57bb184d..00000000 --- a/src/main/java/com/ctci/linkedlists/Palindrome.java +++ /dev/null @@ -1,107 +0,0 @@ -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 stack = new Stack<>(); - // pop all elements into stack - while (curr != null) { - stack.push(curr.val); - curr = curr.next; - } - curr = head; - // as stack contains the elements in reverse order, pop and compare with the list one by one - while (curr != null) { - if (curr.val != stack.pop()) { - return false; - } - curr = curr.next; - } - return true; - } - - /** - * This is a similar approach like above but a bit faster as we are not iterating the entire list twice. - * - * @param head starting node of the linked list. - * @return {@code true} if linked list palindrome, {@code false} otherwise. - */ - private static boolean isPalindromeOptimized(Node head) { - Node slow = head; - Node fast = head; - Stack stack = new Stack<>(); - - // push half of the elements into the stack - while (fast != null && fast.next != null) { - stack.push(slow.val); - slow = slow.next; - fast = fast.next.next; - } - - // linked list has odd number of elements, so forward the slow reference by one - if (fast != null) { - slow = slow.next; - } - - while (slow != null) { - if (slow.val != stack.pop()) { - return false; - } - slow = slow.next; - } - return true; - } - - 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(3); - l1.next.next.next.next = new Node(2); - l1.next.next.next.next.next = new Node(1); - l1.print(); - System.out.println(isPalindrome(l1)); - System.out.println(isPalindromeOptimized(l1)); - System.out.println("------"); - - l1 = new Node(1); - l1.next = new Node(2); - l1.next.next = new Node(3); - l1.next.next.next = new Node(2); - l1.next.next.next.next = new Node(1); - l1.print(); - System.out.println(isPalindrome(l1)); - System.out.println(isPalindromeOptimized(l1)); - System.out.println("------"); - - l1 = new Node(0); - l1.next = new Node(2); - l1.next.next = new Node(3); - l1.next.next.next = new Node(3); - l1.next.next.next.next = new Node(0); - l1.print(); - System.out.println(isPalindrome(l1)); - System.out.println(isPalindromeOptimized(l1)); - System.out.println("------"); - - l1 = new Node(1); - l1.print(); - System.out.println(isPalindrome(l1)); - System.out.println(isPalindromeOptimized(l1)); - - } -} diff --git a/src/main/java/com/ctci/linkedlists/Partition.java b/src/main/java/com/ctci/linkedlists/Partition.java deleted file mode 100644 index 8876a424..00000000 --- a/src/main/java/com/ctci/linkedlists/Partition.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.ctci.linkedlists; - -/** - * Write code to partition a linked list around a value x, such that all nodes less than x come before all - * nodes greater than or equal to x. If x is contained within the list, the values of x only need to be - * after the elements less than x (see below). The partition element x can appear anywhere in the "right - * partition"; it does not need to appear between the left and right partitions. - *

- * 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 deleted file mode 100644 index 31029188..00000000 --- a/src/main/java/com/ctci/linkedlists/RemoveDuplicates.java +++ /dev/null @@ -1,88 +0,0 @@ -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 valuesInList = new HashSet<>(); - Node curr = head; - Node prev = curr; - while (curr != null) { - if (valuesInList.contains(curr.val)) { - prev.next = curr.next; - } - valuesInList.add(curr.val); - prev = curr; - curr = curr.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(5); - System.out.print("With dups: "); - l1.print(); - removeDuplicatesFromUnsortedList(l1); - System.out.print("Without dups: "); - l1.print(); - - Node l2 = new Node(1); - l2.next = new Node(1); - 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(5); - System.out.print("\nWith dups: "); - l2.print(); - removeDuplicatesFromUnsortedList(l2); - System.out.print("Without dups: "); - l2.print(); - - Node l3 = new Node(1); - l3.next = new Node(2); - 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(5); - System.out.print("\nWith dups: "); - l3.print(); - removeDuplicatesFromUnsortedList(l3); - System.out.print("Without dups: "); - l3.print(); - - Node l4 = new Node(1); - System.out.print("\nWith dups: "); - l4.print(); - removeDuplicatesFromUnsortedList(l4); - System.out.print("Without dups: "); - l4.print(); - - Node l5 = null; - System.out.print("\nWith dups: "); - l5.print(); - removeDuplicatesFromUnsortedList(l5); - System.out.print("Without dups: "); - l5.print(); - } -} \ No newline at end of file diff --git a/src/main/java/com/ctci/linkedlists/SumLists.java b/src/main/java/com/ctci/linkedlists/SumLists.java deleted file mode 100644 index befdfc3e..00000000 --- a/src/main/java/com/ctci/linkedlists/SumLists.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.ctci.linkedlists; - -/** - * @author rampatra - * @since 2019-01-31 - */ -public class SumLists { - - /** - * You have two numbers represented by a linked list, where each node contains a single digit. The digits are - * stored in reverse order, such that the 1's digit is at the head of the list (or in other words, the least - * significant digit is stored at the head of the list). Write a function that adds the two numbers and returns - * the sum as a linked list. - *

- * 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 deleted file mode 100644 index caa4d095..00000000 --- a/src/main/java/com/ctci/recursionanddp/FibonacciNumber.java +++ /dev/null @@ -1,64 +0,0 @@ -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 deleted file mode 100644 index 271fd8e4..00000000 --- a/src/main/java/com/ctci/stacksandqueues/QueueViaStacks.java +++ /dev/null @@ -1,61 +0,0 @@ -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 { - - private Stack stackFront = new Stack<>(); - private Stack stackRear = new Stack<>(); - - private T add(T item) { - return stackRear.push(item); - } - - private T remove() { - if (stackFront.empty() && stackRear.empty()) { - throw new NoSuchElementException(); - } else if (!stackFront.empty()) { - return stackFront.pop(); - } else { - while (!stackRear.empty()) { - stackFront.push(stackRear.pop()); - } - return stackFront.pop(); - } - } - - private void print() { - Stack tempStack = new Stack<>(); - while (!stackFront.empty()) { - tempStack.push(stackFront.pop()); - } - System.out.print("["); - tempStack.forEach(item -> System.out.print(item + ",")); - stackRear.forEach(item -> System.out.print(item + ",")); - System.out.println("]"); - while (!tempStack.empty()) { - stackFront.push(tempStack.pop()); - } - } - - public static void main(String[] args) { - QueueViaStacks queue = new QueueViaStacks<>(); - queue.add(1); - queue.add(2); - queue.add(3); - queue.print(); - queue.remove(); - queue.print(); - queue.remove(); - queue.print(); - queue.remove(); - queue.print(); - } -} diff --git a/src/main/java/com/ctci/stacksandqueues/SortStack.java b/src/main/java/com/ctci/stacksandqueues/SortStack.java deleted file mode 100644 index b94c68fb..00000000 --- a/src/main/java/com/ctci/stacksandqueues/SortStack.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.ctci.stacksandqueues; - -import java.util.Arrays; -import java.util.Stack; - -/** - * Write a program to sort a stack such that the smallest items are on the top. You can use an additional temporary - * stack, but you may not copy the elements into any other data structure (such as an array). The stack supports the - * following operations: push, pop, peek, and isEmpty. - * - * @author rampatra - * @since 2019-02-08 - */ -public class SortStack { - - private static void sortStack(Stack stack) { - Stack tempStack = new Stack<>(); - while (!stack.empty()) { - tempStack.push(stack.pop()); - } - while (!tempStack.empty()) { - Integer item = tempStack.pop(); - if (stack.empty()) { - stack.push(item); - } else { - while (!stack.empty() && item > stack.peek()) { - tempStack.push(stack.pop()); - } - stack.push(item); - } - } - } - - private static void printStack(Stack stack) { - System.out.println(Arrays.toString(stack.toArray())); - } - - public static void main(String[] args) { - Stack unsortedStack = new Stack<>(); - unsortedStack.push(2); - unsortedStack.push(5); - unsortedStack.push(1); - unsortedStack.push(3); - printStack(unsortedStack); - sortStack(unsortedStack); - printStack(unsortedStack); - } -} diff --git a/src/main/java/com/ctci/stacksandqueues/StackMin.java b/src/main/java/com/ctci/stacksandqueues/StackMin.java deleted file mode 100644 index 0a5d2d59..00000000 --- a/src/main/java/com/ctci/stacksandqueues/StackMin.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.ctci.stacksandqueues; - -import com.sun.tools.javac.util.Assert; - -import java.util.Stack; - -/** - * How would you design a stack which, in addition to push and pop, has a function min - * which returns the minimum element? Push, pop and min should all operate in 0(1) time. - * - * @author rampatra - * @since 2019-02-04 - */ -public class StackMin { - - // the main stack to do push, pop, and min operations - private static Stack stack = new Stack<>(); - // another stack to store the mins (needed to make min() call O(1)) - private static Stack minStack = new Stack<>(); - - private static int push(int item) { - minPush(item); - return stack.push(item); - } - - private static int pop() { - minPop(stack.peek()); - return stack.pop(); - } - - private static int min() { - return minStack.peek(); - } - - private static void minPush(int item) { - if (minStack.empty() || item <= minStack.peek()) { - minStack.push(item); - } - } - - private static void minPop(int item) { - if (item == minStack.peek()) { - minStack.pop(); - } - } - - public static void main(String[] args) { - push(2); - push(5); - push(1); - push(1); - push(6); - push(8); - Assert.check(min() == 1); - pop(); - pop(); - pop(); - Assert.check(min() == 1); - pop(); - Assert.check(min() == 2); - } -} \ No newline at end of file diff --git a/src/main/java/com/ctci/stacksandqueues/StackOfPlates.java b/src/main/java/com/ctci/stacksandqueues/StackOfPlates.java deleted file mode 100644 index f001c4e4..00000000 --- a/src/main/java/com/ctci/stacksandqueues/StackOfPlates.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.ctci.stacksandqueues; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.EmptyStackException; -import java.util.List; -import java.util.Stack; - -/** - * Imagine a (literal) stack of plates. If the stack gets too high, it might topple. Therefore, in real life, we - * would likely start a new stack when the previous stack exceeds some threshold. Implement a data structure - * SetOfStacks that mimics this. SetOfStacks should be composed of several stacks and should create a new stack once - * the previous one exceeds capacity. SetOfStacks.push() and SetOfStacks. pop() should behave identically to a single - * stack (that is, pop() should return the same values as it would if there were just a single stack). - * - * @author rampatra - * @since 2019-02-08 - */ -public class StackOfPlates { - - private static final int capacity = 3; - private static List> stackList = new ArrayList<>(); - - private static int push(int item) { - return getLastStack().push(item); - } - - private static int pop() { - Stack lastStack = stackList.get(stackList.size() - 1); - if (lastStack == null || (stackList.size() == 1 && lastStack.empty())) { - throw new EmptyStackException(); - } else if (lastStack.empty()) { - stackList.remove(stackList.size() - 1); - return pop(); - } else { - return lastStack.pop(); - } - } - - private static Stack getLastStack() { - if (stackList.size() == 0 || isFull(stackList.get(stackList.size() - 1))) { - stackList.add(new Stack<>()); - } - return stackList.get(stackList.size() - 1); - } - - private static boolean isFull(Stack stack) { - return stack.size() >= capacity; - } - - private static void print() { - System.out.print("["); - stackList.stream().flatMap(Collection::stream).forEach(System.out::print); - System.out.println("]"); - } - - public static void main(String[] args) { - push(1); - push(2); - print(); - push(3); - print(); - push(4); - push(5); - print(); - push(6); - push(7); - print(); - pop(); - print(); - pop(); - pop(); - pop(); - print(); - pop(); - pop(); - pop(); - print(); - } -} diff --git a/src/main/java/com/ctci/treesandgraphs/BuildOrder.java b/src/main/java/com/ctci/treesandgraphs/BuildOrder.java deleted file mode 100644 index 6d64e48a..00000000 --- a/src/main/java/com/ctci/treesandgraphs/BuildOrder.java +++ /dev/null @@ -1,144 +0,0 @@ -package com.ctci.treesandgraphs; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Stream; - -/** - * You are given a list of projects and a list of dependencies (which is a list of pairs of projects, where the second - * project is dependent on the first project). All of a project's dependencies must be built before the project is. Find - * a build order that will allow the projects to be built. If there is no valid build order, return an error. - * EXAMPLE - * Input: projects: a, b, c, d, e, f and dependencies: (a, d), (f, b), (b, d), (f, a), (d, c) - * Output: f, e, a, b, d, c - * - * @author rampatra - * @since 2019-02-21 - */ -public class BuildOrder { - - private class Project { - String name; - Set dependencies = new HashSet<>(); - - Project(String name) { - this.name = name; - } - - @Override - public String toString() { - return name; - } - } - - private final Map projects = new HashMap<>(); - - private void addProjects(Stream projectNames) { - projectNames.forEach(name -> projects.put(name, new Project(name))); - } - - /** - * Adds a directed edge from {@code projectName2} to {@code ProjectName1}. This means {@code projectName2} is - * dependent on {@code projectName1}, i.e, {@code projectName1} has to be built before {@code projectName2}. - * - * @param projectName1 name of project 1 - * @param projectName2 name of project 2 - */ - private void addDependency(String projectName1, String projectName2) { - Project p1 = projects.get(projectName1); - Project p2 = projects.get(projectName2); - - if (p1 == null) { - p1 = new Project(projectName1); - projects.put(projectName1, p1); - } - if (p2 == null) { - p2 = new Project(projectName2); - projects.put(projectName2, p2); - } - - p2.dependencies.add(p1); - } - - /** - * Determines the order in which the projects need to be built. - * Time complexity: TODO - * - * @return a list of projects in the order they should be built, the first project should be built first and so on. - */ - private List getBuildOrder() { - Map projectsBuilt = new LinkedHashMap<>(); // linked hashmap is needed to maintain the insertion order - - while (projectsBuilt.size() != projects.size()) { - // find the projects which are not dependent on any project - Set nextProjectsToBuild = getProjectsWithNoDependencies(projectsBuilt); - - // if there are no further independent projects to build, then we can't proceed further - if (nextProjectsToBuild.size() == 0) { - throw new IllegalStateException("Error: Projects can't be built."); - } - nextProjectsToBuild.forEach(p -> projectsBuilt.put(p.name, p)); - - // once a project is built, remove the dependencies from all other projects dependent on this - removeDependency(nextProjectsToBuild); - } - - return new ArrayList<>(projectsBuilt.values()); - } - - private Set getProjectsWithNoDependencies(Map alreadyBuildProjects) { - Set unBuiltProjectsWithZeroDependencies = new HashSet<>(); - - for (Map.Entry entry : projects.entrySet()) { - if (entry.getValue().dependencies.size() == 0 && alreadyBuildProjects.get(entry.getKey()) == null) { - unBuiltProjectsWithZeroDependencies.add(entry.getValue()); - } - } - - return unBuiltProjectsWithZeroDependencies; - } - - private void removeDependency(Set newlyBuiltProjects) { - projects.forEach((n, p) -> p.dependencies.removeAll(newlyBuiltProjects)); - } - - - public static void main(String[] args) { - /* test case 1 - - ––––––––––– b - | ↑ - ↓ | - f <–– a <–– d <–– c - - Note: Project "a" is dependent on "f", and project "d" is dependent on "a", and so on. - - */ - BuildOrder buildOrder = new BuildOrder(); - buildOrder.addProjects(Stream.of("a", "b", "c", "d", "e", "f")); - buildOrder.addDependency("a", "d"); - buildOrder.addDependency("f", "b"); - buildOrder.addDependency("b", "d"); - buildOrder.addDependency("f", "a"); - buildOrder.addDependency("d", "c"); - System.out.println(buildOrder.getBuildOrder()); - - // test case 2 - buildOrder = new BuildOrder(); - buildOrder.addProjects(Stream.of("a", "b", "c", "d", "e", "f", "g")); - buildOrder.addDependency("d", "g"); - buildOrder.addDependency("f", "b"); - buildOrder.addDependency("f", "c"); - buildOrder.addDependency("f", "a"); - buildOrder.addDependency("c", "a"); - buildOrder.addDependency("b", "a"); - buildOrder.addDependency("b", "e"); - buildOrder.addDependency("a", "e"); - System.out.println(buildOrder.getBuildOrder()); - } -} \ No newline at end of file diff --git a/src/main/java/com/ctci/treesandgraphs/CheckBalanced.java b/src/main/java/com/ctci/treesandgraphs/CheckBalanced.java deleted file mode 100644 index d7658cd8..00000000 --- a/src/main/java/com/ctci/treesandgraphs/CheckBalanced.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.ctci.treesandgraphs; - -/** - * Implement a function to check if a binary tree is balanced. For the purposes of this question, a balanced - * tree is defined to be a tree such that the heights of the two subtrees of any node never differ by more than one. - * - * @author rampatra - * @since 2019-02-16 - */ -public class CheckBalanced { - - /** - * Checks whether its left and right child are balanced, if yes then continues down the - * tree or else stops and returns {@code false}. Time complexity: O(n log n) since each - * node is touched once per node above it. Space complexity: O(h) where, h is the height - * of the tree. - * - * @param node reference to the node for which the balanced property needs to be checked - * @return {@code true} if balanced, {@code false} otherwise - */ - private static boolean isBalanced(TreeNode node) { - if (node == null) return true; - - boolean isBalanced = (height(node.left) - height(node.right)) <= 1; - - /* Note: isBalanced is first checked below as there is no point is checking the left and right child - if the current node itself is not balanced. And, as '&&' is a short circuit operator, it won't evaluate - the rest of the conditions if the first condition is false. */ - return isBalanced && isBalanced(node.left) && isBalanced(node.right); - } - - private static int height(TreeNode node) { - if (node == null) return -1; - - return Math.max(height(node.left), height(node.right)) + 1; - } - - /** - * This approach is a slight modification to the above {@link CheckBalanced#height(TreeNode)} method where - * while calculating the height we also check whether the difference between the left and right child heights - * is more than 1. If yes, we return an error code, which in this case, is {@code Integer.MIN_VALUE}. - * Time complexity: O(n). Space complexity: O(h) where, h is the height of the tree. - * - * @param node reference to the node for which the balanced property needs to be checked - * @return the height of the tree if it's balance, {@code Integer.MIN_VALUE} otherwise - */ - private static int checkHeightAndBalance(TreeNode node) { - if (node == null) return -1; - - int leftHeight = checkHeightAndBalance(node.left); - int rightHeight = checkHeightAndBalance(node.right); - - if (leftHeight == Integer.MIN_VALUE || rightHeight == Integer.MIN_VALUE || !(leftHeight - rightHeight <= 1)) { - return Integer.MIN_VALUE; - } - - return Math.max(leftHeight, rightHeight) + 1; - } - - public static boolean isBalancedOptimized(TreeNode node) { - return checkHeightAndBalance(node) != Integer.MIN_VALUE; - } - - public static void main(String[] args) { - TreeNode treeRoot = new TreeNode(1); - treeRoot.left = new TreeNode(2); - treeRoot.right = new TreeNode(3); - System.out.println("Height: " + height(treeRoot)); - System.out.println("Is Balance: " + isBalanced(treeRoot)); - System.out.println("Is Balance Optimized: " + isBalancedOptimized(treeRoot)); - - treeRoot = new TreeNode(1); - treeRoot.left = new TreeNode(2); - treeRoot.right = new TreeNode(3); - treeRoot.left.left = new TreeNode(4); - treeRoot.left.left.left = new TreeNode(5); - System.out.println("Height: " + height(treeRoot)); - System.out.println("Is Balance: " + isBalanced(treeRoot)); - System.out.println("Is Balance Optimized: " + isBalancedOptimized(treeRoot)); - } -} \ No newline at end of file diff --git a/src/main/java/com/ctci/treesandgraphs/CheckSubtree.java b/src/main/java/com/ctci/treesandgraphs/CheckSubtree.java deleted file mode 100644 index a49f1b74..00000000 --- a/src/main/java/com/ctci/treesandgraphs/CheckSubtree.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.ctci.treesandgraphs; - -/** - * @author rampatra - * @since 2019-02-24 - */ -public class CheckSubtree { - - private static boolean isT2SubtreeOfT1(TreeNode t1, TreeNode t2) { - if (t1 == null) { - return false; - } else if (t2 == null) { - return true; - } - - if (t1.val == t2.val) { - if (matchTree(t1, t2)) { - return true; - } - } - return isT2SubtreeOfT1(t1.left, t2) || isT2SubtreeOfT1(t1.right, t2); - } - - private static boolean matchTree(TreeNode a, TreeNode b) { - if (a == null && b == null) { - return true; - } else if (a == null) { - return false; - } else if (b == null) { - return true; - } else if (a.val != b.val) { - return false; - } else { - return matchTree(a.left, b.left) && matchTree(a.right, b.right); - } - } - - public static void main(String[] args) { - /* - The BST looks like: - - 4 - / \ - 2 8 - / \ / \ - 1 3 6 9 - / - 0 - - */ - TreeNode treeRoot = new TreeNode(4); - treeRoot.left = new TreeNode(2); - treeRoot.right = new TreeNode(8); - treeRoot.left.left = new TreeNode(1); - treeRoot.left.right = new TreeNode(3); - treeRoot.left.left.left = new TreeNode(0); - treeRoot.right.left = new TreeNode(6); - treeRoot.right.right = new TreeNode(9); - System.out.println(isT2SubtreeOfT1(treeRoot, treeRoot)); - System.out.println(isT2SubtreeOfT1(treeRoot, treeRoot.left)); - System.out.println(isT2SubtreeOfT1(treeRoot, treeRoot.right)); - - /* - The sub-tree: - - 8 - / - 6 - */ - TreeNode treeRoot2 = new TreeNode(8); - treeRoot2.left = new TreeNode(6); - System.out.println(isT2SubtreeOfT1(treeRoot, treeRoot2)); - - /* - The sub-tree: - - 2 - / - 1 - */ - TreeNode treeRoot3 = new TreeNode(2); - treeRoot3.left = new TreeNode(1); - System.out.println(isT2SubtreeOfT1(treeRoot, treeRoot3)); - - /* - The sub-tree: - - 8 - / - 9 - */ - TreeNode treeRoot4 = new TreeNode(8); - treeRoot4.left = new TreeNode(9); - System.out.println(isT2SubtreeOfT1(treeRoot, treeRoot4)); - } -} \ No newline at end of file diff --git a/src/main/java/com/ctci/treesandgraphs/FirstCommonAncestor.java b/src/main/java/com/ctci/treesandgraphs/FirstCommonAncestor.java deleted file mode 100644 index 38977be3..00000000 --- a/src/main/java/com/ctci/treesandgraphs/FirstCommonAncestor.java +++ /dev/null @@ -1,103 +0,0 @@ -package com.ctci.treesandgraphs; - -/** - * Design an algorithm and write code to find the first common ancestor of two nodes in a binary - * tree. Avoid storing additional nodes in a data structure. Also, for this question, the tree node - * does NOT have access to its parent node. NOTE: This is not necessarily a binary search tree. - * - * First Common Ancestor or the Least/Lowest Common Ancestor of two nodes is a node which is the - * closest to both of the nodes. - * - * @author rampatra - * @since 2019-02-24 - */ -public class FirstCommonAncestor { - - /** - * We recurse through the entire tree with a function called findFCA(TreeNode root, TreeNode TreeNode a, TreeNode b). - * This function returns values as follows: - * - Returns p, if root's subtree includes p (and not q). - * - Returns q, if root's subtree includes q (and not p). - * - Returns null, if neither p nor q are in root's subtree. - * - Else, returns the common ancestor of p and q. - *

- * See {@link com.rampatra.trees.LeastCommonAncestorInBT} for a 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 deleted file mode 100644 index 5aa453cf..00000000 --- a/src/main/java/com/ctci/treesandgraphs/FirstCommonAncestorWithParentAccess.java +++ /dev/null @@ -1,115 +0,0 @@ -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 deleted file mode 100644 index 573cccf3..00000000 --- a/src/main/java/com/ctci/treesandgraphs/GraphNode.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.ctci.treesandgraphs; - -import java.util.HashSet; -import java.util.Set; - -/** - * @author rampatra - * @since 2019-03-21 - */ -public class GraphNode { - int value; - Set adjacent = new HashSet<>(); - - GraphNode(int value) { - this.value = value; - } -} \ No newline at end of file diff --git a/src/main/java/com/ctci/treesandgraphs/ListOfDepths.java b/src/main/java/com/ctci/treesandgraphs/ListOfDepths.java deleted file mode 100644 index fd5287dc..00000000 --- a/src/main/java/com/ctci/treesandgraphs/ListOfDepths.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.ctci.treesandgraphs; - -import java.util.ArrayList; -import java.util.List; - -/** - * Given a binary tree, design an algorithm which creates a linked list of all the nodes - * at each depth (e.g., if you have a tree with depth D, you'll have D linked lists). - * - * @author rampatra - * @since 2019-02-16 - */ -public class ListOfDepths { - - /** - * This approach visits the root node, adds all its children to a list, then iterates - * that list, and repeats the same process until all nodes are visited. - * - * @param root the root node of the tree - * @return list of nodes at each depth, where depth starts from 0 - */ - private static List> listOfDepths(TreeNode root) { - List> listOfDepths = new ArrayList<>(); - List listOfNodesAtCurrentDepth = new ArrayList<>(); - - if (root != null) { - listOfNodesAtCurrentDepth.add(root); - } - - while (listOfNodesAtCurrentDepth.size() > 0) { - listOfDepths.add(listOfNodesAtCurrentDepth); // add current depth - List listOfNodesAtPreviousDepth = listOfNodesAtCurrentDepth; // make current depth as previous - /* make current depth as the new depth to be processed considering - the nodes from the previous depth as parents */ - listOfNodesAtCurrentDepth = new ArrayList<>(); - - for (TreeNode node : listOfNodesAtPreviousDepth) { - if (node.left != null) { - listOfNodesAtCurrentDepth.add(node.left); - } - if (node.right != null) { - listOfNodesAtCurrentDepth.add(node.right); - } - } - } - - return listOfDepths; - } - - /** - * This is a recursive approach where we pass the depth of each node in the call. We use a - * list {@code listOfDepths} to keep track of all the depths. - * - * @param node - * @param depth - * @param listOfDepths - * @return list of nodes at each depth, where depth starts from 0 - */ - private static List> listOfDepths(TreeNode node, int depth, List> listOfDepths) { - if (node == null) return null; - - List listOfNodesAtDepth; - if (depth == listOfDepths.size()) { - listOfNodesAtDepth = new ArrayList<>(); - listOfDepths.add(listOfNodesAtDepth); - } else { - listOfNodesAtDepth = listOfDepths.get(depth); - } - - listOfNodesAtDepth.add(node); - - listOfDepths(node.left, depth + 1, listOfDepths); - listOfDepths(node.right, depth + 1, listOfDepths); - - return listOfDepths; - } - - private static void printAllDepths(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 deleted file mode 100644 index 4d18faf7..00000000 --- a/src/main/java/com/ctci/treesandgraphs/MinimalTree.java +++ /dev/null @@ -1,43 +0,0 @@ -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 deleted file mode 100644 index b849b8c8..00000000 --- a/src/main/java/com/ctci/treesandgraphs/RouteBetweenNodes.java +++ /dev/null @@ -1,94 +0,0 @@ -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 nodes = new HashMap<>(); - - /** - * Adds an edge from a node with value {@code v1} to another node with value {@code v2}. - * Note: This code doesn't work for nodes having duplicate values. - * - * @param v1 - * @param v2 - */ - void addEdge(int v1, int v2) { - GraphNode n1 = nodes.get(v1); - GraphNode n2 = nodes.get(v2); - - if (n1 == null) { - n1 = new GraphNode(v1); - nodes.put(v1, n1); - } - if (n2 == null) { - n2 = new GraphNode(v2); - nodes.put(v2, n2); - } - - n1.adjacent.add(n2); // as it is a directed graph - } - - /** - * Checks for a path from a node with value {@code v1} to another node with value {@code v2} in a breadth-first - * manner. Note: This code doesn't work for nodes having duplicate values. - * - * @param v1 the value of the first node or starting node. - * @param v2 the value of the ending node. - * @return {@code true} if path exists, {@code false} otherwise. - */ - boolean isRoutePresent(int v1, int v2) { - Queue queue = new ArrayDeque<>(); - Set visited = new HashSet<>(); - - GraphNode n1 = nodes.get(v1); - GraphNode n2 = nodes.get(v2); - - if (n1 == null || n2 == null) { - return false; - } - - queue.add(n1); - - while (!queue.isEmpty()) { - GraphNode n = queue.poll(); - - if (visited.contains(n)) { - continue; - } - if (n.adjacent.contains(n2)) { - return true; - } - queue.addAll(n.adjacent); - visited.add(n); - } - - return false; - } - } - - public static void main(String[] args) { - Graph g = new RouteBetweenNodes().new Graph(); - g.addEdge(1, 2); - g.addEdge(2, 3); - g.addEdge(4, 5); - g.addEdge(5, 6); - System.out.println("Route exists from 1 to 2: " + g.isRoutePresent(1, 2)); - System.out.println("Route exists from 2 to 5: " + g.isRoutePresent(2, 5)); - System.out.println("Route exists from 1 to 3: " + g.isRoutePresent(1, 3)); - System.out.println("Route exists from 4 to 6: " + g.isRoutePresent(4, 6)); - System.out.println("Route exists from 6 to 4: " + g.isRoutePresent(6, 4)); - System.out.println("Route exists from 6 to 5: " + g.isRoutePresent(6, 5)); - } -} \ No newline at end of file diff --git a/src/main/java/com/ctci/treesandgraphs/Successor.java b/src/main/java/com/ctci/treesandgraphs/Successor.java deleted file mode 100644 index d37488bd..00000000 --- a/src/main/java/com/ctci/treesandgraphs/Successor.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.ctci.treesandgraphs; - -/** - * Write an algorithm to find the "next" node (i.e., in-order successor) of a given node - * in a binary search tree. You may assume that each node has a link to its parent. - * - * @author rampatra - * @since 2019-02-17 - */ -public class Successor { - - /** - * To get the inorder successor what this method does is that it checks if the right child of the input node - * is null and if not, gets the leftmost child of the right child. And, if the right child of the input - * node is null, it checks all the parents until it finds the next successor. - * - * @param node - * @return - */ - private static TreeNode getInOrderSuccessor(TreeNode node) { - if (node == null) return null; - - if (node.right != null) { - return getLeftmostNode(node.right); - } else { - TreeNode curr = node; - - while (curr != null) { - if (curr.parent != null && curr.parent.left == curr) { - return curr.parent; - } - curr = curr.parent; - } - } - return null; - } - - private static TreeNode getLeftmostNode(TreeNode node) { - TreeNode curr = node; - while (curr != null && curr.left != null) { - curr = curr.left; - } - return curr; - } - - private static class TreeNode { - int val; - TreeNode parent; - TreeNode left; - TreeNode right; - - TreeNode(int val) { - this.val = val; - } - } - - public static void main(String[] args) { - /* - The binary search tree looks like: - - 4 - / \ - 2 8 - / \ / \ - 1 3 6 9 - / \ - 0 7 - - */ - TreeNode treeRoot = new TreeNode(4); - treeRoot.left = new TreeNode(2); - treeRoot.left.parent = treeRoot; - treeRoot.right = new TreeNode(8); - treeRoot.right.parent = treeRoot; - treeRoot.left.left = new TreeNode(1); - treeRoot.left.left.parent = treeRoot.left; - treeRoot.left.right = new TreeNode(3); - treeRoot.left.right.parent = treeRoot.left; - treeRoot.left.left.left = new TreeNode(0); - treeRoot.left.left.left.parent = treeRoot.left.left; - treeRoot.right.left = new TreeNode(6); - treeRoot.right.left.parent = treeRoot.right; - treeRoot.right.right = new TreeNode(9); - treeRoot.right.right.parent = treeRoot.right; - treeRoot.right.left.right = new TreeNode(7); - treeRoot.right.left.right.parent = treeRoot.right.left; - - System.out.println("InOrder successor of 0 is: " + getInOrderSuccessor(treeRoot.left.left.left).val); - System.out.println("InOrder successor of 1 is: " + getInOrderSuccessor(treeRoot.left.left).val); - System.out.println("InOrder successor of 2 is: " + getInOrderSuccessor(treeRoot.left).val); - System.out.println("InOrder successor of 3 is: " + getInOrderSuccessor(treeRoot.left.right).val); - System.out.println("InOrder successor of 4 is: " + getInOrderSuccessor(treeRoot).val); - System.out.println("InOrder successor of 6 is: " + getInOrderSuccessor(treeRoot.right.left).val); - System.out.println("InOrder successor of 7 is: " + getInOrderSuccessor(treeRoot.right.left.right).val); - System.out.println("InOrder successor of 8 is: " + getInOrderSuccessor(treeRoot.right).val); - System.out.println("InOrder successor of 9 is: " + getInOrderSuccessor(treeRoot.right.right)); - } -} \ No newline at end of file diff --git a/src/main/java/com/ctci/treesandgraphs/TreeNode.java b/src/main/java/com/ctci/treesandgraphs/TreeNode.java deleted file mode 100644 index 3fe24210..00000000 --- a/src/main/java/com/ctci/treesandgraphs/TreeNode.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.ctci.treesandgraphs; - -/** - * @author rampatra - * @since 2019-02-15 - */ -public class TreeNode { - public int val; - public TreeNode left; - public TreeNode right; - - public TreeNode(int val) { - this.val = val; - } -} diff --git a/src/main/java/com/ctci/treesandgraphs/ValidateBST.java b/src/main/java/com/ctci/treesandgraphs/ValidateBST.java deleted file mode 100644 index 0170cdfe..00000000 --- a/src/main/java/com/ctci/treesandgraphs/ValidateBST.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.ctci.treesandgraphs; - -import java.util.ArrayList; -import java.util.List; - -/** - * Implement a function to check if a binary tree is a binary search tree. - * - * @author rampatra - * @since 2019-02-17 - */ -public class ValidateBST { - - private static boolean isBST(TreeNode node) { - return isBST(node, new ArrayList<>()); - } - - /** - * This method exploits the fact that the inorder traversal of a binary search tree - * results in the values being sorted in ascending order. Here, we have used a list - * but if you see closely we use this list to only compare with the previous element. - * Ergo, we can use an instance/class variable to store just the last element. This - * will be a good optimization for space. - *

- * 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 values) { - if (node == null) return true; - - isBST(node.left, values); - if (values.isEmpty() || node.val > values.get(values.size() - 1)) { - values.add(node.val); - } else { - return false; - } - isBST(node.right, values); - - return true; - } - - private static boolean isBSTApproach2(TreeNode node) { - return isBSTApproach2(node, Integer.MIN_VALUE, Integer.MAX_VALUE); - } - - /** - * This approach exploits the condition that all left nodes must be less than or equal to - * the current node, which must be less than all the right nodes. - *

- * 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/main/java/com/design/LRUCache.java b/src/main/java/com/design/LRUCache.java new file mode 100644 index 00000000..3b18ee23 --- /dev/null +++ b/src/main/java/com/design/LRUCache.java @@ -0,0 +1,92 @@ +package com.design; + +import com.linkedlist.model.DoublyLLNode; + +import java.util.HashMap; + +/** + * Design and implement a data structure for Least Recently Used (LRU) cache, which supports get and put. + * The key to solve this problem is using a double linked list which enables us to quickly move nodes. + * + * The LRU cache is a hash table of keys and double linked nodes. + * The hash table makes the time of get() to be O(1). The list of double linked nodes make the nodes adding/removal operations O(1). + * + * By analyzing the get and put, we can summarize there are 2 basic operations: + * 1) removeNode(Node t), 2) offerNode(Node t). + * + */ +class LRUCache { + DoublyLLNode head; + DoublyLLNode tail; + HashMap map = null; + int cap = 0; + + public LRUCache(int capacity) { + this.cap = capacity; + this.map = new HashMap<>(); + } + + public int get(int key) { + if(map.get(key)==null){ + return -1; + } + + //move to tail + DoublyLLNode t = map.get(key); + + removeDoublyLLNode(t); + offerDoublyLLNode(t); + + return t.value; + } + + public void put(int key, int value) { + if(map.containsKey(key)){ + DoublyLLNode t = map.get(key); + t.value = value; + + //move to tail + removeDoublyLLNode(t); + offerDoublyLLNode(t); + }else{ + if(map.size()>=cap){ + //delete head + map.remove(head.key); + removeDoublyLLNode(head); + } + + //add to tail + DoublyLLNode DoublyLLNode = new DoublyLLNode(key, value); + offerDoublyLLNode(DoublyLLNode); + map.put(key, DoublyLLNode); + } + } + + private void removeDoublyLLNode(DoublyLLNode n){ + if(n.prev!=null){ + n.prev.next = n.next; + }else{ + head = n.next; + } + + if(n.next!=null){ + n.next.prev = n.prev; + }else{ + tail = n.prev; + } + } + + private void offerDoublyLLNode(DoublyLLNode n){ + if(tail!=null){ + tail.next = n; + } + + n.prev = tail; + n.next = null; + tail = n; + + if(head == null){ + head = tail; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/design/LowLevelDesign.java b/src/main/java/com/design/LowLevelDesign.java new file mode 100644 index 00000000..11059607 --- /dev/null +++ b/src/main/java/com/design/LowLevelDesign.java @@ -0,0 +1,79 @@ +package com.design; + +import javax.jms.Message; +import javax.jms.MessageListener; +import javax.jms.TextMessage; + +/** + * This design uses Strategy Pattern + * + * Strategy pattern and the open closed principle + * According to the strategy pattern, the behaviour of a class should be encapsulated + * using interfaces and should not be inherited. + * This is compatible with the open closed principle, + */ + +public class LowLevelDesign { + + MessageProcessor processor; + + class MessageConsumer implements MessageListener{ + + @JMSListener + public void onMessage(Message message){ + if (message instanceof TextMessage){ + processor = new MessageProcessor(); + MessageParser mp = new swiftParser(); + processor.setParser(mp); + processor.process(message); + } + if (message instanceof BytesMessage){ + + } + + + } + + } + + class MessageProcessor { + + MessageParser parser; + + public void setParser(MessageParser p){ + this.parser = p; + } + + public void process(Message message){ + parser.parse(message); + } + + } + + interface MessageParser{ + void parse(Message message); + } + + class SwiftParser implements MessageParser{ + + @Override + public void parse(Message message) { + + } + } + class JsonParser implements MessageParser{ + + @Override + public void parse(Message message) { + + } + } + class XMLParser implements MessageParser{ + + @Override + public void parse(Message message) { + + } + } + +} diff --git a/src/main/java/com/design/OnlineBookingSystem.java b/src/main/java/com/design/OnlineBookingSystem.java new file mode 100644 index 00000000..b80ebe6f --- /dev/null +++ b/src/main/java/com/design/OnlineBookingSystem.java @@ -0,0 +1,99 @@ +package com.design; + +// Java code skeleton to design an online hotel +// booking system. + +enum RoomStatus { + EMPTY, + NOT_EMPTY; + } + +enum RoomType { + SINGLE, + DOUBLE, + TRIPLE; +} + +enum PaymentStatus { + PAID, + UNPAID; +} + +public enum Facility { + LIFT; + POWER_BACKUP; + HOT_WATERR; + BREAKFAST_FREE; + SWIMMING_POOL; +} + +class User { + + int userId; + String name; + Date dateOfBirth; + String mobNo; + String emailId; + String sex; +} + +// For the room in any hotel +class Room { + + int roomId; // roomNo + int hotelId; + RoomType roomType; + RoomStatus roomStatus; +} + +class Hotel { + + int hotelId; + String hotelName; + Adress adress; + + // hotel contains the list of rooms + List rooms; + float rating; + Facilities facilities; +} + +// a new booking is created for each booking +// done by any user +class Booking { + int bookingId; + int userId; + int hotelId; + + // We are assuming that in a single + // booking we can book only the rooms + // of a single hotel + List bookedRooms; + + int amount; + PaymentStatus status_of_payment; + Date bookingTime; + Duration duration; +} + +class Address { + + String city; + String pinCode; + String state; + String streetNo; + String landmark; +} + +class Duration { + + Date from; + Date to; + +} + +class Facilities { + + List facilitiesList; +} + diff --git a/src/main/java/com/design/OnlineReaderSystem.java b/src/main/java/com/design/OnlineReaderSystem.java new file mode 100644 index 00000000..20ede4d3 --- /dev/null +++ b/src/main/java/com/design/OnlineReaderSystem.java @@ -0,0 +1,372 @@ +package com.design; + +import java.util.HashMap; + +/* + * This class represents the system + */ + +class OnlineReaderSystem { + private Library library; + private UserManager userManager; + private Display display; + private Book activeBook; + private User activeUser; + + public OnlineReaderSystem() + { + userManager = new UserManager(); + library = new Library(); + display = new Display(); + } + + public Library getLibrary() + { + return library; + } + + public UserManager getUserManager() + { + return userManager; + } + + public Display getDisplay() + { + return display; + } + + public Book getActiveBook() + { + return activeBook; + } + + public void setActiveBook(Book book) + { + activeBook = book; + display.displayBook(book); + } + + public User getActiveUser() + { + return activeUser; + } + + public void setActiveUser(User user) + { + activeUser = user; + display.displayUser(user); + } +} + +/* + * We then implement separate classes to handle the user + * manager, the library, and the display components + */ + +/* + * This class represents the Library which is responsible + * for storing and searching the books. + */ +class Library { + private HashMap books; + + public Library() + { + books = new HashMap(); + } + + public Boolean addBook(int id, String details, String title) + { + if (books.containsKey(id)) { + return false; + } + Book book = new Book(id, details, title); + books.put(id, book); + return true; + } + + public Boolean addBook(Book book) + { + if (books.containsKey(book.getId())) { + return false; + } + + books.put(book.getId(), book); + return true; + } + + public boolean remove(Book b) + { + return remove(b.getId()); + } + + public boolean remove(int id) + { + if (!books.containsKey(id)) { + return false; + } + books.remove(id); + return true; + } + + public Book find(int id) + { + return books.get(id); + } +} + +/* + * This class represents the UserManager which is responsible + * for managing the users, their membership etc. + */ + +class UserManager { + private HashMap users; + + public UserManager() + { + users = new HashMap(); + } + public Boolean addUser(int id, String details, String name) + { + if (users.containsKey(id)) { + return false; + } + User user = new User(id, details, name); + users.put(id, user); + return true; + } + + public Boolean addUser(User user) + { + if (users.containsKey(user.getId())) { + return false; + } + + users.put(user.getId(), user); + return true; + } + + public boolean remove(User u) + { + return remove(u.getId()); + } + + public boolean remove(int id) + { + if (users.containsKey(id)) { + return false; + } + users.remove(id); + return true; + } + + public User find(int id) + { + return users.get(id); + } +} + +/* + * This class represents the Display, which is responsible + * for displaying the book, it's pages and contents. It also + * shows the current user. * It provides the method + * turnPageForward, turnPageBackward, refreshPage etc. + */ + +class Display { + private Book activeBook; + private User activeUser; + private int pageNumber = 0; + + public void displayUser(User user) + { + activeUser = user; + refreshUsername(); + } + + public void displayBook(Book book) + { + pageNumber = 0; + activeBook = book; + + refreshTitle(); + refreshDetails(); + refreshPage(); + } + + public void turnPageForward() + { + pageNumber++; + System.out.println("Turning forward to page no " + + pageNumber + " of book having title " + + activeBook.getTitle()); + refreshPage(); + } + + public void turnPageBackward() + { + pageNumber--; + System.out.println("Turning backward to page no " + + pageNumber + " of book having title " + + activeBook.getTitle()); + refreshPage(); + } + + public void refreshUsername() + { + /* updates username display */ + System.out.println("User name " + activeUser.getName() + + " is refreshed"); + } + + public void refreshTitle() + { + /* updates title display */ + System.out.println("Title of the book " + + activeBook.getTitle() + " refreshed"); + } + + public void refreshDetails() + { + /* updates details display */ + System.out.println("Details of the book " + + activeBook.getTitle() + " refreshed"); + } + + public void refreshPage() + { + /* updated page display */ + System.out.println("Page no " + pageNumber + " refreshed"); + } +} + +/* + * The classes for User and Book simply hold data and + * provide little functionality. + * This class represents the Book which is a simple POJO + */ + +class Book { + private int bookId; + private String details; + private String title; + + public Book(int id, String details, String title) + { + bookId = id; + this.details = details; + this.title = title; + } + + public int getId() + { + return bookId; + } + + public void setId(int id) + { + bookId = id; + } + + public String getDetails() + { + return details; + } + + public void setDetails(String details) + { + this.details = details; + } + + public String getTitle() + { + return title; + } + + public void setTitle(String title) + { + this.title = title; + } +} + +/* + * This class represents the User which is a simple POJO + */ + +class User { + private int userId; + private String name; + private String details; + + public void renewMembership() + { + } + + public User(int id, String details, String name) + { + this.userId = id; + this.details = details; + this.name = name; + } + + public int getId() + { + return userId; + } + + public void setId(int id) + { + userId = id; + } + + public String getDetails() + { + return details; + } + + public void setDetails(String details) + { + this.details = details; + } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } +} + +// This class is used to test the Application + +public class AppTest { + + public static void main(String[] args) + { + + OnlineReaderSystem onlineReaderSystem = new OnlineReaderSystem(); + + Book dsBook = new Book(1, "It contains Data Structures", "Ds"); + Book algoBook = new Book(2, "It contains Algorithms", "Algo"); + + onlineReaderSystem.getLibrary().addBook(dsBook); + onlineReaderSystem.getLibrary().addBook(algoBook); + + User user1 = new User(1, " ", "Ram"); + User user2 = new User(2, " ", "Gopal"); + + onlineReaderSystem.getUserManager().addUser(user1); + onlineReaderSystem.getUserManager().addUser(user2); + + onlineReaderSystem.setActiveBook(algoBook); + onlineReaderSystem.setActiveUser(user1); + + onlineReaderSystem.getDisplay().turnPageForward(); + onlineReaderSystem.getDisplay().turnPageForward(); + onlineReaderSystem.getDisplay().turnPageBackward(); + } +} diff --git a/src/main/java/com/graph/DijkstraShortestPath.java b/src/main/java/com/graph/DijkstraShortestPath.java new file mode 100644 index 00000000..78e9020d --- /dev/null +++ b/src/main/java/com/graph/DijkstraShortestPath.java @@ -0,0 +1,36 @@ +//package com.graph; +// +//public class DijkstraShortestPath { +// +// +// public static void main(String args[]){ +// Graph graph = new Graph<>(false); +// /*graph.addEdge(0, 1, 4); +// graph.addEdge(1, 2, 8); +// graph.addEdge(2, 3, 7); +// graph.addEdge(3, 4, 9); +// graph.addEdge(4, 5, 10); +// graph.addEdge(2, 5, 4); +// graph.addEdge(1, 7, 11); +// graph.addEdge(0, 7, 8); +// graph.addEdge(2, 8, 2); +// graph.addEdge(3, 5, 14); +// graph.addEdge(5, 6, 2); +// graph.addEdge(6, 8, 6); +// graph.addEdge(6, 7, 1); +// graph.addEdge(7, 8, 7);*/ +// +// graph.addEdge(1, 2, 5); +// graph.addEdge(2, 3, 2); +// graph.addEdge(1, 4, 9); +// graph.addEdge(1, 5, 3); +// graph.addEdge(5, 6, 2); +// graph.addEdge(6, 4, 2); +// graph.addEdge(3, 4, 3); +// +// DijkstraShortestPath dsp = new DijkstraShortestPath(); +// Vertex sourceVertex = graph.getVertex(1); +// Map,Integer> distance = dsp.shortestPath(graph, sourceVertex); +// System.out.print(distance); +// } +//} diff --git a/src/main/java/com/hackerrank/algorithms/arraysandsorting/InsertionSort1.java b/src/main/java/com/hackerrank/algorithms/arraysandsorting/InsertionSort1.java deleted file mode 100644 index 6fd03542..00000000 --- a/src/main/java/com/hackerrank/algorithms/arraysandsorting/InsertionSort1.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.hackerrank.algorithms.arraysandsorting; - -import java.util.Scanner; - -/** - * Created by IntelliJ IDEA. - * User: rampatra - * Date: 3/1/15 - * Time: 8:58 PM - * To change this template go to Preferences | IDE Settings | File and Code Templates - */ -public class InsertionSort1 { - - static void insertIntoSorted(int[] ar) { - int V = ar[ar.length - 1], i = ar.length - 2; - - for (; i >= 0; i--) { - if (V < ar[i]) { - ar[i + 1] = ar[i]; - } else { - break; - } - printArray(ar); - } - - ar[i + 1] = V; - printArray(ar); - } - - /* Tail starts here */ - public static void main(String[] args) { - Scanner in = new Scanner(System.in); - int s = in.nextInt(); - int[] ar = new int[s]; - for (int i = 0; i < s; i++) { - ar[i] = in.nextInt(); - } - insertIntoSorted(ar); - } - - private static void printArray(int[] ar) { - for (int n : ar) { - System.out.print(n + " "); - } - System.out.println(""); - } - -} diff --git a/src/main/java/com/hackerrank/algorithms/arraysandsorting/InsertionSort2.java b/src/main/java/com/hackerrank/algorithms/arraysandsorting/InsertionSort2.java deleted file mode 100644 index cd710eb9..00000000 --- a/src/main/java/com/hackerrank/algorithms/arraysandsorting/InsertionSort2.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.hackerrank.algorithms.arraysandsorting; - -import java.util.Scanner; - -/** - * Created by IntelliJ IDEA. - * User: rampatra - * Date: 3/1/15 - * Time: 9:42 PM - * To change this template go to Preferences | IDE Settings | File and Code Templates - */ -public class InsertionSort2 { - - static void insertionSortPart2(int[] ar) { - for (int i = 1; i < ar.length; i++) { - int V = ar[i], j; - /** - * keep shifting no.s to right until - * right place for insertion(of V) is found - */ - for (j = i - 1; j >= 0 && ar[j] > V; j--) { - ar[j + 1] = ar[j]; - } - ar[j + 1] = V; - printArray(ar); - } - } - - public static void main(String[] args) { - Scanner in = new Scanner(System.in); - int s = in.nextInt(); - int[] ar = new int[s]; - for (int i = 0; i < s; i++) { - ar[i] = in.nextInt(); - } - insertionSortPart2(ar); - - } - - private static void printArray(int[] ar) { - for (int n : ar) { - System.out.print(n + " "); - } - System.out.println(""); - } -} diff --git a/src/main/java/com/hackerrank/algorithms/arraysandsorting/IntroTutorial.java b/src/main/java/com/hackerrank/algorithms/arraysandsorting/IntroTutorial.java deleted file mode 100644 index aeb8ea5f..00000000 --- a/src/main/java/com/hackerrank/algorithms/arraysandsorting/IntroTutorial.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.hackerrank.algorithms.arraysandsorting; - -import java.util.Arrays; -import java.util.Scanner; - -/** - * Created by IntelliJ IDEA. - * User: rampatra - * Date: 3/1/15 - * Time: 3:38 PM - * To change this template go to Preferences | IDE Settings | File and Code Templates - */ -public class IntroTutorial { - static int search(int searchVal, int[] arr) { - return Arrays.binarySearch(arr, searchVal); - } - - public static void main(String[] args) { - Scanner in = new Scanner(System.in); - - int searchVal = in.nextInt(); - int arrSize = in.nextInt(); - int[] arr = new int[arrSize]; - // as nextInt() doesn't read new line character - in.nextLine(); - String next = in.nextLine(); - String[] next_split = next.split(" "); - - for (int _a_i = 0; _a_i < arrSize; _a_i++) { - arr[_a_i] = Integer.parseInt(next_split[_a_i]); - } - - System.out.print(search(searchVal, arr)); - } -} diff --git a/src/main/java/com/hackerrank/algorithms/arraysandsorting/LoopInvariant.java b/src/main/java/com/hackerrank/algorithms/arraysandsorting/LoopInvariant.java deleted file mode 100644 index dd12ee7e..00000000 --- a/src/main/java/com/hackerrank/algorithms/arraysandsorting/LoopInvariant.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.hackerrank.algorithms.arraysandsorting; - -import java.util.Scanner; - -/** - * Created by IntelliJ IDEA. - * User: rampatra - * Date: 3/2/15 - * Time: 3:26 PM - * To change this template go to Preferences | IDE Settings | File and Code Templates - */ -public class LoopInvariant { - - public static void insertionSort(int[] A) { - for (int i = 1; i < A.length; i++) { - int value = A[i]; - int j = i - 1; - while (j >= 0 && A[j] > value) { - A[j + 1] = A[j]; - j = j - 1; - } - A[j + 1] = value; - } - - printArray(A); - } - - - static void printArray(int[] ar) { - for (int n : ar) { - System.out.print(n + " "); - } - } - - public static void main(String[] args) { - Scanner in = new Scanner(System.in); - int n = in.nextInt(); - int[] ar = new int[n]; - for (int i = 0; i < n; i++) { - ar[i] = in.nextInt(); - } - insertionSort(ar); - } -} diff --git a/src/main/java/com/hackerrank/algorithms/arraysandsorting/QuickSort1.java b/src/main/java/com/hackerrank/algorithms/arraysandsorting/QuickSort1.java deleted file mode 100644 index 0753f812..00000000 --- a/src/main/java/com/hackerrank/algorithms/arraysandsorting/QuickSort1.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.hackerrank.algorithms.arraysandsorting; - -import java.util.Scanner; - -/** - * Created by IntelliJ IDEA. - * User: rampatra - * Date: 3/2/15 - * Time: 5:13 PM - * To change this template go to Preferences | IDE Settings | File and Code Templates - */ -public class QuickSort1 { - - static void partition(int[] ar) { - int pivot = ar[0], j = 0; - int[] arCopy = ar.clone(); - - for (int i = 0; i < arCopy.length; i++) { - if (arCopy[i] < pivot) ar[j++] = arCopy[i]; - } - for (int i = 0; i < arCopy.length; i++) { - if (arCopy[i] >= pivot) ar[j++] = arCopy[i]; - } - printArray(ar); - } - - static void printArray(int[] ar) { - for (int n : ar) { - System.out.print(n + " "); - } - System.out.println(""); - } - - public static void main(String[] args) { - Scanner in = new Scanner(System.in); - int n = in.nextInt(); - int[] ar = new int[n]; - for (int i = 0; i < n; i++) { - ar[i] = in.nextInt(); - } - partition(ar); - } -} diff --git a/src/main/java/com/hackerrank/algorithms/arraysandsorting/QuickSort2.java b/src/main/java/com/hackerrank/algorithms/arraysandsorting/QuickSort2.java deleted file mode 100644 index b9b1dcba..00000000 --- a/src/main/java/com/hackerrank/algorithms/arraysandsorting/QuickSort2.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.hackerrank.algorithms.arraysandsorting; - -import java.util.Scanner; - -/** - * Created by IntelliJ IDEA. - * User: rampatra - * Date: 3/3/15 - * Time: 1:05 PM - * To change this template go to Preferences | IDE Settings | File and Code Templates - */ -public class QuickSort2 { - - static int partition(int[] a, int start, int end) { - - int pivot = start, temp; - - for (int i = start + 1; i <= end; i++) { - // maintains the relative positioning of elements in each partition - if (a[i] < a[pivot]) { - start++; - temp = a[i]; - int j; - for (j = i; j > start; j--) { - a[j] = a[j - 1]; - } - a[j] = temp; - } - } - - temp = a[pivot]; - while (pivot < start) { - a[pivot] = a[pivot + 1]; - pivot++; - } - a[pivot] = temp; - - return pivot; - } - - static void quickSort(int[] ar, int start, int end) { - if (start < end) { - int p = partition(ar, start, end); - quickSort(ar, start, p - 1); - quickSort(ar, p + 1, end); - for (int i = start; i <= end; i++) { - System.out.print(ar[i] + " "); - } - System.out.println(); - } - } - - public static void main(String[] args) { - Scanner in = new Scanner(System.in); - int n = in.nextInt(); - int[] ar = new int[n]; - for (int i = 0; i < n; i++) { - ar[i] = in.nextInt(); - } - quickSort(ar, 0, n - 1); - } -} diff --git a/src/main/java/com/hackerrank/algorithms/arraysandsorting/RunningTime.java b/src/main/java/com/hackerrank/algorithms/arraysandsorting/RunningTime.java deleted file mode 100644 index 27a0bd77..00000000 --- a/src/main/java/com/hackerrank/algorithms/arraysandsorting/RunningTime.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.hackerrank.algorithms.arraysandsorting; - -import java.util.Scanner; - -/** - * Created by IntelliJ IDEA. - * User: rampatra - * Date: 3/2/15 - * Time: 5:02 PM - * To change this template go to Preferences | IDE Settings | File and Code Templates - */ -public class RunningTime { - static void insertionSortPart2(int[] ar) { - int c = 0; - for (int i = 1; i < ar.length; i++) { - int V = ar[i], j; - for (j = i - 1; j >= 0 && ar[j] > V; j--, c++) { - ar[j + 1] = ar[j]; - } - ar[j + 1] = V; - //printArray(ar); - } - System.out.print(c); - } - - public static void main(String[] args) { - Scanner in = new Scanner(System.in); - int s = in.nextInt(); - int[] ar = new int[s]; - for (int i = 0; i < s; i++) { - ar[i] = in.nextInt(); - } - insertionSortPart2(ar); - - } - - private static void printArray(int[] ar) { - for (int n : ar) { - System.out.print(n + " "); - } - System.out.println(""); - } -} diff --git a/src/main/java/com/hackerrank/algorithms/implementation/CavityMap.java b/src/main/java/com/hackerrank/algorithms/implementation/CavityMap.java deleted file mode 100644 index 0bc4a052..00000000 --- a/src/main/java/com/hackerrank/algorithms/implementation/CavityMap.java +++ /dev/null @@ -1,30 +0,0 @@ -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 deleted file mode 100644 index 230a18aa..00000000 --- a/src/main/java/com/hackerrank/algorithms/implementation/ExtraLongFactorials.java +++ /dev/null @@ -1,19 +0,0 @@ -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 deleted file mode 100644 index a317913c..00000000 --- a/src/main/java/com/hackerrank/algorithms/implementation/GridSearch.java +++ /dev/null @@ -1,68 +0,0 @@ -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 deleted file mode 100644 index 4915014b..00000000 --- a/src/main/java/com/hackerrank/algorithms/implementation/TheTimeInWords.java +++ /dev/null @@ -1,38 +0,0 @@ -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 deleted file mode 100644 index cd9cae21..00000000 --- a/src/main/java/com/hackerrank/algorithms/recursion/RecursiveDigitSum.java +++ /dev/null @@ -1,60 +0,0 @@ -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/main/java/com/hackerrank/algorithms/strings/AlternatingCharacters.java b/src/main/java/com/hackerrank/algorithms/strings/AlternatingCharacters.java deleted file mode 100644 index c81f5c22..00000000 --- a/src/main/java/com/hackerrank/algorithms/strings/AlternatingCharacters.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.hackerrank.algorithms.strings; - -import java.util.Scanner; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 10/22/15 - * @time: 9:24 AM - */ -public class AlternatingCharacters { - - public static int countDeletions(String s) { - int count = 0, index = 0; - for (int i = 1; i < s.length(); i++) { - if (s.charAt(i) == s.charAt(index)) { - count++; - } else { - index = i; - } - } - return count; - } - - public static void main(String[] args) { - Scanner in = new Scanner(System.in); - int t = Integer.parseInt(in.nextLine()); - String[] input = new String[t]; - for (int i = 0; i < t; i++) { - input[i] = in.nextLine(); - } - for (int i = 0; i < t; i++) { - System.out.println(countDeletions(input[i])); - } - } -} diff --git a/src/main/java/com/hackerrank/algorithms/strings/MakingAnagrams.java b/src/main/java/com/hackerrank/algorithms/strings/MakingAnagrams.java deleted file mode 100644 index b218c04e..00000000 --- a/src/main/java/com/hackerrank/algorithms/strings/MakingAnagrams.java +++ /dev/null @@ -1,53 +0,0 @@ -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/main/java/com/hackerrank/algorithms/strings/PalindromeIndex.java b/src/main/java/com/hackerrank/algorithms/strings/PalindromeIndex.java deleted file mode 100644 index 294c4dd2..00000000 --- a/src/main/java/com/hackerrank/algorithms/strings/PalindromeIndex.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.hackerrank.algorithms.strings; - -import java.util.Scanner; - -/** - * Created by IntelliJ IDEA. - * User: rampatra - * Date: 3/18/15 - * Time: 12:27 PM - * To change this template go to Preferences | IDE Settings | File and Code Templates - */ -public class PalindromeIndex { - - static int makePalindrome(String s) { - int index = -1, l = s.length(); - if (isPalindrome(s)) { - return -1; - } - for (int i = 0; i < l; i++) { - StringBuilder sb = new StringBuilder(s); - sb.deleteCharAt(i); - String str = sb.toString(); - if (isPalindrome(str)) { - return i; - } - } - return index; - } - - static boolean isPalindrome(String s) { - int l = s.length(), i, j; - for (i = 0, j = l - 1; i < l / 2; i++, j--) { - if ((int) s.charAt(i) != (int) s.charAt(j)) { - return false; - } - } - return true; - } - - public static void main(String[] args) { - Scanner in = new Scanner(System.in); - - int t = in.nextInt(); - String s[] = new String[t]; - - for (int i = 0; i < t; i++) { - s[i] = in.next(); - } - - for (int i = 0; i < t; i++) { - System.out.println(makePalindrome(s[i])); - } - } -} diff --git a/src/main/java/com/hackerrank/algorithms/strings/Pangram.java b/src/main/java/com/hackerrank/algorithms/strings/Pangram.java deleted file mode 100644 index fa98b4fd..00000000 --- a/src/main/java/com/hackerrank/algorithms/strings/Pangram.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.hackerrank.algorithms.strings; - -import java.util.Scanner; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 10/22/15 - * @time: 8:47 AM - */ -public class Pangram { - - public static String isPangram(String s) { - - char c; - s = s.replaceAll("\\s+", ""); - s = s.toUpperCase(); - int[] alphabets = new int[26]; - - // check if all alphabets are present only once - for (int i = 0; i < s.length(); i++) { - c = s.charAt(i); - if (alphabets[c - 65] == 0) { - alphabets[c - 65] = 1; - } - } - - // check if all alphabets are present in string at least once - for (int i = 0; i < alphabets.length; i++) { - if (alphabets[i] == 0) return "not pangram"; - } - - return "pangram"; - } - - public static void main(String[] args) { - Scanner in = new Scanner(System.in); - String s = in.nextLine(); - System.out.println(isPangram(s)); - } -} diff --git a/src/main/java/com/hackerrank/algorithms/strings/TwoStrings.java b/src/main/java/com/hackerrank/algorithms/strings/TwoStrings.java deleted file mode 100644 index 779a148b..00000000 --- a/src/main/java/com/hackerrank/algorithms/strings/TwoStrings.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.hackerrank.algorithms.strings; - -import java.util.Scanner; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 10/22/15 - * @time: 10:08 AM - */ -public class TwoStrings { - - public static String isSubstringInBoth(String[] a) { - char[] alphabets = new char[]{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', - 'q', 'r', 's', 't', 'u', 'v', 'x', 'y', 'z'}; - - for (int i = 0; i < alphabets.length; i++) { - if (a[0].indexOf(alphabets[i]) != -1 && a[1].indexOf(alphabets[i]) != -1) return "YES"; - } - - return "NO"; - } - - public static void main(String[] args) { - Scanner in = new Scanner(System.in); - - int t = Integer.parseInt(in.nextLine()); - String[][] input = new String[t][2]; - - for (int i = 0; i < t; i++) { - input[i][0] = in.nextLine(); - input[i][1] = in.nextLine(); - } - - for (int i = 0; i < t; i++) { - System.out.println(isSubstringInBoth(input[i])); - } - } -} diff --git a/src/main/java/com/hackerrank/algorithms/warmup/FlippingBits.java b/src/main/java/com/hackerrank/algorithms/warmup/FlippingBits.java deleted file mode 100644 index e335efe1..00000000 --- a/src/main/java/com/hackerrank/algorithms/warmup/FlippingBits.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.hackerrank.algorithms.warmup; - -import java.util.Scanner; - -/** - * Created by IntelliJ IDEA. - * User: rampatra - * Date: 2/28/15 - * Time: 12:41 PM - * To change this template go to Preferences | IDE Settings | File and Code Templates - */ -public class FlippingBits { - - static long flipBits(long i) { - return i ^ 4294967295l; - } - - public static void main(String[] args) { - Scanner in = new Scanner(System.in); - - int t = Integer.parseInt(in.nextLine()); - long[] in_ar = new long[t]; - - for (int i = 0; i < t; i++) { - in_ar[i] = in.nextLong(); - } - - for (long i : in_ar) { - System.out.println(flipBits(i)); - } - } -} diff --git a/src/main/java/com/hackerrank/algorithms/warmup/LonelyInteger.java b/src/main/java/com/hackerrank/algorithms/warmup/LonelyInteger.java deleted file mode 100644 index 666b3fa0..00000000 --- a/src/main/java/com/hackerrank/algorithms/warmup/LonelyInteger.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.hackerrank.algorithms.warmup; - -import java.util.HashMap; -import java.util.Map; -import java.util.Scanner; - -/** - * Created by IntelliJ IDEA. - * User: rampatra - * Date: 2/28/15 - * Time: 12:16 PM - * To change this template go to Preferences | IDE Settings | File and Code Templates - */ -public class LonelyInteger { - - static int lonelyInteger(int[] a) { - - Map map = new HashMap<>(); - for (int i : a) { - map.put(i, map.get(i) == null ? 1 : map.get(i) + 1); - } - - for (Map.Entry entry : map.entrySet()) { - if (entry.getValue() == 1) { - return entry.getKey(); - } - } - - return 1; - } - - public static void main(String[] args) { - Scanner in = new Scanner(System.in); - int res; - - int _a_size = Integer.parseInt(in.nextLine()); - int[] _a = new int[_a_size]; - int _a_item; - String next = in.nextLine(); - String[] next_split = next.split(" "); - - for (int _a_i = 0; _a_i < _a_size; _a_i++) { - _a_item = Integer.parseInt(next_split[_a_i]); - _a[_a_i] = _a_item; - } - - res = lonelyInteger(_a); - System.out.println(res); - } -} diff --git a/src/main/java/com/hackerrank/algorithms/warmup/LoveLetterMystery.java b/src/main/java/com/hackerrank/algorithms/warmup/LoveLetterMystery.java deleted file mode 100644 index 8855498c..00000000 --- a/src/main/java/com/hackerrank/algorithms/warmup/LoveLetterMystery.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.hackerrank.algorithms.warmup; - -import java.util.Scanner; - -/** - * Created by IntelliJ IDEA. - * User: rampatra - * Date: 3/17/15 - * Time: 3:22 PM - * To change this template go to Preferences | IDE Settings | File and Code Templates - */ -public class LoveLetterMystery { - static int calcPalindromeSteps(String s) { - int steps = 0, length = s.length(), a, b; - for (int i = 0, j = length - 1; i < length / 2; i++, j--) { - if ((a = (int) s.charAt(i)) != (b = (int) s.charAt(j))) { - steps += Math.abs(a - b); - } - } - return steps; - } - - public static void main(String[] args) { - Scanner in = new Scanner(System.in); - - int t = in.nextInt(); - String s[] = new String[t]; - - for (int i = 0; i < t; i++) { - s[i] = in.next(); - } - - for (int i = 0; i < t; i++) { - System.out.println(calcPalindromeSteps(s[i])); - } - } -} diff --git a/src/main/java/com/hackerrank/algorithms/warmup/MaximizingXor.java b/src/main/java/com/hackerrank/algorithms/warmup/MaximizingXor.java deleted file mode 100644 index 2b0cc0ab..00000000 --- a/src/main/java/com/hackerrank/algorithms/warmup/MaximizingXor.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.hackerrank.algorithms.warmup; - -import java.util.Scanner; -import java.util.TreeSet; - -/** - * Created by IntelliJ IDEA. - * User: rampatra - * Date: 3/7/15 - * Time: 11:07 AM - * To change this template go to Preferences | IDE Settings | File and Code Templates - */ -public class MaximizingXor { - - static int maxXor(int l, int r) { - TreeSet res = new TreeSet(); - for (int i = l; i <= r; i++) { - for (int j = i; j <= r; j++) { - res.add(i ^ j); - } - } - return (int) res.last(); - } - - public static void main(String[] args) { - Scanner in = new Scanner(System.in); - int res; - int _l; - _l = Integer.parseInt(in.nextLine()); - - int _r; - _r = Integer.parseInt(in.nextLine()); - - res = maxXor(_l, _r); - System.out.println(res); - - } -} diff --git a/src/main/java/com/hackerrank/algorithms/warmup/UtopianTree.java b/src/main/java/com/hackerrank/algorithms/warmup/UtopianTree.java deleted file mode 100644 index 43e455c2..00000000 --- a/src/main/java/com/hackerrank/algorithms/warmup/UtopianTree.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.hackerrank.algorithms.warmup; - -import java.util.Scanner; - -/** - * Created by IntelliJ IDEA. - * User: rampatra - * Date: 3/1/15 - * Time: 3:07 PM - * To change this template go to Preferences | IDE Settings | File and Code Templates - */ -public class UtopianTree { - static int calcHeight(int growthCycles) { - int h = 1; - - for (int i = 1; i <= growthCycles; i++) { - if (i % 2 != 0) - h *= 2; - else - h += 1; - } - - return h; - } - - public static void main(String[] args) { - Scanner in = new Scanner(System.in); - - int t = in.nextInt(); - int n[] = new int[t]; - - for (int i = 0; i < t; i++) { - n[i] = in.nextInt(); - } - - for (int i = 0; i < t; i++) { - System.out.println(calcHeight(n[i])); - } - } -} diff --git a/src/main/java/com/hackerrank/bitmanipulation/CounterGame.java b/src/main/java/com/hackerrank/bitmanipulation/CounterGame.java deleted file mode 100644 index b2a03e21..00000000 --- a/src/main/java/com/hackerrank/bitmanipulation/CounterGame.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.hackerrank.bitmanipulation; - -import java.math.BigInteger; -import java.util.Scanner; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/24/15 - * @time: 12:03 PM - */ -public class CounterGame { - - public static boolean isPowerOf2(BigInteger n) { - return !n.equals(BigInteger.ZERO) && (n.and(n.subtract(BigInteger.ONE))).equals(BigInteger.ZERO); - } - - public static BigInteger nextLowerPowerOf2(BigInteger n) { - BigInteger p = BigInteger.ONE; - while (p.compareTo(n) == -1) { - p = p.shiftLeft(1); - } - return (n.compareTo(BigInteger.ONE) == 1) ? p.shiftRight(1) : n; // check for n = 0 or 1; - } - - public static String computeWinner(BigInteger n) { - boolean louiseTurn = true; - while (!n.equals(BigInteger.ONE)) { - if (isPowerOf2(n)) { - n = n.shiftRight(1); - } else { - n = n.subtract(nextLowerPowerOf2(n)); - } - louiseTurn = !louiseTurn; - } - return (louiseTurn) ? "Richard" : "Louise"; - } - - public static void main(String[] args) { - Scanner in = new Scanner(System.in); - - int t = Integer.parseInt(in.nextLine()); - BigInteger[] in_ar = new BigInteger[t]; - - for (int i = 0; i < t; i++) { - in_ar[i] = in.nextBigInteger(); - } - - for (BigInteger i : in_ar) { - System.out.println(computeWinner(i)); - } - } -} diff --git a/src/main/java/com/hackerrank/bitmanipulation/Solution.java b/src/main/java/com/hackerrank/bitmanipulation/Solution.java deleted file mode 100644 index d07b9f37..00000000 --- a/src/main/java/com/hackerrank/bitmanipulation/Solution.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.hackerrank.bitmanipulation; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; - -/** - * Created by IntelliJ IDEA. - * - * @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[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; - } - } - - 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--) { - 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; - sb.append(bits + "\n"); - } - System.out.print(sb); - } - - //Bit count in number - private static int getHammingWeight(int n) { - byte count = 0; - while (n != 0) { - count++; - n &= n - 1; - } - return count; - } - - //Bit count to number, inclusive - private static long bitCountToNum(int n) { - long count = 0; - for (byte b = BITS; n != 0; ) { - int x = 1 << --b; - if ((n & x) != 0) { - n &= ~x; - count += BIT_COUNT_TO_BIT[b] + n; - } - } - return count; - } -} diff --git a/src/main/java/com/hackerrank/bitmanipulation/TwosCompliment.java b/src/main/java/com/hackerrank/bitmanipulation/TwosCompliment.java deleted file mode 100644 index 0bfdc29f..00000000 --- a/src/main/java/com/hackerrank/bitmanipulation/TwosCompliment.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.hackerrank.bitmanipulation; - -import java.util.Scanner; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/24/15 - * @time: 10:25 PM - */ -public class TwosCompliment { - - public static long countSetBitsInRange(int start, int end) { - int count = 0; - for (int i = start; i <= end; i++) { - count += Integer.bitCount(i); - } - return count; - } - - public static void main(String[] args) { - Scanner in = new Scanner(System.in); - - int t = Integer.parseInt(in.nextLine()); - String[][] in_ar = new String[t][2]; - - for (int i = 0; i < t; i++) { - in_ar[i] = in.nextLine().split(" "); - } - - for (String[] i : in_ar) { - System.out.println(countSetBitsInRange(Integer.parseInt(i[0]), Integer.parseInt(i[1]))); - } - } -} diff --git a/src/main/java/com/hackerrank/contests/SwappingInAnArray.java b/src/main/java/com/hackerrank/contests/SwappingInAnArray.java deleted file mode 100644 index d21866d8..00000000 --- a/src/main/java/com/hackerrank/contests/SwappingInAnArray.java +++ /dev/null @@ -1,75 +0,0 @@ -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 deleted file mode 100644 index ba7a2fe6..00000000 --- a/src/main/java/com/hackerrank/interviewpreparation/arrays/DS2DArrayProblem.java +++ /dev/null @@ -1,55 +0,0 @@ -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 deleted file mode 100644 index a065be9d..00000000 --- a/src/main/java/com/hackerrank/interviewpreparation/arrays/NewYearChaos.java +++ /dev/null @@ -1,56 +0,0 @@ -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 deleted file mode 100644 index 3cf74165..00000000 --- a/src/main/java/com/hackerrank/interviewpreparation/greedyalgorithmns/LuckBalance.java +++ /dev/null @@ -1,77 +0,0 @@ -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 lucksForImportantContests = new ArrayList<>(); - for (int i = 0; i < contests.length; i++) { - if (contests[i][1] == 1) { - lucksForImportantContests.add(contests[i][0]); - } else { - lucks += contests[i][0]; - } - } - lucksForImportantContests.sort(Collections.reverseOrder()); - for (int i = 0; i < lucksForImportantContests.size(); i++) { - if (i < k) { // can lose at most k of the important contests - lucks += lucksForImportantContests.get(i); - } else { - lucks -= lucksForImportantContests.get(i); - } - } - return lucks; - } - - 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(" "); - - int n = Integer.parseInt(nk[0]); - - int k = Integer.parseInt(nk[1]); - - int[][] contests = new int[n][2]; - - for (int i = 0; i < n; i++) { - String[] contestsRowItems = scanner.nextLine().split(" "); - scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?"); - - for (int j = 0; j < 2; j++) { - int contestsItem = Integer.parseInt(contestsRowItems[j]); - contests[i][j] = contestsItem; - } - } - - int result = luckBalance(k, contests); - - bufferedWriter.write(String.valueOf(result)); - bufferedWriter.newLine(); - - bufferedWriter.close(); - - scanner.close(); - } -} diff --git a/src/main/java/com/hackerrank/interviewpreparation/greedyalgorithmns/MinimumAbsoluteDifference.java b/src/main/java/com/hackerrank/interviewpreparation/greedyalgorithmns/MinimumAbsoluteDifference.java deleted file mode 100644 index 6cff867b..00000000 --- a/src/main/java/com/hackerrank/interviewpreparation/greedyalgorithmns/MinimumAbsoluteDifference.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.hackerrank.interviewpreparation.greedyalgorithmns; - -import java.io.BufferedWriter; -import java.io.FileWriter; -import java.io.IOException; -import java.util.Arrays; -import java.util.Scanner; - -/** - * @author rpatra16 - * @since 04/11/2018 - */ -public class MinimumAbsoluteDifference { - - /** - * Finds the minimum absolute difference in the array. - * - * @param a input array - * @return the minimum absolute difference between any two different elements in the array a - */ - static int minimumAbsoluteDifference(int[] a) { - int minDiff = Integer.MAX_VALUE, diff; - Arrays.sort(a); - for (int i = 0; i < a.length - 1; i++) { - if ((diff = Math.abs(a[i] - a[i + 1])) < minDiff) { - minDiff = diff; - } - } - return minDiff; - } - - 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[] arr = new int[n]; - - String[] arrItems = scanner.nextLine().split(" "); - scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?"); - - for (int i = 0; i < n; i++) { - int arrItem = Integer.parseInt(arrItems[i]); - arr[i] = arrItem; - } - - int result = minimumAbsoluteDifference(arr); - - bufferedWriter.write(String.valueOf(result)); - bufferedWriter.newLine(); - - bufferedWriter.close(); - - scanner.close(); - } -} diff --git a/src/main/java/com/hackerrank/interviewpreparation/warmup/JumpingClouds.java b/src/main/java/com/hackerrank/interviewpreparation/warmup/JumpingClouds.java deleted file mode 100644 index 36cab3dc..00000000 --- a/src/main/java/com/hackerrank/interviewpreparation/warmup/JumpingClouds.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.hackerrank.interviewpreparation.warmup; - -import java.io.BufferedWriter; -import java.io.FileWriter; -import java.io.IOException; -import java.util.Scanner; - -/** - * @author rpatra16 - * @since 31/10/2018 - */ -public class JumpingClouds { - - private static final Scanner scanner = new Scanner(System.in); - - private static int jumpingOnClouds(int[] c) { - int jumps = 0; - int i = 0; - while (i < c.length) { - if (((i + 2) < c.length) && c[i + 2] != 1) { - i += 2; - } else if (((i + 1) < c.length) && c[i + 1] != 1) { - i += 1; - } - jumps++; - if (i == c.length - 1) { - break; - } - } - return jumps; - } - - 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[] c = new int[n]; - - String[] cItems = scanner.nextLine().split(" "); - scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?"); - - for (int i = 0; i < n; i++) { - int cItem = Integer.parseInt(cItems[i]); - c[i] = cItem; - } - - int result = jumpingOnClouds(c); - - bufferedWriter.write(String.valueOf(result)); - bufferedWriter.newLine(); - - bufferedWriter.close(); - - scanner.close(); - } -} diff --git a/src/main/java/com/hackerrank/interviewpreparation/warmup/RepeatedString.java b/src/main/java/com/hackerrank/interviewpreparation/warmup/RepeatedString.java deleted file mode 100644 index 63b4ffba..00000000 --- a/src/main/java/com/hackerrank/interviewpreparation/warmup/RepeatedString.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.hackerrank.interviewpreparation.warmup; - -import java.io.BufferedWriter; -import java.io.FileWriter; -import java.io.IOException; -import java.util.Scanner; - -/** - * Repeated String problem. - * - * @author rpatra16 - * @since 29/10/2018 - */ -public class RepeatedString { - - private static final Scanner scanner = new Scanner(System.in); - - private static long repeatedString(String s, long n) { - int extraLetters; - long totalCount = 0, count = 0, stringLength = s.length(); - // count the no of a in non-repeated string - for (int i = 0; i < stringLength; i++) { - if (s.charAt(i) == 'a') { - count++; - } - } - totalCount += (n / stringLength * count); - extraLetters = (int) (n % stringLength); - // count the no of a in the remainder of the string - for (int i = 0; i < extraLetters; i++) { - if (s.charAt(i) == 'a') { - totalCount++; - } - } - return totalCount; - } - - public static void main(String[] args) throws IOException { - BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(System.getenv("OUTPUT_PATH"))); - - String s = scanner.nextLine(); - - long n = scanner.nextLong(); - scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?"); - - long result = repeatedString(s, n); - - bufferedWriter.write(String.valueOf(result)); - bufferedWriter.newLine(); - - bufferedWriter.close(); - - scanner.close(); - } -} - diff --git a/src/main/java/com/hackerrank/java/advanced/JavaVisitorPattern.java b/src/main/java/com/hackerrank/java/advanced/JavaVisitorPattern.java deleted file mode 100644 index 5f91e9b5..00000000 --- a/src/main/java/com/hackerrank/java/advanced/JavaVisitorPattern.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.hackerrank.java.advanced; - -import java.util.*; - -/** - * Level: Medium - * Problem Link: https://www.hackerrank.com/challenges/java-vistor-pattern/ - * - * @author rampatra - * @since 2019-06-22 - */ -enum Color { - RED, GREEN -} - -abstract class Tree { - - private int value; - private Color color; - private int depth; - - public Tree(int value, Color color, int depth) { - this.value = value; - this.color = color; - this.depth = depth; - } - - public int getValue() { - return value; - } - - public Color getColor() { - return color; - } - - public int getDepth() { - return depth; - } - - public abstract void accept(TreeVis visitor); - - -} - -class TreeNode extends Tree { - - private ArrayList children = new ArrayList<>(); - - public TreeNode(int value, Color color, int depth) { - super(value, color, depth); - } - - public void accept(TreeVis visitor) { - visitor.visitNode(this); - - for (Tree child : children) { - child.accept(visitor); - } - } - - public void addChild(Tree child) { - children.add(child); - } -} - -class TreeLeaf extends Tree { - - public TreeLeaf(int value, Color color, int depth) { - super(value, color, depth); - } - - public void accept(TreeVis visitor) { - visitor.visitLeaf(this); - } -} - -abstract class TreeVis { - public abstract int getResult(); - - public abstract void visitNode(TreeNode node); - - public abstract void visitLeaf(TreeLeaf leaf); - -} - -class SumInLeavesVisitor extends TreeVis { - int nodeSum = 0; - int leafSum = 0; - - public int getResult() { - //implement this - return leafSum; - } - - public void visitNode(TreeNode node) { - //implement this - //nodeSum += node.getValue(); - } - - public void visitLeaf(TreeLeaf leaf) { - //implement this - leafSum += leaf.getValue(); - } -} - -class ProductOfRedNodesVisitor extends TreeVis { - int prodOfRedNodesAndLeaves = 1; - private final int M = 1000000007; - - public int getResult() { - //implement this - return prodOfRedNodesAndLeaves; - } - - public void visitNode(TreeNode node) { - //implement this - if (node.getColor() == Color.RED) { - prodOfRedNodesAndLeaves *= (node.getValue() % M); - } - } - - public void visitLeaf(TreeLeaf leaf) { - //implement this - if (leaf.getColor() == Color.RED) { - prodOfRedNodesAndLeaves *= (leaf.getValue() % M); - } - } -} - -class FancyVisitor extends TreeVis { - int sumOfNodesAtEvenDepth = 0; - int sumOfGreenLeaves = 0; - - public int getResult() { - //implement this - return Math.abs(sumOfNodesAtEvenDepth - sumOfGreenLeaves); - } - - public void visitNode(TreeNode node) { - //implement this - if (node.getDepth() % 2 == 0) { - sumOfNodesAtEvenDepth += node.getValue(); - } - } - - public void visitLeaf(TreeLeaf leaf) { - //implement this - if (leaf.getColor() == Color.GREEN) { - sumOfGreenLeaves += leaf.getValue(); - } - } -} - -public class JavaVisitorPattern { - - public static Tree solve() { - //read the tree from STDIN and return its root as a return value of this function - Scanner s = new Scanner(System.in); - - int numOfNodes = s.nextInt(); - int[] nodeValues = new int[numOfNodes]; - int[] nodeColors = new int[numOfNodes]; - Map> parentToChildMap = new HashMap<>(); - Map childToParentMap = new HashMap<>(); - - for (int i = 0; i < numOfNodes; i++) { - nodeValues[i] = s.nextInt(); - } - for (int i = 0; i < numOfNodes; i++) { - nodeColors[i] = s.nextInt(); - } - for (int i = 0; i < numOfNodes - 1; i++) { - int parentIndex = s.nextInt(); - int childIndex = s.nextInt(); - - Set children = parentToChildMap.get(parentIndex - 1) != null ? parentToChildMap.get(parentIndex - 1) : new HashSet<>(); - children.add(childIndex - 1); - parentToChildMap.put(parentIndex - 1, children); - childToParentMap.put(childIndex - 1, parentIndex - 1); - } - - List nodes = new ArrayList<>(numOfNodes); - for (int i = 0; i < numOfNodes; i++) { - - int depth = childToParentMap.get(i) == null ? -1 : nodes.get(childToParentMap.get(i)).getDepth(); - - if (parentToChildMap.get(i) != null) { - nodes.add(new TreeNode(nodeValues[i], nodeColors[i] == 0 ? Color.RED : Color.GREEN, depth + 1)); - } else { - nodes.add(new TreeLeaf(nodeValues[i], nodeColors[i] == 0 ? Color.RED : Color.GREEN, depth + 1)); - } - } - - - for (Map.Entry> entry : parentToChildMap.entrySet()) { - - TreeNode parent = (TreeNode) nodes.get(entry.getKey()); - - for (Integer childIndex : entry.getValue()) { - parent.addChild(nodes.get(childIndex)); - } - } - - return nodes.get(0); - } - - - public static void main(String[] args) { - Tree root = solve(); - SumInLeavesVisitor vis1 = new SumInLeavesVisitor(); - ProductOfRedNodesVisitor vis2 = new ProductOfRedNodesVisitor(); - FancyVisitor vis3 = new FancyVisitor(); - - root.accept(vis1); - root.accept(vis2); - root.accept(vis3); - - int res1 = vis1.getResult(); - int res2 = vis2.getResult(); - int res3 = vis3.getResult(); - - System.out.println(res1); - System.out.println(res2); - System.out.println(res3); - } -} \ No newline at end of file diff --git a/src/main/java/com/hackerrank/java/bignumber/BigDecimal.java b/src/main/java/com/hackerrank/java/bignumber/BigDecimal.java deleted file mode 100644 index 7e1b804e..00000000 --- a/src/main/java/com/hackerrank/java/bignumber/BigDecimal.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.hackerrank.java.bignumber; - -import java.util.Arrays; -import java.util.List; -import java.util.Scanner; - -/** - * Problem Link: https://www.hackerrank.com/challenges/java-bigdecimal/ - * - * @author rampatra - * @since 2019-06-22 - */ -class BigDecimal { - public static void main(String[] args) { - //Input - Scanner sc = new Scanner(System.in); - int n = sc.nextInt(); - String[] s = new String[n + 2]; - for (int i = 0; i < n; i++) { - s[i] = sc.next(); - } - sc.close(); - - //Write your code here - s = Arrays.copyOfRange(s, 0, s.length - 2); - List input = Arrays.asList(s); - Arrays.sort(s, (s1, s2) -> { - int compare = new java.math.BigDecimal(s2).compareTo(new java.math.BigDecimal(s1)); - if (compare == 0) { - return Integer.compare(input.indexOf(s1), input.indexOf(s2)); - } - return compare; - }); - - //Output - for (int i = 0; i < n; i++) { - System.out.println(s[i]); - } - } -} \ No newline at end of file diff --git a/src/main/java/com/hackerrank/java/oops/JavaInheritance.java b/src/main/java/com/hackerrank/java/oops/JavaInheritance.java deleted file mode 100644 index b8d0d9e4..00000000 --- a/src/main/java/com/hackerrank/java/oops/JavaInheritance.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.hackerrank.java.oops; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/19/15 - * @time: 3:36 PM - */ -public class JavaInheritance { - - public void JavaInheritance() { - - } - - public static void main(String[] args) { - - } -} - - -class Arithmetic { - -} - -class Adder extends Arithmetic { - int add(int a, int b) { - return a + b; - } -} diff --git a/src/main/java/com/hackerrank/projecteuler/MultiplesOf3and5.java b/src/main/java/com/hackerrank/projecteuler/MultiplesOf3and5.java deleted file mode 100644 index f56da78e..00000000 --- a/src/main/java/com/hackerrank/projecteuler/MultiplesOf3and5.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.hackerrank.projecteuler; - -import java.util.Scanner; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 1/1/16 - * @time: 8:48 AM - */ -public class MultiplesOf3and5 { - - 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/tutorials/ctci/QueuesWithTwoStacks.java b/src/main/java/com/hackerrank/tutorials/ctci/QueuesWithTwoStacks.java deleted file mode 100644 index 333ecd1d..00000000 --- a/src/main/java/com/hackerrank/tutorials/ctci/QueuesWithTwoStacks.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.hackerrank.tutorials.ctci; - -import java.util.Scanner; -import java.util.Stack; - -/** - * Question: https://www.hackerrank.com/challenges/ctci-queue-using-two-stacks - * Level: Medium - * - * @author rampatra - * @version 07/10/2016 - */ -public class QueuesWithTwoStacks { - - public static class MyQueue { - Stack stackNewestOnTop = new Stack(); - Stack stackOldestOnTop = new Stack(); - - public void enqueue(T value) { // Push onto newest stack - stackNewestOnTop.push(value); - } - - public T peek() { - return stackOldestOnTop.isEmpty() ? stackNewestOnTop.firstElement() : stackOldestOnTop.peek(); - } - - public T dequeue() { - if (stackOldestOnTop.isEmpty()) { - while (!stackNewestOnTop.isEmpty()) { - stackOldestOnTop.push(stackNewestOnTop.pop()); - } - } - return stackOldestOnTop.pop(); - } - } - - - public static void main(String[] args) { - MyQueue queue = new MyQueue<>(); - - Scanner scan = new Scanner(System.in); - int n = scan.nextInt(); - - for (int i = 0; i < n; i++) { - int operation = scan.nextInt(); - if (operation == 1) { // enqueue - queue.enqueue(scan.nextInt()); - } else if (operation == 2) { // dequeue - queue.dequeue(); - } else if (operation == 3) { // print/peek - System.out.println(queue.peek()); - } - } - scan.close(); - } -} diff --git a/src/main/java/com/hackerrank/tutorials/ctci/RansomNote.java b/src/main/java/com/hackerrank/tutorials/ctci/RansomNote.java deleted file mode 100644 index b0d45c75..00000000 --- a/src/main/java/com/hackerrank/tutorials/ctci/RansomNote.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.hackerrank.tutorials.ctci; - -import java.util.HashMap; -import java.util.Map; -import java.util.Scanner; - -/** - * Question: https://www.hackerrank.com/challenges/ctci-ransom-note - * Level: Easy - * - * @author rampatra - * @version 30/09/2016 - */ -public class RansomNote { - - Map magazineMap; - Map noteMap; - - public RansomNote(String magazine, String note) { - - magazineMap = new HashMap<>(); - noteMap = new HashMap<>(); - String[] magazineWords = magazine.split(" "); - String[] noteWords = note.split(" "); - Integer c; - - for (int i = 0; i < magazineWords.length; i++) { - if ((c = magazineMap.get(magazineWords[i])) == null) { - magazineMap.put(magazineWords[i], 1); - } else { - magazineMap.put(magazineWords[i], c + 1); - } - } - - for (int i = 0; i < noteWords.length; i++) { - if ((c = noteMap.get(noteWords[i])) == null) { - noteMap.put(noteWords[i], 1); - } else { - noteMap.put(noteWords[i], c + 1); - } - } - } - - public boolean solve() { - for (Map.Entry entry : noteMap.entrySet()) { - if (magazineMap.get(entry.getKey()) == null || magazineMap.get(entry.getKey()) - entry.getValue() < 0) { - return false; - } - } - return true; - } - - public static void main(String[] args) { - Scanner scanner = new Scanner(System.in); - int m = scanner.nextInt(); - int n = scanner.nextInt(); - - // Eat whitespace to beginning of next line - scanner.nextLine(); - - RansomNote s = new RansomNote(scanner.nextLine(), scanner.nextLine()); - scanner.close(); - - if (s.solve()) { - System.out.println("Yes"); - } else { - System.out.println("No"); - } - } -} diff --git a/src/main/java/com/heaps/FindMedianFromDataStream.java b/src/main/java/com/heaps/FindMedianFromDataStream.java new file mode 100644 index 00000000..8c46d39a --- /dev/null +++ b/src/main/java/com/heaps/FindMedianFromDataStream.java @@ -0,0 +1,59 @@ +package com.heaps; + +import java.util.Collections; +import java.util.Comparator; +import java.util.PriorityQueue; + +/** + * Median is the middle value in an ordered integer list. + * If the size of the list is even, there is no middle value. So the median is the mean of the two middle value. + *

+ * First of all, it seems that the best time complexity we can get for this problem is O(log(n)) of add() and O(1) of getMedian(). + * This data structure seems highly likely to be a tree. + * O(log(n)) of add() and O(1) of getMedian() + */ +class FindMedianFromDataStream { + + PriorityQueue minHeap = null; + PriorityQueue maxHeap = null; + + /** + * initialize your data structure here. + */ + public FindMedianFromDataStream() { + minHeap = new PriorityQueue<>(); + maxHeap = new PriorityQueue<>(Comparator.reverseOrder()); + } + + public void addNum(int num) { + minHeap.offer(num); /** Step 1- Each element is first added to minHeap First */ + maxHeap.offer(minHeap.poll()); /** Step 2- Minimum element is poped put and offered to MaxHeap . + This assures all the elements in minHeap are greater than maxHeap */ + + if (minHeap.size() < maxHeap.size()) { /** Step 3- The two heaps need to be laod balanced */ + minHeap.offer(maxHeap.poll()); + } + } + + public double findMedian() { + if (minHeap.size() > maxHeap.size()) { /** Odd num of total elements */ + return minHeap.peek(); + } else { + return (minHeap.peek() + maxHeap.peek()) / 2.0; /** Even num of total elements */ + } + } + + public static void main(String[] args) { + FindMedianFromDataStream stream = new FindMedianFromDataStream(); + + stream.addNum(2); + stream.addNum(5); + stream.addNum(8); + stream.addNum(18); + stream.addNum(20); + stream.addNum(28); + + System.out.println("Median " + stream.findMedian()); + } +} + diff --git a/src/main/java/com/heaps/FindMedianFromDataStream.jpg b/src/main/java/com/heaps/FindMedianFromDataStream.jpg new file mode 100644 index 00000000..0ea46f22 Binary files /dev/null and b/src/main/java/com/heaps/FindMedianFromDataStream.jpg differ diff --git a/src/main/java/com/heaps/KthLargestElement.java b/src/main/java/com/heaps/KthLargestElement.java new file mode 100644 index 00000000..4e253650 --- /dev/null +++ b/src/main/java/com/heaps/KthLargestElement.java @@ -0,0 +1,37 @@ +package com.heaps; + +import java.util.PriorityQueue; + +/** + +Link to priority Queue - +https://onedrive.live.com/redir?resid=26052E8C3C647484%21105&page=Edit&wd=target%28Queue.one%7C71d394a6-f4c4-41dd-b56a-e1878e78a88a%2FPriorityQueue%7C27bf58ff-75e1-4c3a-aa71-2823e1ff846b%2F%29&wdorigin=703 + +An Efficient Solution is to use Min Heap of size k to store k largest elements of the stream. +The k’th largest element is always at root and can be found in O(1) time. + +Time complexity of finding the k’th largest element is O(Logk). + + */ +public class KthLargestElement { + + public static int findKthLargest(int arr[], int k) { + PriorityQueue minHeap = new PriorityQueue<>(); + for (int num : arr) { + minHeap.add(num); + if (minHeap.size() > k) { + + //this will remove the element from root since its minHeap it will remove minimum element. + //this will rearrange the elements back in proper heap with min element on root. + minHeap.remove(); + } + } + return minHeap.remove(); + } + + public static void main(String args[]) { + int arr[] = {10, 70, 20, 30, 50, 80}; + int result = findKthLargest(arr, 2); + System.out.println(result); + } +} diff --git a/src/main/java/com/heaps/KthSmallestElement.java b/src/main/java/com/heaps/KthSmallestElement.java new file mode 100644 index 00000000..5cca239e --- /dev/null +++ b/src/main/java/com/heaps/KthSmallestElement.java @@ -0,0 +1,46 @@ +package com.heaps; + +import java.util.PriorityQueue; + + +/* + +Example: + +int[] A = { 1, 2, 10, 20, 40, 32, 44, 51, 6 }; + +K=4. 4th smallest element in given array: 10 + +Approach: (Kth Smallest Element) + Use min-Heap. (Click here to read about Priority Queue). + Insert all the elements in the Priority Queue. + Extract K elements from the priority queue. + The last element (kth) extracted with be the kth smallest element in the array. + +Link to priority Queue - +https://onedrive.live.com/redir?resid=26052E8C3C647484%21105&page=Edit&wd=target%28Queue.one%7C71d394a6-f4c4-41dd-b56a-e1878e78a88a%2FPriorityQueue%7C27bf58ff-75e1-4c3a-aa71-2823e1ff846b%2F%29 + + +*/ +public class KthSmallestElement { + + public static int findKthSmallest(int arr[], int k) { + PriorityQueue minHeap = new PriorityQueue<>(); + for (int num : arr) { + minHeap.add(num); + } + int n = -1; + while(k>0){ + n = minHeap.poll(); + k--; + } + + return n; + } + + public static void main(String args[]) { + int arr[] = {10, 70, 20, 30, 50, 80}; + int result = findKthSmallest(arr, 5); + System.out.println(result); + } +} diff --git a/src/main/java/com/leetcode/arrays/BuySellStocks.java b/src/main/java/com/leetcode/arrays/BuySellStocks.java deleted file mode 100644 index 4d4ba02b..00000000 --- a/src/main/java/com/leetcode/arrays/BuySellStocks.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.leetcode.arrays; - -/** - * Level: Easy - * Link: https://leetcode.com/problems/best-time-to-buy-and-sell-stock/ - * Description: - * Say you have an array for which the ith element is the price of a given stock on day i. - * - * If you were only permitted to complete at most one transaction (i.e., buy one and sell one share of the stock), - * design an algorithm to find the maximum profit. - * - * Note that you cannot sell a stock before you buy one. - * - * Example 1: - * - * Input: [7,1,5,3,6,4] - * Output: 5 - * Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5. - * Not 7-1 = 6, as selling price needs to be larger than buying price. - * - * Example 2: - * - * Input: [7,6,4,3,1] - * Output: 0 - * Explanation: In this case, no transaction is done, i.e. max profit = 0. - * - * @author rampatra - * @since 2019-04-23 - */ -public class BuySellStocks { - - /** - * Time complexity: O(n) - * where, - * n = no. of stock prices - *

- * Runtime: 0 ms. - * - * @param prices - * @return - */ - public static int maxProfit(int[] prices) { - int profit = 0; - int buyPrice = Integer.MAX_VALUE; - - for (int i = 0; i < prices.length; i++) { - if (prices[i] < buyPrice) { - buyPrice = prices[i]; - } else if (prices[i] - buyPrice > profit) { - profit = prices[i] - buyPrice; - } - } - - return profit; - } - - public static void main(String[] args) { - - System.out.println(maxProfit(new int[]{7, 1, 5, 3, 6, 4})); - System.out.println(maxProfit(new int[]{7, 1, 5, 0, 6, 4})); - System.out.println(maxProfit(new int[]{4, 3, 2, 1})); - - // edge cases - System.out.println(maxProfit(new int[]{})); - System.out.println(maxProfit(new int[]{1})); - } -} \ No newline at end of file diff --git a/src/main/java/com/leetcode/arrays/BuySellStocksII.java b/src/main/java/com/leetcode/arrays/BuySellStocksII.java deleted file mode 100644 index d215246e..00000000 --- a/src/main/java/com/leetcode/arrays/BuySellStocksII.java +++ /dev/null @@ -1,94 +0,0 @@ -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 deleted file mode 100644 index 916499ac..00000000 --- a/src/main/java/com/leetcode/arrays/CanPlaceFlowers.java +++ /dev/null @@ -1,68 +0,0 @@ -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 deleted file mode 100644 index 1b15d996..00000000 --- a/src/main/java/com/leetcode/arrays/FindTheCelebrity.java +++ /dev/null @@ -1,105 +0,0 @@ -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 deleted file mode 100644 index 52155f19..00000000 --- a/src/main/java/com/leetcode/arrays/InsertInterval.java +++ /dev/null @@ -1,78 +0,0 @@ -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 deleted file mode 100644 index 2ccdd116..00000000 --- a/src/main/java/com/leetcode/arrays/MajorityElement.java +++ /dev/null @@ -1,47 +0,0 @@ -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 deleted file mode 100644 index 58f56ebc..00000000 --- a/src/main/java/com/leetcode/arrays/MergeIntervals.java +++ /dev/null @@ -1,78 +0,0 @@ -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 { - @Override - public int compare(int[] interval1, int[] interval2) { - return interval1[0] - interval2[0]; - } - } - - public static void main(String[] args) { - System.out.println(Arrays.deepToString(merge(new int[][]{{1, 3}, {2, 6}, {8, 10}, {15, 18}}))); - System.out.println(Arrays.deepToString(merge(new int[][]{{1, 4}, {4, 5}}))); - } -} \ No newline at end of file diff --git a/src/main/java/com/leetcode/arrays/MergeSortedArray.java b/src/main/java/com/leetcode/arrays/MergeSortedArray.java deleted file mode 100644 index 975db8ec..00000000 --- a/src/main/java/com/leetcode/arrays/MergeSortedArray.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.leetcode.arrays; - -import java.util.Arrays; - -/** - * Level: Easy - * Link: https://leetcode.com/problems/merge-sorted-array/ - * Description: - * Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. - * - * Note: - * The number of elements initialized in nums1 and nums2 are m and n respectively. - * You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold - * additional elements from nums2. - * - * Example: - * Input: - * nums1 = [1,2,3,0,0,0], m = 3 - * nums2 = [2,5,6], n = 3 - * Output: [1,2,2,3,5,6] - * - * @author rampatra - * @since 2019-04-26 - */ -public class MergeSortedArray { - - /** - * Time complexity: O(m*n) - * Runtime: 1 ms. - * - * @param nums1 - * @param m - * @param nums2 - * @param n - */ - public static void mergeSimple(int[] nums1, int m, int[] nums2, int n) { - int i = 0; - - for (int j = 0; j < n; j++) { - // find the index where the element from nums2 need to be inserted - while (i < m + j && nums1[i] < nums2[j]) { - i++; - } - // copy elements from i+1th position to one position right - for (int k = m + j; k > i; k--) { // note: replacing this with System.arraycopy() gives a 0 ms runtime - nums1[k] = nums1[k - 1]; - } - nums1[i] = nums2[j]; - } - } - - /** - * Time complexity: O(m+n) - * Runtime: 0 ms. - * - * @param nums1 - * @param m - * @param nums2 - * @param n - */ - public static void merge(int[] nums1, int m, int[] nums2, int n) { - for (int i = m + n - 1; i >= 0; i--) { - if (m == 0) { - nums1[i] = nums2[--n]; - } else if (n == 0) { // we ran out of nums2 elements so there is nothing left to merge - return; - } else if (nums1[m - 1] > nums2[n - 1]) { - nums1[i] = nums1[--m]; - } else { - nums1[i] = nums2[--n]; - } - } - } - - public static void main(String[] args) { - int[] nums1 = {1, 2, 3, 0, 0, 0}; - int[] nums2 = {4, 5, 6}; - merge(nums1, 3, nums2, 3); - System.out.println(Arrays.toString(nums1)); - - nums1 = new int[]{4, 5, 6, 0, 0, 0}; - nums2 = new int[]{1, 2, 3}; - merge(nums1, 3, nums2, 3); - System.out.println(Arrays.toString(nums1)); - } -} \ No newline at end of file diff --git a/src/main/java/com/leetcode/arrays/NumberOfIslands.java b/src/main/java/com/leetcode/arrays/NumberOfIslands.java deleted file mode 100644 index 04ac6831..00000000 --- a/src/main/java/com/leetcode/arrays/NumberOfIslands.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.leetcode.arrays; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * Level: Medium - * Link: https://leetcode.com/problems/number-of-islands/ - * Description: - * Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surrounded by water - * and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid - * are all surrounded by water. - *

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

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

- * Time Complexity: O(n) - * Space Complexity: O(n) - * Runtime: 1 ms. - * - * @param grid - * @return - */ - public static int numIslands(char[][] grid) { - int count = 0; - - for (int i = 0; i < grid.length; i++) { - for (int j = 0; j < grid[0].length; j++) { - if (grid[i][j] == '1') { - drownTheIsland(grid, i, j); - count++; - } - } - } - - return count; - } - - private static void drownTheIsland(char[][] grid, int i, int j) { - if (i < 0 || j < 0 || i >= grid.length || j >= grid[0].length || grid[i][j] == '0') { - return; - } - - grid[i][j] = '0'; - - drownTheIsland(grid, i, j + 1); - drownTheIsland(grid, i, j - 1); - drownTheIsland(grid, i + 1, j); - drownTheIsland(grid, i - 1, j); - } - - public static void main(String[] args) { - assertEquals(1, numIslands(new char[][]{ - {'1', '1', '1', '1', '0'}, - {'1', '1', '0', '1', '0'}, - {'1', '1', '0', '0', '0'}, - {'0', '0', '0', '0', '0'} - })); - - assertEquals(2, numIslands(new char[][]{ - {'1', '1', '1', '1', '0'}, - {'1', '1', '0', '1', '0'}, - {'1', '1', '0', '0', '0'}, - {'0', '0', '0', '1', '0'} - })); - - assertEquals(1, numIslands(new char[][]{ - {'1', '1', '1', '1', '1'}, - {'1', '1', '1', '1', '1'}, - {'1', '1', '1', '1', '1'}, - {'1', '1', '1', '1', '1'} - })); - - assertEquals(1, numIslands(new char[][]{ - {'1'} - })); - - assertEquals(0, numIslands(new char[][]{ - {'0'} - })); - - assertEquals(0, numIslands(new char[][]{ - {} - })); - } -} \ No newline at end of file diff --git a/src/main/java/com/leetcode/arrays/PascalsTriangle.java b/src/main/java/com/leetcode/arrays/PascalsTriangle.java deleted file mode 100644 index 5f32d69f..00000000 --- a/src/main/java/com/leetcode/arrays/PascalsTriangle.java +++ /dev/null @@ -1,53 +0,0 @@ -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> generatePascalsTriangle(int numRows) { - List> pascalsTriangle = new ArrayList<>(); - - if (numRows == 0) return pascalsTriangle; - - List firstRow = new ArrayList<>(); - firstRow.add(1); - pascalsTriangle.add(firstRow); - - List prevRow; - for (int i = 1; i < numRows; i++) { - prevRow = pascalsTriangle.get(i - 1); - - List currRow = new ArrayList<>(); - currRow.add(1); - for (int j = 0; j < prevRow.size() - 1; j++) { - currRow.add(prevRow.get(j) + prevRow.get(j + 1)); - } - currRow.add(1); - - pascalsTriangle.add(currRow); - } - - return pascalsTriangle; - } - - public static void main(String[] args) { - System.out.println(generatePascalsTriangle(5)); - } -} diff --git a/src/main/java/com/leetcode/arrays/RemoveDuplicates.java b/src/main/java/com/leetcode/arrays/RemoveDuplicates.java deleted file mode 100644 index 57eba5ad..00000000 --- a/src/main/java/com/leetcode/arrays/RemoveDuplicates.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.leetcode.arrays; - -import java.util.Arrays; - -/** - * Level: Easy - * Problem Link: https://leetcode.com/problems/remove-duplicates-from-sorted-array/ - * Problem Description: - * Given a sorted array nums, remove the duplicates in-place such that each element appear only once and return the new length. - *

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

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

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

- * 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 deleted file mode 100644 index 91475160..00000000 --- a/src/main/java/com/leetcode/arrays/RotateArray.java +++ /dev/null @@ -1,93 +0,0 @@ -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 deleted file mode 100644 index 5cd0c821..00000000 --- a/src/main/java/com/leetcode/arrays/ShortestWordDistance.java +++ /dev/null @@ -1,71 +0,0 @@ -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 deleted file mode 100644 index 0d404633..00000000 --- a/src/main/java/com/leetcode/arrays/ShortestWordDistanceIII.java +++ /dev/null @@ -1,80 +0,0 @@ -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 deleted file mode 100644 index 78c884e4..00000000 --- a/src/main/java/com/leetcode/arrays/SparseMatrixMultiplication.java +++ /dev/null @@ -1,87 +0,0 @@ -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 deleted file mode 100644 index cdbfb0c5..00000000 --- a/src/main/java/com/leetcode/arrays/ValidTriangleNumber.java +++ /dev/null @@ -1,117 +0,0 @@ -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 deleted file mode 100644 index 3591c50e..00000000 --- a/src/main/java/com/leetcode/arrays/binarysearch/PowXN.java +++ /dev/null @@ -1,85 +0,0 @@ -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 deleted file mode 100644 index 2f13214a..00000000 --- a/src/main/java/com/leetcode/arrays/binarysearch/SearchInsertPosition.java +++ /dev/null @@ -1,64 +0,0 @@ -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 deleted file mode 100644 index e44dc339..00000000 --- a/src/main/java/com/leetcode/arrays/binarysearch/SmallestLetterGreaterThanTarget.java +++ /dev/null @@ -1,87 +0,0 @@ -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 deleted file mode 100644 index 0dde1308..00000000 --- a/src/main/java/com/leetcode/arrays/binarysearch/SqrtX.java +++ /dev/null @@ -1,62 +0,0 @@ -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 deleted file mode 100644 index 51f771d7..00000000 --- a/src/main/java/com/leetcode/design/AllOne.java +++ /dev/null @@ -1,125 +0,0 @@ -package com.leetcode.design; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * Level: Hard - * Link: https://leetcode.com/problems/all-oone-data-structure/ - * Description: - * Implement a data structure supporting the following operations: - * Inc(Key) - Inserts a new key with value 1. Or increments an existing key by 1. Key is guaranteed to be a non-empty - * string. - * Dec(Key) - If Key's value is 1, remove it from the data structure. Otherwise decrements an existing key by 1. If - * the key does not exist, this function does nothing. Key is guaranteed to be a non-empty string. - * GetMaxKey() - Returns one of the keys with maximal value. If no element exists, return an empty string "". - * GetMinKey() - Returns one of the keys with minimal value. If no element exists, return an empty string "". - *

- * Challenge: Perform all these in O(1) time complexity. - * - * @author rampatra - * @since 2019-08-11 - */ -public class AllOne { - - - - Map keyToValMap; - Map> valToKeyMap; - - /** - * Initialize your data structure here. - */ - public AllOne() { - keyToValMap = new HashMap<>(); - valToKeyMap = new HashMap<>(); - } - - /** - * Inserts a new key with value 1. Or increments an existing key by 1. - */ - public void inc(String key) { - - } - - /** - * Decrements an existing key by 1. If Key's value is 1, remove it from the data structure. - */ - public void dec(String key) { - - } - - /** - * Returns one of the keys with maximal value. - */ - public String getMaxKey() { - return null; - } - - /** - * Returns one of the keys with Minimal value. - */ - public String getMinKey() { - return null; - } - - public static void main(String[] args) { - AllOne allOne = new AllOne(); - allOne.inc("r"); - allOne.inc("r"); - allOne.dec("r"); - allOne.inc("a"); - allOne.inc("b"); - allOne.inc("b"); - assertEquals("b", allOne.getMaxKey()); - assertEquals("a", allOne.getMinKey()); - - allOne = new AllOne(); - allOne.dec("hello"); - assertEquals("", allOne.getMaxKey()); - - allOne = new AllOne(); - allOne.inc("a"); - allOne.inc("b"); - allOne.inc("b"); - allOne.inc("b"); - allOne.inc("b"); - allOne.dec("b"); - allOne.dec("b"); - assertEquals("b", allOne.getMaxKey()); - assertEquals("a", allOne.getMinKey()); - - allOne = new AllOne(); - allOne.inc("hello"); - allOne.inc("hello"); - assertEquals("hello", allOne.getMaxKey()); - assertEquals("hello", allOne.getMinKey()); - allOne.inc("leet"); - assertEquals("hello", allOne.getMaxKey()); - assertEquals("leet", allOne.getMinKey()); - - allOne = new AllOne(); - allOne.inc("a"); - allOne.inc("b"); - allOne.inc("b"); - allOne.inc("c"); - allOne.inc("c"); - allOne.inc("c"); - allOne.dec("b"); - allOne.dec("b"); - assertEquals("a", allOne.getMinKey()); - allOne.dec("a"); - assertEquals("c", allOne.getMaxKey()); - //assertEquals("c", allOne.getMinKey()); - - allOne = new AllOne(); - allOne.inc("hello"); - allOne.dec("hello"); - assertEquals("", allOne.getMaxKey()); - assertEquals("", allOne.getMinKey()); - } -} \ No newline at end of file diff --git a/src/main/java/com/leetcode/design/DesignHitCounter.java b/src/main/java/com/leetcode/design/DesignHitCounter.java deleted file mode 100644 index 62133196..00000000 --- a/src/main/java/com/leetcode/design/DesignHitCounter.java +++ /dev/null @@ -1,117 +0,0 @@ -package com.leetcode.design; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * Level: Medium - * Problem Link: https://leetcode.com/problems/design-hit-counter/ - * Problem Description: - * Design a hit counter which counts the number of hits received in the past 5 minutes. - * - * Each function accepts a timestamp parameter (in seconds granularity) and you may assume that calls are being made - * to the system in chronological order (ie, the timestamp is monotonically increasing). You may assume that the - * earliest timestamp starts at 1. - * - * It is possible that several hits arrive roughly at the same time. - * - * Example: - * - * HitCounter counter = new HitCounter(); - * - * // hit at timestamp 1. - * counter.hit(1); - * - * // hit at timestamp 2. - * counter.hit(2); - * - * // hit at timestamp 3. - * counter.hit(3); - * - * // get hits at timestamp 4, should return 3. - * counter.getHits(4); - * - * // hit at timestamp 300. - * counter.hit(300); - * - * // get hits at timestamp 300, should return 4. - * counter.getHits(300); - * - * // get hits at timestamp 301, should return 3. - * counter.getHits(301); - * - * Follow up: - * What if the number of hits per second could be very large? Does your design scale? - * - * Runtime: 42 ms (better than ~98%). - * - * @author rampatra - * @since 2019-08-04 - */ -public class DesignHitCounter { - - private int[] timestamps; - private int[] hits; - - /** - * Initialize your data structure here. - */ - public DesignHitCounter() { - this.timestamps = new int[300]; - this.hits = new int[300]; - } - - /** - * Record a hit. - * - * @param timestamp - The current timestamp (in seconds granularity). - */ - public void hit(int timestamp) { - int bucket = timestamp % 300; - if (timestamps[bucket] == timestamp) { - hits[bucket]++; - } else { - timestamps[bucket] = timestamp; - hits[bucket] = 1; - } - } - - /** - * Return the number of hits in the past 5 minutes. - * - * @param timestamp - The current timestamp (in seconds granularity). - */ - public int getHits(int timestamp) { - int totalHits = 0; - for (int i = 0; i < 300; i++) { - if (timestamp - 300 < timestamps[i]) { - totalHits += hits[i]; - } - } - return totalHits; - } - - public static void main(String[] args) { - DesignHitCounter counter = new DesignHitCounter(); - - // hit at timestamp 1. - counter.hit(1); - - // hit at timestamp 2. - counter.hit(2); - - // hit at timestamp 3. - counter.hit(3); - - // get hits at timestamp 4, should return 3. - assertEquals(3, counter.getHits(4)); - - // hit at timestamp 300. - counter.hit(300); - - // get hits at timestamp 300, should return 4. - assertEquals(4, counter.getHits(300)); - - // get hits at timestamp 301, should return 3. - assertEquals(3, counter.getHits(301)); - } -} diff --git a/src/main/java/com/leetcode/design/InsertDeleteGetRandom.java b/src/main/java/com/leetcode/design/InsertDeleteGetRandom.java deleted file mode 100644 index a6c2f376..00000000 --- a/src/main/java/com/leetcode/design/InsertDeleteGetRandom.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.leetcode.design; - -import java.util.*; - -import static org.junit.jupiter.api.Assertions.*; - -/** - * Level: Medium - * Link: https://leetcode.com/problems/insert-delete-getrandom-o1/ - * Description: - * Design a data structure that supports all following operations in average O(1) time. - * - * insert(val): Inserts an item val to the set if not already present. - * remove(val): Removes an item val from the set if present. - * getRandom: Returns a random element from current set of elements. Each element must have the same probability of - * being returned. - * - * Example: - * - * // Init an empty set. - * RandomizedSet randomSet = new RandomizedSet(); - * - * // Inserts 1 to the set. Returns true as 1 was inserted successfully. - * randomSet.insert(1); - * - * // Returns false as 2 does not exist in the set. - * randomSet.remove(2); - * - * // Inserts 2 to the set, returns true. Set now contains [1,2]. - * randomSet.insert(2); - * - * // getRandom should return either 1 or 2 randomly. - * randomSet.getRandom(); - * - * // Removes 1 from the set, returns true. Set now contains [2]. - * randomSet.remove(1); - * - * // 2 was already in the set, so return false. - * randomSet.insert(2); - * - * // Since 2 is the only number in the set, getRandom always return 2. - * randomSet.getRandom(); - * - * Runtime: 54 ms. - * - * @author rampatra - * @since 2019-08-20 - */ -public class LRUCache { - - private LinkedHashMap cache; - - public LRUCache(int capacity) { - this.cache = new LinkedHashMap(capacity, 0.75f, true) { - @Override - protected boolean removeEldestEntry(Map.Entry eldest) { - return size() > capacity; - } - }; - } - - public int get(int key) { - Integer val = cache.get(key); - return val == null ? -1 : val; - } - - public void put(int key, int value) { - cache.put(key, value); - } - - public static void main(String[] args) { - LRUCache cache = new LRUCache(2); - cache.put(1,1); - cache.put(2,2); - cache.put(1,1); - cache.put(3,3); - assertEquals(1, cache.get(1)); - assertEquals(-1, cache.get(2)); - assertEquals(3, cache.get(3)); - } -} \ No newline at end of file diff --git a/src/main/java/com/leetcode/dynamicprogramming/MaximumProductSubArray.java b/src/main/java/com/leetcode/dynamicprogramming/MaximumProductSubArray.java deleted file mode 100644 index 781cad13..00000000 --- a/src/main/java/com/leetcode/dynamicprogramming/MaximumProductSubArray.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.leetcode.dynamicprogramming; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * Level: Medium - * Link: https://leetcode.com/problems/maximum-product-subarray/ - * Description: - * Given an integer array nums, find the contiguous subarray within an array (containing at least one number) which - * has the largest product. - *

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

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

- * Runtime: 1 ms. - * - * @param nums - * @return - */ - public static int maxProduct(int[] nums) { - int maxProd = nums[0]; - int maxUntilIndex = nums[0]; - int minUntilIndex = nums[0]; - - for (int i = 1; i < nums.length; i++) { - if (nums[i] >= 0) { - maxUntilIndex = Math.max(nums[i], maxUntilIndex * nums[i]); - minUntilIndex = Math.min(nums[i], minUntilIndex * nums[i]); - } else { - int prevMaxUntilIndex = maxUntilIndex; - maxUntilIndex = Math.max(nums[i], minUntilIndex * nums[i]); // when current number is -ve then multiply with minUntilIndex to get the max as product of two negatives is a positive - minUntilIndex = Math.min(nums[i], prevMaxUntilIndex * nums[i]); - } - - maxProd = Math.max(maxProd, maxUntilIndex); - } - - return maxProd; - } - - public static void main(String[] args) { - assertEquals(24, maxProduct(new int[]{-2, 3, -4})); - } -} \ No newline at end of file diff --git a/src/main/java/com/leetcode/dynamicprogramming/MaximumSubArray.java b/src/main/java/com/leetcode/dynamicprogramming/MaximumSubArray.java deleted file mode 100644 index 90a28c93..00000000 --- a/src/main/java/com/leetcode/dynamicprogramming/MaximumSubArray.java +++ /dev/null @@ -1,104 +0,0 @@ -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 deleted file mode 100644 index 5692b0d8..00000000 --- a/src/main/java/com/leetcode/dynamicprogramming/PaintHouse.java +++ /dev/null @@ -1,52 +0,0 @@ -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 deleted file mode 100644 index 431ce612..00000000 --- a/src/main/java/com/leetcode/dynamicprogramming/PaintHouseII.java +++ /dev/null @@ -1,120 +0,0 @@ -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 deleted file mode 100644 index 15950143..00000000 --- a/src/main/java/com/leetcode/graphs/GraphValidTree.java +++ /dev/null @@ -1,131 +0,0 @@ -package com.leetcode.graphs; - -import java.util.ArrayList; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -/** - * Level: Medium - * Problem Link: https://leetcode.com/problems/graph-valid-tree/ - * Problem Description: - * Given n nodes labeled from 0 to n-1 and a list of undirected edges (each edge is a pair of nodes), write a function - * to check whether these edges make up a valid tree. - *

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

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

- * Note: you can assume that no duplicate edges will appear in edges. Since all edges are undirected, [0,1] is the - * same as [1,0] and thus will not appear together in edges. - * - * @author rampatra - * @since 2019-08-05 - */ -public class GraphValidTree { - - /** - * - * @param n - * @param edges - * @return - */ - public static boolean isValidTree(int n, int[][] edges) { - List> adjacencyList = new ArrayList<>(n); - - for (int i = 0; i < n; i++) { - adjacencyList.add(new ArrayList<>()); - } - - for (int i = 0; i < edges.length; i++) { - adjacencyList.get(edges[i][0]).add(edges[i][1]); - } - - boolean[] visited = new boolean[n]; - - if (hasCycle(adjacencyList, 0, -1, visited)) { - return false; - } - - for (int i = 0; i < n; i++) { - if (!visited[i]) { - return false; - } - } - - return true; - } - - private static boolean hasCycle(List> adjacencyList, int node1, int exclude, boolean[] visited) { - visited[node1] = true; - - for (int i = 0; i < adjacencyList.get(node1).size(); i++) { - int node2 = adjacencyList.get(node1).get(i); - - if ((visited[node2] && exclude != node2) || (!visited[node2] && hasCycle(adjacencyList, node2, node1, visited))) { - return true; - } - } - - return false; - } - - - /** - * Union-find algorithm: We keep all connected nodes in one set in the union operation and in find operation we - * check whether two nodes belong to the same set. If yes then there's a cycle and if not then no cycle. - * - * Good articles on union-find: - * - https://www.hackerearth.com/practice/notes/disjoint-set-union-union-find/ - * - https://www.youtube.com/watch?v=wU6udHRIkcc - * - * @param n - * @param edges - * @return - */ - public static boolean isValidTreeUsingUnionFind(int n, int[][] edges) { - int[] roots = new int[n]; - - for (int i = 0; i < n; i++) { - roots[i] = i; - } - - for (int i = 0; i < edges.length; i++) { - // find operation - if (roots[edges[i][0]] == roots[edges[i][1]]) { - return false; - } - // union operation - roots[edges[i][1]] = findRoot(roots, roots[edges[i][0]]); // note: we can optimize this even further by - // considering size of each side and then join the side with smaller size to the one with a larger size (weighted union). - // We can use another array called size to keep count of the size or we can use the same root array with - // negative values, i.e, negative resembles that the node is pointing to itself and the number will represent - // the size. For example, roots = [-2, -1, -1, 0] means that node 3 is pointing to node 0 and node 0 is pointing - // to itself and is has 2 nodes under it including itself. - } - - return edges.length == n - 1; - } - - private static int findRoot(int[] roots, int node) { - while (roots[node] != node) { - node = roots[node]; - } - return node; - } - - public static void main(String[] args) { - assertTrue(isValidTree(5, new int[][]{{0, 1}, {0, 2}, {0, 3}, {1, 4}})); - assertFalse(isValidTree(5, new int[][]{{0, 1}, {1, 2}, {2, 3}, {1, 3}, {1, 4}})); - assertFalse(isValidTree(3, new int[][]{{0, 1}, {1, 2}, {2, 0}})); - - assertTrue(isValidTreeUsingUnionFind(5, new int[][]{{0, 1}, {0, 2}, {0, 3}, {1, 4}})); - assertFalse(isValidTreeUsingUnionFind(5, new int[][]{{0, 1}, {1, 2}, {2, 3}, {1, 3}, {1, 4}})); - assertFalse(isValidTreeUsingUnionFind(3, new int[][]{{0, 1}, {1, 2}, {2, 0}})); - } -} \ No newline at end of file diff --git a/src/main/java/com/leetcode/graphs/WordLadder.java b/src/main/java/com/leetcode/graphs/WordLadder.java deleted file mode 100644 index 61e706ce..00000000 --- a/src/main/java/com/leetcode/graphs/WordLadder.java +++ /dev/null @@ -1,121 +0,0 @@ -package com.leetcode.graphs; - - -import javafx.util.Pair; - -import java.util.*; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * Level: Medium - * Link: https://leetcode.com/problems/word-ladder/ - * Description: - * Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation - * sequence from beginWord to endWord, such that: - *

- * Only one letter can be changed at a time. Each transformed word must exist in the word list. Note that beginWord - * is not a transformed word. - *

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

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

- * Output: 5 - *

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

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

- * Output: 0 - *

- * Explanation: The endWord "cog" is not in wordList, therefore no possible transformation. - * - * @author rampatra - * @since 2019-08-15 - */ -public class WordLadder { - - /** - * Runtime: 79 ms. - * - * @param beginWord - * @param endWord - * @param wordList - * @return - */ - public static int ladderLength(String beginWord, String endWord, List wordList) { - int L = beginWord.length(); - Map> transformedToOriginalWordMap = new HashMap<>(); - Queue> queue = new LinkedList<>(); - - wordList.forEach(word -> { - String transformedWord; - for (int i = 0; i < L; i++) { - transformedWord = word.substring(0, i) + "*" + word.substring(i + 1, L); - transformedToOriginalWordMap.putIfAbsent(transformedWord, new HashSet<>()); - transformedToOriginalWordMap.get(transformedWord).add(word); - } - } - ); - - Set visited = new HashSet<>(); - queue.add(new Pair<>(beginWord, 1)); - visited.add(beginWord); - - while (!queue.isEmpty()) { - Pair currPair = queue.poll(); - String word = currPair.getKey(); - Integer level = currPair.getValue(); - - if (word.equals(endWord)) { - return level; - } - - String transformedWord; - for (int i = 0; i < L; i++) { - transformedWord = word.substring(0, i) + "*" + word.substring(i + 1, L); - - for (String originalWord : transformedToOriginalWordMap.getOrDefault(transformedWord, Collections.emptySet())) { - if (!visited.contains(originalWord)) { - queue.add(new Pair<>(originalWord, level + 1)); - visited.add(originalWord); - } - } - } - } - - return 0; - } - - /** - * TODO: Optimized both end BFS solution - * - * @param beginWord - * @param endWord - * @param wordList - * @return - */ - public static int ladderLengthOptimized(String beginWord, String endWord, List wordList) { - return -1; - } - - public static void main(String[] args) { - assertEquals(5, ladderLength("hit", "cog", Arrays.asList("hot", "dot", "dog", "lot", "log", "cog"))); - assertEquals(0, ladderLength("hit", "cog", Arrays.asList("hot", "dot", "dog", "lot", "log"))); - } -} \ No newline at end of file diff --git a/src/main/java/com/leetcode/graphs/WordLadderII.java b/src/main/java/com/leetcode/graphs/WordLadderII.java deleted file mode 100644 index 8265c259..00000000 --- a/src/main/java/com/leetcode/graphs/WordLadderII.java +++ /dev/null @@ -1,152 +0,0 @@ -package com.leetcode.graphs; - -import javafx.util.Pair; - -import java.util.*; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * Level: Hard - * Link: https://leetcode.com/problems/word-ladder-ii/ - * Description: - * Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) - * from beginWord to endWord, such that: - *

- * Only one letter can be changed at a time - * Each transformed word must exist in the word list. Note that beginWord is not a transformed word. - *

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

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

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

- *

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

- * Output: [] - * Explanation: The endWord "cog" is not in wordList, therefore no possible transformation. - * - * @author rampatra - * @since 2019-08-15 - */ -public class WordLadderII { - - /** - * The approach is same as {@link WordLadder}. We calculate the {@code minDistance} from start to end word and also - * keep a map of words and its adjacent words (i.e, with only character difference). After we are done calculating - * the {@code mindistance}, we perform a dfs on the map upto depth {@code minDistance} and if the last word at this - * depth is equal to the end word then we add all words to the result. - * - * @param beginWord - * @param endWord - * @param wordList - * @return - */ - public static List> findLadders(String beginWord, String endWord, List wordList) { - int L = beginWord.length(); - List> ladders = new LinkedList<>(); - Map> transformedToOriginalWordMap = new HashMap<>(); - Queue> queue = new LinkedList<>(); - - wordList.forEach(word -> { - String transformedWord; - for (int i = 0; i < L; i++) { - transformedWord = word.substring(0, i) + "*" + word.substring(i + 1, L); - transformedToOriginalWordMap.putIfAbsent(transformedWord, new HashSet<>()); - transformedToOriginalWordMap.get(transformedWord).add(word); - } - } - ); - - int minDistance = -1; - Set visited = new HashSet<>(); - queue.add(new Pair<>(beginWord, 1)); - visited.add(beginWord); - - HashMap> connectedNodes = new HashMap<>(); - - while (!queue.isEmpty()) { - Pair currPair = queue.poll(); - String word = currPair.getKey(); - Integer level = currPair.getValue(); - - if (word.equals(endWord) && minDistance == -1) { - minDistance = level - 1; - } - - String transformedWord; - for (int i = 0; i < L; i++) { - transformedWord = word.substring(0, i) + "*" + word.substring(i + 1, L); - - for (String originalWord : transformedToOriginalWordMap.getOrDefault(transformedWord, Collections.emptySet())) { - if (!visited.contains(originalWord)) { - queue.add(new Pair<>(originalWord, level + 1)); - visited.add(originalWord); - } - - if (!word.equals(originalWord)) { - connectedNodes.putIfAbsent(word, new HashSet<>()); - connectedNodes.get(word).add(originalWord); - } - } - } - } - - dfs(ladders, new LinkedHashSet<>(), connectedNodes, beginWord, endWord, 0, minDistance); - - return ladders; - } - - /** - * Perform dfs on the map which contains words and its adjacent words. - * - * @param ladders - * @param ladder - * @param connectedNodes - * @param startNode - * @param endNode - * @param distance - * @param minDistance - */ - private static void dfs(List> ladders, Set ladder, Map> connectedNodes, - String startNode, String endNode, int distance, int minDistance) { - if (distance == minDistance && startNode.equals(endNode)) { - ladder.add(endNode); - ladders.add(new ArrayList<>(ladder)); - return; - } else if (distance > minDistance) { - return; - } - - ladder.add(startNode); - for (String nextNode : connectedNodes.getOrDefault(startNode, new HashSet<>())) { - if (!ladder.contains(nextNode)) { - dfs(ladders, new LinkedHashSet<>(ladder), connectedNodes, nextNode, endNode, distance + 1, minDistance); - } - } - } - - public static void main(String[] args) { - assertEquals("[[hit, hot, lot, log, cog], [hit, hot, dot, dog, cog]]", findLadders("hit", "cog", Arrays.asList("hot", "dot", "dog", "lot", "log", "cog")).toString()); - // TODO Fix this test case System.out.println(findLadders("cet", "ism", Arrays.asList("kid", "tag", "pup", "ail", "tun", "woo", "erg", "luz", "brr", "gay", "sip", "kay", "per", "val", "mes", "ohs", "now", "boa", "cet", "pal", "bar", "die", "war", "hay", "eco", "pub", "lob", "rue", "fry", "lit", "rex", "jan", "cot", "bid", "ali", "pay", "col", "gum", "ger", "row", "won", "dan", "rum", "fad", "tut", "sag", "yip", "sui", "ark", "has", "zip", "fez", "own", "ump", "dis", "ads", "max", "jaw", "out", "btu", "ana", "gap", "cry", "led", "abe", "box", "ore", "pig", "fie", "toy", "fat", "cal", "lie", "noh", "sew", "ono", "tam", "flu", "mgm", "ply", "awe", "pry", "tit", "tie", "yet", "too", "tax", "jim", "san", "pan", "map", "ski", "ova", "wed", "non", "wac", "nut", "why", "bye", "lye", "oct", "old", "fin", "feb", "chi", "sap", "owl", "log", "tod", "dot", "bow", "fob", "for", "joe", "ivy", "fan", "age", "fax", "hip", "jib", "mel", "hus", "sob", "ifs", "tab", "ara", "dab", "jag", "jar", "arm", "lot", "tom", "sax", "tex", "yum", "pei", "wen", "wry", "ire", "irk", "far", "mew", "wit", "doe", "gas", "rte", "ian", "pot", "ask", "wag", "hag", "amy", "nag", "ron", "soy", "gin", "don", "tug", "fay", "vic", "boo", "nam", "ave", "buy", "sop", "but", "orb", "fen", "paw", "his", "sub", "bob", "yea", "oft", "inn", "rod", "yam", "pew", "web", "hod", "hun", "gyp", "wei", "wis", "rob", "gad", "pie", "mon", "dog", "bib", "rub", "ere", "dig", "era", "cat", "fox", "bee", "mod", "day", "apr", "vie", "nev", "jam", "pam", "new", "aye", "ani", "and", "ibm", "yap", "can", "pyx", "tar", "kin", "fog", "hum", "pip", "cup", "dye", "lyx", "jog", "nun", "par", "wan", "fey", "bus", "oak", "bad", "ats", "set", "qom", "vat", "eat", "pus", "rev", "axe", "ion", "six", "ila", "lao", "mom", "mas", "pro", "few", "opt", "poe", "art", "ash", "oar", "cap", "lop", "may", "shy", "rid", "bat", "sum", "rim", "fee", "bmw", "sky", "maj", "hue", "thy", "ava", "rap", "den", "fla", "auk", "cox", "ibo", "hey", "saw", "vim", "sec", "ltd", "you", "its", "tat", "dew", "eva", "tog", "ram", "let", "see", "zit", "maw", "nix", "ate", "gig", "rep", "owe", "ind", "hog", "eve", "sam", "zoo", "any", "dow", "cod", "bed", "vet", "ham", "sis", "hex", "via", "fir", "nod", "mao", "aug", "mum", "hoe", "bah", "hal", "keg", "hew", "zed", "tow", "gog", "ass", "dem", "who", "bet", "gos", "son", "ear", "spy", "kit", "boy", "due", "sen", "oaf", "mix", "hep", "fur", "ada", "bin", "nil", "mia", "ewe", "hit", "fix", "sad", "rib", "eye", "hop", "haw", "wax", "mid", "tad", "ken", "wad", "rye", "pap", "bog", "gut", "ito", "woe", "our", "ado", "sin", "mad", "ray", "hon", "roy", "dip", "hen", "iva", "lug", "asp", "hui", "yak", "bay", "poi", "yep", "bun", "try", "lad", "elm", "nat", "wyo", "gym", "dug", "toe", "dee", "wig", "sly", "rip", "geo", "cog", "pas", "zen", "odd", "nan", "lay", "pod", "fit", "hem", "joy", "bum", "rio", "yon", "dec", "leg", "put", "sue", "dim", "pet", "yaw", "nub", "bit", "bur", "sid", "sun", "oil", "red", "doc", "moe", "caw", "eel", "dix", "cub", "end", "gem", "off", "yew", "hug", "pop", "tub", "sgt", "lid", "pun", "ton", "sol", "din", "yup", "jab", "pea", "bug", "gag", "mil", "jig", "hub", "low", "did", "tin", "get", "gte", "sox", "lei", "mig", "fig", "lon", "use", "ban", "flo", "nov", "jut", "bag", "mir", "sty", "lap", "two", "ins", "con", "ant", "net", "tux", "ode", "stu", "mug", "cad", "nap", "gun", "fop", "tot", "sow", "sal", "sic", "ted", "wot", "del", "imp", "cob", "way", "ann", "tan", "mci", "job", "wet", "ism", "err", "him", "all", "pad", "hah", "hie", "aim", "ike", "jed", "ego", "mac", "baa", "min", "com", "ill", "was", "cab", "ago", "ina", "big", "ilk", "gal", "tap", "duh", "ola", "ran", "lab", "top", "gob", "hot", "ora", "tia", "kip", "han", "met", "hut", "she", "sac", "fed", "goo", "tee", "ell", "not", "act", "gil", "rut", "ala", "ape", "rig", "cid", "god", "duo", "lin", "aid", "gel", "awl", "lag", "elf", "liz", "ref", "aha", "fib", "oho", "tho", "her", "nor", "ace", "adz", "fun", "ned", "coo", "win", "tao", "coy", "van", "man", "pit", "guy", "foe", "hid", "mai", "sup", "jay", "hob", "mow", "jot", "are", "pol", "arc", "lax", "aft", "alb", "len", "air", "pug", "pox", "vow", "got", "meg", "zoe", "amp", "ale", "bud", "gee", "pin", "dun", "pat", "ten", "mob"))); - } -} diff --git a/src/main/java/com/leetcode/hashtables/ContainsDuplicates.java b/src/main/java/com/leetcode/hashtables/ContainsDuplicates.java deleted file mode 100644 index 7b12311b..00000000 --- a/src/main/java/com/leetcode/hashtables/ContainsDuplicates.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.leetcode.hashtables; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -/** - * Level: Easy - * Problem Link: https://leetcode.com/problems/contains-duplicate/ - * - * @author rampatra - * @since 2019-04-24 - */ -public class ContainsDuplicates { - - public static boolean containsDuplicates(int[] nums) { - Set numSet = new HashSet<>(); - for (int num : nums) { - if (!numSet.add(num)) { - return true; - } - } - return false; - } - - /** - * Runtime: 5 ms. - * - * @param nums - * @return - */ - public static boolean containsDuplicatesWithoutSet(int[] nums) { - Arrays.sort(nums); - for (int i = 0; i < nums.length - 1; i++) { - if (nums[i] == nums[i + 1]) { - return true; - } - } - return false; - } - - public static void main(String[] args) { - System.out.println(containsDuplicates(new int[]{1, 2, 3, 1})); - System.out.println(containsDuplicates(new int[]{1, 2, 3, 4})); - - System.out.println(containsDuplicatesWithoutSet(new int[]{1, 2, 3, 1})); - System.out.println(containsDuplicatesWithoutSet(new int[]{1, 2, 3, 4})); - } -} diff --git a/src/main/java/com/leetcode/hashtables/IsomorphicStrings.java b/src/main/java/com/leetcode/hashtables/IsomorphicStrings.java deleted file mode 100644 index f9a7f4eb..00000000 --- a/src/main/java/com/leetcode/hashtables/IsomorphicStrings.java +++ /dev/null @@ -1,104 +0,0 @@ -package com.leetcode.hashtables; - -import java.util.HashMap; -import java.util.Map; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -/** - * Level: Easy - * Link: https://leetcode.com/problems/isomorphic-strings/ - * Description: - * Given two strings s and t, determine if they are isomorphic. - * - * Two strings are isomorphic if the characters in s can be replaced to get t. - * - * All occurrences of a character must be replaced with another character while preserving the order of characters. No - * two characters may map to the same character but a character may map to itself. - * - * Example 1: - * Input: s = "egg", t = "add" - * Output: true - * - * Example 2: - * Input: s = "foo", t = "bar" - * Output: false - * - * Example 3: - * Input: s = "paper", t = "title" - * Output: true - * - * Note: - * You may assume both s and t have the same length. - * - * @author rampatra - * @since 2019-08-11 - */ -public class IsomorphicStrings { - - /** - * Time Complexity: - * Space Complexity: - * Runtime: 8 ms. - * - * @param s - * @param t - * @return - */ - public static boolean isIsomorphic(String s, String t) { - - Map sToTCharMap = new HashMap<>(); - Map tToSCharMap = new HashMap<>(); - - for (int i = 0; i < s.length(); i++) { - char chFromS = s.charAt(i); - char chFromT = t.charAt(i); - if (sToTCharMap.get(chFromS) == null && tToSCharMap.get(chFromT) == null) { - sToTCharMap.put(chFromS, chFromT); - tToSCharMap.put(chFromT, chFromS); - } - Character mappedChFromSToT = sToTCharMap.get(chFromS); - if (mappedChFromSToT == null || mappedChFromSToT != chFromT) { - return false; - } - } - - return true; - } - - /** - * Time Complexity: - * Space Complexity: - * Runtime: 3 ms. - * - * @param s - * @param t - * @return - */ - public static boolean isIsomorphicWithoutMaps(String s, String t) { - int[] charMap = new int[512]; - for (int i = 0; i < s.length(); i++) { - char chFromS = s.charAt(i); - char chFromT = t.charAt(i); - if (charMap[chFromS] != charMap[chFromT + 256]) { - return false; - } - charMap[chFromS] = charMap[chFromT + 256] = i + 1; - } - - return true; - } - - public static void main(String[] args) { - assertTrue(isIsomorphic("egg", "add")); - assertFalse(isIsomorphic("foo", "bar")); - assertTrue(isIsomorphic("paper", "title")); - assertFalse(isIsomorphic("ab", "aa")); - - assertTrue(isIsomorphicWithoutMaps("egg", "add")); - assertFalse(isIsomorphicWithoutMaps("foo", "bar")); - assertTrue(isIsomorphicWithoutMaps("paper", "title")); - assertFalse(isIsomorphicWithoutMaps("ab", "aa")); - } -} diff --git a/src/main/java/com/leetcode/hashtables/MyHashMap.java b/src/main/java/com/leetcode/hashtables/MyHashMap.java deleted file mode 100644 index cf13c344..00000000 --- a/src/main/java/com/leetcode/hashtables/MyHashMap.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.leetcode.hashtables; - -/** - * Level: Learning cards - * Problem Link: https://leetcode.com/explore/learn/card/hash-table/182/practical-applications/1140/ - * Runtime: https://leetcode.com/submissions/detail/224928756/ - * - * @author rampatra - * @since 2019-04-25 - */ -public class MyHashMap { - - class Entry { - int key; - int value; - Entry next; - - Entry(int key, int value) { - this.key = key; - this.value = value; - } - } - - private final int SIZE = 10000; - private final Entry[] entries; - - /** - * Initialize your data structure here. - */ - public MyHashMap() { - entries = new Entry[SIZE]; - } - - /** - * value will always be non-negative. - */ - public void put(int key, int value) { - int bucket = key % SIZE; - Entry entry = entries[bucket]; - - if (entry == null) { - entries[bucket] = new Entry(key, value); - } else { - while (entry.next != null && entry.key != key) { - entry = entry.next; - } - - if (entry.key == key) { - entry.value = value; - } else { - entry.next = new Entry(key, value); - } - } - } - - /** - * Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key - */ - public int get(int key) { - int bucket = key % SIZE; - Entry entry = entries[bucket]; - while (entry != null) { - if (entry.key == key) { - return entry.value; - } - entry = entry.next; - } - return -1; - } - - /** - * Removes the mapping of the specified value key if this map contains a mapping for the key - */ - public void remove(int key) { - int bucket = key % SIZE; - Entry entry = entries[bucket]; - - if (entry != null && entry.key == key) { - entries[bucket] = entry.next; - return; - } - - Entry curr = new Entry(0, 0); - curr.next = entry; - - while (curr.next != null && curr.next.key != key) { - curr = curr.next; - } - - if (curr.next != null) { - curr.next = curr.next.next; - } - } - - public static void main(String[] args) { - MyHashMap map = new MyHashMap(); - map.put(1, 2); - System.out.println("1 -> " + map.get(1)); - map.put(1, 4); - System.out.println("1 -> " + map.get(1)); - map.remove(1); - System.out.println("1 -> " + map.get(1)); - System.out.println("5 -> " + map.get(5)); - } -} \ No newline at end of file diff --git a/src/main/java/com/leetcode/hashtables/MyHashSet.java b/src/main/java/com/leetcode/hashtables/MyHashSet.java deleted file mode 100644 index 3c13d488..00000000 --- a/src/main/java/com/leetcode/hashtables/MyHashSet.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.leetcode.hashtables; - -/** - * Level: Learning Cards - * Problem Link: https://leetcode.com/explore/learn/card/hash-table/182/practical-applications/1139/ - * Runtime: https://leetcode.com/submissions/detail/224872991/ - * - * @author rampatra - * @since 2019-04-24 - */ -public class MyHashSet { - - private final int SIZE = 10000; - private final Entry[] entries; - - class Entry { - int key; - Entry next; - - Entry(int key) { - this.key = key; - } - } - - /** - * Initialize your data structure here. - */ - public MyHashSet() { - entries = new Entry[SIZE]; - } - - public void add(int key) { - if (contains(key)) return; - - Entry newEntry = new Entry(key); - int bucket = key % SIZE; - - newEntry.next = entries[bucket]; - entries[bucket] = newEntry; - } - - public void remove(int key) { - int bucket = key % SIZE; - Entry entry = entries[bucket]; - - if (entry != null && entry.key == key) { - entries[bucket] = entry.next; - return; - } - - Entry curr = new Entry(0); - curr.next = entry; - - while (curr.next != null && curr.next.key != key) { - curr = curr.next; - } - - if (curr.next != null) { - curr.next = curr.next.next; - } - } - - /** - * Returns true if this set contains the specified element - */ - public boolean contains(int key) { - int bucket = key % SIZE; - Entry entry = entries[bucket]; - - while (entry != null) { - if (entry.key == key) { - return true; - } - entry = entry.next; - } - - return false; - } - - public static void main(String[] args) { - MyHashSet set = new MyHashSet(); - set.add(1); - set.add(2); - set.add(3); - System.out.println(set.contains(1)); - System.out.println(set.contains(2)); - set.remove(2); - System.out.println(set.contains(2)); - System.out.println(set.contains(3)); - set.remove(3); - System.out.println(set.contains(3)); - } -} \ No newline at end of file diff --git a/src/main/java/com/leetcode/hashtables/RepeatedDnaSequence.java b/src/main/java/com/leetcode/hashtables/RepeatedDnaSequence.java deleted file mode 100644 index 7674273d..00000000 --- a/src/main/java/com/leetcode/hashtables/RepeatedDnaSequence.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.leetcode.hashtables; - -import java.util.*; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * Level: Medium - * Problem Link: https://leetcode.com/problems/repeated-dna-sequences/submissions/ - * Problem Description: - * All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: "ACGAATTCCG". When - * studying DNA, it is sometimes useful to identify repeated sequences within the DNA. - * - * Write a function to find all the 10-letter-long sequences (substrings) that occur more than once in a DNA molecule. - * - * Example: - * Input: s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT" - * Output: ["AAAAACCCCC", "CCCCCAAAAA"] - * - * TODO: Figure another method which would have a better runtime. - * - * @author rampatra - * @since 2019-07-29 - */ -public class RepeatedDnaSequence { - - /** - * Rabin-Karp Algorithm: https://brilliant.org/wiki/rabin-karp-algorithm/ - * Following Rabin-Karp's approach let's you avoid spurious hits (worst case scenario) but once the hash matches, - * you will have to compare and check the string you're searching. I tried to just rely on the hash and few test - * cases failed for me (https://leetcode.com/submissions/detail/247342702/). - *

- * Time Complexity: - * Space Complexity: - * Runtime: 38 ms. - * - * @param s - * @return - */ - public static List findRepeatedDnaSequences(String s) { - if (s.length() < 10) return new ArrayList<>(); - - Set repeatedSequences = new HashSet<>(); - Map> hashToStringMap = new HashMap<>(); - long hashOfSequence = computeHash(s); - hashToStringMap.put(hashOfSequence, new HashSet() {{ - add(s.substring(0, 10)); - }}); - - long pow = (long) Math.pow(4, 9); - - for (int i = 10; i < s.length(); i++) { - hashOfSequence = (hashOfSequence - (pow * (s.charAt(i - 10) - 'A'))) * 4 + (s.charAt(i) - 'A'); - String subString = s.substring(i - 10 + 1, i + 1); - - if (hashToStringMap.get(hashOfSequence) != null && hashToStringMap.get(hashOfSequence).contains(subString)) { - repeatedSequences.add(subString); - continue; - } - - hashToStringMap.putIfAbsent(hashOfSequence, new HashSet<>()); - hashToStringMap.get(hashOfSequence).add(subString); - } - - return new ArrayList<>(repeatedSequences); - } - - private static long computeHash(String s) { - long hash = 0; - for (int i = 0; i < 10; i++) { - hash += (Math.pow(4, i) * (s.charAt(9 - i) - 'A')); - } - return hash; - } - - public static void main(String[] args) { - assertEquals(new ArrayList<>(), - findRepeatedDnaSequences("AAAAACCC")); - - assertEquals(Arrays.asList("AAAAACCCCC", "CCCCCAAAAA"), - findRepeatedDnaSequences("AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT")); - - assertEquals(Collections.singletonList("AAAAAAAAAA"), - findRepeatedDnaSequences("AAAAAAAAAAAA")); - - assertEquals(Collections.singletonList("BBBBBBBBBB"), - findRepeatedDnaSequences("BBBBBBBBBBBB")); - } -} \ No newline at end of file diff --git a/src/main/java/com/leetcode/hashtables/ShortestWordDistanceII.java b/src/main/java/com/leetcode/hashtables/ShortestWordDistanceII.java deleted file mode 100644 index 3932cebf..00000000 --- a/src/main/java/com/leetcode/hashtables/ShortestWordDistanceII.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.leetcode.hashtables; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * Level: Medium - * Problem Link: https://leetcode.com/problems/shortest-word-distance-ii/ - * Problem Description: - * Design a class which receives a list of words in the constructor, and implements a method that takes two words - * word1 and word2 and return the shortest distance between these two words in the list. Your method will be called - * repeatedly many times with different parameters. For a simpler variant, see {@link com.leetcode.arrays.ShortestWordDistance}. - *

- * 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> wordsToIndexesMap; - - ShortestWordDistanceII(String[] words) { - this.words = words; - this.wordsToIndexesMap = getWordsToIndexesMap(); - } - - /** - * Runtime: 65 ms. - * - * @param word1 - * @param word2 - * @return - */ - public int findShortestDistance(String word1, String word2) { - return findShortestDistance(wordsToIndexesMap.get(word1), wordsToIndexesMap.get(word2)); - } - - private int findShortestDistance(List indexes1, List indexes2) { - int minDistance = Integer.MAX_VALUE; - - for (int i = 0, j = 0; i < indexes1.size() && j < indexes2.size(); ) { - if (indexes1.get(i) <= indexes2.get(j)) { - minDistance = Math.min(minDistance, Math.abs(indexes1.get(i) - indexes2.get(j))); - i++; - } else if (indexes1.get(i) > indexes2.get(j)) { - minDistance = Math.min(minDistance, Math.abs(indexes1.get(i) - indexes2.get(j))); - j++; - } - } - - return minDistance; - } - - private Map> getWordsToIndexesMap() { - Map> wordsToIndexesMap = new HashMap<>(); - - for (int i = 0; i < words.length; i++) { - wordsToIndexesMap.putIfAbsent(words[i], new ArrayList<>()); - wordsToIndexesMap.get(words[i]).add(i); - } - return wordsToIndexesMap; - } - - public static void main(String[] args) { - ShortestWordDistanceII shortestWordDist = new ShortestWordDistanceII(new String[]{"practice", "makes", "perfect", "coding", "makes"}); - assertEquals(1, shortestWordDist.findShortestDistance("coding", "makes")); - assertEquals(1, shortestWordDist.findShortestDistance("perfect", "makes")); - assertEquals(1, shortestWordDist.findShortestDistance("practice", "makes")); - assertEquals(1, shortestWordDist.findShortestDistance("makes", "practice")); - assertEquals(3, shortestWordDist.findShortestDistance("coding", "practice")); - assertEquals(0, shortestWordDist.findShortestDistance("coding", "coding")); - assertEquals(0, shortestWordDist.findShortestDistance("makes", "makes")); - } -} \ No newline at end of file diff --git a/src/main/java/com/leetcode/hashtables/TwoSumIII.java b/src/main/java/com/leetcode/hashtables/TwoSumIII.java deleted file mode 100644 index 88916db0..00000000 --- a/src/main/java/com/leetcode/hashtables/TwoSumIII.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.leetcode.hashtables; - -import java.util.HashMap; -import java.util.Map; - -import static org.junit.jupiter.api.Assertions.assertTrue; - -/** - * Level: Easy - * Problem Link: https://leetcode.com/problems/two-sum-iii-data-structure-design/ - * Problem Description: - * Design and implement a TwoSum class. It should support the following operations: add and find. - *

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

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

- * Example 2: - * add(3); add(1); add(2); - * find(3) -> true - * find(6) -> false - * - * @author rampatra - * @since 2019-08-03 - */ -public class TwoSumIII { - - Map numCount; - - /** - * Initialize your data structure here. - */ - public TwoSumIII() { - this.numCount = new HashMap<>(); - } - - /** - * Add the number to an internal data structure.. - */ - public void add(int number) { - if (numCount.containsKey(number)) { - numCount.put(number, 2); - } else { - numCount.put(number, 1); - } - } - - /** - * Find if there exists any pair of numbers which sum is equal to the value. - */ - public boolean find(int value) { - for (Map.Entry entry : numCount.entrySet()) { - int num1 = entry.getKey(); - int num2 = value - num1; - if ((num2 == num1 && entry.getValue() == 2) || (num1 != num2 && numCount.containsKey(num2))) { - return true; - } - } - return false; - } - - /** - * Runtime: 115 ms. - * - * @param args - */ - public static void main(String[] args) { - TwoSumIII twoSumIII = new TwoSumIII(); - twoSumIII.add(0); - twoSumIII.add(-1); - twoSumIII.add(1); - assertTrue(twoSumIII.find(0)); - } -} \ No newline at end of file diff --git a/src/main/java/com/leetcode/hashtables/slidingwindow/LongestSubstringWithKDistinctCharacters.java b/src/main/java/com/leetcode/hashtables/slidingwindow/LongestSubstringWithKDistinctCharacters.java deleted file mode 100644 index 4b209b6e..00000000 --- a/src/main/java/com/leetcode/hashtables/slidingwindow/LongestSubstringWithKDistinctCharacters.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.leetcode.hashtables.slidingwindow; - -import java.util.HashMap; -import java.util.Map; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * Level: Hard - * Link: https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/ - * Description: - * Given a string, find the length of the longest substring T that contains at most k distinct characters. - *

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

- * Example 2: - * Input: s = "aa", k = 1 - * Output: 2 - * Explanation: T is "aa" which its length is 2. - * - * @author rampatra - * @since 2019-08-09 - */ -public class LongestSubstringWithKDistinctCharacters { - - /** - * Time Complexity: O(n) - * Space Complexity: O(k), as we keep at most k characters in the hash table - * - * @param str - * @param k - * @return - */ - public static int lengthOfLongestSubstringKDistinct(String str, int k) { - int length = 0; - Map letterCountInWindow = new HashMap<>(); - - int left = 0; // start of window - int right = 0; // end of window - - while (right < str.length()) { - char ch = str.charAt(right); - - letterCountInWindow.put(ch, letterCountInWindow.getOrDefault(ch, 0) + 1); - - // when number of distinct characters in the window exceeds k: - // - update length - // - remove the first character in the window or reduce its count if the window has more than one of this character - // - lastly, move the window forward - if (letterCountInWindow.keySet().size() > k) { - char firstChar = str.charAt(left); - int firstCharCount = letterCountInWindow.get(firstChar); - if (firstCharCount > 1) { - letterCountInWindow.put(firstChar, firstCharCount - 1); - } else { - letterCountInWindow.remove(firstChar); - } - length = Math.max(length, right - left); - left++; - } - right++; - } - - return Math.max(length, right - left); - } - - public static void main(String[] args) { - assertEquals(3, lengthOfLongestSubstringKDistinct("eceba", 2)); - assertEquals(7, lengthOfLongestSubstringKDistinct("eceeeeeba", 2)); - assertEquals(12, lengthOfLongestSubstringKDistinct("bbbeeeeebaaaaaaaaaaa", 2)); - assertEquals(2, lengthOfLongestSubstringKDistinct("abcdef", 2)); - assertEquals(1, lengthOfLongestSubstringKDistinct("a", 1)); - assertEquals(0, lengthOfLongestSubstringKDistinct("aa", 0)); - assertEquals(2, lengthOfLongestSubstringKDistinct("aa", 1)); - assertEquals(3, lengthOfLongestSubstringKDistinct("aaa", 1)); - assertEquals(3, lengthOfLongestSubstringKDistinct("aab", 2)); - assertEquals(8, lengthOfLongestSubstringKDistinct("abcabcbb", 3)); - assertEquals(5, lengthOfLongestSubstringKDistinct("pwwkew", 3)); - } -} diff --git a/src/main/java/com/leetcode/hashtables/slidingwindow/LongestSubstringWithoutRepeatingCharacters.java b/src/main/java/com/leetcode/hashtables/slidingwindow/LongestSubstringWithoutRepeatingCharacters.java deleted file mode 100644 index 93a940e4..00000000 --- a/src/main/java/com/leetcode/hashtables/slidingwindow/LongestSubstringWithoutRepeatingCharacters.java +++ /dev/null @@ -1,128 +0,0 @@ -package com.leetcode.hashtables.slidingwindow; - -import java.util.HashSet; -import java.util.Set; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * Level: Medium - * Link: https://leetcode.com/problems/longest-substring-without-repeating-characters/ - * Description: - * Given a string, find the length of the longest substring without repeating characters. - *

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

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

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

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

- * Commonly used tables are: - *

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

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

- * Example: - *

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

- * Note: - * - If there is no such window in S that covers all characters in T, return the empty string "". - * - If there is such window, you are guaranteed that there will always be only one unique minimum window in S. - * - * @author rampatra - * @since 2019-08-13 - */ -public class MinimumWindowSubstring { - - /** - * Sliding Window Approach (using map). - * - * Note: - * If we know that the charset is rather small, we can replace the Map with an integer array as direct access table. - * - * Commonly used tables are: - * - * int[26] for Letters 'a' - 'z' or 'A' - 'Z' - * int[128] for ASCII - * int[256] for Extended ASCII - * - * Runtime: 22 ms. - * - * @param s - * @param t - * @return - */ - public static String minWindow(String s, String t) { - - int left = 0; // start of window - int right = 0; // end of window - int begin = 0; - int windowSize = Integer.MAX_VALUE; - int charsInWindow = 0; // to check whether the window has all the characters in t with the required frequency - - // characters and their counts in t - Map dictT = new HashMap<>(); - for (int i = 0; i < t.length(); i++) { - char ch = t.charAt(i); - dictT.put(ch, dictT.getOrDefault(ch, 0) + 1); - } - - // characters and their counts in the window - Map dictWindow = new HashMap<>(); - - while (right < s.length()) { - char rightChar = s.charAt(right); - int rightCharCount; - dictWindow.put(rightChar, (rightCharCount = dictWindow.getOrDefault(rightChar, 0) + 1)); - - // once the window has a character in t with the required frequency, increment charsInWindow - if (dictT.get(rightChar) != null && dictT.get(rightChar).equals(rightCharCount)) { - charsInWindow++; - } - - // once the window has all characters in t with required frequency then shorten the window by moving the - // left window forward until the window no longer has all characters of t - while (left <= right && charsInWindow == dictT.size()) { - if (right - left < windowSize) { - windowSize = right - left + 1; - begin = left; - } - - char leftChar = s.charAt(left); - Integer leftCharCount = dictWindow.get(leftChar); - dictWindow.put(leftChar, leftCharCount - 1); - - if (dictT.get(leftChar) != null && leftCharCount - 1 < dictT.get(leftChar)) { - charsInWindow--; - } - left++; - } - right++; - } - - return windowSize == Integer.MAX_VALUE ? "" : s.substring(begin, begin + windowSize); - } - - public static void main(String[] args) { - assertEquals("BANC", minWindow("ADOBECODEBANC", "ABC")); - assertEquals("BAC", minWindow("ADOBECODEBAC", "ABC")); - assertEquals("ba", minWindow("bba", "ab")); - assertEquals("baca", minWindow("acbbaca", "aba")); - } -} \ No newline at end of file diff --git a/src/main/java/com/leetcode/heaps/KthLargestElementInArray.java b/src/main/java/com/leetcode/heaps/KthLargestElementInArray.java deleted file mode 100644 index 2422de08..00000000 --- a/src/main/java/com/leetcode/heaps/KthLargestElementInArray.java +++ /dev/null @@ -1,143 +0,0 @@ -package com.leetcode.heaps; - -import com.rampatra.base.MaxHeap; - -import java.util.PriorityQueue; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * Level: Medium - * Link: https://leetcode.com/problems/kth-largest-element-in-an-array/ - * Description: - * Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not - * the kth distinct element. - *

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

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

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

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

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

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

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

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

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

- * Runtime: 51 ms. - * - * @param nums - * @param k - * @return - */ - public static List topKFrequent(int[] nums, int k) { - Map numCount = new HashMap<>(); - PriorityQueue> pq = new PriorityQueue<>(Comparator.comparing(Pair::getValue)); - - for (int num : nums) { - numCount.put(num, numCount.getOrDefault(num, 0) + 1); - } - - for (Map.Entry entry : numCount.entrySet()) { - pq.add(new Pair<>(entry.getKey(), entry.getValue())); - - if (pq.size() > k) { - pq.poll(); - } - } - - return pq.stream().map(Pair::getKey).collect(Collectors.toList()); - } - - public static void main(String[] args) { - assertEquals("[2, 1]", topKFrequent(new int[]{1, 1, 1, 2, 2, 3}, 2).toString()); - assertEquals("[0]", topKFrequent(new int[]{3, 0, 1, 0}, 1).toString()); - assertEquals("[1]", topKFrequent(new int[]{1}, 1).toString()); - assertEquals("[1, 2]", topKFrequent(new int[]{1, 2}, 2).toString()); - assertEquals("[2, -1]", topKFrequent(new int[]{4, 1, -1, 2, -1, 2, 3}, 2).toString()); - } -} diff --git a/src/main/java/com/leetcode/linkedlists/AddOneToNumberInList.java b/src/main/java/com/leetcode/linkedlists/AddOneToNumberInList.java deleted file mode 100644 index 9f0a029c..00000000 --- a/src/main/java/com/leetcode/linkedlists/AddOneToNumberInList.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.leetcode.linkedlists; - -/** - * Level: Easy - * Problem Link: https://leetcode.com/problems/plus-one-linked-list/ - * Problem Description: Given a non-empty single linked list representing a number where the head is the - * most significant bit, add one to the number and return a new linked list. - * - * @author rampatra - * @since 2019-06-19 - */ -public class AddOneToNumberInList { - - - /** - * Add {@code one} to the number represented by linked list {@code head}. - * - * @param head the starting node of the linked list - * @return the head of the linked list after adding {@code one} - */ - private static Node addOne(Node head) { - Node currOrig = reverse(head); - Node currRes = null; - Node res = null; - - int sum = 1; - int carry = 0; - int rem; - - while (currOrig != null) { - sum += carry + currOrig.val; - rem = sum % 10; - carry = sum / 10; - - if (res == null) { - res = currRes = new Node(rem); - } else { - currRes.next = new Node(rem); - currRes = currRes.next; - } - - sum = 0; - currOrig = currOrig.next; - } - - if (carry != 0) { - currRes.next = new Node(carry); - } - - return reverse(res); - } - - private static Node reverse(Node head) { - Node prev = null; - Node curr = head; - Node next; - - while (curr != null) { - next = curr.next; - curr.next = prev; - - prev = curr; - curr = next; - } - - return prev; - } - - - public static void main(String[] args) { - Node node = new Node(9); - node.next = new Node(9); - node.next.next = new Node(9); - node.print(); - addOne(node).print(); - - System.out.println("---------"); - - node = new Node(1); - node.next = new Node(9); - node.next.next = new Node(9); - node.print(); - addOne(node).print(); - - System.out.println("---------"); - - node = new Node(0); - node.print(); - addOne(node).print(); - } -} \ No newline at end of file diff --git a/src/main/java/com/leetcode/linkedlists/LinkedListCycleII.java b/src/main/java/com/leetcode/linkedlists/LinkedListCycleII.java deleted file mode 100644 index d5fe0e50..00000000 --- a/src/main/java/com/leetcode/linkedlists/LinkedListCycleII.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.leetcode.linkedlists; - -/** - * Level: Medium - * Link: https://leetcode.com/problems/linked-list-cycle-ii/ - * Description: - * Given a linked list, return the node where the cycle begins. If there is no cycle, return null. - * - * To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in - * the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list. - * - * Note: Do not modify the linked list. - * - * Example 1: - * - * Input: head = [3,2,0,-4], pos = 1 - * Output: tail connects to node index 1 - * Explanation: There is a cycle in the linked list, where tail connects to the second node. - * - * - * Example 2: - * - * Input: head = [1,2], pos = 0 - * Output: tail connects to node index 0 - * Explanation: There is a cycle in the linked list, where tail connects to the first node. - * - * - * Example 3: - * - * Input: head = [1], pos = -1 - * Output: no cycle - * Explanation: There is no cycle in the linked list. - * - * Follow-up: - * Can you solve it without using extra space? - * - * @author rampatra - * @since 2019-08-18 - */ -public class LinkedListCycleII { - - /** - * Runtime: 0 ms. - * - * @param head - * @return - */ - public Node detectCycle(Node head) { - Node slow = head; - Node fast = head; - - while (fast != null && fast.next != null) { - slow = slow.next; - fast = fast.next.next; - if (slow == fast) { - break; - } - } - - if (fast == null || fast.next == null) { - return null; - } else { - slow = head; - - while (slow != fast) { - slow = slow.next; - fast = fast.next; - } - - return slow; - } - } -} \ No newline at end of file diff --git a/src/main/java/com/leetcode/linkedlists/Node.java b/src/main/java/com/leetcode/linkedlists/Node.java deleted file mode 100644 index 3276413f..00000000 --- a/src/main/java/com/leetcode/linkedlists/Node.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.leetcode.linkedlists; - -/** - * @author rampatra - * @since 21/11/2018 - */ -class Node { - int val; - Node next; - - Node(int val) { - this.val = val; - } - - public void print() { - Node curr = this; - while (curr.next != null) { - System.out.print(curr.val + "->"); - curr = curr.next; - } - System.out.println(curr.val); - } -} diff --git a/src/main/java/com/leetcode/math/BestMeetingPoint.java b/src/main/java/com/leetcode/math/BestMeetingPoint.java deleted file mode 100644 index 84d96fe9..00000000 --- a/src/main/java/com/leetcode/math/BestMeetingPoint.java +++ /dev/null @@ -1,141 +0,0 @@ -package com.leetcode.math; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * Level: Hard - * Link: https://leetcode.com/problems/best-meeting-point/ - * Description: - * A group of two or more people wants to meet and minimize the total travel distance. You are given a 2D grid - * of values 0 or 1, where each 1 marks the home of someone in the group. The distance is calculated using - * Manhattan Distance, where distance(p1, p2) = |p2.x - p1.x| + |p2.y - p1.y|. - * - * Example: - * - * Input: - * - * 1 - 0 - 0 - 0 - 1 - * | | | | | - * 0 - 0 - 0 - 0 - 0 - * | | | | | - * 0 - 0 - 1 - 0 - 0 - * - * Output: 6 - * - * Explanation: Given three people living at (0,0), (0,4), and (2,2): - * The point (0,2) is an ideal meeting point, as the total travel distance - * of 2+2+2=6 is minimal. So, return 6. - * - * @author rampatra - * @since 2019-08-07 - */ -public class BestMeetingPoint { - - /** - * Time Complexity: O(k * i * j) - * Space Complexity: O(1) - * where, - * k = no of homes - * i = rows in grid - * j = columns in grid - * - * So, if i = j = k then you can see that it has a O(n^3) time complexity. - * - * @param grid - * @return - */ - public static int minTotalDistanceBrutForce(int[][] grid) { - int minDistance = Integer.MAX_VALUE; - List> homeCoordinates = new ArrayList<>(); - - for (int i = 0; i < grid.length; i++) { - for (int j = 0; j < grid[0].length; j++) { - if (grid[i][j] == 1) { - homeCoordinates.add(Arrays.asList(i, j)); - } - } - } - - for (int i = 0; i < grid.length; i++) { - for (int j = 0; j < grid[0].length; j++) { - int distance = 0; - for (int k = 0; k < homeCoordinates.size(); k++) { - distance += Math.abs(homeCoordinates.get(k).get(0) - i) + Math.abs(homeCoordinates.get(k).get(1) - j); - } - minDistance = Math.min(minDistance, distance); - } - } - - return minDistance; - } - - public static int minTotalDistance(int[][] grid) { - return -1; // todo - } - - public static void main(String[] args) { - assertEquals(6, minTotalDistanceBrutForce(new int[][]{ - {1,0,0,0,1}, - {0,0,0,0,0}, - {0,0,1,0,0} - })); - - assertEquals(4, minTotalDistanceBrutForce(new int[][]{ - {1,0,0,0,1}, - {0,0,0,0,0}, - {0,0,0,0,0} - })); - - assertEquals(1, minTotalDistanceBrutForce(new int[][]{ - {1,1,0,0,0}, - {0,0,0,0,0}, - {0,0,0,0,0} - })); - - assertEquals(0, minTotalDistanceBrutForce(new int[][]{ - {1,0,0,0,0}, - {0,0,0,0,0}, - {0,0,0,0,0} - })); - - assertEquals(0, minTotalDistanceBrutForce(new int[][]{ - {0,0,0,0,0}, - {0,0,0,0,0}, - {0,0,0,0,0} - })); - - assertEquals(6, minTotalDistance(new int[][]{ - {1,0,0,0,1}, - {0,0,0,0,0}, - {0,0,1,0,0} - })); - - assertEquals(4, minTotalDistance(new int[][]{ - {1,0,0,0,1}, - {0,0,0,0,0}, - {0,0,0,0,0} - })); - - assertEquals(1, minTotalDistance(new int[][]{ - {1,1,0,0,0}, - {0,0,0,0,0}, - {0,0,0,0,0} - })); - - assertEquals(0, minTotalDistance(new int[][]{ - {1,0,0,0,0}, - {0,0,0,0,0}, - {0,0,0,0,0} - })); - - assertEquals(0, minTotalDistance(new int[][]{ - {0,0,0,0,0}, - {0,0,0,0,0}, - {0,0,0,0,0} - })); - } -} \ No newline at end of file diff --git a/src/main/java/com/leetcode/math/ExcelSheetColumnNumber.java b/src/main/java/com/leetcode/math/ExcelSheetColumnNumber.java deleted file mode 100644 index 29e1dded..00000000 --- a/src/main/java/com/leetcode/math/ExcelSheetColumnNumber.java +++ /dev/null @@ -1,44 +0,0 @@ -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 deleted file mode 100644 index 7e540778..00000000 --- a/src/main/java/com/leetcode/math/ReverseInteger.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.leetcode.math; - -/** - * Level: Easy - * Problem Link: https://leetcode.com/problems/reverse-integer/ - * Problem Description: - * Given a 32-bit signed integer, reverse digits of an integer. - *

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

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

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

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

- * Runtime: 1 ms. - * - * @param num an integer. - * @return the reverse of {@code num}. - */ - private static int reverse(int num) { - long reverse = 0; - int pop; - - while (num != 0) { - pop = num % 10; - num = num / 10; - reverse = reverse * 10 + pop; - } - - return reverse < Integer.MIN_VALUE || reverse > Integer.MAX_VALUE ? 0 : (int) reverse; - } - - public static void main(String[] args) { - System.out.println(reverse(0)); - System.out.println(reverse(-0)); - System.out.println(reverse(123)); - System.out.println(reverse(-123)); - System.out.println(reverse(Integer.MAX_VALUE)); - System.out.println(reverse(Integer.MIN_VALUE)); - } -} \ No newline at end of file diff --git a/src/main/java/com/leetcode/recursion/FlattenNestListIterator.java b/src/main/java/com/leetcode/recursion/FlattenNestListIterator.java deleted file mode 100644 index b443e954..00000000 --- a/src/main/java/com/leetcode/recursion/FlattenNestListIterator.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.leetcode.recursion; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -/** - * Level: Medium - * Link: https://leetcode.com/problems/flatten-nested-list-iterator/ - * Description: - * Given a nested list of integers, implement an iterator to flatten it. - * - * Each element is either an integer, or a list -- whose elements may also be integers or other lists. - * - * Example 1: - * Input: [[1,1],2,[1,1]] - * Output: [1,1,2,1,1] - * Explanation: By calling next repeatedly until hasNext returns false, - * the order of elements returned by next should be: [1,1,2,1,1]. - * - * Example 2: - * Input: [1,[4,[6]]] - * Output: [1,4,6] - * Explanation: By calling next repeatedly until hasNext returns false, - * the order of elements returned by next should be: [1,4,6]. - * - * Runtime: 2 ms. - * - * @author rampatra - * @since 2019-08-12 - */ -public class FlattenNestListIterator implements Iterator { - - private int index; - private List flattenedList; - - public FlattenNestListIterator(List nestedList) { - index = 0; - flattenedList = getFlattenedList(nestedList); - } - - private List getFlattenedList(List nestedList) { - List flattenedList = new ArrayList<>(); - - for (NestedInteger nestedInteger : nestedList) { - if (nestedInteger.isInteger()) { - flattenedList.add(nestedInteger.getInteger()); - } else { - flattenedList.addAll(getFlattenedList(nestedInteger.getList())); - } - } - - return flattenedList; - } - - @Override - public Integer next() { - return flattenedList.get(index++); - } - - @Override - public boolean hasNext() { - return index < flattenedList.size(); - } - - public static void main(String[] args) { - // TODO add some test cases - } -} \ No newline at end of file diff --git a/src/main/java/com/leetcode/recursion/NestedInteger.java b/src/main/java/com/leetcode/recursion/NestedInteger.java deleted file mode 100644 index 1bba817e..00000000 --- a/src/main/java/com/leetcode/recursion/NestedInteger.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.leetcode.recursion; - -import java.util.ArrayList; -import java.util.List; - -/** - * Class needed for various problems like {@link NestedListWeightSumII}, {@link FlattenNestListIterator}, etc. - * - * @author rampatra - * @since 2019-08-12 - */ -public class NestedInteger { - - private Integer integer; - private List list; - - public NestedInteger() { - this.list = new ArrayList<>(); - } - - public NestedInteger(int integer) { - this.integer = integer; - this.list = new ArrayList<>(); - } - - public boolean isInteger() { - return this.integer != null; - } - - public Integer getInteger() { - return integer; - } - - public void setInteger(Integer integer) { - this.integer = integer; - } - - public List getList() { - return list; - } - - public NestedInteger add(NestedInteger nestedInteger) { - this.list.add(nestedInteger); - return this; - } -} diff --git a/src/main/java/com/leetcode/recursion/NestedListWeightSum.java b/src/main/java/com/leetcode/recursion/NestedListWeightSum.java deleted file mode 100644 index 1079b29f..00000000 --- a/src/main/java/com/leetcode/recursion/NestedListWeightSum.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.leetcode.recursion; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * Level: Easy - * Problem Link: https://leetcode.com/problems/nested-list-weight-sum/ - * Problem Description: - * Given a nested list of integers, return the sum of all integers in the list weighted by their depth. Each element - * is either an integer, or a list – whose elements may also be integers or other lists. - *

- * 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 deleted file mode 100644 index eadd121b..00000000 --- a/src/main/java/com/leetcode/recursion/NestedListWeightSumII.java +++ /dev/null @@ -1,80 +0,0 @@ -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 nestedList) { - int weightedSum = 0; - int unweightedSum = 0; - - while (!nestedList.isEmpty()) { - List nextLevel = new ArrayList<>(); - - for (NestedInteger ni : nestedList) { - if (ni.isInteger()) { - unweightedSum += ni.getInteger(); - } else { - nextLevel.addAll(ni.getList()); - } - } - - unweightedSum += unweightedSum; // multiplication by repetitive addition - weightedSum = unweightedSum; - nestedList = nextLevel; - } - - return weightedSum; - } - - public static void main(String[] args) { - assertEquals(0, nestedSum(Collections.singletonList(new NestedInteger()))); - - assertEquals(0, nestedSum(Collections.singletonList(new NestedInteger().add(new NestedInteger())))); - - // TODO: fix the test cases - // {2, {1,1}, {1,1}} - NestedInteger ni = new NestedInteger(2); - ni.add(new NestedInteger().add(new NestedInteger(1)).add(new NestedInteger(1))); - ni.add(new NestedInteger().add(new NestedInteger(1)).add(new NestedInteger(1))); - - assertEquals(6, nestedSum(Collections.singletonList(ni))); - - // {1, {4, {6}}} - ni = new NestedInteger(1); - ni.add(new NestedInteger(4).add(new NestedInteger(6))); - - assertEquals(17, nestedSum(Collections.singletonList(ni))); - } -} \ No newline at end of file diff --git a/src/main/java/com/leetcode/stacks/ExclusiveTimeOfFunctions.java b/src/main/java/com/leetcode/stacks/ExclusiveTimeOfFunctions.java deleted file mode 100644 index 63c61dc2..00000000 --- a/src/main/java/com/leetcode/stacks/ExclusiveTimeOfFunctions.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.leetcode.stacks; - -import javafx.util.Pair; - -import java.util.Arrays; -import java.util.List; -import java.util.Stack; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * Level: Medium - * Link: https://leetcode.com/problems/exclusive-time-of-functions/ - * Description: - * On a single threaded CPU, we execute some functions. Each function has a unique id between 0 and N-1. - * - * We store logs in timestamp order that describe when a function is entered or exited. - * - * Each log is a string with this format: "{function_id}:{"start" | "end"}:{timestamp}". For example, "0:start:3" - * means the function with id 0 started at the beginning of timestamp 3. "1:end:2" means the function with id 1 ended - * at the end of timestamp 2. - * - * A function's exclusive time is the number of units of time spent in this function. Note that this does not include - * any recursive calls to child functions. - * - * The CPU is single threaded which means that only one function is being executed at a given time unit. - * - * Return the exclusive time of each function, sorted by their function id. - * - * Input: - * n = 2 - * logs = ["0:start:0","1:start:2","1:end:5","0:end:6"] - * Output: [3, 4] - * Explanation: - * Function 0 starts at the beginning of time 0, then it executes 2 units of time and reaches the end of time 1. - * Now function 1 starts at the beginning of time 2, executes 4 units of time and ends at time 5. - * Function 0 is running again at the beginning of time 6, and also ends at the end of time 6, thus executing for 1 unit of time. - * So function 0 spends 2 + 1 = 3 units of total time executing, and function 1 spends 4 units of total time executing. - * - * - * Note: - * -> 1 <= n <= 100 - * -> Two functions won't start or end at the same time. - * -> Functions will always log when they exit. - * - * @author rampatra - * @since 2019-08-17 - */ -public class ExclusiveTimeOfFunctions { - - /** - * Runtime: 18 ms. - * - * @param n - * @param logs - * @return - */ - public static int[] exclusiveTime(int n, List logs) { - int[] times = new int[n]; - Stack> stack = new Stack<>(); - - for (String log : logs) { - String[] l = log.split(":"); - int id = Integer.parseInt(l[0]); - String operation = l[1]; - int timestamp = Integer.parseInt(l[2]); - - if (operation.equals("start")) { - if (!stack.empty()) { // if there are other processes started before, calculate their time until now - times[stack.peek().getKey()] += (timestamp - stack.peek().getValue() - 1); - } - stack.push(new Pair<>(id, timestamp)); - } else { - times[id] += timestamp - stack.pop().getValue() + 1; - if (!stack.isEmpty()) { // if there are other processes, make their start time to now - stack.push(new Pair<>(stack.pop().getKey(), timestamp)); - } - } - } - - return times; - } - - public static void main(String[] args) { - assertEquals("[4]", Arrays.toString(exclusiveTime(1, Arrays.asList("0:start:0", "0:start:1", "0:end:2", "0:end:3")))); - assertEquals("[6]", Arrays.toString(exclusiveTime(1, Arrays.asList("0:start:0", "0:start:1", "0:start:2", "0:end:3", "0:end:4", "0:end:5")))); - assertEquals("[3, 4]", Arrays.toString(exclusiveTime(2, Arrays.asList("0:start:0", "1:start:2", "1:end:5", "0:end:6")))); - } -} \ No newline at end of file diff --git a/src/main/java/com/leetcode/stacks/ReversePolishNotation.java b/src/main/java/com/leetcode/stacks/ReversePolishNotation.java deleted file mode 100644 index f917099a..00000000 --- a/src/main/java/com/leetcode/stacks/ReversePolishNotation.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.leetcode.stacks; - -import java.util.Stack; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * Level: Medium - * Problem Link: https://leetcode.com/problems/evaluate-reverse-polish-notation - * Problem Description: - * Evaluate the value of an arithmetic expression in Reverse Polish Notation. - *

- * Valid operators are +, -, *, /. Each operand may be an integer or another expression. - *

- * Note: - * Division between two integers should truncate toward zero. - * The given RPN expression is always valid. That means the expression would always evaluate to a result and there - * won't be any divide by zero operation. - *

- * Example 1: - * Input: ["2", "1", "+", "3", "*"] - * Output: 9 - * Explanation: ((2 + 1) * 3) = 9 - *

- * Example 2: - * Input: ["4", "13", "5", "/", "+"] - * Output: 6 - * Explanation: (4 + (13 / 5)) = 6 - *

- * Example 3: - * Input: ["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"] - * Output: 22 - * Explanation: - * ((10 * (6 / ((9 + 3) * -11))) + 17) + 5 - * = ((10 * (6 / (12 * -11))) + 17) + 5 - * = ((10 * (6 / -132)) + 17) + 5 - * = ((10 * 0) + 17) + 5 - * = (0 + 17) + 5 - * = 17 + 5 - * = 22 - * - * @author rampatra - * @since 2019-07-27 - */ -public class ReversePolishNotation { - - /** - * Time Complexity: - * Space Complexity: - * Runtime: 5 ms. - * - * @param tokens - * @return - */ - public static int evalRPN(String[] tokens) { - int operand1; - int operand2; - - Stack stack = new Stack<>(); - - for (String s : tokens) { - switch (s) { - case "+": - stack.push(stack.pop() + stack.pop()); - break; - case "-": - operand1 = stack.pop(); - operand2 = stack.pop(); - stack.push(operand2 - operand1); - break; - case "*": - stack.push(stack.pop() * stack.pop()); - break; - case "/": - operand1 = stack.pop(); - operand2 = stack.pop(); - stack.push(operand2 / operand1); - break; - default: - stack.push(Integer.parseInt(s)); - } - } - - return stack.pop(); - } - - public static void main(String[] args) { - assertEquals(18, evalRPN(new String[]{"18"})); - assertEquals(9, evalRPN(new String[]{"2", "1", "+", "3", "*"})); - assertEquals(6, evalRPN(new String[]{"4", "13", "5", "/", "+"})); - assertEquals(22, evalRPN(new String[]{"10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"})); - } -} diff --git a/src/main/java/com/leetcode/strings/AnagramsInString.java b/src/main/java/com/leetcode/strings/AnagramsInString.java deleted file mode 100644 index 12e7d766..00000000 --- a/src/main/java/com/leetcode/strings/AnagramsInString.java +++ /dev/null @@ -1,143 +0,0 @@ -package com.leetcode.strings; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * Level: Medium - * Problem: https://leetcode.com/problems/find-all-anagrams-in-a-string/ - * Description: - * Given a string s and a non-empty string p, find all the start indices of p's anagrams in s. - * - * Strings consists of lowercase English letters only and the length of both strings s and p will not be larger - * than 20,100. - * - * The order of output does not matter. - * - * Example 1: - * - * Input: - * s: "cbaebabacd" p: "abc" - * - * Output: - * [0, 6] - * - * Explanation: - * The substring with start index = 0 is "cba", which is an anagram of "abc". - * The substring with start index = 6 is "bac", which is an anagram of "abc". - * - * Example 2: - * - * Input: - * s: "abab" p: "ab" - * - * Output: - * [0, 1, 2] - * - * Explanation: - * The substring with start index = 0 is "ab", which is an anagram of "ab". - * The substring with start index = 1 is "ba", which is an anagram of "ab". - * The substring with start index = 2 is "ab", which is an anagram of "ab". - * - * @author rampatra - * @since 2019-04-13 - */ -public class AnagramsInString { - - /** - * Time complexity: O((n-m) * m log m) - * where, - * n = text length - * m = pattern length - * - * @param text - * @param pattern - * @return - */ - private static List findAllAnagramsInTextNaive(String text, String pattern) { - List indexes = new ArrayList<>(); - - int textLen = text.length(); - int patternLen = pattern.length(); - - char[] patternChars = pattern.toCharArray(); - Arrays.sort(patternChars); // takes O(m log m) time - String patternSorted = String.valueOf(patternChars); - - String subText; - char[] subTextChars; - String subTextSorted; - - for (int i = 0; i <= textLen - patternLen; i++) { // loops n-m number of times - subText = text.substring(i, i + patternLen); - subTextChars = subText.toCharArray(); - Arrays.sort(subTextChars); // sorts m number of characters, takes O(m log m) - subTextSorted = String.valueOf(subTextChars); - - if (subTextSorted.equals(patternSorted)) { // compare m characters takes m time - indexes.add(i); - } - } - return indexes; - } - - /** - * Time complexity: O(n) - * where, - * n = length of text or number of characters in text - *

- * Runtime: 6 ms. - * - * @param text - * @param pattern - * @return - */ - private static List findAllAnagramsInText(String text, String pattern) { - List indices = new ArrayList<>(); - - int textLen = text.length(); - int patternLen = pattern.length(); - - int[] textCharCountInWindow = new int[26]; - int[] patternCharCount = new int[26]; - - for (int i = 0; i < patternLen; i++) { - patternCharCount[pattern.charAt(i) - 'a']++; - } - - for (int i = 0; i < textLen; i++) { - textCharCountInWindow[text.charAt(i) - 'a']++; - if (i >= patternLen) { - textCharCountInWindow[text.charAt(i - patternLen) - 'a']--; - } - if (Arrays.equals(textCharCountInWindow, patternCharCount)) { // loops 26 times no matter the text/pattern length - indices.add(i - patternLen + 1); - } - } - - return indices; - } - - public static void main(String[] args) { - // basic use cases - System.out.println(findAllAnagramsInTextNaive("cbaebabacd", "abc")); - System.out.println(findAllAnagramsInTextNaive("abab", "ab")); - System.out.println(findAllAnagramsInTextNaive("af", "af")); - System.out.println(findAllAnagramsInTextNaive("af", "be")); - - // corner case - System.out.println(findAllAnagramsInTextNaive("", "ab")); - - System.out.println("-----"); - - // basic use cases - System.out.println(findAllAnagramsInText("cbaebabacd", "abc")); - System.out.println(findAllAnagramsInText("abab", "ab")); - System.out.println(findAllAnagramsInText("af", "af")); - System.out.println(findAllAnagramsInText("af", "be")); - - // corner case - System.out.println(findAllAnagramsInText("", "ab")); - } -} \ No newline at end of file diff --git a/src/main/java/com/leetcode/strings/CountAndSay.java b/src/main/java/com/leetcode/strings/CountAndSay.java deleted file mode 100644 index 24f41a3e..00000000 --- a/src/main/java/com/leetcode/strings/CountAndSay.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.leetcode.strings; - -/** - * Level: Easy - * Problem: https://leetcode.com/problems/count-and-say/ - * - * @author rampatra - * @since 2019-04-20 - */ -public class CountAndSay { - - /** - * Time complexity: - * Runtime: 1 ms. - * - * @param n - * @return - */ - public static String countAndSay(int n) { - if (n == 1) return "1"; - - String s = countAndSay(n - 1); - StringBuilder sb = new StringBuilder(); - int count = 0; - - for (int i = 0; i < s.length(); i++) { - count++; - - if (i + 1 >= s.length() || s.charAt(i) != s.charAt(i + 1)) { - sb.append(count); - sb.append(s.charAt(i)); - count = 0; - } - } - - return sb.toString(); - } - - public static void main(String[] args) { - System.out.println(countAndSay(1)); - System.out.println(countAndSay(2)); - System.out.println(countAndSay(3)); - System.out.println(countAndSay(4)); - System.out.println(countAndSay(5)); - System.out.println(countAndSay(6)); - System.out.println(countAndSay(10)); - } -} \ No newline at end of file diff --git a/src/main/java/com/leetcode/strings/LongestCommonPrefix.java b/src/main/java/com/leetcode/strings/LongestCommonPrefix.java deleted file mode 100644 index 07bd6392..00000000 --- a/src/main/java/com/leetcode/strings/LongestCommonPrefix.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.leetcode.strings; - -/** - * Level: Easy - * Problem: https://leetcode.com/problems/longest-common-prefix/ - * - * @author rampatra - * @since 2019-04-20 - */ -public class LongestCommonPrefix { - - /** - * Time complexity: O(r * c) - * where, - * r = no. of strings - * c = max. no. of characters in a particular string - *

- * Runtime: 1 ms. - * - * @param strs - * @return - */ - public static String longestCommonPrefix(String[] strs) { - 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 deleted file mode 100644 index c6b66fb0..00000000 --- a/src/main/java/com/leetcode/strings/RansomNote.java +++ /dev/null @@ -1,40 +0,0 @@ -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 deleted file mode 100644 index 4a5aabd4..00000000 --- a/src/main/java/com/leetcode/strings/ReverseStringII.java +++ /dev/null @@ -1,46 +0,0 @@ -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 deleted file mode 100644 index 25518cac..00000000 --- a/src/main/java/com/leetcode/strings/ReverseVowels.java +++ /dev/null @@ -1,66 +0,0 @@ -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 deleted file mode 100644 index aa3bc896..00000000 --- a/src/main/java/com/leetcode/strings/StrStr.java +++ /dev/null @@ -1,59 +0,0 @@ -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 deleted file mode 100644 index 7697f591..00000000 --- a/src/main/java/com/leetcode/strings/StringCompression.java +++ /dev/null @@ -1,15 +0,0 @@ -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 deleted file mode 100644 index da155710..00000000 --- a/src/main/java/com/leetcode/strings/UniqueCharacterInString.java +++ /dev/null @@ -1,38 +0,0 @@ -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 deleted file mode 100644 index 451849b6..00000000 --- a/src/main/java/com/leetcode/strings/ValidPalindrome.java +++ /dev/null @@ -1,59 +0,0 @@ -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 deleted file mode 100644 index aa43bf50..00000000 --- a/src/main/java/com/leetcode/trees/BinaryTreeUpsideDown.java +++ /dev/null @@ -1,207 +0,0 @@ -package com.leetcode.trees; - -import java.util.Stack; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; - -/** - * Level: Medium - * Problem Link: https://leetcode.com/problems/binary-tree-upside-down/ - * Problem Description: - * Given a binary tree where all the right nodes are either leaf nodes with a sibling (a left node that shares the - * same parent node) or empty, flip it upside down and turn it into a tree where the original right nodes turned into - * left leaf nodes. Return the new root. - * - * Example: - * Input: [1,2,3,4,5] - * - * 1 - * / \ - * 2 3 - * / \ - * 4 5 - * - * Output: return the root of the binary tree [4,5,2,#,#,3,1] - * - * 4 - * / \ - * 5 2 - * / \ - * 3 1 - * - * Clarification: - * Confused what [4,5,2,#,#,3,1] means? Read more below on how binary tree is serialized on OJ. The serialization of - * a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below. - * - * Here's an example: - * - * 1 - * / \ - * 2 3 - * / - * 4 - * \ - * 5 - * - * The above binary tree is serialized as [1,2,3,#,#,4,#,#,5]. - * - * @author rampatra - * @since 2019-08-04 - */ -public class BinaryTreeUpsideDown { - - /** - * The solution is simple, every node (except the root) on the left of the tree would have its parent's right child - * as it's left child and parent as its right child. That's all you have to do to flip the tree upside down. - * - * Time Complexity: O(h) - * Space Complexity: O(h) - * where, - * h = height of the tree - * - * Runtime: 1 ms. - * - * @param root - * @return - */ - public static TreeNode upsideDownBinaryTreeUsingStack(TreeNode root) { - if (root == null) return null; - - TreeNode curr = root; - TreeNode currParent; - TreeNode newRoot = null; - - // using stack to keep track of the parent node - Stack stack = new Stack<>(); - - while (curr != null) { - stack.add(curr); - curr = curr.left; - } - - while (!stack.empty()) { - curr = stack.pop(); - currParent = stack.empty() ? null : stack.peek(); - - if (newRoot == null) newRoot = curr; - - if (currParent != null) { - curr.left = currParent.right; - curr.right = currParent; - } else { - curr.left = null; - curr.right = null; - } - } - - return newRoot; - } - - /** - * The solution is simple, every node (except the root) on the left of the tree would have its parent's right child - * as it's left child and parent as its right child. That's all you have to do to flip the tree upside down. - * - * Time Complexity: O(h) - * Space Complexity: O(h) - * where, - * h = height of the tree - * - * Runtime: 0 ms. - * - * @param node - * @return - */ - public static TreeNode upsideDownBinaryTree(TreeNode node) { - if (node == null || node.left == null) return node; - - // go to the last node on the extreme left branch - TreeNode newRoot = upsideDownBinaryTree(node.left); - - // do the node changes as you backtrack - node.left.left = node.right; - node.left.right = node; - - // clean up - node.left = null; - node.right = null; - - return newRoot; - } - - public static void main(String[] args) { - /* - Binary Tree - - 1 - / \ - 2 3 - / \ - 4 5 - */ - TreeNode tree = new TreeNode(1); - tree.left = new TreeNode(2); - tree.right = new TreeNode(3); - tree.left.left = new TreeNode(4); - tree.left.right = new TreeNode(5); - - /* - Upside Down Binary Tree - - 4 - / \ - 5 2 - / \ - 3 1 - */ - TreeNode upsideDownTree = upsideDownBinaryTreeUsingStack(tree); - assertEquals(4, upsideDownTree.val); - assertEquals(5, upsideDownTree.left.val); - assertEquals(2, upsideDownTree.right.val); - assertEquals(1, upsideDownTree.right.right.val); - assertEquals(3, upsideDownTree.right.left.val); - assertNull(upsideDownTree.right.right.left); - assertNull(upsideDownTree.right.right.right); - - - - /****************************** - * - * Test for the recursive method - * - ******************************/ - - /* - Binary Tree - - 1 - / \ - 2 3 - / \ - 4 5 - */ - tree = new TreeNode(1); - tree.left = new TreeNode(2); - tree.right = new TreeNode(3); - tree.left.left = new TreeNode(4); - tree.left.right = new TreeNode(5); - - /* - Upside Down Binary Tree - - 4 - / \ - 5 2 - / \ - 3 1 - */ - upsideDownTree = upsideDownBinaryTree(tree); - assertEquals(4, upsideDownTree.val); - assertEquals(5, upsideDownTree.left.val); - assertEquals(2, upsideDownTree.right.val); - assertEquals(1, upsideDownTree.right.right.val); - assertEquals(3, upsideDownTree.right.left.val); - assertNull(upsideDownTree.right.right.right); - assertNull(upsideDownTree.right.right.left); - } -} \ No newline at end of file diff --git a/src/main/java/com/leetcode/trees/BinaryTreeZigZagLevelOrderTraversal.java b/src/main/java/com/leetcode/trees/BinaryTreeZigZagLevelOrderTraversal.java deleted file mode 100644 index 1a54d952..00000000 --- a/src/main/java/com/leetcode/trees/BinaryTreeZigZagLevelOrderTraversal.java +++ /dev/null @@ -1,100 +0,0 @@ -package com.leetcode.trees; - -import java.util.*; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * Level: Medium - * Link: https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/ - * Description: - * Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then - * right to left for the next level and alternate between). - * - * For example: - * Given binary tree [3,9,20,null,null,15,7], - * 3 - * / \ - * 9 20 - * / \ - * 15 7 - * return its zigzag level order traversal as: - * [ - * [3], - * [20,9], - * [15,7] - * ] - * - * @author rampatra - * @since 2019-08-11 - */ -public class BinaryTreeZigZagLevelOrderTraversal { - - /** - * Time Complexity: - * Space Complexity: - * Runtime: 1 ms. - * - * @param root - * @return - */ - public static List> zigzagLevelOrder(TreeNode root) { - - int levelNo = 0; - LinkedList currLevel = new LinkedList<>(); - List> levelOrderTraversal = new LinkedList<>(); - - if (root == null) { - return levelOrderTraversal; - } - - Queue queue = new LinkedList<>(); - queue.add(root); - queue.add(null); - - while (!queue.isEmpty()) { - - TreeNode treeNode = queue.poll(); - - if (treeNode == null) { - levelOrderTraversal.add(currLevel); - currLevel = new LinkedList<>(); - levelNo++; - - if (queue.size() > 0) { - queue.add(null); - } - } else { - if (levelNo % 2 == 0) { - currLevel.add(treeNode.val); - } else { - currLevel.add(0, treeNode.val); - } - if (treeNode.left != null) queue.add(treeNode.left); - if (treeNode.right != null) queue.add(treeNode.right); - } - } - - return levelOrderTraversal; - } - - public static void main(String[] args) { - /* - Binary Tree - - 1 - / \ - 2 3 - / \ - 4 5 - */ - TreeNode tree = new TreeNode(1); - tree.left = new TreeNode(2); - tree.right = new TreeNode(3); - tree.left.left = new TreeNode(4); - tree.left.right = new TreeNode(5); - - assertEquals("[[1], [3, 2], [4, 5]]", zigzagLevelOrder(tree).toString()); - assertEquals("[]", zigzagLevelOrder(null).toString()); - } -} diff --git a/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValue.java b/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValue.java deleted file mode 100644 index ca6d94b7..00000000 --- a/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValue.java +++ /dev/null @@ -1,110 +0,0 @@ -package com.leetcode.trees; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * Level: Easy - * Problem Link: https://leetcode.com/problems/closest-binary-search-tree-value/ - * Problem Description: - * Given a non-empty binary search tree and a target value, find the value in the BST that is closest to the target. - *

- * Note: - * - Given target value is a floating point. - * - You are guaranteed to have only one unique value in the BST that is closest to the target. - * - * @author rampatra - * @since 2019-07-31 - */ -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 deleted file mode 100644 index e583723a..00000000 --- a/src/main/java/com/leetcode/trees/ClosestBinarySearchTreeValueII.java +++ /dev/null @@ -1,166 +0,0 @@ -package com.leetcode.trees; - -import java.util.LinkedList; -import java.util.List; -import java.util.Queue; -import java.util.Stack; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * Level: Hard - * Problem Link: https://leetcode.com/problems/closest-binary-search-tree-value-ii/ - * Problem Description: - * Given a non-empty binary search tree and a target value, find k values in the BST that are closest to the target. - * - * Note: - * - Given target value is a floating point. - * - You may assume k is always valid, that is: k ≤ total nodes. - * - You are guaranteed to have only one unique set of k values in the BST that are closest to the target. - * - * Example: - * Input: root = [4,2,5,1,3], target = 3.714286, and k = 2 - * - * 4 - * / \ - * 2 5 - * / \ - * 1 3 - * - * Output: [4,3] - * - * Follow up: - * Assume that the BST is balanced, could you solve it in less than O(n) runtime (where n = total nodes)? - * - * @author rampatra - * @since 2019-07-31 - */ -public class ClosestBinarySearchTreeValueII { - - - /** - * The idea is simple. We do the inorder traversal and keep the values less than or equal to target in a stack and - * the values greater than target in a queue. And finally, we compare values from both stack and queue and take - * whichever is the closest to target value each time. - * - * Note: We can optimize it even further in terms of space. We can get rid of the stack and queue and just fill up - * the result list in the recursive inOrder call. Once the result list is of size k, we can compare and remove the - * farthest value and insert the closer value. See {@link ClosestBinarySearchTreeValueII#closestKValuesOptimized(TreeNode, double, int)}. - * - * @param root - * @param target - * @param k - * @return - */ - public static List closestKValues(TreeNode root, double target, int k) { - int count = 0; - List closestKValues = new LinkedList<>(); - - Stack predecessors = new Stack<>(); - Queue successors = new LinkedList<>(); - inOrder(root, predecessors, successors, target, k); - - while (count < k) { - if (predecessors.empty()) { - closestKValues.add(successors.poll()); - } else if (successors.isEmpty()) { - closestKValues.add(predecessors.pop()); - } else if (Math.abs(target - predecessors.peek()) < Math.abs(target - successors.peek())) { - closestKValues.add(predecessors.pop()); - } else { - closestKValues.add(successors.poll()); - } - count++; - } - - return closestKValues; - } - - private static void inOrder(TreeNode root, Stack predecessors, Queue successors, double target, int k) { - if (root == null || successors.size() == k) return; - inOrder(root.left, predecessors, successors, target, k); - if (root.val <= target) { - predecessors.add(root.val); - } else { - successors.add(root.val); - } - inOrder(root.right, predecessors, successors, target, k); - } - - - /** - * This approach is similar to the above one but it doesn't use stack or queue. - * - * @param root - * @param target - * @param k - * @return - */ - public static List closestKValuesOptimized(TreeNode root, double target, int k) { - LinkedList closestKValues = new LinkedList<>(); - inOrder(root, target, k, closestKValues); - return closestKValues; - } - - private static void inOrder(TreeNode root, double target, int k, LinkedList closestKValues) { - if (root == null) return; - - inOrder(root.left, target, k, closestKValues); - if (closestKValues.size() == k) { - //if size k, add current and remove head if it's closer to target, otherwise return - if (Math.abs(target - root.val) < Math.abs(target - closestKValues.peekFirst())) - closestKValues.removeFirst(); - else { - return; - } - } - closestKValues.add(root.val); - inOrder(root.right, target, k, closestKValues); - } - - public static void main(String[] args) { - - /* - BST looks like: - - 9 - / \ - 7 13 - / \ \ - 5 8 20 - / \ - 2 6 - */ - TreeNode root = new TreeNode(9); - root.left = new TreeNode(7); - root.right = new TreeNode(13); - root.left.left = new TreeNode(5); - root.left.right = new TreeNode(8); - root.left.left.left = new TreeNode(2); - root.left.left.right = new TreeNode(6); - root.right.right = new TreeNode(20); - - assertEquals("[9, 8, 7, 6, 5]", closestKValues(root, 8.5, 5).toString()); - assertEquals("[5, 6, 7, 8, 9]", closestKValuesOptimized(root, 8.5, 5).toString()); - - /* - BST looks like: - - 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.right.left = new TreeNode(13); - root.left.right = new TreeNode(8); - root.right.right = new TreeNode(20); - - assertEquals("[13, 13, 9, 20, 8]", closestKValues(root, 14, 5).toString()); - assertEquals("[8, 9, 13, 13, 20]", closestKValuesOptimized(root, 14, 5).toString()); - } -} diff --git a/src/main/java/com/leetcode/trees/LeavesOfBinaryTree.java b/src/main/java/com/leetcode/trees/LeavesOfBinaryTree.java deleted file mode 100644 index 6ca15e22..00000000 --- a/src/main/java/com/leetcode/trees/LeavesOfBinaryTree.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.leetcode.trees; - -import java.util.ArrayList; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * Level: Medium - * Problem Link: https://leetcode.com/problems/find-leaves-of-binary-tree/ - * Problem Description: - * Given a binary tree, collect a tree's nodes as if you were doing this: Collect and remove all leaves, repeat - * until the tree is empty. - * - * Example: - * Input: [1,2,3,4,5] - * - * 1 - * / \ - * 2 3 - * / \ - * 4 5 - * - * Output: [[4,5,3],[2],[1]] - * - * Explanation: - * 1. Removing the leaves [4,5,3] would result in this tree: - * 1 - * / - * 2 - * - * 2. Now removing the leaf [2] would result in this tree: - * 1 - * - * 3. Now removing the leaf [1] would result in the empty tree: - * [] - * - * @author rampatra - * @since 2019-08-01 - */ -public class LeavesOfBinaryTree { - - /** - * THe idea is to perform a DFS and backtrack. While backtracking, check the height of the node and insert - * the node into the list indexed by their heights. - * Time Complexity: - * Space Complexity: - * Runtime: 1 ms. - * - * @param root - * @return - */ - public static List> findLeavesOfBinaryTree(TreeNode root) { - List> levels = new ArrayList<>(); - findLeavesOfBinaryTree(root, levels); - return levels; - } - - private static int findLeavesOfBinaryTree(TreeNode root, List> levels) { - if (root == null) return -1; - - int leftHeight = findLeavesOfBinaryTree(root.left, levels); - int rightHeight = findLeavesOfBinaryTree(root.right, levels); - int height = Math.max(leftHeight, rightHeight) + 1; - - if (height >= levels.size()) { - levels.add(height, new ArrayList<>()); - } - levels.get(height).add(root.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 deleted file mode 100644 index a8cddf74..00000000 --- a/src/main/java/com/leetcode/trees/SecondMinNodeInBinaryTree.java +++ /dev/null @@ -1,108 +0,0 @@ -package com.leetcode.trees; - -import java.util.Stack; - -/** - * Level: Easy - * Problem Link: https://leetcode.com/problems/second-minimum-node-in-a-binary-tree/ - * Problem Description: - * Given a non-empty special binary tree consisting of nodes with the non-negative value, where each node in this - * tree has exactly two or zero sub-node. If the node has two sub-nodes, then this node's value is the smaller value - * among its two sub-nodes. More formally, the property root.val = min(root.left.val, root.right.val) always holds. - * - * Given such a binary tree, you need to output the second minimum value in the set made of all the nodes' value in - * the whole tree. - * - * If no such second minimum value exists, output -1 instead. - * - * Example 1: - * Input: - * 2 - * / \ - * 2 5 - * / \ - * 5 7 - * - * Output: 5 - * Explanation: The smallest value is 2, the second smallest value is 5. - * - * - * Example 2: - * Input: - * 2 - * / \ - * 2 2 - * - * Output: -1 - * Explanation: The smallest value is 2, but there isn't any second smallest value. - * - * @author rampatra - * @since 2019-08-03 - */ -public class SecondMinNodeInBinaryTree { - - /** - * Time Complexity: O(n) - * Space Complexity: O(n) - * Runtime: 1 ms. - * @param root - * @return - */ - public static int findSecondMinimumValueIterative(TreeNode root) { - if (root == null || (root.left == null && root.right == null)) return -1; - - int min = root.val; - long secondMin = Long.MAX_VALUE; - - Stack stack = new Stack<>(); - stack.push(root); - - while (!stack.empty()) { - TreeNode node = stack.pop(); - if (node == null) continue; - - if (node.val > min && node.val < secondMin) { - secondMin = node.val; - } - stack.push(node.left); - stack.push(node.right); - } - - return secondMin == Long.MAX_VALUE ? -1 : (int) secondMin; - } - - - /** - * Time Complexity: - * Space Complexity: - * Runtime: 0 ms. - * - * @param root - * @return - */ - public static int findSecondMinimumValue(TreeNode root) { - // passing a long as secondMin because TreeNode can have Integer.MAX_VALUE as its value - long ans = findSecondMinimumValue(root, root.val, Long.MAX_VALUE); - return ans == Long.MAX_VALUE ? -1 : (int) ans; - } - - private static long findSecondMinimumValue(TreeNode root, int min, long secondMin) { - if (root == null) return Long.MAX_VALUE; - - if (root.val > min && root.val < secondMin) { - return root.val; - } else { - return Math.min(findSecondMinimumValue(root.left, min, secondMin), - findSecondMinimumValue(root.right, min, secondMin)); - } - } - - public static void main(String[] args) { - System.out.println((int) 2147483647L); - System.out.println(Integer.MAX_VALUE); - // TODO: A function called buildTree which would take an array like [1,1,3,1,1,3,4,3,1,1,1,3,8,4,8,3,3,1,6,2,1] - // and return a Binary Tree - //assertEquals(2, findSecondMinimumValue(buildTree(new int[]{1,1,3,1,1,3,4,3,1,1,1,3,8,4,8,3,3,1,6,2,1}))); - //assertEquals(2147483647, findSecondMinimumValue(buildTree(new int[]{2,2,2147483647}))); - } -} diff --git a/src/main/java/com/leetcode/trees/SerializeDeserializeBinaryTree.java b/src/main/java/com/leetcode/trees/SerializeDeserializeBinaryTree.java deleted file mode 100644 index 690de39d..00000000 --- a/src/main/java/com/leetcode/trees/SerializeDeserializeBinaryTree.java +++ /dev/null @@ -1,179 +0,0 @@ -package com.leetcode.trees; - - -import java.util.LinkedList; -import java.util.Queue; - -/** - * Level: Hard - * Link: https://leetcode.com/problems/serialize-and-deserialize-binary-tree/ - * Description: - * Serialization is the process of converting a data structure or object into a sequence of bits so that it can be - * stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in - * the same or another computer environment. - * - * Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how your - * serialization/deserialization algorithm should work. You just need to ensure that a binary tree can be serialized - * to a string and this string can be deserialized to the original tree structure. - * - * Example: - * - * You may serialize the following tree: - * - * 1 - * / \ - * 2 3 - * / \ - * 4 5 - * - * as "[1,2,3,null,null,4,5]" - * - * Clarification: The above format is the same as how LeetCode serializes a binary tree. You do not necessarily need - * to follow this format, so please be creative and come up with different approaches yourself. - * - * Note: Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms - * should be stateless. - * - * @author rampatra - * @since 2019-08-17 - */ -public class SerializeDeserializeBinaryTree { - - /** - * Runtime: 31 ms. - * - * @param root - * @return - */ - public static String serialize(TreeNode root) { - if (root == null) { - return "[]"; - } - - StringBuilder sb = new StringBuilder(); - sb.append("["); - - Queue queue = new LinkedList<>(); - queue.add(root); - - while (!queue.isEmpty()) { - TreeNode node = queue.poll(); - - if (sb.length() > 1) { - sb.append(", "); - } - if (node == null) { - sb.append("null"); - continue; - } - - sb.append(node.val); - - queue.add(node.left); - queue.add(node.right); - } - - sb.append("]"); - return removeExtraNulls(sb.toString()); - } - - private static String removeExtraNulls(String data) { - int i = data.length() - 1; - while (!(data.charAt(i) >= 48 && data.charAt(i) <= 57)) { - i--; - } - return data.substring(0, i + 1) + "]"; - } - - /** - * - * @param data - * @return - */ - public static TreeNode deserialize(String data) { - data = data.substring(1, data.length() - 1); - - if (data.length() == 0) { - return null; - } - - String[] values = data.split(", "); - - TreeNode root = new TreeNode(Integer.parseInt(values[0])); - - Queue queue = new LinkedList<>(); - queue.add(root); - - for (int i = 0; i < values.length && !queue.isEmpty(); i += 2) { - TreeNode currNode = queue.poll(); - - if (i + 1 < values.length && !values[i + 1].equals("null")) { - TreeNode leftNode = new TreeNode(Integer.parseInt(values[i + 1])); - currNode.left = leftNode; - queue.add(leftNode); - } - - if (i + 2 < values.length && !values[i + 2].equals("null")) { - TreeNode rightNode = new TreeNode(Integer.parseInt(values[i + 2])); - currNode.right = rightNode; - queue.add(rightNode); - } - } - - return root; - } - - public static void main(String[] args) { - // TODO Convert the print statements to asserts - - System.out.println(serialize(new TreeNode(1))); - - /* - Binary Tree - - 1 - / \ - 2 3 - / \ - 4 5 - */ - TreeNode tree = new TreeNode(1); - tree.left = new TreeNode(2); - tree.right = new TreeNode(3); - tree.left.left = new TreeNode(4); - tree.left.right = new TreeNode(5); - - System.out.println(serialize(tree)); - - System.out.println(serialize(deserialize(serialize(tree)))); - - System.out.println(serialize(deserialize(serialize(null)))); - - TreeNode tree2 = new TreeNode(1); - tree2.right = new TreeNode(2); - tree2.right.right = new TreeNode(3); - tree2.right.right.right = new TreeNode(4); - tree2.right.right.right.right = new TreeNode(5); - tree2.right.right.right.right.right = new TreeNode(6); - tree2.right.right.right.right.right.right = new TreeNode(7); - tree2.right.right.right.right.right.right.right = new TreeNode(8); - - System.out.println(serialize(tree2)); - System.out.println(serialize(deserialize(serialize(tree2)))); - - System.out.println("---"); - - System.out.println(serialize(deserialize("[1, 2]"))); - System.out.println(serialize(deserialize("[1, 2, 3]"))); - System.out.println(serialize(deserialize("[3, 2, 4, 1]"))); - System.out.println(serialize(deserialize("[3, 2, 4, 1, 5, 6]"))); - System.out.println(serialize(deserialize("[1, 2, 3, null, null, 4, 5]"))); - System.out.println(serialize(deserialize("[5, 2, 3, null, null, 2, 4, 3, 1]"))); - - System.out.println(serialize(deserialize("[1, null, 2, null, 3, null, 4, null, 5]"))); - System.out.println(serialize(deserialize("[1, null, 2, null, 3, null, 4, null, 5, null, 6]"))); - System.out.println(serialize(deserialize("[1, null, 2, null, 3, null, 4, null, 5, null, 6, null, 7]"))); - System.out.println(serialize(deserialize("[1, null, 2, null, 3, null, 4, null, 5, null, 6, null, 7, null, 8]"))); - System.out.println(serialize(deserialize("[1, null, 2, null, 3, null, 4, null, 5, null, 6, null, 7, null, 8, null, 9]"))); - } -} \ No newline at end of file diff --git a/src/main/java/com/leetcode/trees/SymmetricTree.java b/src/main/java/com/leetcode/trees/SymmetricTree.java deleted file mode 100644 index 093d9a6f..00000000 --- a/src/main/java/com/leetcode/trees/SymmetricTree.java +++ /dev/null @@ -1,117 +0,0 @@ -package com.leetcode.trees; - -import java.util.LinkedList; -import java.util.Queue; - -import static org.junit.jupiter.api.Assertions.assertTrue; - -/** - * Level: Easy - * Problem Link: https://leetcode.com/problems/symmetric-tree/ - * Problem Description: - * Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). - * - * For example, this binary tree [1,2,2,3,4,4,3] is symmetric: - * - * 1 - * / \ - * 2 2 - * / \ / \ - * 3 4 4 3 - * - * - * But the following [1,2,2,null,3,null,3] is not: - * - * 1 - * / \ - * 2 2 - * \ \ - * 3 3 - * - * - * Note: - * Bonus points if you could solve it both recursively and iteratively. - * - * @author rampatra - * @since 2019-07-25 - */ -public class SymmetricTree { - - /** - * Time Complexity: O(n) Because we traverse the entire input tree once, the total run time is O(n), where n is - * the total number of nodes in the tree. - * Space Complexity: O(n) The number of recursive calls is bound by the height of the tree. In the worst case, the - * tree is linear and the height is in O(n). Therefore, space complexity due to recursive calls on the stack is - * O(n) in the worst case. - * Runtime: 0 ms. - * - * @param root - * @return - */ - public static boolean isSymmetric(TreeNode root) { - if (root == null) { - return true; - } - - return isSymmetric(root.left, root.right); - } - - private static boolean isSymmetric(TreeNode leftRoot, TreeNode rightRoot) { - if (leftRoot == null && rightRoot == null) { - return true; - } else if (leftRoot == null || rightRoot == null) { - return false; - } - - return isSymmetric(leftRoot.left, rightRoot.right) && isSymmetric(leftRoot.right, rightRoot.left) && leftRoot.val == rightRoot.val; - } - - /** - * Time Complexity: O(n) Because we traverse the entire input tree once, the total run time is O(n), where n is the - * total number of nodes in the tree. - * Space Complexity: There is additional space required for the search queue. In the worst case, we have to - * insert O(n) nodes in the queue. Therefore, space complexity is O(n). - * Runtime: 1 ms. - * - * @param root - * @return - */ - public static boolean isSymmetricIterative(TreeNode root) { - if (root == null || (root.left == null && root.right == null)) return true; - if (root.left == null || root.right == null) return false; - - Queue queue = new LinkedList<>(); - queue.add(root.left); - queue.add(root.right); - - while (!queue.isEmpty()) { - TreeNode t1 = queue.poll(); - TreeNode t2 = queue.poll(); - - if (t1 == null && t2 == null) continue; - if (t1 == null || t2 == null) return false; - if (t1.val != t2.val) return false; - - // enqueue left and then right child of t1 but do the opposite for t2 - queue.add(t1.left); - queue.add(t2.right); - queue.add(t1.right); - queue.add(t2.left); - } - - return true; - } - - public static void main(String[] args) { - TreeNode root = new TreeNode(1); - root.left = new TreeNode(2); - root.right = new TreeNode(2); - root.left.left = new TreeNode(4); - root.left.right = new TreeNode(3); - root.right.left = new TreeNode(3); - root.right.right = new TreeNode(4); - - assertTrue(isSymmetric(root)); - assertTrue(isSymmetricIterative(root)); - } -} diff --git a/src/main/java/com/leetcode/trees/TreeNode.java b/src/main/java/com/leetcode/trees/TreeNode.java deleted file mode 100644 index 4c4c2569..00000000 --- a/src/main/java/com/leetcode/trees/TreeNode.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.leetcode.trees; - -/** - * @author rampatra - * @since 2019-07-25 - */ -public class TreeNode { - - int val; - TreeNode left; - TreeNode right; - - public TreeNode(int val) { - this.val = val; - } - - @Override - public String toString() { - return val + ""; - } -} \ No newline at end of file diff --git a/src/main/java/com/leetcode/trie/LongestWord.java b/src/main/java/com/leetcode/trie/LongestWord.java deleted file mode 100644 index 155ea295..00000000 --- a/src/main/java/com/leetcode/trie/LongestWord.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.leetcode.trie; - -import java.util.HashMap; -import java.util.Stack; - -/** - * Level: Easy - * Problem: https://leetcode.com/problems/longest-word-in-dictionary/ - * - * @author rampatra - * @since 2019-04-10 - */ -public class LongestWord { - - private class TrieNode { - char ch; - HashMap children = new HashMap<>(); - String completeWord; // to mark a complete word in the trie data structure - - TrieNode(char ch) { - this.ch = ch; - } - } - - private TrieNode root = new TrieNode('0'); - - /** - * Inserts {@code data} in trie. - * - * @param str - */ - public void insert(String str) { - char c; - TrieNode curr = root; - - for (int i = 0; i < str.length(); i++) { - c = str.charAt(i); - curr.children.putIfAbsent(c, new TrieNode(c)); - curr = curr.children.get(c); - } - - curr.completeWord = str; - } - - public String longestWord(String[] words) { - for (int i = 0; i < words.length; i++) { - insert(words[i]); - } - - return longestWord(); - } - - private String longestWord() { - String longestWord = ""; - TrieNode curr; - Stack stack = new Stack<>(); - stack.addAll(root.children.values()); - - while (!stack.empty()) { - curr = stack.pop(); - if (curr.completeWord != null) { - if (curr.completeWord.length() > longestWord.length() || - (curr.completeWord.length() == longestWord.length() && - curr.completeWord.compareTo(longestWord) < 0)) { - longestWord = curr.completeWord; - } - stack.addAll(curr.children.values()); - } - } - return longestWord; - } - - public static void main(String[] args) { - LongestWord longestWord = new LongestWord(); - System.out.println(longestWord.longestWord(new String[]{"w", "wo", "wor", "worl", "world"})); - System.out.println(longestWord.longestWord(new String[]{"a", "banana", "app", "appl", "ap", "apply", "apple"})); - } -} \ No newline at end of file diff --git a/src/main/java/com/linkedlist/DetectLoopInLinkedList_LoopInLinkedList.java b/src/main/java/com/linkedlist/DetectLoopInLinkedList_LoopInLinkedList.java new file mode 100644 index 00000000..73347bcd --- /dev/null +++ b/src/main/java/com/linkedlist/DetectLoopInLinkedList_LoopInLinkedList.java @@ -0,0 +1,41 @@ +package com.linkedlist; + +import com.linkedlist.model.Node; + +public class DetectLoopInLinkedList_LoopInLinkedList { + + public static void main(String args[]) { + + Node node1 = new Node(4); + Node node2 = new Node(6); + Node node3 = new Node(8); + Node node4 = new Node(12); + Node node5 = new Node(14); + + Node startNode = node1; + + node1.setNext(node2); + node2.setNext(node3); + node3.setNext(node4); + node4.setNext(node5); + node5.setNext(node2); + + System.out.println("Loop:" + detectLoop(startNode)); + + } + + private static boolean detectLoop(Node startNode) { + Node slowPointer = startNode; // Initially ptr1 is at starting location. + Node fastPointer = startNode; // Initially ptr2 is at starting location. + + while (fastPointer != null && fastPointer.getNext() != null) { // If ptr2 encounters NULL, it means there is no Loop in Linked list. + slowPointer = slowPointer.getNext(); // ptr1 moving one node at at time + fastPointer = fastPointer.getNext().getNext(); // ptr2 moving two nodes at at time + + if (slowPointer == fastPointer) // if ptr1 and ptr2 meets, it means linked list contains loop. + return true; + } + return false; + } + +} diff --git a/src/main/java/com/linkedlist/IntersectionOfTwoLinkedLists.java b/src/main/java/com/linkedlist/IntersectionOfTwoLinkedLists.java new file mode 100644 index 00000000..e80cc703 --- /dev/null +++ b/src/main/java/com/linkedlist/IntersectionOfTwoLinkedLists.java @@ -0,0 +1,71 @@ +package com.linkedlist; + +import com.linkedlist.model.Node; + +import java.util.HashSet; +import java.util.Set; + +/** + * Write a program to find the node at which the intersection of two singly linked lists begins. + * + * For example, the following two linked lists: + * + * Input: intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3 + * Output: Reference of the node with value = 8 + * Input Explanation: The intersected node's value is 8 (note that this must not be 0 if the two lists intersect). + * From the head of A, it reads as [4,1,8,4,5]. From the head of B, it reads as [5,0,1,8,4,5]. + * There are 2 nodes before the intersected node in A; There are 3 nodes before the intersected node in B. + * + * Notes + * If the two linked lists have no intersection at all, return null. + * The linked lists must retain their original structure after the function returns. + * You may assume there are no cycles anywhere in the entire linked structure. + * Your code should preferably run in O(n) time and use only O(1) memory. + * + */ +public class IntersectionOfTwoLinkedLists { + + //Approach 2: Hash Table (10ms) + + /** Space -> O(n) where n is the size of first linked list as we are storing in HashSet + * Time -> O(n+m) as we traverse the complete list once. n size of first list & m size of second list. + * @param headA + * @param headB + * @return + */ + public Node getIntersectionNode(Node headA, Node headB) { + Set nodes = new HashSet<>(); + Node pa = headA; + while (pa != null) { + nodes.add(pa); + pa = pa.next; + } + if (nodes.isEmpty()) { + return null; + } + Node pb = headB; + while (pb != null) { + if (nodes.contains(pb)) { + return pb; + } + pb = pb.next; + } + return null; + } + + //Approach 3: Two Pointers (1ms) + + public Node getIntersectionNode_1(Node headA, Node headB) { + Node pa = headA, pb = headB; + while (pa != pb) { + pa = (pa != null) ? pa.next : headB; + pb = (pb != null) ? pb.next : headA; + } + return pa; + } + + +} + + + diff --git a/src/main/java/com/linkedlist/LRUCache.adoc b/src/main/java/com/linkedlist/LRUCache.adoc new file mode 100644 index 00000000..ff78e3b7 --- /dev/null +++ b/src/main/java/com/linkedlist/LRUCache.adoc @@ -0,0 +1 @@ +image::../../../images/LRUCache.png[] \ No newline at end of file diff --git a/src/main/java/com/linkedlist/LRUCache.java b/src/main/java/com/linkedlist/LRUCache.java new file mode 100644 index 00000000..2c29dc32 --- /dev/null +++ b/src/main/java/com/linkedlist/LRUCache.java @@ -0,0 +1,92 @@ +package com.linkedlist; + +import com.linkedlist.model.DoublyLLNode; + +import java.util.HashMap; + +/** + * Design and implement a data structure for Least Recently Used (LRU) cache, which supports get and put. + * The key to solve this problem is using a double linked list which enables us to quickly move nodes. + * + * The LRU cache is a hash table of keys and double linked nodes. + * The hash table makes the time of get() to be O(1). The list of double linked nodes make the nodes adding/removal operations O(1). + * + * By analyzing the get and put, we can summarize there are 2 basic operations: + * 1) removeNode(Node t), 2) offerNode(Node t). + * + */ +class LRUCache { + DoublyLLNode head; + DoublyLLNode tail; + HashMap map = null; + int cap = 0; + + public LRUCache(int capacity) { + this.cap = capacity; + this.map = new HashMap<>(); + } + + public int get(int key) { + if(map.get(key)==null){ + return -1; + } + + //move to tail + DoublyLLNode t = map.get(key); + + removeDoublyLLNode(t); + offerDoublyLLNode(t); + + return t.value; + } + + public void put(int key, int value) { + if(map.containsKey(key)){ + DoublyLLNode t = map.get(key); + t.value = value; + + //move to tail + removeDoublyLLNode(t); + offerDoublyLLNode(t); + }else{ + if(map.size()>=cap){ + //delete head + map.remove(head.key); + removeDoublyLLNode(head); + } + + //add to tail + DoublyLLNode DoublyLLNode = new DoublyLLNode(key, value); + offerDoublyLLNode(DoublyLLNode); + map.put(key, DoublyLLNode); + } + } + + private void removeDoublyLLNode(DoublyLLNode n){ + if(n.prev!=null){ + n.prev.next = n.next; + }else{ + head = n.next; + } + + if(n.next!=null){ + n.next.prev = n.prev; + }else{ + tail = n.prev; + } + } + + private void offerDoublyLLNode(DoublyLLNode n){ + if(tail!=null){ + tail.next = n; + } + + n.prev = tail; + n.next = null; + tail = n; + + if(head == null){ + head = tail; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/linkedlist/LoopInLinkedList_FloydCycleDetectionAlgo.html b/src/main/java/com/linkedlist/LoopInLinkedList_FloydCycleDetectionAlgo.html new file mode 100644 index 00000000..6352ea01 --- /dev/null +++ b/src/main/java/com/linkedlist/LoopInLinkedList_FloydCycleDetectionAlgo.html @@ -0,0 +1,2324 @@ + + + + + + + + + + +Floyd's Cycle Detection Algorithm in Java | JavaByPatel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ + +
+
+
+ +
+
+
+ + +
+ +
+
+
+
+
+
+ +
+ + +
+ + +
+ +
+
+

+Floyd's Cycle Detection Algorithm in Java +

+ +
+
+
+
+
+
+
+ + + + + + +
+
+
+
+

+Floyd's Cycle Detection Algorithm in Java. OR
Detect loop in Linked list.

+
+Floyd's Cycle Detection Algorithm in Java. Floyd's Cycle finding algorithm helps to detect loop  in linked list. How Floyd's Cycle Algorithm works.
+ 
+
+Let's start with, What is Loop in Linked list?
+
+Generally, the last node of the linked list points to NULL, which is a indication of end of list.
But in Linked list containing Loop, last node instead of pointing NULL, it points to some of the internal node/starting node/itself.
In this case, If we traverse the Linked list node one by one, our traversal will never ends as it goes in loop. +

+Check below images for better understanding on how Linked list containing loop looks like.

+
+
+
+
+

+Algorithm

+
+ +Before going into detecting loop in linked list, Lets understand few basic points with help of example.
+
+1. Jayesh and Khyati daily goes for jogging at Circular park(Park is completely circular of 1 Km).
2. Jayesh is bit lazy and jogs at "x" speed. Khyati is more energetic and jogs at 2x speed.
3. It means, when they both start from same point, and when Jayesh complete half jogging track, 

+    Khyati will complete one jogging track round and reached at starting place again.

So if they both starts from common point, Jayesh running at speed "x" and Khyati running at speed "2x", Will they both meet again?
They will surely meet at the same location they started from.
Look at below image for better understanding.
 

+
+
+
+

Now, instead of starting from same point, if the starting point for Jayesh and Khyati is different still they will meet?

+Yes they will meet. Not at same place but at some point in track.

Look at below image for better understanding.

+
+
+
+
+They are meeting at some point because of the circular track and speed in which both are traveling. +
+
+Now, If Jayesh travels at "x" speed and Khyati travels at "3x" speed, still they both will meet, but numbers of complete cycles Khyati will perform and then meet Jayesh might increase.
+
+ +Now, Lets look at our original problem
+
+

+Detect loop in Linked list. (Floyd's Cycle detection algorithm)

+
+So the algorithm behind identifying the loop in linked list is very similar to our jogging track example.
+
+STEP 1:  Take 2 pointers ptr1 and ptr2, both pointing at the start node initially.
                

+STEP 2:  Move ptr1 forward one node at a time and move ptr2 forward two nodes at same time.
+
STEP 3: 
ptr2
is running at double speed, so definitely it will be ahead of ptr1,
                If ptr2 encounters NULL, it means there is no loop in a Linked list and stop execution.

+                If linked list contains loop, then ptr2 at some point will enter in the loop. some time later
+                ptr1 will also enter in the loop.
+
+STEP 4:  Now, when both pointers are in the loop, and if they continue to move at same speed then 
+                 eventually they will meet at some point.
+                 (From our jogging track example, we have already seen that)    
                 If they both meet, it means Linked list contains loop
and stop execution.
+
+
+

+Java Program to Detect loop in linked list in Java.

+
+
+
package linkedlist.singly;
+
+public class DetectLoopInLinkedList{
+ private Node startNode;
+
+ public static void main(String[] args) {
+  DetectLoopInLinkedList detectLoopInLinkedList = new DetectLoopInLinkedList();
+
+  Node n1 = new Node(10);
+  Node n2 = new Node(20);
+  Node n3 = new Node(30);
+  Node n4 = new Node(40);
+  Node n5 = new Node(50);
+  Node n6 = new Node(60);
+  Node n7 = new Node(70);
+  Node n8 = new Node(80);
+
+  detectLoopInLinkedList.startNode = n1;
+
+  n1.setNext(n2);
+  n2.setNext(n3);
+  n3.setNext(n4);
+  n4.setNext(n5);
+  n5.setNext(n6);
+  n6.setNext(n7);
+  n7.setNext(n8);
+  n8.setNext(n6);
+
+  if(isLoopPresent(detectLoopInLinkedList.startNode)){
+   System.out.println("Loop is present in list");
+  }else{
+   System.out.println("No Loop present in list");
+  }
+ }
+
+ private static boolean isLoopPresent(Node startNode){
+  Node slowPointer = startNode; // Initially ptr1 is at starting location.
+  Node fastPointer = startNode; // Initially ptr2 is at starting location.
+
+  while(fastPointer!=null && fastPointer.getNext()!=null){ // If ptr2 encounters NULL, it means there is no Loop in Linked list.
+   slowPointer = slowPointer.getNext(); // ptr1 moving one node at at time
+   fastPointer = fastPointer.getNext().getNext(); // ptr2 moving two nodes at at time
+
+   if(slowPointer==fastPointer) // if ptr1 and ptr2 meets, it means linked list contains loop.
+    return true;
+  }
+  return false; 
+ }
+
+}
+
+
+
+
public class Node{
+ 
+ private int data;
+ private Node next;
+ 
+ public Node(int data) {
+  this.data = data;
+ }
+ public int getData() {
+  return data;
+ }
+ public void setData(int data) {
+  this.data = data;
+ }
+ public Node getNext() {
+  return next;
+ }
+ public void setNext(Node next) {
+  this.next = next;
+ }
+}
+
+
+
+

+ +Why increase pointer by two while finding loop in linked list, why not 3,4,5? +

+So, the condition here is you cannot change the speed of ptr1, it has to move one node at a time. 
+but the choice for ptr2 to move can be 2 nodes at a time, 3 nodes at a time or any number of nodes at a time. 
+
+More the gap in which both pointers move forward, more the time they might take in worst case to meet. 
+So the lowest possible iteration in which we can find their meeting points is by moving ptr2 two nodes at a time.
+
+
+

+Identify start node of loop in linked list.

+
+
+If the linked list is like shown below, Find a node from where loop/cycle starts. 
+(In below example, it starts at Node 5).
+
+
+
+
+
+We just saw that, loop in a linked list can be identified by,

1. Initializing 2 pointers(tortoise, hare) at start node and then
2. Moving tortoise pointer forward 1 node at a time and moving hare pointer forward 2 nodes at same
    time.
    In this way, if the linked list contains loop then tortoise and hare will meet at some node in 

+    loop otherwise hare will reach NULL.

Now point is, how we will come to know the start node of a loop.

+
+STEP 1: After finding the loop, both pointers are pointing to common node that is at meeting point 
+                inside loop,
+
+STEP 2: Now, move one pointer among them(say tortoise) to the head of list, keeping hare 
+                pointer at the same position that is at meeting point inside loop.
+
+STEP 3: Start moving both pointers one node at a time. The place they both will meet is the start
+                node of the loop/cycle.
+
+

+How does the Algorithm work?

+
+Lets understand with the help of example.
+
+
+
+
+1. Consider the distance between start node of the list and start of loop node be "p" and
+2. Consider the distance between start of loop node and the meeting point(node) of both pointers 
+    be "q".
+3. Consider the distance between the meeting point of both pointers and the start node of the loop 
+    be "r".
+
+Tortoise pointer was moving one node at a time and hare pointer was moving 2 nodes at same time.
So we can say, when tortoise pointer has moved distance "d" 

+then hare pointer has moved distance "2d".
From the above image, the length of loop is q+r.

When tortoise and hare meet,  tortoise has covered distance  d = p+q and hare has covered distance 2*d = p+q+r+q

2*d = p + q + r + q
2(p+q) = p + 2q + r
2p + 2q = p + 2q + r
p = r
(It means distance from head node to the start of loop node is same as distance between meeting point of the pointers to the start of loop node)


So this shows after getting meeting point, if one pointer is placed at the beginning of the list, then moving both pointer one node at a time then they will meet at the start of loop.

+
+

+Identify start node of loop in Linked List. (in Java)

+
+
package linkedlist.singly;
+
+public class ReturnStartNodeOfLoopInLinkList {
+ 
+ Node startNode;
+
+ public static void main(String[] args) {
+ 
+  ReturnStartNodeOfLoopInLinkList g = new ReturnStartNodeOfLoopInLinkList();
+  
+  Node n1 = new Node(10);
+  Node n2 = new Node(20);
+  Node n3 = new Node(30);
+  Node n4 = new Node(40);
+  Node n5 = new Node(50);
+  Node n6 = new Node(60);
+  Node n7 = new Node(70);
+  Node n8 = new Node(80);
+  
+  g.startNode = n1;
+  
+  n1.setNext(n2);
+  n2.setNext(n3);
+  n3.setNext(n4);
+  n4.setNext(n5);
+  n5.setNext(n6);
+  n6.setNext(n7);
+  n7.setNext(n8);
+  n8.setNext(n6);
+  
+  Node loopNode = g.getStartNodeOfLoopInLinklist(g.startNode);
+  
+  if(loopNode==null){
+   System.out.println("Loop not present");
+  }else{
+   System.out.println("Start node of Loop is :"+loopNode.getData()); 
+  }
+ }
+ 
+ private Node getStartNodeOfLoopInLinklist(Node startNode){
+  Node tortoisePointer = startNode; // Initially ptr1 is at starting location.
+  Node harePointer = startNode; // Initially ptr2 is at starting location.
+  
+  // If ptr2 encounters NULL, it means there is no Loop in Linked list.
+  while(harePointer!=null && harePointer.getNext()!=null){
+   tortoisePointer = tortoisePointer.getNext(); // ptr1 moving one node at at time
+   harePointer = harePointer.getNext().getNext(); // ptr2 moving two nodes at at time
+   
+   // if ptr1 and ptr2 meets, it means linked list contains loop.
+   if(tortoisePointer==harePointer){ 
+    
+    //After meet, moving tortoisePointer to start node of list.
+    tortoisePointer = startNode; 
+    
+    //Moving tortoisePointer and harePointer one node at a time till the time they meet at common point. 
+    while(tortoisePointer!=harePointer){ 
+     tortoisePointer = tortoisePointer.getNext(); 
+     harePointer = harePointer.getNext();
+    }
+    
+    //returning start node of loop.
+    return tortoisePointer;
+    
+   }
+  }
+  
+  // this condition will arise when there is no loop in list.
+  return null; 
+ }
+ 
+}
+
+
+
+
+
+

+Remove loop in Linked list.

+
+Removing the loop in Linked list is simple,
+
+After identifying the loop node, we just require the previous node of loop node, So that we can set it to NULL.
+
+For identifying the previous node of loop node, we will keep the previousPointer pointing to just previous node of loop node.
+
+CASE 2:
+When the meeting node of both pointers in loop is start node or root node itself, in this case by just setting previousPointer to NULL will work because previousPointer is already pointing to last node of the linked list.
+
+CASE 1:
+When the meeting node of both pointers in loop is in-between the linked list, in this case, first task is to identify the start of loop node in the way as we saw above and then by setting fastPointer, which is already pointing to last node of list to NULL will work.
+
+

+Program to Remove loop in linked list.

+
+
package linkedlist.singly;
+
+public class RemoveLoopInLinkList {
+ 
+ Node startNode;
+ public static void main(String[] args) {
+  RemoveLoopInLinkList g = new RemoveLoopInLinkList();
+  
+  Node n1 = new Node(10);
+  Node n2 = new Node(20);
+  Node n3 = new Node(30);
+  Node n4 = new Node(40);
+  Node n5 = new Node(50);
+  Node n6 = new Node(60);
+  Node n7 = new Node(70);
+  Node n8 = new Node(80);
+  
+  g.startNode = n1;
+  
+  n1.setNext(n2);
+  n2.setNext(n3);
+  n3.setNext(n4);
+  n4.setNext(n5);
+  n5.setNext(n6);
+  n6.setNext(n7);
+  n7.setNext(n8);
+  n8.setNext(n6);
+  
+  //Detect and Remove Loop in a Linked List
+  Node newStart = detectAndRemoveLoopInLinkedList(g.startNode);
+  g.printList(newStart);
+ }
+ 
+ private static Node detectAndRemoveLoopInLinkedList(Node startNode) {
+  Node slowPointer=startNode;
+  Node fastPointer=startNode;
+  Node previousPointer=null;
+  
+  while(fastPointer!=null && fastPointer.getNext()!=null){
+   slowPointer = slowPointer.getNext();
+   previousPointer = fastPointer.getNext(); // For capturing just previous node of loop node for setting it to null for breaking loop.
+   fastPointer = fastPointer.getNext().getNext();
+   
+   if(slowPointer==fastPointer){ // Loop identified.
+    slowPointer = startNode;
+ 
+    //If loop start node is starting at the root Node, then we slowpointer, fastpointer and head all point at same location. 
+    //we already capture previous node, just setting it to null will work in this case.
+    if(slowPointer == fastPointer){
+     previousPointer.setNext(null);
+     
+    }else{
+     // We need to first identify the start of loop node and then by setting just previous node of loop node next to null.  
+     while(slowPointer.getNext()!=fastPointer.getNext()){
+      slowPointer = slowPointer.getNext();
+      fastPointer = fastPointer.getNext();
+     }
+     fastPointer.setNext(null);
+    }
+   }
+  }
+  return startNode; 
+ }
+ 
+ //Print linked list.
+ private void printList(Node startNode){
+  while(startNode!=null){
+   System.out.print(startNode.getData() + " " ); 
+   startNode=startNode.getNext();
+  }
+ }
+ 
+}
+
+
+
+
+
+
+Enjoy !!!! 
+
+
+If you find any issue in post or face any error while implementing, Please comment.
+
+
+ +
+
+
+ + + + +
+
+
+ +
+ +
+ +
+
+
+
+
+
+

Post a Comment

+
+ +

+

+ + + + + +
+
+
+ + + +
+ +
+ + +
+
+ +Newer Post + + +Older Post + +Home +
+
+
+
+
+ + +
+ +
+
+ + + + +
+ + + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/linkedlist/MergeTwoSortedLinkedLists.java b/src/main/java/com/linkedlist/MergeTwoSortedLinkedLists.java new file mode 100644 index 00000000..ec6f8e4a --- /dev/null +++ b/src/main/java/com/linkedlist/MergeTwoSortedLinkedLists.java @@ -0,0 +1,77 @@ +package com.linkedlist; + +import com.linkedlist.model.Node; + +/** + * Time complexity : O ( k N ) O(kN) O(kN) where k is the number of linked lists. + * We can merge two sorted linked list in O ( n ) O(n) O(n) time where n is the total number of nodes in two lists + */ +public class MergeTwoSortedLinkedLists { + + public static void main (String args[]){ + Node node1 = new Node(4); + Node node2 = new Node(6); + Node node3 = new Node(8); + Node node4 = new Node(12); + Node node5 = new Node(14); + + node1.setNext(node2); + node2.setNext(node3); + node3.setNext(node4); + node4.setNext(node5); + node5.setNext(null); + + Node list1 = node1; + + Node node11 = new Node(41); + Node node21 = new Node(61); + Node node31 = new Node(81); + Node node41 = new Node(121); + Node node51 = new Node(141); + + node11.setNext(node21); + node21.setNext(node31); + node31.setNext(node41); + node41.setNext(node51); + node51.setNext(null); + + Node list2 = node11; + + mergeSortedList(list1, list2); + printList( mergeSortedList(list1, list2)); + + } + + private static void printList(Node mergeSortedList) { + while(mergeSortedList!= null) { + System.out.println(mergeSortedList.getData()); + mergeSortedList = mergeSortedList.getNext(); + } + + } + + private static Node mergeSortedList(Node list1, Node list2) { + + if(list1 == null) return list2; + if(list2 == null) return list1; + + Node result ; + + if(list1.getData() < list2.getData()) + { + result = new Node(list1.getData()); + result.setNext(mergeSortedList(list1.getNext(), list2)); + } + else + { + result = new Node(list2.getData()); + result.setNext(mergeSortedList(list1, list2.getNext())); + } + + return result; + + } + + + } + diff --git a/src/main/java/com/linkedlist/MiddleElementOfLinkedList.html b/src/main/java/com/linkedlist/MiddleElementOfLinkedList.html new file mode 100644 index 00000000..95fe8023 --- /dev/null +++ b/src/main/java/com/linkedlist/MiddleElementOfLinkedList.html @@ -0,0 +1,2066 @@ + + + + + + + + + + +Find middle element of a linked list | JavaByPatel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+
+
+ + +
+ +
+
+
+
+
+
+ +
+ + +
+ + +
+ +
+
+

+Find middle element of a linked list +

+ +
+
+
+
+
+
+
+ + + + + + +
+
+
+
+Find middle element of a linked list in Java
+
+Given a singly linked list find middle of the linked list.
+
+Find Nth node from last in a linked list
+
+Lets understand the problem statement graphically and it will be more clear,
+
+
+
+
+

+ +Algorithm

+
+There are 2 approach to get middle element of Linked list.
+
+Approach 1:
+
+
    +
  1. Initialize the counter = 0.  
  2. +
    +
    +
  3. Iterate through a linked list and increment counter till you encounter null. 
  4. +
  5. Once you got the length of linked list, say 7. Middle element of linked list is located at
    (length of linked list / 2) 7/2 = 3.
     
  6. +
  7. Traverse the list again till (length of linked list / 2) and return the node at
    (
    length of linked list / 2).
  8. +
+
+Approach 2:
+We can get the middle element of linked list in one pass, lets see how,
+
    +
  1. In this approach, we take 2 pointers, fastPointer and slowPointer and initialize both to list head.
  2. +
    +
    +
  3. Iterate through list and move slowPointer 1 node at a time and fastPointer 2 nodes at a time.
  4. +
  5. When fastPointer reaches end of list, slowPointer will be pointing to middle element of list.
  6. +
+
    +
+
    +
+

+ 

+

+Java Program to find middle element of Linked list using Approach 2

+
+
package linkedlist.singly;
+
+public class GetMiddleOfLinkedList {
+
+ public static void main(String[] args) {
+  new GetMiddleOfLinkList();
+ }
+
+ public GetMiddleOfLinkedList() {
+  Node startNode = new Node(10);
+  Node temp2 = new Node(20);
+  Node temp3 = new Node(30);
+  Node temp4 = new Node(40);
+  Node temp5 = new Node(50);
+  Node temp6 = new Node(60);
+  Node temp7 = new Node(70);
+  Node temp8 = new Node(80);
+
+  startNode.setNext(temp2);
+  temp2.setNext(temp3);
+  temp3.setNext(temp4);
+  temp4.setNext(temp5);
+  temp5.setNext(temp6);
+  temp6.setNext(temp7);
+  temp7.setNext(temp8);
+
+  Node temp = findMiddleNodeOfLinkedList(startNode);
+  System.out.println(temp.getData());
+ }
+
+ private Node findMiddleNodeOfLinkedList(Node startNode) {
+  if(startNode==null){
+   return startNode;
+  }
+
+  Node slowPointer = startNode;
+  Node fastPointer = startNode;
+  while(fastPointer!=null && fastPointer.getNext()!=null && fastPointer.getNext().getNext()!=null){
+   slowPointer = slowPointer.getNext();
+   fastPointer = fastPointer.getNext().getNext();
+
+  }
+  return slowPointer;
+ }
+}
+
+
+
class Node{
+ private int data;
+ private Node next;
+ public Node(int data, Node next) {
+  this.data = data;
+  this.next = next;
+ }
+ public Node(int data) {
+  this.data = data;
+ }
+ public int getData() {
+  return data;
+ }
+ public void setData(int data) {
+  this.data = data;
+ }
+ public Node getNext() {
+  return next;
+ }
+ public void setNext(Node next) {
+  this.next = next;
+ }
+}
+
+
+
+

+You may also like to see +

+
+

+Detect loop in linked list

+

+Reverse Linked list in Java

+

+Find Nth node from last in a linked list

+

+Sort Linked list.

+

+Clone Linked list.

+

+How is ambiguous overloaded method call resolved in java

+
+
+Enjoy !!!! 
+
+
+If you find any issue in post or face any error while implementing, Please comment.
+
+
+ +
+
+
+ + + + +
+
+
+ +
+ +
+ +
+
+
+
+
+
+

Post a Comment

+
+ +

+

+ + + + + +
+
+
+ + + +
+ +
+ + +
+
+ +Newer Post + + +Older Post + +Home +
+
+
+
+
+ + +
+ +
+
+ + + + +
+ + + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/linkedlist/MiddleElementOfLinkedList.java b/src/main/java/com/linkedlist/MiddleElementOfLinkedList.java new file mode 100644 index 00000000..9eda3a52 --- /dev/null +++ b/src/main/java/com/linkedlist/MiddleElementOfLinkedList.java @@ -0,0 +1,50 @@ +package com.linkedlist; + +import com.linkedlist.model.Node; + +public class MiddleElementOfLinkedList { + + public static void main(String[] args) { + new MiddleElementOfLinkedList(); + } + + public MiddleElementOfLinkedList() { + Node startNode = new Node(10); + Node temp2 = new Node(20); + Node temp3 = new Node(30); + Node temp4 = new Node(40); + Node temp5 = new Node(50); + Node temp6 = new Node(60); + Node temp7 = new Node(70); + Node temp8 = new Node(80); + + startNode.setNext(temp2); + temp2.setNext(temp3); + temp3.setNext(temp4); + temp4.setNext(temp5); + temp5.setNext(temp6); + temp6.setNext(temp7); + temp7.setNext(temp8); + + Node temp = findMiddleNodeOfLinkedList(startNode); + System.out.println(temp.getData()); + } + + private Node findMiddleNodeOfLinkedList(Node startNode) { + if(startNode==null){ + return startNode; + } + + Node slowPointer = startNode; + Node fastPointer = startNode; + + /** important */ + while(fastPointer!=null && fastPointer.getNext()!=null && fastPointer.getNext().getNext()!=null){ + slowPointer = slowPointer.getNext(); + fastPointer = fastPointer.getNext().getNext(); + + } + return slowPointer; + } + +} diff --git a/src/main/java/com/linkedlist/NthNodeFromEndOfLinkedList.java b/src/main/java/com/linkedlist/NthNodeFromEndOfLinkedList.java new file mode 100644 index 00000000..65164342 --- /dev/null +++ b/src/main/java/com/linkedlist/NthNodeFromEndOfLinkedList.java @@ -0,0 +1,60 @@ +package com.linkedlist; + +import com.linkedlist.model.Node; + +/** + * Time Complexity O(n) as we are traversing the list just once. + */ + +public class NthNodeFromEndOfLinkedList { + + public static void main(String args[]) { + + Node node1 = new Node(4); + Node node2 = new Node(6); + Node node3 = new Node(8); + Node node4 = new Node(12); + Node node5 = new Node(14); + + Node startNode = node1; + + node1.setNext(node2); + node2.setNext(node3); + node3.setNext(node4); + node4.setNext(node5); + node5.setNext(null); + + System.out.println("Loop:" + findNthNodeFromEnd(startNode, 3).getData()); + + } + + private static Node findNthNodeFromEnd(Node startNode, int n) { + Node firstPointer = startNode, secondPointer = startNode; + int count = 1; + + /** + * We start the firstPointer and move by one step till count is equal to Nth. + * Once count is equal to Nth number means firstPointer standing at Nth Node, + * then we start secondPointer and move one step each till firstPointer reaches end. + * + */ + while (count <= n) { + firstPointer = firstPointer.getNext(); + count++; + } + + /**At this point both firstPointer and secondPointer are at Nth distance from each other + * So we start secondPointer now and increment by one till firstPointer reaches end of linked list. + * when firstPointer reaches end means second pointer is at Nth Node from end of linked List + */ + while (firstPointer != null) { + firstPointer = firstPointer.getNext(); + secondPointer = secondPointer.getNext(); + } + + return secondPointer; + + } + + +} diff --git a/src/main/java/com/linkedlist/ReverseLinkedList.java b/src/main/java/com/linkedlist/ReverseLinkedList.java new file mode 100644 index 00000000..9b8a946d --- /dev/null +++ b/src/main/java/com/linkedlist/ReverseLinkedList.java @@ -0,0 +1,45 @@ +package com.linkedlist; + +import com.linkedlist.model.Node; + +/** + * For Reversing a linked list we update + * the pointer of each node to point to previous node instead of next node + */ +public class ReverseLinkedList { + + public static void main(String args[]) { + Node targetList = new Node(4); + targetList.setNext(new Node(8)); + targetList.getNext().setNext(new Node(10)); + targetList.getNext().getNext().setNext(new Node(12)); + + Node headOfReverseList = reverseLinkedList(targetList); + + while (headOfReverseList != null) { + System.out.println(headOfReverseList.getData()); + headOfReverseList = headOfReverseList.getNext(); + } + + } + + private static Node reverseLinkedList(Node head) { + /** Initialize 3 pointers */ + Node previous = null; + Node current = head; + Node next = null; + + while (current != null) { + + next = current.getNext(); /**save next */ + current.setNext(previous); /** reverse */ + + /** Advance prev and current */ + previous = current; + current = next; + } + + return previous; /** return ne head at the end */ + + } +} diff --git a/src/main/java/com/linkedlist/StartNodeOfLoopInLinkList_LoopInLinkedList.java b/src/main/java/com/linkedlist/StartNodeOfLoopInLinkList_LoopInLinkedList.java new file mode 100644 index 00000000..e7c72772 --- /dev/null +++ b/src/main/java/com/linkedlist/StartNodeOfLoopInLinkList_LoopInLinkedList.java @@ -0,0 +1,73 @@ +package com.linkedlist; + +import com.linkedlist.model.Node; + +public class StartNodeOfLoopInLinkList_LoopInLinkedList { + + Node startNode; + + public static void main(String[] args) { + + StartNodeOfLoopInLinkList_LoopInLinkedList g = new StartNodeOfLoopInLinkList_LoopInLinkedList(); + + Node n1 = new Node(10); + Node n2 = new Node(20); + Node n3 = new Node(30); + Node n4 = new Node(40); + Node n5 = new Node(50); + Node n6 = new Node(60); + Node n7 = new Node(70); + Node n8 = new Node(80); + + g.startNode = n1; + + n1.setNext(n2); + n2.setNext(n3); + n3.setNext(n4); + n4.setNext(n5); + n5.setNext(n6); + n6.setNext(n7); + n7.setNext(n8); + n8.setNext(n6); + + Node loopNode = g.getStartNodeOfLoopInLinklist(g.startNode); + + if (loopNode == null) { + System.out.println("Loop not present"); + } else { + System.out.println("Start node of Loop is :" + loopNode.getData()); + } + } + + private Node getStartNodeOfLoopInLinklist(Node startNode) { + Node slowPointer = startNode; // Initially ptr1 is at starting location. + Node fastPointer = startNode; // Initially ptr2 is at starting location. + + // If ptr2 encounters NULL, it means there is no Loop in Linked list. + while (fastPointer != null && fastPointer.getNext() != null) { + slowPointer = slowPointer.getNext(); // ptr1 moving one node at at time + fastPointer = fastPointer.getNext().getNext(); // ptr2 moving two nodes at at time + + // if ptr1 and ptr2 meets, it means linked list contains loop. + if (slowPointer == fastPointer) { + + //After meet, moving slowPointer to start node of list. + slowPointer = startNode; + + //Moving slowPointer and fastPointer one node at a time till the time they meet at common point. + while (slowPointer != fastPointer) { + slowPointer = slowPointer.getNext(); + fastPointer = fastPointer.getNext(); + } + + //returning start node of loop. + return slowPointer; + + } + } + + // this condition will arise when there is no loop in list. + return null; + } +} + diff --git a/src/main/java/com/linkedlist/UnionOfTwoLinkedList.java b/src/main/java/com/linkedlist/UnionOfTwoLinkedList.java new file mode 100644 index 00000000..78073e9d --- /dev/null +++ b/src/main/java/com/linkedlist/UnionOfTwoLinkedList.java @@ -0,0 +1,71 @@ +package com.linkedlist; + +import com.linkedlist.model.Node; + +import java.util.HashMap; + +/** + * Input: + * List1: 10->15->4->20 + * lsit2: 8->4->2->10 + * Output: + * Intersection List: 4->10 + * Union List: 2->8->20->4->15->10 + */ +public class UnionOfTwoLinkedList { + Node getUnion(Node head1, Node head2) + { + // HashMap that will store the + // elements of the lists with their counts + HashMap hmap = new HashMap<>(); + Node n1 = head1; + Node n2 = head2; + Node result = null; + + // loop inserts the elements and the count of + // that element of list1 into the hmap + while(n1 != null) + { + if(hmap.containsKey(n1.data)) + { + int val = hmap.get(n1.data); + hmap.put(n1.data, val + 1); + } + else + { + hmap.put(n1.data, 1); + } + n1 = n1.next; + } + + // loop further adds the elements of list2 with + // their counts into the hmap + while(n2 != null) + { + if(hmap.containsKey(n2.data)) + { + int val = hmap.get(n2.data); + hmap.put(n2.data, val + 1); + } + else + { + hmap.put(n2.data, 1); + } + n2 = n2.next; + } + + // Eventually add all the elements + // into the result that are present in the hmap + result = new Node(0); + + for(int a:hmap.keySet()) + { + result.setNext(new Node(a)); + } + return result; + } + + /* Driver program to test above functions */ + +} + diff --git a/src/main/java/com/linkedlist/model/DoublyLLNode.java b/src/main/java/com/linkedlist/model/DoublyLLNode.java new file mode 100644 index 00000000..930ef602 --- /dev/null +++ b/src/main/java/com/linkedlist/model/DoublyLLNode.java @@ -0,0 +1,14 @@ +package com.linkedlist.model; + +public class DoublyLLNode { + public int key; + public int value; + public DoublyLLNode prev; + public DoublyLLNode next; + + public DoublyLLNode(int key, int value) { + this.key = key; + this.value = value; + } +} + diff --git a/src/main/java/com/linkedlist/model/Node.java b/src/main/java/com/linkedlist/model/Node.java new file mode 100644 index 00000000..f0fd62e0 --- /dev/null +++ b/src/main/java/com/linkedlist/model/Node.java @@ -0,0 +1,28 @@ +package com.linkedlist.model; + +public class Node{ + + public int data; + public Node next; + + public Node(int data, Node next) { + this.data = data; + this.next = next; + } + public Node(int data) { + this.data = data; + } + + public int getData() { + return data; + } + public void setData(int data) { + this.data = data; + } + public Node getNext() { + return next; + } + public void setNext(Node next) { + this.next = next; + } +} \ No newline at end of file diff --git a/src/main/java/com/rampatra/Main.java b/src/main/java/com/rampatra/Main.java deleted file mode 100644 index 9306b1a2..00000000 --- a/src/main/java/com/rampatra/Main.java +++ /dev/null @@ -1,322 +0,0 @@ -package com.rampatra; - -import com.rampatra.base.CircularSingleLinkedList; -import com.rampatra.base.DoubleLinkedList; -import com.rampatra.base.LinkedList; -import com.rampatra.base.LinkedQueue; -import com.rampatra.base.LinkedStack; -import com.rampatra.base.Queue; -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.Stack; - -import java.util.Scanner; - -import static java.lang.System.out; - -public class Main { - - public static void main(String[] args) { - int k1, k2; - Scanner in = new Scanner(System.in); - Stack stack = new LinkedStack<>(); - Queue queue = new LinkedQueue<>(); - LinkedList singleLinkedList = new SingleLinkedList<>(); - LinkedList doubleLinkedList = new DoubleLinkedList<>(); - LinkedList circularSingleLinkedList = new CircularSingleLinkedList<>(); - chooseModule: - while (true) { - out.println("Choose module:"); - out.println("=============="); - out.println("1. Stack"); - out.println("2. Queue"); - out.println("3. SingleLinkedList"); - out.println("4. DoubleLinkedList"); - out.println("5. CircularSingleLinkedList"); - out.println("6. CircularDoubleLinkedList"); - out.println("7. Exit"); - k1 = Integer.parseInt(in.nextLine()); - switch (k1) { - case 1: - while (true) { - out.println("Select operation:"); - out.println("================="); - out.println("1. Push"); - out.println("2. Pop"); - out.println("3. Peek"); - out.println("4. Print"); - out.println("5. Exit module"); - k2 = Integer.parseInt(in.nextLine()); - switch (k2) { - case 1: - out.println("Enter value:"); - int input = Integer.parseInt(in.nextLine()); - stack.push(input); - stack.print(); - break; - case 2: - out.println("Removed element: " + stack.pop()); - stack.print(); - break; - case 3: - out.println("Front element: " + stack.peek()); - stack.print(); - break; - case 4: - stack.print(); - break; - case 5: - continue chooseModule; - default: - out.println("Wrong choice!"); - } - } - case 2: - while (true) { - out.println("Select operation:"); - out.println("================="); - out.println("1. Add"); - out.println("2. Remove"); - out.println("3. Front element"); - out.println("4. Print"); - out.println("5. Exit module"); - k2 = Integer.parseInt(in.nextLine()); - switch (k2) { - case 1: - out.println("Enter value:"); - int input = Integer.parseInt(in.nextLine()); - queue.add(input); - queue.print(); - break; - case 2: - out.println("Removed element: " + queue.remove()); - queue.print(); - break; - case 3: - out.println("Front element: " + queue.element()); - queue.print(); - break; - case 4: - queue.print(); - break; - case 5: - continue chooseModule; - default: - out.println("Wrong choice!"); - } - } - case 3: - while (true) { - out.println("Select operation:"); - out.println("================="); - out.println("1. Add"); - out.println("2. Add at index"); - out.println("3. Remove"); - out.println("4. Remove at index"); - out.println("5. Remove item"); - out.println("6. Edit item"); - out.println("7. Delete LinkedList"); - out.println("8. Print"); - out.println("9. Exit module"); - k2 = Integer.parseInt(in.nextLine()); - int item, index; - switch (k2) { - case 1: - out.println("Enter value:"); - item = Integer.parseInt(in.nextLine()); - singleLinkedList.add(item); - singleLinkedList.printList(); - break; - case 2: - out.println("Enter value:"); - item = Integer.parseInt(in.nextLine()); - out.println("Enter index:"); - index = Integer.parseInt(in.nextLine()); - singleLinkedList.add(index, item); - singleLinkedList.printList(); - break; - case 3: - out.println("Removed element: " + singleLinkedList.remove()); - singleLinkedList.printList(); - break; - case 4: - out.println("Enter index:"); - index = Integer.parseInt(in.nextLine()); - out.println("Removed element: " + singleLinkedList.remove(index)); - singleLinkedList.printList(); - break; - case 5: - out.println("Enter value:"); - item = Integer.parseInt(in.nextLine()); - out.println("Removed: " + singleLinkedList.removeItem(item)); - singleLinkedList.printList(); - break; - case 6: - out.println("Enter index to edit:"); - index = Integer.parseInt(in.nextLine()); - out.println("Enter new value:"); - item = Integer.parseInt(in.nextLine()); - singleLinkedList.set(index, item); - singleLinkedList.printList(); - break; - case 7: - singleLinkedList.clear(); - out.println("LinkedList deleted."); - singleLinkedList.printList(); - break; - case 8: - singleLinkedList.printList(); - break; - case 9: - continue chooseModule; - default: - out.println("Wrong choice!"); - } - } - case 4: - while (true) { - out.println("Select operation:"); - out.println("================="); - out.println("1. Add"); - out.println("2. Add at index"); - out.println("3. Remove"); - out.println("4. Remove at index"); - out.println("5. Remove item"); - out.println("6. Edit item"); - out.println("7. Delete LinkedList"); - out.println("8. Print"); - out.println("9. Exit module"); - k2 = Integer.parseInt(in.nextLine()); - int item, index; - switch (k2) { - case 1: - out.println("Enter value:"); - item = Integer.parseInt(in.nextLine()); - doubleLinkedList.add(item); - doubleLinkedList.printList(); - break; - case 2: - out.println("Enter value:"); - item = Integer.parseInt(in.nextLine()); - out.println("Enter index:"); - index = Integer.parseInt(in.nextLine()); - doubleLinkedList.add(index, item); - doubleLinkedList.printList(); - break; - case 3: - out.println("Removed element: " + doubleLinkedList.remove()); - doubleLinkedList.printList(); - break; - case 4: - out.println("Enter index:"); - index = Integer.parseInt(in.nextLine()); - out.println("Removed element: " + doubleLinkedList.remove(index)); - doubleLinkedList.printList(); - break; - case 5: - out.println("Enter value:"); - item = Integer.parseInt(in.nextLine()); - out.println("Removed: " + doubleLinkedList.removeItem(item)); - doubleLinkedList.printList(); - break; - case 6: - out.println("Enter index to edit:"); - index = Integer.parseInt(in.nextLine()); - out.println("Enter new value:"); - item = Integer.parseInt(in.nextLine()); - doubleLinkedList.set(index, item); - doubleLinkedList.printList(); - break; - case 7: - doubleLinkedList.clear(); - out.println("LinkedList deleted."); - doubleLinkedList.printList(); - break; - case 8: - doubleLinkedList.printList(); - break; - case 9: - continue chooseModule; - default: - out.println("Wrong choice!"); - } - } - case 5: - while (true) { - out.println("Select operation:"); - out.println("================="); - out.println("1. Add"); - out.println("2. Add at index"); - out.println("3. Remove"); - out.println("4. Remove at index"); - out.println("5. Remove item"); - out.println("6. Edit item"); - out.println("7. Delete LinkedList"); - out.println("8. Print"); - out.println("9. Exit module"); - k2 = Integer.parseInt(in.nextLine()); - int item, index; - switch (k2) { - case 1: - out.println("Enter value:"); - item = Integer.parseInt(in.nextLine()); - circularSingleLinkedList.add(item); - circularSingleLinkedList.printList(); - break; - case 2: - out.println("Enter value:"); - item = Integer.parseInt(in.nextLine()); - out.println("Enter index:"); - index = Integer.parseInt(in.nextLine()); - circularSingleLinkedList.add(index, item); - circularSingleLinkedList.printList(); - break; - case 3: - out.println("Removed element: " + circularSingleLinkedList.remove()); - circularSingleLinkedList.printList(); - break; - case 4: - out.println("Enter index:"); - index = Integer.parseInt(in.nextLine()); - out.println("Removed element: " + circularSingleLinkedList.remove(index)); - circularSingleLinkedList.printList(); - break; - case 5: - out.println("Enter value:"); - item = Integer.parseInt(in.nextLine()); - out.println("Removed: " + circularSingleLinkedList.removeItem(item)); - circularSingleLinkedList.printList(); - break; - case 6: - out.println("Enter index to edit:"); - index = Integer.parseInt(in.nextLine()); - out.println("Enter new value:"); - item = Integer.parseInt(in.nextLine()); - circularSingleLinkedList.set(index, item); - circularSingleLinkedList.printList(); - break; - case 7: - circularSingleLinkedList.clear(); - out.println("LinkedList deleted."); - circularSingleLinkedList.printList(); - break; - case 8: - circularSingleLinkedList.printList(); - break; - case 9: - continue chooseModule; - default: - out.println("Wrong choice!"); - } - } - case 6: - out.println("Yet to be developed!"); - break; - case 7: - out.println("Exiting..."); - return; - default: - out.println("Wrong choice!"); - } - } - } -} diff --git a/src/main/java/com/rampatra/arrays/ArrangeNosToFormBiggestNo.java b/src/main/java/com/rampatra/arrays/ArrangeNosToFormBiggestNo.java deleted file mode 100644 index ce069e34..00000000 --- a/src/main/java/com/rampatra/arrays/ArrangeNosToFormBiggestNo.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.rampatra.arrays; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 11/1/15 - */ -public class ArrangeNosToFormBiggestNo { - - /** - * Sorts {@code numbers} such that if you form a number {@code n} - * by concatenating digits in order a[0]....a[size], it results being the - * largest number possible. - *

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

- * I/P: {1, 34, 3, 98, 9, 76, 45, 4} - * O/P: {9, 98, 76, 45, 4, 34, 3, 1}, i.e, 998764543431 - * - * @param numbers input integer array - * @return integer array where if you concatenate all its elements, you will get the largest number - */ - private static Integer[] arrangeArrayOfNosToFormBiggestNo(Integer[] numbers) { - - Arrays.sort(numbers, (o1, o2) -> Integer.parseInt(o1 + "" + o2) >= Integer.parseInt(o2 + "" + o1) ? -1 : 1); - - /* - Use the below version (without lambda) if you use JDK < 8 - - Arrays.sort(numbers, new Comparator() { - @Override - public int compare(Integer o1, Integer o2) { - return Integer.parseInt(o1 + "" + o2) >= Integer.parseInt(o2 + "" + o1) ? -1 : 1; - } - }); - */ - return numbers; - } - - public static void main(String[] args) { - System.out.println(Arrays.toString(arrangeArrayOfNosToFormBiggestNo(new Integer[]{45, 567, 12, 1}))); - System.out.println(Arrays.toString(arrangeArrayOfNosToFormBiggestNo(new Integer[]{54, 546, 548, 60}))); - System.out.println(Arrays.toString(arrangeArrayOfNosToFormBiggestNo(new Integer[]{1, 34, 3, 98, 9, 76, 45, 4}))); - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/arrays/BooleanMatrix.java b/src/main/java/com/rampatra/arrays/BooleanMatrix.java deleted file mode 100644 index 04ee2d88..00000000 --- a/src/main/java/com/rampatra/arrays/BooleanMatrix.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.rampatra.arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 9/11/15 - * @time: 3:28 PM - * @see: http://www.geeksforgeeks.org/a-boolean-matrix-question/ - */ -public class BooleanMatrix { - - /** - * Given a boolean matrix mat[M][N] of size M X N, modify it such that - * if a matrix cell mat[i][j] is 1 (or true) then make all the cells of - * ith row and jth column as 1. - * - * @param a - */ - public static void modifyBooleanMatrix(int[][] a) { - int rowFlag = 0, colFlag = 0; - - // if a[i][j] is 1 then we make a[0][j] 1 and a[i][0] 1 - for (int i = 0; i < a.length; i++) { - for (int j = 0; j < a[0].length; j++) { - if (i == 0 || j == 0) { - if (a[i][0] == 1) { - rowFlag = 1; - } - if (a[0][j] == 1) { - colFlag = 1; - } - } else if (a[i][j] == 1) { - a[0][j] = 1; - a[i][0] = 1; - } - } - } - - // if a[0][j] is 1 or a[i][0] is 1 then a[i][j] is 1 - for (int i = 1; i < a.length; i++) { - for (int j = 1; j < a[0].length; j++) { - if (a[0][j] == 1 || a[i][0] == 1) { - a[i][j] = 1; - } - } - } - - if (rowFlag == 1) { - for (int j = 0; j < a[0].length; j++) { - a[0][j] = 1; - } - } - if (colFlag == 1) { - for (int i = 0; i < a.length; i++) { - a[i][0] = 1; - } - } - } - - private static void print2DMatrix(int[][] a) { - for (int i = 0; i < a.length; i++) { - for (int j = 0; j < a[0].length; j++) { - System.out.print(a[i][j]); - } - System.out.println(); - } - } - - public static void main(String[] args) { - int[][] ar = new int[][]{{1, 0, 0, 1}, {0, 0, 1, 0}, {0, 0, 0, 0}}; - print2DMatrix(ar); - modifyBooleanMatrix(ar); - print2DMatrix(ar); - System.out.println("-------"); - ar = new int[][]{{1, 0}, {0, 0}}; - print2DMatrix(ar); - modifyBooleanMatrix(ar); - print2DMatrix(ar); - } -} diff --git a/src/main/java/com/rampatra/arrays/CelebrityProblem.java b/src/main/java/com/rampatra/arrays/CelebrityProblem.java deleted file mode 100644 index 8b7278ea..00000000 --- a/src/main/java/com/rampatra/arrays/CelebrityProblem.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.rampatra.arrays; - -import com.rampatra.base.LinkedStack; -import com.rampatra.base.Stack; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 10/2/15 - * @time: 10:48 PM - *

- * In a party of N people, only one person is known to everyone. Such a person may be present in the party, if yes, - * (s)he doesn’t know anyone in the party. We can only ask questions like “does A know B? “. Find the stranger - * (celebrity) in minimum number of questions. - *

- * TODO: Not tested. - */ -public class CelebrityProblem { - - /** - * Checks if person {@param a} knows person {@param b}. - * - * @param peoples - * @param a - * @param b - * @return - */ - public static boolean haveAcquaintance(int[][] peoples, int a, int b) { - return peoples[a][b] == 1; - } - - /** - * Finds the celebrity in {@param peoples} where - * peoples[i][j] is 1 when person i knows person j. - *

- * Algorithm: - * - If A knows B, then A can’t be celebrity. Discard A, but B may be celebrity. - * - If A does not know B, then B can’t be celebrity. Discard B, but A may be celebrity. - * - Repeat above two steps till we left with only one person. - * Find celebrity within remaining persons by performing the below operations: - * - Push all the celebrities into a stack. - * - Pop off top two persons from the stack, discard one person based on return status of HaveAcquaintance(A, 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 - */ - public static int findCelebrity(int[][] peoples) { - - Stack possibleCelebrities = new LinkedStack<>(); - - for (int i = 0; i < peoples.length; i++) { - for (int j = 0; j < peoples[0].length; j++) { - if (haveAcquaintance(peoples, i, j)) { - possibleCelebrities.push(j); - } - } - } - - int firstPerson = -1, secondPerson; - while (!possibleCelebrities.isEmpty()) { - firstPerson = possibleCelebrities.pop(); - - // we have found the celebrity - if (possibleCelebrities.isEmpty()) break; - - secondPerson = possibleCelebrities.pop(); - if (haveAcquaintance(peoples, firstPerson, secondPerson)) { - possibleCelebrities.push(secondPerson); - } else { - possibleCelebrities.push(firstPerson); - } - } - - return firstPerson; - } - - public static void main(String[] args) { - System.out.println(findCelebrity(new int[][]{{0, 0, 1, 0}, {0, 0, 1, 0}, {0, 0, 0, 0}, {0, 0, 1, 0}})); - System.out.println(findCelebrity(new int[][]{{0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}})); - } -} diff --git a/src/main/java/com/rampatra/arrays/ConsecutiveElements.java b/src/main/java/com/rampatra/arrays/ConsecutiveElements.java deleted file mode 100644 index f8dc151e..00000000 --- a/src/main/java/com/rampatra/arrays/ConsecutiveElements.java +++ /dev/null @@ -1,113 +0,0 @@ -package com.rampatra.arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 8/28/15 - * @time: 10:32 AM - */ -public class ConsecutiveElements { - - /** - * Given an unsorted array of numbers, write a function that returns true if array consists of consecutive numbers. - *

- * Examples: - * a) If array is {5, 2, 3, 1, 4}, then the function should return true because the array has consecutive numbers - * from 1 to 5. - * b) If array is {34, 23, 52, 12, 3 }, then the function should return false because the elements are not consecutive. - * c) If the array is {7, 6, 5, 5, 3, 4}, then the function should return false because 5 and 5 are not consecutive. - *

- * ALGORITHM: - * The idea is to check for following two conditions. If following two conditions are true, then return true. - * 1) max – min + 1 = n where max is the maximum element in array, min is minimum element in array and n is the number - * of elements in array. - * 2) All elements are distinct. - *

- * To check if all elements are distinct, we can create a visited[] array of size n. We can map the ith element of input - * array arr[] to visited array by using arr[i] – min as index in visited[]. So we need O(n) auxiliary space. - * - * @param a - * @return - */ - public static boolean areConsecutiveElements(int[] a) { - int min = a[0], max = a[0]; - int[] visitedArray = new int[a.length]; - - // find min and max element - for (int i = 1; i < a.length; i++) { - if (a[i] < min) { - min = a[i]; - } - if (a[i] > max) { - max = a[i]; - } - } - - // diff of max and min should be equal to length of array - if (a.length != max - min + 1) { - return false; - } - - // check for distinct elements - for (int i = 0; i < a.length; i++) { - if (visitedArray[a[i] - min] == 0) { - visitedArray[a[i] - min] = a[i]; - } else { - return false; - } - } - - return true; - } - - /** - * 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}. - * - * @param a - * @return - */ - public static boolean areConsecutiveElementsInO1Space(int[] a) { - int min = a[0], max = a[0]; - - // find min and max element - for (int i = 1; i < a.length; i++) { - if (a[i] < min) { - min = a[i]; - } - if (a[i] > max) { - max = a[i]; - } - } - - // diff of max and min should be equal to length of array - if (a.length != max - min + 1) { - return false; - } - - // check for distinct elements - for (int i = 0; i < a.length; i++) { - if (a[Math.abs(a[i]) - min] >= 0) { - a[Math.abs(a[i]) - min] = -(a[Math.abs(a[i]) - min]); - } else { - return false; - } - } - - return true; - } - - 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})); - System.out.println(areConsecutiveElements(new int[]{8, 5, 2, 4, 3, 1})); - System.out.println("=============="); - System.out.println(areConsecutiveElementsInO1Space(new int[]{5, 4, 3, 2, 1})); - System.out.println(areConsecutiveElementsInO1Space(new int[]{67, 68, 69, 72, 70, 71})); - System.out.println(areConsecutiveElementsInO1Space(new int[]{67, 68, 69, 72, 70, 71, 70})); - System.out.println(areConsecutiveElementsInO1Space(new int[]{8, 5, 2, 4, 3, 1})); - } -} diff --git a/src/main/java/com/rampatra/arrays/CountDivisors.java b/src/main/java/com/rampatra/arrays/CountDivisors.java deleted file mode 100644 index 3023dc3c..00000000 --- a/src/main/java/com/rampatra/arrays/CountDivisors.java +++ /dev/null @@ -1,35 +0,0 @@ -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/main/java/com/rampatra/arrays/CountSmallerElementsOnRHS.java b/src/main/java/com/rampatra/arrays/CountSmallerElementsOnRHS.java deleted file mode 100644 index 413234ec..00000000 --- a/src/main/java/com/rampatra/arrays/CountSmallerElementsOnRHS.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.rampatra.arrays; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 9/19/15 - * @time: 11:33 PM - */ -public class CountSmallerElementsOnRHS { - - public static int[] getSmallerElementsCountOnRHSNaive(int[] a) { - // TODO - return null; - } - - 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 deleted file mode 100644 index 3ba861ab..00000000 --- a/src/main/java/com/rampatra/arrays/DistinctPairs.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.rampatra.arrays; - -import java.util.HashSet; -import java.util.Set; - -/** - * Level: Easy - * Problem Description: - * Given an array and a target sum, return the number of distinct pairs whose sum is equal to the target sum. - *

- * For Example, given an array [1, 2, 3, 6, 7, 8, 9, 1] and a target sum of 10, - * the 7 pairs, i.e, (1, 9), (2, 8), (3, 7), (8, 2), (9, 1), (9, 1), and (1, 9) all sum to 10 but there are only - * three distinct pairs, i.e, (1, 9), (2, 8), and (3, 7) so the answer would be 3. - * - * @author rampatra - * @since 2019-06-03 - */ -public class DistinctPairs { - - /** - * Time complexity: O(n), n = size of the array - * Space complexity: O(n) - * - * @param arr - * @param targetSum - * @return - */ - private static int numberOfDistinctPairs(int[] arr, int targetSum) { - Set numSet = new HashSet<>(); - Set> pairSet = new HashSet<>(); - - for (int i = 0; i < arr.length; i++) { - if (numSet.contains(targetSum - arr[i])) { - Set pair = new HashSet<>(); - pair.add(arr[i]); - pair.add(targetSum - arr[i]); - pairSet.add(pair); - } - numSet.add(arr[i]); - } - - return pairSet.size(); - } - - public static void main(String[] args) { - System.out.println(numberOfDistinctPairs(new int[]{1, 2, 3, 6, 7, 8, 9, 1}, 1)); - System.out.println(numberOfDistinctPairs(new int[]{1, 2, 3, 6, 7, 8, 9, 1}, 2)); - System.out.println(numberOfDistinctPairs(new int[]{1, 2, 3, 6, 7, 8, 9, 1}, 10)); - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/arrays/DuplicatesInArray.java b/src/main/java/com/rampatra/arrays/DuplicatesInArray.java deleted file mode 100644 index 5cb9cbe8..00000000 --- a/src/main/java/com/rampatra/arrays/DuplicatesInArray.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.rampatra.arrays; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 8/21/15 - */ -public class DuplicatesInArray { - - /** - * Given an array of n elements which contains elements from 0 to n-1, with any of - * these numbers appearing any number of times. Find these repeating numbers in O(n) - * time complexity. - *

- * For example, let n be 7 and array be {1, 2, 3, 1, 3, 6, 6}, the answer should be - * 1, 3 and 6. - *

- * EXPLANATION: - * The algorithm is simple. We use index of the array to track repeating elements. - * Once we encounter a element lets say 2 then we make the element in 2nd index -ve just - * to mark that we have encountered 2. When we encounter 2 again and see that 2nd index - * is already -ve we conclude that 2 is repeated. - *

- * Similar to {@link TwoRepeatingElements#findTwoRepeatingElements(int[])}. - * - * @param a - * @return - */ - public static int[] findDuplicatesInArray(int[] a) { - int[] duplicates = new int[a.length]; - - for (int i = 0, j = 0; i < a.length; i++) { - if (a[Math.abs(a[i])] >= 0) { - a[Math.abs(a[i])] = -a[Math.abs(a[i])]; - } else { - duplicates[j++] = Math.abs(a[i]); - } - } - return duplicates; - } - - public static void main(String[] args) { - System.out.println(Arrays.toString(findDuplicatesInArray(new int[]{1, 1, 2, 3, 1, 3, 6, 6}))); - // doesn't work if 0 is present in array (as -0 makes no sense but we can modify the algorithm to handle 0) - System.out.println(Arrays.toString(findDuplicatesInArray(new int[]{1, 0, 1, 2, 3, 1, 3, 6, 6}))); - System.out.println(Arrays.toString(findDuplicatesInArray(new int[]{0, 0, 1, 2, 3, 1, 3, 6, 6}))); - } -} diff --git a/src/main/java/com/rampatra/arrays/DuplicatesInArrayWithinKDistance.java b/src/main/java/com/rampatra/arrays/DuplicatesInArrayWithinKDistance.java deleted file mode 100644 index 2117d712..00000000 --- a/src/main/java/com/rampatra/arrays/DuplicatesInArrayWithinKDistance.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.rampatra.arrays; - -import java.util.Arrays; -import java.util.HashSet; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 10/18/15 - */ -public class DuplicatesInArrayWithinKDistance { - - /** - * Finds duplicates in an unsorted array {@code a} which are - * only k distance apart from each other. - * - * @param a - * @param k - * @return - */ - public static int[] findDuplicatesInArrayWithinKDistance(int[] a, int k) { - int index = 0; - int[] duplicates = new int[a.length]; - - HashSet hashSet = new HashSet<>(); - - for (int i = 0; i < a.length; i++) { - if (hashSet.contains(a[i])) { - duplicates[index++] = a[i]; - } else { - hashSet.add(a[i]); - } - - if (i >= k) { - hashSet.remove(a[i - k]); - } - } - - return Arrays.copyOf(duplicates, index); - } - - public static void main(String[] args) { - System.out.println(Arrays.toString(findDuplicatesInArrayWithinKDistance(new int[]{1, 2, 8, 1, 3, 4, 5, 6, 6, 7}, 3))); - } -} diff --git a/src/main/java/com/rampatra/arrays/EqualProbabilityRandomNoGenerator.java b/src/main/java/com/rampatra/arrays/EqualProbabilityRandomNoGenerator.java deleted file mode 100644 index c26d8694..00000000 --- a/src/main/java/com/rampatra/arrays/EqualProbabilityRandomNoGenerator.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.rampatra.arrays; - -import java.util.Random; -import java.util.Scanner; - -/** - * Given a random number generator f(n) which generates a random number - * from {@code 0} (inclusive) to {@code n} (exclusive), design a method - * which uses f(n) to generate non repeating random numbers from - * {@code 0} (inclusive) to {@code n} (exclusive)? - * - * @author rampatra - * @since 8/13/15 - * @time: 1:41 PM - */ -public class EqualProbabilityRandomNoGenerator { - - static int[] bucket; - static int size; - - /** - * The algorithm is to create a bucket of numbers and then to keep on - * removing the elements from the bucket which are returned. - * - * @return - */ - public static int getRandom() { - int random = f(size--); - int result = bucket[random]; - bucket[random] = bucket[size]; - return result; - } - - public static int f(int n) { - return new Random().nextInt(n); - } - - public static void main(String[] args) { - Scanner in = new Scanner(System.in); - - System.out.println("How many random numbers you would like to generate?"); - size = in.nextInt(); - - bucket = new int[size]; - - for (int i = 0; i < bucket.length; i++) { - bucket[i] = i; - } - for (int i = 0; i < bucket.length; i++) { - System.out.println(getRandom()); - } - } -} diff --git a/src/main/java/com/rampatra/arrays/EquilibriumIndex.java b/src/main/java/com/rampatra/arrays/EquilibriumIndex.java deleted file mode 100644 index c943c603..00000000 --- a/src/main/java/com/rampatra/arrays/EquilibriumIndex.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.rampatra.arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 8/22/15 - * @time: 11:56 AM - */ -public class EquilibriumIndex { - - /** - * EQUILIBRIUM INDEX of an array is an index such that the sum of elements at lower - * indexes is equal to the sum of elements at higher indexes. - *

- * For example, in an array A = {-7, 1, 5, 2, -4, 3, 0} - *

- * 3 is an equilibrium index, because - * A[0] + A[1] + A[2] = A[4] + A[5] + A[6] - *

- * 6 is also an equilibrium index, because sum of zero elements is zero, - * i.e., A[0] + A[1] + A[2] + A[3] + A[4] + A[5] = 0 - *

- * 7 is not an equilibrium index, because it is not a valid index of array A. - * - * @param a - * @return equilibrium index of array {@param a}. - */ - public static int getEquilibriumIndex(int[] a) { - int totalSum = 0, leftSum = 0; - - for (int i = 0; i < a.length; i++) { - totalSum += a[i]; - } - - for (int i = 0; i < a.length; i++) { - totalSum -= a[i]; // totalSum now holds the right sum from ith index to end - if (leftSum == totalSum) { - return i; // left sum == right sum - } - leftSum += a[i]; // update left sum - } - - return -1; - } - - public static void main(String[] args) { - System.out.println(getEquilibriumIndex(new int[]{-7, 1, 5, 2, -4, 3, 0})); - System.out.println(getEquilibriumIndex(new int[]{-7, 1, 5, 0, 0, 0, 0, 1, 2, -4, 1, 3, 0})); - System.out.println(getEquilibriumIndex(new int[]{4, 5, 2, 1, 6, 7, 8, 0, 1})); - System.out.println(getEquilibriumIndex(new int[]{0})); - System.out.println(getEquilibriumIndex(new int[]{0, 0, 0})); - System.out.println(getEquilibriumIndex(new int[]{1, 1})); - System.out.println(getEquilibriumIndex(new int[]{1, 1, 1})); - } -} diff --git a/src/main/java/com/rampatra/arrays/FixedPoint.java b/src/main/java/com/rampatra/arrays/FixedPoint.java deleted file mode 100644 index 99e8a333..00000000 --- a/src/main/java/com/rampatra/arrays/FixedPoint.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.rampatra.arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 9/8/15 - * @time: 11:34 PM - */ -public class FixedPoint { - - /** - * Finds the FIXED POINT in an array {@param a} of n distinct integers sorted - * in ascending order. If there is no fixed point it returns -1. - * FIXED POINT in an array is an index i such that arr[i] is equal to i. Note that - * integers in array can be negative. - * - * @param a - * @return - */ - public static int findFixedPoint(int[] a) { - int low = 0, high = a.length - 1, mid; - while (low <= high) { - mid = (low + high) / 2; - if (a[mid] == mid) { - return mid; - } else if (a[mid] > mid) { - high = mid - 1; - } else { - low = mid + 1; - } - } - return -1; - } - - public static void main(String[] args) { - System.out.println(findFixedPoint(new int[]{-10, -5, 0, 3, 7})); - System.out.println(findFixedPoint(new int[]{0, 2, 5, 8, 17})); - System.out.println(findFixedPoint(new int[]{-10, -5, 3, 4, 7, 9})); - } -} diff --git a/src/main/java/com/rampatra/arrays/FlattenArray.java b/src/main/java/com/rampatra/arrays/FlattenArray.java deleted file mode 100644 index e68c250b..00000000 --- a/src/main/java/com/rampatra/arrays/FlattenArray.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.rampatra.arrays; - -import java.util.ArrayList; -import java.util.List; - -public class FlattenArray { - - /** - * Given a nested array like [[1, 2], 3, [4]], return an array like [1, 2, 3, 4, 5]. - * - * @param nestedArray an Object array - * @return a list of all elements in the nestedArray but all at the same level - */ - private static List flattenArray(Object[] nestedArray) { - if (nestedArray == null || nestedArray.length == 0) return new ArrayList<>(); - - List flattenedArray = new ArrayList<>(); - - for (Object obj : nestedArray) { - if (obj instanceof Object[]) { - flattenedArray.addAll(flattenArray((Object[]) obj)); - } else if (obj instanceof Integer) { - flattenedArray.add((Integer) obj); - } - } - - return flattenedArray; - } - - public static void main(String[] args) { - System.out.println(flattenArray(null)); - System.out.println(flattenArray(new Object[]{null})); - System.out.println(flattenArray(new Object[]{new Object[]{}})); - System.out.println(flattenArray(new Object[]{new Object[]{1, 2}})); - System.out.println(flattenArray(new Object[]{1, 2, new Object[]{4, 5}, 6})); - System.out.println(flattenArray(new Object[]{new Object[]{4, 5}, 1, 2, 6})); - System.out.println(flattenArray(new Object[]{1, 2, 6, new Object[]{4, 5}})); - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/arrays/IntersectionAndUnionOf2SortedArrays.java b/src/main/java/com/rampatra/arrays/IntersectionAndUnionOf2SortedArrays.java deleted file mode 100644 index 595e85a5..00000000 --- a/src/main/java/com/rampatra/arrays/IntersectionAndUnionOf2SortedArrays.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.rampatra.arrays; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 8/13/15 - * @time: 3:56 PM - */ -public class IntersectionAndUnionOf2SortedArrays { - - /** - * Returns a 2-D array consisting of intersection and union of - * two sorted arrays {@param a} and {@param b} respectively. - * - * @param a - * @param b - * @return - */ - public static int[][] getIntersectionAndUnionOf2SortedArrays(int[] a, int[] b) { - int length = a.length + b.length, x = 0, y = 0; - int[] intersection = new int[length], union = new int[length]; - - for (int i = 0, j = 0; i < a.length || j < b.length; ) { - - // if either of the arrays runs out first - if (i == a.length) { - union[y++] = b[j++]; - continue; - } - if (j == b.length) { - union[y++] = a[i++]; - continue; - } - - if (a[i] < b[j]) { - union[y++] = a[i++]; - } else if (a[i] > b[j]) { - union[y++] = b[j++]; - } else { - intersection[x++] = a[i]; - union[y++] = a[i]; - i++; - j++; - } - } - - return new int[][]{intersection, union}; - } - - public static void main(String[] args) { - int[] a1 = new int[]{2, 3, 4, 5, 6, 7, 8}; - int[] a2 = new int[]{6, 7, 8, 10, 12, 14, 16}; - int[][] result = getIntersectionAndUnionOf2SortedArrays(a1, a2); - // intersection - System.out.println(Arrays.toString(result[0])); - // union - System.out.println(Arrays.toString(result[1])); - } -} diff --git a/src/main/java/com/rampatra/arrays/InversionsInArray.java b/src/main/java/com/rampatra/arrays/InversionsInArray.java deleted file mode 100644 index 1677764d..00000000 --- a/src/main/java/com/rampatra/arrays/InversionsInArray.java +++ /dev/null @@ -1,102 +0,0 @@ -package com.rampatra.arrays; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/29/15 - * @time: 8:37 PM - */ -public class InversionsInArray { - - static int inversionCount = 0; - - /** - * Naive approach. - *

- * INVERSION COUNT for an array indicates how far (or close) the array is from being - * sorted. If array is already sorted then inversion count is 0. If array is sorted in - * reverse order then inversion count is the maximum. - *

- * Formally speaking, two elements a[i] and a[j] form an inversion if a[i] > a[j] and i < j. - *

- * Example: - * The sequence 2, 4, 1, 3, 5 has three inversions (2, 1), (4, 1), (4, 3). - * - * @param a - * @return - */ - public static int getInversionCountNaiveApproach(int[] a) { - int count = 0; - for (int i = 0; i < a.length - 2; i++) { - for (int j = 1; j < a.length - 1; j++) { - if (a[i] > a[j]) count++; - } - } - return count; - } - - /** - * Optimized approach. - *

- * 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. - * - * @param a - * @return - * @see: http://www.geeksforgeeks.org/counting-inversions/ - */ - public static int getInversionCount(int[] a) { - mergeSort(a); - return inversionCount; - } - - /** - * Merge sort. - *

- * Time complexity: O(n log n) - * Space complexity: O(n) (also needs O(log n) stack space as it is recursive) - * - * @param a - * @return - */ - public static int[] mergeSort(int[] a) { - if (a.length == 1) return a; - - int[] x = mergeSort(Arrays.copyOfRange(a, 0, a.length / 2)); - int[] y = mergeSort(Arrays.copyOfRange(a, a.length / 2, a.length)); - - return merge(x, y); - } - - /** - * Merges two sorted arrays {@param a} and {@param b}. - * - * @param a - * @param b - * @return - */ - public static int[] merge(int[] a, int[] b) { - int lenA = a.length, lenB = b.length, k = 0; - int[] sortedArray = new int[lenA + lenB]; - - for (int i = 0, j = 0; i < lenA || j < lenB; ) { - if (j == lenB || (i < lenA && a[i] < b[j])) { - sortedArray[k++] = a[i++]; - } else { - sortedArray[k++] = b[j++]; - inversionCount += lenA - i; - } - } - - return sortedArray; - } - - public static void main(String[] args) { - System.out.println(getInversionCountNaiveApproach(new int[]{2, 4, 1, 3, 5})); - System.out.println(getInversionCount(new int[]{2, 4, 1, 3, 5})); - } -} diff --git a/src/main/java/com/rampatra/arrays/KLargestElements.java b/src/main/java/com/rampatra/arrays/KLargestElements.java deleted file mode 100644 index 87546e7d..00000000 --- a/src/main/java/com/rampatra/arrays/KLargestElements.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.rampatra.arrays; - -import com.rampatra.base.MinHeap; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @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 - * @param k - * @return - */ - public static int[] getKLargestElements(int[] a, int k) { - - int[] kElements = Arrays.copyOfRange(a, 0, k); - - MinHeap minHeap = new MinHeap(kElements); - minHeap.buildMinHeap(); - - for (int i = k; i < a.length; i++) { - if (a[i] > minHeap.findMin()) { - minHeap.extractMin(); - minHeap.insert(a[i]); - } - } - - return minHeap.getHeap(); - } - - public static void main(String[] args) { - System.out.println(Arrays.toString(getKLargestElements(new int[]{2, 3, 4, 1, 5, 7, 9}, 3))); - } -} diff --git a/src/main/java/com/rampatra/arrays/KthLargestElement.java b/src/main/java/com/rampatra/arrays/KthLargestElement.java deleted file mode 100644 index 65ca77c7..00000000 --- a/src/main/java/com/rampatra/arrays/KthLargestElement.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.rampatra.arrays; - -import com.rampatra.sorting.MergeSort; -import com.rampatra.base.MaxHeap; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 8/1/15 - * @time: 11:26 PM - */ -public class KthLargestElement { - - /** - * Naive approach. - *

- * Time complexity: O(n log n) - * - * @param a - * @param k - * @return - */ - public static int getKthLargestElementNaive(int[] a, int k) { - if (k >= a.length) return -1; - - a = MergeSort.mergeSort(a); - - return a[a.length - k]; - } - - /** - * Determines the kth largest element by building a max heap - * k times removing the root each time. - * - * @param a - * @param k - * @return - */ - public static int getKthLargestElement(int[] a, int k) { - MaxHeap maxHeap = new MaxHeap(a); - maxHeap.buildMaxHeap(); - while (true) { - if (k == 1) break; - - maxHeap.extractMax(); - k--; - } - - return maxHeap.findMax(); - } - - 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)); - System.out.println(Arrays.toString(ar)); - System.out.println(getKthLargestElement(ar, 3)); - System.out.println(Arrays.toString(ar)); - } -} diff --git a/src/main/java/com/rampatra/arrays/LargestProductContiguousSubArray.java b/src/main/java/com/rampatra/arrays/LargestProductContiguousSubArray.java deleted file mode 100644 index c7afb19b..00000000 --- a/src/main/java/com/rampatra/arrays/LargestProductContiguousSubArray.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.rampatra.arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 5/28/15 - * @time: 12:44 PM - */ -public class LargestProductContiguousSubArray { - - /** - * @param a - * @return - */ - public static int getLargestProductContiguousSubArray(int[] a) { - return 0; - } - - public static void main(String[] args) { - System.out.println(getLargestProductContiguousSubArray(new int[]{-2, 1, -3, 4, 5, -1, 4})); - System.out.println(getLargestProductContiguousSubArray(new int[]{6, -3, -10, 0, 2})); - } -} diff --git a/src/main/java/com/rampatra/arrays/LargestSumContiguousSubArray.java b/src/main/java/com/rampatra/arrays/LargestSumContiguousSubArray.java deleted file mode 100644 index 8b34d9ef..00000000 --- a/src/main/java/com/rampatra/arrays/LargestSumContiguousSubArray.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.rampatra.arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 5/28/15 - * @time: 12:44 PM - */ -public class LargestSumContiguousSubArray { - - /** - * Based on Kadane's Algorithm. Doesn't work when all - * elements in array {@param a} are negative. - * - * @param a - * @return - */ - public static int getLargestSumOfContiguousSubArray(int[] a) { - int maxSum = 0, maxSumTillIndex = 0; - - for (int i = 0; i < a.length; i++) { - maxSumTillIndex += a[i]; // keep on adding elements - if (maxSumTillIndex < 0) { - maxSumTillIndex = 0; // once the sum is less than 0 restart adding elements from next index - } else if (maxSumTillIndex > maxSum) { - maxSum = maxSumTillIndex; - } - } - return maxSum; - } - - /** - * Below algorithm works even when all elements in array {@param a} are negative. - * - * @param a - * @return - */ - public static int getLargestSumOfContiguousSubArrayWhenAllNosNegative(int[] a) { - int maxSum = a[0], maxSumTillIndex = a[0]; - - for (int i = 1; i < a.length; i++) { - maxSumTillIndex = Math.max(a[i], maxSumTillIndex + a[i]); - maxSum = Math.max(maxSum, maxSumTillIndex); - } - - return maxSum; - } - - 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 - System.out.println(getLargestSumOfContiguousSubArray(new int[]{-2, -1, -3, -4, -5, -1, -4})); - - System.out.println(getLargestSumOfContiguousSubArrayWhenAllNosNegative(new int[]{-2, 1, -3, 4, 5, -1, 4})); - System.out.println(getLargestSumOfContiguousSubArrayWhenAllNosNegative(new int[]{2, -1, -3, 4, -5, 1, 4})); - System.out.println(getLargestSumOfContiguousSubArrayWhenAllNosNegative(new int[]{-2, -1, -3, -4, -5, -1, -4})); - } -} diff --git a/src/main/java/com/rampatra/arrays/LeadersInArray.java b/src/main/java/com/rampatra/arrays/LeadersInArray.java deleted file mode 100644 index c2075751..00000000 --- a/src/main/java/com/rampatra/arrays/LeadersInArray.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.rampatra.arrays; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/29/15 - * @time: 12:06 PM - */ -public class LeadersInArray { - - /** - * Returns an array containing all leaders present in {@param a}. - * An element is a LEADER if its greater than all elements to - * the right of it in the array. - * - * @param a - * @return - */ - public static int[] getAllLeaders(int[] a) { - - int i = a.length - 2, j = 0; - int[] leaders = new int[a.length]; - - // rightmost element is always a leader - leaders[0] = a[a.length - 1]; - - for (; i >= 0; i--) { - if (a[i] > leaders[j]) { - leaders[++j] = a[i]; - } - } - - // omit the extra space which aren't filled with leaders - return Arrays.copyOfRange(leaders, 0, j + 1); - } - - public static void main(String[] args) { - System.out.println(Arrays.toString(getAllLeaders(new int[]{16, 17, 4, 3, 5, 2}))); - System.out.println(Arrays.toString(getAllLeaders(new int[]{16, 1, 4, 3, 5, 12}))); - System.out.println(Arrays.toString(getAllLeaders(new int[]{16, 15, 14, 13, 12, 10}))); - } -} diff --git a/src/main/java/com/rampatra/arrays/LongestBitonicSubArray.java b/src/main/java/com/rampatra/arrays/LongestBitonicSubArray.java deleted file mode 100644 index dc3caafb..00000000 --- a/src/main/java/com/rampatra/arrays/LongestBitonicSubArray.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.rampatra.arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 9/18/15 - * @time: 5:10 PM - */ -public class LongestBitonicSubArray { - - /** - * Returns the length of the longest bitonic sub-array in - * array {@param a}. - *

- * A subarray A[i … j] is bitonic if there is a k with i <= k <= j such - * that A[i] <= A[i + 1] ... <= A[k] >= A[k + 1] >= ... A[j – 1] > = A[j]. - * - * @param a - * @return - */ - public static int getLongestBitonicSubArrayLength(int[] a) { - int len = a.length; - int bitonicLength; - int[] increasingSequence = new int[len]; - int[] decreasingSequence = new int[len]; - - increasingSequence[0] = 1; // stores the length of the increasing sequence so far - decreasingSequence[len - 1] = 1; // stores the length of the decreasing sequence so far - - for (int i = 1; i < len; i++) { - if (a[i] > a[i - 1]) { - increasingSequence[i] = increasingSequence[i - 1] + 1; - } else { - increasingSequence[i] = 1; - } - } - - for (int i = len - 2; i >= 0; i--) { - if (a[i] > a[i + 1]) { - decreasingSequence[i] = decreasingSequence[i + 1] + 1; - } else { - decreasingSequence[i] = 1; - } - } - - bitonicLength = increasingSequence[0] + decreasingSequence[0] - 1; - for (int i = 0; i < len; i++) { - if ((increasingSequence[i] + decreasingSequence[i] - 1) > bitonicLength) { - bitonicLength = increasingSequence[i] + decreasingSequence[i] - 1; - } - } - - return bitonicLength; - } - - 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})); - System.out.println(getLongestBitonicSubArrayLength(new int[]{40, 30, 20, 10})); - System.out.println(getLongestBitonicSubArrayLength(new int[]{10})); - } -} diff --git a/src/main/java/com/rampatra/arrays/LongestConsecutiveSubsequence.java b/src/main/java/com/rampatra/arrays/LongestConsecutiveSubsequence.java deleted file mode 100644 index 8e6a99f8..00000000 --- a/src/main/java/com/rampatra/arrays/LongestConsecutiveSubsequence.java +++ /dev/null @@ -1,80 +0,0 @@ -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 numSet = new HashSet<>(); - for (int n : arr) { - numSet.add(n); - } - - for (int n : arr) { - subseqCount = 1; - currElem = n; - // check for the next consecutive elements - while (numSet.contains(currElem + 1)) { - numSet.remove(currElem); - numSet.remove(currElem + 1); - currElem++; - subseqCount++; - } - // check for the previous consecutive elements - while (numSet.contains(currElem - 1)) { - numSet.remove(currElem); - numSet.remove(currElem - 1); - currElem--; - subseqCount++; - } - // update longest counter if the length of the current subsequence is larger - if (subseqCount > longestSubseqCount) { - longestSubseqCount = subseqCount; - } - } - return longestSubseqCount; - } - - public static void main(String[] args) { - - System.out.println("{1, 9, 3, 10, 4, 20, 2}: " + - findLengthOfLongestConsecutiveSubsequence(new int[]{1, 9, 3, 10, 4, 20, 2})); - System.out.println("{36, 41, 56, 35, 44, 33, 34, 92, 43, 32, 42}: " + - findLengthOfLongestConsecutiveSubsequence(new int[]{36, 41, 56, 35, 44, 33, 34, 92, 43, 32, 42})); - System.out.println("{1,5,8,3}: " + findLengthOfLongestConsecutiveSubsequence(new int[]{1, 5, 8, 3})); - - // corner cases - System.out.println("{1}: " + findLengthOfLongestConsecutiveSubsequence(new int[]{1})); - System.out.println("{}: " + findLengthOfLongestConsecutiveSubsequence(new int[]{})); - } -} diff --git a/src/main/java/com/rampatra/arrays/MajorityElement.java b/src/main/java/com/rampatra/arrays/MajorityElement.java deleted file mode 100644 index 51e5d11f..00000000 --- a/src/main/java/com/rampatra/arrays/MajorityElement.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.rampatra.arrays; - -/** - * The algorithm for finding a possible candidate - * works in O(n) which is known as Moore’s Voting Algorithm. - * Basic idea of the algorithm is if we cancel out each - * occurrence of an element e with all the other elements - * that are different from e then e will exist until end - * if it is a majority element. - *

- * Time Complexity: O(n) - * Auxiliary Space : O(1) - * - * @author rampatra - * @since 5/20/15 - */ -public class MajorityElement { - - /** - * Uses Moore’s Voting Algorithm to - * get a candidate for majority element. - * - * @param a - * @return - */ - public static int findCandidate(int[] a) { - int candidate = a[0], count = 1; - for (int i = 1; i < a.length; i++) { - if (candidate == a[i]) { - count++; - } else { - count--; - } - if (count == 0) { - candidate = a[i]; - count = 1; - } - } - return candidate; - } - - public static void majorityElement(int[] a) { - int candidate = findCandidate(a), - count = 0; - - // check if the candidate is really a majority element - for (int i = 0; i < a.length; i++) { - if (candidate == a[i]) { - count++; - } - } - if (count > a.length / 2) { - System.out.print(candidate); - } else { - System.out.print("NONE"); - } - } - - public static void main(String[] args) { - majorityElement(new int[]{1, 6, 2, 2, 2, 1, 2, 2, 7, 2}); - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/arrays/MajorityElementInSortedArray.java b/src/main/java/com/rampatra/arrays/MajorityElementInSortedArray.java deleted file mode 100644 index ded2db27..00000000 --- a/src/main/java/com/rampatra/arrays/MajorityElementInSortedArray.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.rampatra.arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/31/15 - */ -public class MajorityElementInSortedArray { - - /** - * Checks if {@code n} is a majority element in array {@code arr} - * by performing a binary search. - *

- * Time complexity: O(log n) - * - * @param arr - * @param n - * @return - */ - public static boolean isMajorityElement(int[] arr, int n) { - int l = arr.length; - int startIndex = getFirstIndexOf(arr, n, 0, l - 1); - - // element not found - if (startIndex == -1) return false; - - if (startIndex + l / 2 < l && arr[startIndex + l / 2] == n) { - return true; - } else { - return false; - } - - } - - /** - * Returns the index of first occurrence of {@code n} in array {@code arr}. - * - * @param arr - * @param low - * @param high - * @param n - * @return - */ - public static int getFirstIndexOf(int[] arr, int n, int low, int high) { - if (low <= high) { - int mid = (low + high) / 2; - /** - * Check if a[mid] is the first occurrence of n: - * a[mid] is first occurrence if n is one of the following - * is true: - * (i) mid == 0 and a[mid] == n - * (ii) n > a[mid-1] and a[mid] == n - */ - if (arr[mid] == n && (mid == 0 || n > arr[mid - 1])) { - return mid; - } else if (n <= arr[mid]) { - return getFirstIndexOf(arr, n, low, mid - 1); - } else { - return getFirstIndexOf(arr, n, mid + 1, high); - } - } - return -1; - } - - public static void main(String[] args) { - System.out.println(isMajorityElement(new int[]{2, 2}, 2)); - System.out.println(isMajorityElement(new int[]{1, 2}, 2)); - System.out.println(isMajorityElement(new int[]{1, 2, 2, 2, 2, 2, 3, 3}, 2)); - System.out.println(isMajorityElement(new int[]{1, 2, 2, 2, 2, 3, 3, 3}, 2)); - } -} diff --git a/src/main/java/com/rampatra/arrays/MatrixInSpiral.java b/src/main/java/com/rampatra/arrays/MatrixInSpiral.java deleted file mode 100644 index a498f39a..00000000 --- a/src/main/java/com/rampatra/arrays/MatrixInSpiral.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.rampatra.arrays; - -import static java.lang.System.out; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 9/9/15 - * @time: 2:55 PM - */ -public class MatrixInSpiral { - - /** - * Prints a 2D array {@param a} in spiral form (clockwise). - * - * @param a - */ - public static void printMatrixInSpiral(int[][] a) { - int row = a.length, col = a[0].length; - - // this loop iterates for the entire matrix - for (int r = row, c = col, x = 0; r >= 0 && c >= 0; r--, c--, x++) { - /** - * Below 4 {@code for} loops print the perimeter of a matrix - */ - // prints the top row - for (int i = x, j = x; i < r && j < c; j++) { - out.print(a[i][j] + " "); - } - // prints the right most column - for (int i = x + 1, j = c - 1; i < r; i++) { - out.print(a[i][j] + " "); - } - // prints the bottom row - for (int i = r - 1, j = c - 2; i > x && j >= x; j--) { - out.print(a[i][j] + " "); - } - // prints the left most column - for (int i = r - 2, j = x; i > x; i--) { - out.print(a[i][j] + " "); - } - } - } - - public static void main(String[] args) { - printMatrixInSpiral(new int[][]{{1}, {2}}); - out.println(); - printMatrixInSpiral(new int[][]{{1, 2}, {3, 4}}); - out.println(); - printMatrixInSpiral(new int[][]{{1, 2, 3}, {4, 5, 6}}); - out.println(); - printMatrixInSpiral(new int[][]{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}); - out.println(); - printMatrixInSpiral(new int[][]{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}}); - out.println(); - printMatrixInSpiral(new int[][]{{1, 2, 3, 4, 5, 6}, {7, 8, 9, 10, 11, 12}, {13, 14, 15, 16, 17, 18}}); - out.println(); - printMatrixInSpiral(new int[][]{{1, 2, 3, 4, 5, 6, 7, 8}, {9, 10, 11, 12, 13, 14, 15, 16}}); - } -} diff --git a/src/main/java/com/rampatra/arrays/MaxDiffWithLargerElementAfterSmallerElement.java b/src/main/java/com/rampatra/arrays/MaxDiffWithLargerElementAfterSmallerElement.java deleted file mode 100644 index 04d7a9f8..00000000 --- a/src/main/java/com/rampatra/arrays/MaxDiffWithLargerElementAfterSmallerElement.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.rampatra.arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 8/12/15 - * @time: 5:40 PM - */ -public class MaxDiffWithLargerElementAfterSmallerElement { - - /** - * Finds the difference between any two elements such that larger - * element appears after the smaller number in array {@param a}. - *

- * Example: - * If array is [2, 3, 10, 6, 4, 8, 1] then returned value should be 8 (Diff between 10 and 2). - * If array is [ 7, 9, 5, 6, 3, 2 ] then returned value should be 2 (Diff between 7 and 9). - * - * @param a - * @return - */ - public static int getMaxDiffWithLargerElementAfterSmallerElement(int[] a) { - int minElement = a[0], maxDiff = a[1] - a[0]; - - for (int i = 1; i < a.length; i++) { - if (a[i] < minElement) { - minElement = a[i]; - } - if (a[i] - minElement > maxDiff) { - maxDiff = a[i] - minElement; - } - } - - return maxDiff; - } - - public static void main(String[] args) { - System.out.println(getMaxDiffWithLargerElementAfterSmallerElement(new int[]{2, 1, 4, 5, 10, 0})); - System.out.println(getMaxDiffWithLargerElementAfterSmallerElement(new int[]{2, -6, 4, 5, 10, 1})); - System.out.println(getMaxDiffWithLargerElementAfterSmallerElement(new int[]{-2, -6, -4, -5, -10, -1})); - } -} diff --git a/src/main/java/com/rampatra/arrays/MaxInAllSubArrays.java b/src/main/java/com/rampatra/arrays/MaxInAllSubArrays.java deleted file mode 100644 index 8061d44d..00000000 --- a/src/main/java/com/rampatra/arrays/MaxInAllSubArrays.java +++ /dev/null @@ -1,102 +0,0 @@ -package com.rampatra.arrays; - -import com.rampatra.base.MaxHeap; - -import java.util.ArrayDeque; -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 9/3/15 - * @time: 9:21 PM - */ -public class MaxInAllSubArrays { - - /** - * Naive approach. - *

- * Finds the maximum element in each and every sub-array - * in {@param a} of size {@param k}. - *

- * Time complexity: O(n*k), or more precisely O((n-k) * k) - * - * @param a - * @param k - */ - public static int[] maxInAllSubArraysOfSizeKNaive(int[] a, int k) { - int[] maxElements = new int[a.length - k + 1]; - int[] kElements; - - for (int i = 0; i <= a.length - k; i++) { - kElements = Arrays.copyOfRange(a, i, i + k); - /** - * maxHeapify() can't be used because to call maxHeapify() on i because left(i) and right (i) should - * already satisfy the max heap property which isn't true in this case. - */ - MaxHeap maxHeap = new MaxHeap(kElements); - maxHeap.buildMaxHeap(); - maxElements[i] = maxHeap.findMax(); - } - - return maxElements; - } - - /** - * Finds the maximum element in each and every sub-array - * in {@param a} of size {@param k}. - *

- * Time complexity: O(n) - * Auxiliary Space: O(k) - * - * @param a - * @param k - * @return - */ - public static int[] maxInAllSubArraysOfSizeK(int[] a, int k) { - int i, j = 0; - int[] result = new int[a.length - k + 1]; - /** - * Create a Double Ended Queue, Qi that will store indexes of array elements - * The queue will store indexes of useful elements in every window and it will - * maintain decreasing order of values from front to rear in Qi, i.e, - * arr[Qi.front[]] to arr[Qi.rear()] are sorted in decreasing order. - */ - ArrayDeque deque = new ArrayDeque<>(); - - for (i = 0; i < k; i++) { - // remove smaller elements on left side of current element - while (!deque.isEmpty() && a[i] > a[deque.peekLast()]) { - deque.removeLast(); - } - deque.addLast(i); - } - - for (; i < a.length; i++) { - result[j++] = a[deque.peekFirst()]; - - // remove elements that are outside window k - while (!deque.isEmpty() && deque.peekFirst() <= i - k) { - deque.removeFirst(); - } - // remove smaller elements on left side of current element - while (!deque.isEmpty() && a[i] > a[deque.peekLast()]) { - deque.removeLast(); - } - deque.addLast(i); - } - - // for max in last k elements - result[j] = a[deque.peekFirst()]; - - return result; - } - - 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))); - System.out.println(Arrays.toString(maxInAllSubArraysOfSizeK(new int[]{8, 5, 10, 7, 9, 4, 15, 12, 90, 13}, 4))); - } -} diff --git a/src/main/java/com/rampatra/arrays/MaxIndexDiff.java b/src/main/java/com/rampatra/arrays/MaxIndexDiff.java deleted file mode 100644 index 9eb982c4..00000000 --- a/src/main/java/com/rampatra/arrays/MaxIndexDiff.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.rampatra.arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 9/1/15 - * @time: 10:21 PM - */ -public class MaxIndexDiff { - - /** - * Given an array arr[], find the maximum j – i such that arr[j] > arr[i]. - * - * @param a - * @return - */ - public static int maxDiff(int[] a) { - int maxDiff = -1; - int[] leftMin = new int[a.length], rightMax = new int[a.length]; - - /** - * leftMin[i] holds the smallest element on left side of arr[i] including arr[i]. - * In other words, leftMin[i] stores the minimum value from (arr[0], arr[1], ... arr[i]). - */ - leftMin[0] = a[0]; - for (int i = 1; i < a.length; i++) { - leftMin[i] = Math.min(a[i], leftMin[i - 1]); - } - - /** - * rightMax[i] holds the greatest element on right side of arr[i] including arr[i]. - * In other words, rightMax[i] stores the maximum value from (arr[i], arr[i+1], ..arr[n-1]) - */ - rightMax[a.length - 1] = a[a.length - 1]; - for (int i = a.length - 2; i >= 0; i--) { - rightMax[i] = Math.max(a[i], rightMax[i + 1]); - } - - // traverse both arrays from left to right to find maximum j - i - for (int i = 0, j = 0; i < a.length && j < a.length; ) { - if (rightMax[j] > leftMin[i]) { - maxDiff = Math.max(maxDiff, j - i); - j++; - } else { - i++; - } - } - return maxDiff; - } - - 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})); - System.out.println(maxDiff(new int[]{6, 5, 4, 3, 2, 1})); - System.out.println(maxDiff(new int[]{10, 11, 12, 13, 14, 6, 9, 7, 5, 3})); - } -} diff --git a/src/main/java/com/rampatra/arrays/MaxMinWithMinComparisons.java b/src/main/java/com/rampatra/arrays/MaxMinWithMinComparisons.java deleted file mode 100644 index 23e3e99d..00000000 --- a/src/main/java/com/rampatra/arrays/MaxMinWithMinComparisons.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.rampatra.arrays; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/31/15 - * @time: 3:16 PM - */ -public class MaxMinWithMinComparisons { - - /** - * Finds the minimum and maximum number in array {@param a} - * with minimum no. of comparisons. - *

- * If length of array is even: - * No. of comparisons = 1+3*(n-2)/2 - * and if length is odd: - * No. of comparisons = 3*(n-1)/2 - * - * @param a - * @return - */ - public static int[] getMaxMinWithMinComparisons(int[] a) { - int min, max, i; - - if (a.length % 2 == 0) { // this is not a comparison - if (a[0] < a[1]) { // this is a comparison - min = a[0]; - max = a[1]; - } else { - min = a[1]; - max = a[0]; - } - i = 2; - } else { - min = max = a[0]; - i = 1; - } - - for (; i < a.length - 1; i += 2) { - if (a[i] < a[i + 1]) { // 1st comparison - if (a[i] < min) min = a[i]; // 2nd comparison - if (a[i + 1] > max) max = a[i + 1]; // 3rd comparison - } else { - if (a[i] > max) max = a[i]; // 2nd comparison - if (a[i + 1] < min) min = a[i + 1]; // 3rd comparison - } - } - - return new int[]{min, max}; - } - - 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 deleted file mode 100644 index 7db17c18..00000000 --- a/src/main/java/com/rampatra/arrays/MaxSpan.java +++ /dev/null @@ -1,45 +0,0 @@ -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/main/java/com/rampatra/arrays/MaximumSizeSquareSubMatrix.java b/src/main/java/com/rampatra/arrays/MaximumSizeSquareSubMatrix.java deleted file mode 100644 index 0c9c4419..00000000 --- a/src/main/java/com/rampatra/arrays/MaximumSizeSquareSubMatrix.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.rampatra.arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 8/4/15 - * @time: 11:48 PM - */ -public class MaximumSizeSquareSubMatrix { - - /** - * Prints the maximum size square sub-matrix in {@param a} with all 1s. - *

- * Algorithm: - * 1) Construct a sum matrix/auxiliary matrix aux[R][C] for the given a[R][C]. - * ...a) Copy first row and first columns as it is from a[][] to aux[][] - * ...b) For other entries, use following expressions to construct aux[][] - * ........If a[i][j] is 1 then - * ........aux[i][j] = min(aux[i][j-1], aux[i-1][j], aux[i-1][j-1]) + 1 - * ........Else - * ........aux[i][j] = 0 - * 2) Find the maximum entry in aux[R][C] - * 3) Using the value and coordinates of maximum entry in aux[i], print sub-matrix of a[][] - * - * @param a - */ - public static void printMaximumSizeSquareSubMatrix(int[][] a) { - int size = a[0].length; // no. of rows/columns - int maxI = 0, maxJ = 0, maxSubMatrixSize = 0; - int[][] auxMatrix = new int[size][size]; - - // construct auxiliary matrix - for (int i = 0, j = 0; j < size; j++) { // copy 1st row - auxMatrix[i][j] = a[i][j]; - } - - for (int i = 0, j = 0; i < size; i++) { // copy 1st column - auxMatrix[i][j] = a[i][j]; - } - - for (int i = 1; i < size; i++) { - for (int j = 1; j < size; j++) { - if (a[i][j] == 1) { - auxMatrix[i][j] = Math.min(Math.min(auxMatrix[i - 1][j], auxMatrix[i][j - 1]), auxMatrix[i - 1][j - 1]) + 1; - } else { - auxMatrix[i][j] = 0; - } - - if (auxMatrix[i][j] > maxSubMatrixSize) { - maxSubMatrixSize = auxMatrix[i][j]; - maxI = i; - maxJ = j; - } - } - } - - // print max size sub-matrix in array 'a' from the co-ordinates in auxiliary matrix - for (int i = maxI; i > maxI - maxSubMatrixSize; i--) { - for (int j = maxJ; j > maxJ - maxSubMatrixSize; j--) { - System.out.print(a[i][j]); - } - System.out.println(); - } - } - - public static void main(String[] args) { - int[][] ar = new int[][]{{0, 1, 1, 1}, - {1, 1, 0, 1}, - {1, 0, 0, 1}, - {1, 0, 0, 1}}; - printMaximumSizeSquareSubMatrix(ar); - int[][] ar1 = new int[][]{{0, 1, 1, 1, 0}, - {1, 1, 0, 1, 1}, - {1, 1, 1, 0, 1}, - {1, 1, 1, 1, 1}, - {1, 1, 1, 0, 0}}; - printMaximumSizeSquareSubMatrix(ar1); - } -} diff --git a/src/main/java/com/rampatra/arrays/MaximumSumNonAdjacentSubSequence.java b/src/main/java/com/rampatra/arrays/MaximumSumNonAdjacentSubSequence.java deleted file mode 100644 index 9734aa29..00000000 --- a/src/main/java/com/rampatra/arrays/MaximumSumNonAdjacentSubSequence.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.rampatra.arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/29/15 - * @time: 9:18 AM - */ -public class MaximumSumNonAdjacentSubSequence { - - /** - * Given an array of positive numbers, finds the maximum sum of a sub-sequence - * with the constraint that no 2 numbers in the sub-sequence should be adjacent - * in the array. - *

- * 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. - * - * @param a - * @return - */ - 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 - 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 - prevIncl = incl; - } - return Math.max(incl, excl); - } - - public static void main(String[] args) { - System.out.println(maximumSumNonAdjacentSubSequence(new int[]{3, 2, 7, 10})); - System.out.println(maximumSumNonAdjacentSubSequence(new int[]{3, 2, 5, 10, 7})); - } -} diff --git a/src/main/java/com/rampatra/arrays/MedianOfStream.java b/src/main/java/com/rampatra/arrays/MedianOfStream.java deleted file mode 100644 index 47781bc0..00000000 --- a/src/main/java/com/rampatra/arrays/MedianOfStream.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.rampatra.arrays; - -import com.rampatra.base.MaxHeap; -import com.rampatra.base.MinHeap; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 9/12/15 - * @time: 11:19 PM - */ -public class MedianOfStream { - - /** - * @param med - * @param elem - * @param maxHeap - * @param minHeap - * @return - */ - public static int getMedianOfStream(int med, int elem, MaxHeap maxHeap, MinHeap minHeap) { - - switch (compare(maxHeap.getSize(), minHeap.getSize())) { - case 0: // sizes of maxHeap and minHeap are same - if (elem < med) { - maxHeap.insert(elem); - med = maxHeap.findMax(); - } else { - minHeap.insert(elem); - med = minHeap.findMin(); - } - break; - case 1: // size of maxHeap greater than minHeap - if (elem < med) { - minHeap.insert(maxHeap.extractMax()); - maxHeap.insert(elem); - } else { - minHeap.insert(elem); - } - med = (maxHeap.findMax() + minHeap.findMin()) / 2; - break; - case -1: // size of maxHeap smaller than minHeap - if (elem < med) { - maxHeap.insert(elem); - } else { - maxHeap.insert(minHeap.extractMin()); - minHeap.insert(elem); - } - med = (maxHeap.findMax() + minHeap.findMin()) / 2; - break; - } - return med; - } - - static void printMedianOfStream(int[] a) { - int m = 0; - MaxHeap maxHeap = new MaxHeap(a); - MinHeap minHeap = new MinHeap(a); - - // calling in a loop so at to resemble a stream - for (int i = 0; i < a.length; i++) { - m = getMedianOfStream(m, a[i], maxHeap, minHeap); - } - System.out.println(m); - } - - static int compare(int a, int b) { - if (a == b) { - return 0; - } else { - return a < b ? -1 : 1; - } - } - - public static void main(String[] args) { - printMedianOfStream(new int[]{5, 15, 1, 3, 2, 8, 7, 9, 10, 6, 11, 4}); - printMedianOfStream(new int[]{5, 15, 1}); - printMedianOfStream(new int[]{5, 15, 10, 20}); - } -} diff --git a/src/main/java/com/rampatra/arrays/MedianOfTwoSortedArrays.java b/src/main/java/com/rampatra/arrays/MedianOfTwoSortedArrays.java deleted file mode 100644 index d64ec757..00000000 --- a/src/main/java/com/rampatra/arrays/MedianOfTwoSortedArrays.java +++ /dev/null @@ -1,104 +0,0 @@ -package com.rampatra.arrays; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/27/15 - * @time: 5:50 PM - */ -public class MedianOfTwoSortedArrays { - - /** - * Returns the median of a sorted array {@param a}. - * - * @param a - * @return - */ - public static int median(int a[]) { - int l = a.length; - if (l % 2 == 0) { - return (a[l / 2] + a[l / 2 - 1]) / 2; - } else { - return a[l / 2]; - } - } - - /** - * Returns the median of two sorted arrays {@param a1} and {@param a2} having same length. - * In case of any error, it returns {@code -1}. - *

- * Example: - *

- *

- * ar1[] = {1, 12, 15, 26, 38} - * ar2[] = {2, 13, 17, 30, 45} - * For above two arrays m1 = 15 and m2 = 17 - *

- * For the above ar1[] and ar2[], m1 is smaller than m2. So median is present in one of - * the following two sub-arrays: - *

- * [15, 26, 38] and [2, 13, 17] - * Let us repeat the process for above two sub-arrays: - *

- * m1 = 26 m2 = 13. - * m1 is greater than m2. So the sub-arrays become - *

- * [15, 26] and [13, 17] - * Now size is 2, so median = (max(ar1[0], ar2[0]) + min(ar1[1], ar2[1]))/2 - * = (max(15, 13) + min(26, 17))/2 - * = (15 + 17)/2 - * = 16 - * - * @param a1 - * @param a2 - * @return - */ - public static int median(int[] a1, int[] a2) { - - int l1 = a1.length, l2 = a2.length, m1, m2; - - if (l1 != l2 || l1 <= 0) { - return -1; - } - - if (l1 == 1) { - return (a1[0] + a2[0]) / 2; - } - - if (l1 == 2) { - return (Math.max(a1[0], a2[0]) + Math.min(a1[1], a2[1])) / 2; - } - - m1 = median(a1); - m2 = median(a2); - - if (m1 == m2) { - return m1; - } - - if (m1 < m2) { // median exists in a1[m1....] and a2[....m2] - if (l1 % 2 == 0) { - return median(Arrays.copyOfRange(a1, l1 / 2 - 1, l1), Arrays.copyOfRange(a2, 0, l2 / 2 + 1)); - } else { - return median(Arrays.copyOfRange(a1, l1 / 2, l1), Arrays.copyOfRange(a2, 0, l2 / 2 + 1)); - } - } else { - if (l1 % 2 == 0) { // median exists in a1[....m1] and a2 [m2....] - return median(Arrays.copyOfRange(a1, 0, l1 / 2 + 1), Arrays.copyOfRange(a2, l2 / 2 - 1, l2)); - } else { - return median(Arrays.copyOfRange(a1, 0, l1 / 2 + 1), Arrays.copyOfRange(a2, l2 / 2, l2)); - } - } - } - - 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})); - System.out.println(median(new int[]{1, 2}, new int[]{3, 4})); - System.out.println(median(new int[]{2, 2}, new int[]{2, 2})); - } -} diff --git a/src/main/java/com/rampatra/arrays/MergeArrayOfNIntoArrayOfMPlusN.java b/src/main/java/com/rampatra/arrays/MergeArrayOfNIntoArrayOfMPlusN.java deleted file mode 100644 index e95c653a..00000000 --- a/src/main/java/com/rampatra/arrays/MergeArrayOfNIntoArrayOfMPlusN.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.rampatra.arrays; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/27/15 - * @time: 12:15 PM - */ -public class MergeArrayOfNIntoArrayOfMPlusN { - - private static final int NA = -1; - - /** - * Move non {@code NA} elements to the end of array leaving everything else unchanged. - *

- * For example, - * Input: {2, NA, 7, NA, NA, 10, NA}; - * Output: {2, NA, 7, NA, 2, 7, 10} - * - * @param arrayMPlusN - */ - public static void moveElementsToEnd(int[] arrayMPlusN) { - int i = arrayMPlusN.length - 1, j = i; - for (; i >= 0; i--) { - if (arrayMPlusN[i] != NA) { - arrayMPlusN[j] = arrayMPlusN[i]; - j--; - } - } - } - - /** - * Merge {@param n} into {@param mPlusN} - * - * @param mPlusN - * @param n - */ - public static void merge(int[] mPlusN, int[] n) { - moveElementsToEnd(mPlusN); - - int i = n.length, // current index in mPlusN[] - j = 0, // current index in n[] - k = 0; // current index in final result - - while (k < mPlusN.length) { - if (j == n.length || (i < mPlusN.length && mPlusN[i] < n[j])) { - mPlusN[k] = mPlusN[i]; - i++; - } else { - mPlusN[k] = n[j]; - j++; - } - k++; - } - } - - public static void main(String[] args) { - int[] mPlusN = {2, NA, 12, NA, NA, 14, NA}; - int[] n = {5, 7, 8, 10}; - merge(mPlusN, n); - System.out.println(Arrays.toString(mPlusN)); - } -} diff --git a/src/main/java/com/rampatra/arrays/MinimumDistanceBetweenTwoNos.java b/src/main/java/com/rampatra/arrays/MinimumDistanceBetweenTwoNos.java deleted file mode 100644 index 48edc1a9..00000000 --- a/src/main/java/com/rampatra/arrays/MinimumDistanceBetweenTwoNos.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.rampatra.arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 9/6/15 - * @time: 10:53 PM - */ -public class MinimumDistanceBetweenTwoNos { - - /** - * Finds the minimum distance between two no.s {@param x} - * and {@param y} in an unsorted array {@param a} which - * may contain duplicates. - *

- * Note: Either of the no.s may occur first in the array. - * - * @param a - * @param x - * @param y - * @return - */ - public static int getMinimumDistanceBetweenTwoNos(int[] a, int x, int y) { - int startIndex = -1, endIndex = a.length, minDiff = a.length; - - for (int i = 0; i < a.length; i++) { - // find the 1st occurrence of either of the numbers - if (startIndex == -1 && (a[i] == x || a[i] == y)) { - startIndex = i; // holds the index of the number that occurred first in array - } else if (a[i] == x || a[i] == y) { - // see if it is same as the number that occurred first - if (a[startIndex] == a[i]) { - startIndex = i; - } else { - endIndex = i; - } - } - // if distance is less, then update - if (Math.abs(endIndex - startIndex) < minDiff) { - minDiff = Math.abs(endIndex - startIndex); - } - } - - return minDiff; - } - - 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)); - System.out.println(getMinimumDistanceBetweenTwoNos(new int[]{3, 5, 4, 2, 6, 5, 6, 6, 5, 4, 8, 1, 2, 4, 3}, 3, 6)); - System.out.println(getMinimumDistanceBetweenTwoNos(new int[]{2, 5, 3, 5, 4, 4, 2, 3}, 3, 2)); - } -} diff --git a/src/main/java/com/rampatra/arrays/MissingAndRepeatingElements.java b/src/main/java/com/rampatra/arrays/MissingAndRepeatingElements.java deleted file mode 100644 index 5fe08bf2..00000000 --- a/src/main/java/com/rampatra/arrays/MissingAndRepeatingElements.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.rampatra.arrays; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 9/7/15 - * @time: 10:54 AM - */ -public class MissingAndRepeatingElements { - - /** - * Finds two numbers in an unsorted array of size n with elements in range from - * 1 to n where one number from set {1, 2, …n} is missing and one number occurs - * twice in array. - * - * @param a - * @return an array where 1st element is the repeating element and 2nd is the missing one - */ - public static int[] findMissingAndRepeatingElements(int[] a) { - int[] result = new int[2]; - for (int i = 0; i < a.length; i++) { - // we use indices to mark already encountered numbers - if (a[Math.abs(a[i]) - 1] < 0) { - result[0] = Math.abs(a[i]); // repeating element - } else { - a[Math.abs(a[i]) - 1] = -a[Math.abs(a[i]) - 1]; - } - } - // no. is +ve means its index wasn't encountered - for (int i = 0; i < a.length; i++) { - if (a[i] > 0) { - result[1] = i + 1; // missing element - } - } - return result; - } - - public static void main(String[] args) { - System.out.println(Arrays.toString(findMissingAndRepeatingElements(new int[]{3, 1, 3}))); - System.out.println(Arrays.toString(findMissingAndRepeatingElements(new int[]{4, 3, 6, 2, 1, 1}))); - System.out.println(Arrays.toString(findMissingAndRepeatingElements(new int[]{4, 4, 6, 2, 5, 1}))); - } -} diff --git a/src/main/java/com/rampatra/arrays/MissingNumber.java b/src/main/java/com/rampatra/arrays/MissingNumber.java deleted file mode 100644 index 6691f6db..00000000 --- a/src/main/java/com/rampatra/arrays/MissingNumber.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.rampatra.arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 5/28/15 - * @time: 4:34 PM - */ - -/** - * You are given a list of n-1 integers and these integers are in the - * range of 1 to n. There are no duplicates in list. One of the integers - * is missing in the list. Write an efficient code to find the missing integer. - */ -public class MissingNumber { - - public static int missingNumber(int a[], int n) { - int sum = n * (n + 1) / 2; - int arraySum = 0; - - for (int i = 0; i < a.length; i++) { - arraySum += a[i]; - } - return sum - arraySum; - } - - /** - * Using XOR: - * 1) XOR all the array elements, let the result of XOR be X1. - * 2) XOR all numbers from 1 to n, let XOR be X2. - * 3) XOR of X1 and X2 gives the missing number. - * - * @param a - * @param n - * @return - */ - public static int missingNumberUsingXOR(int a[], int n) { - int nXOR = 0, arrayXOR = 0; - - for (int i = 1; i <= n; i++) { - nXOR ^= i; - } - - for (int i = 0; i < a.length; i++) { - arrayXOR ^= a[i]; - } - return nXOR ^ arrayXOR; - } - - public static void main(String[] args) { - System.out.println("Missing No: " + missingNumber(new int[]{2, 3, 1, 4, 6, 7, 8}, 8)); - System.out.println("Missing No using XOR: " + missingNumberUsingXOR(new int[]{2, 3, 1, 4, 6, 7, 8}, 8)); - } -} diff --git a/src/main/java/com/rampatra/arrays/NextGreaterElement.java b/src/main/java/com/rampatra/arrays/NextGreaterElement.java deleted file mode 100644 index 96c568f1..00000000 --- a/src/main/java/com/rampatra/arrays/NextGreaterElement.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.rampatra.arrays; - -import com.rampatra.base.LinkedStack; -import com.rampatra.base.Stack; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 8/26/15 - * @time: 12:35 PM - */ -public class NextGreaterElement { - - /** - * Given an array, print the Next Greater Element (NGE) for every element. The Next greater Element - * for an element x is the first greater element on the right side of x in array. Elements for which - * no greater element exist, consider next greater element as -1. - * - * @param a - * @return - */ - public static void nextGreaterElements(int[] a) { - int i = 0; - Stack stack = new LinkedStack<>(); // used to store elements whose NGE is yet to be determined - - for (; i < a.length - 1; i++) { - stack.push(a[i]); - - while (!stack.isEmpty()) { - Integer pop = stack.pop(); - if (pop < a[i + 1]) { // NGE found for popped element - System.out.println(pop + "->" + a[i + 1]); - } else { - stack.push(pop); // NGE still not found for popped element, so push it again - break; - } - } - } - - // no NGE for elements left in stack - while (!stack.isEmpty()) { - System.out.println(stack.pop() + "->" + -1); - } - - // no NGE for last element - System.out.println(a[i] + "->" + -1); - } - - public static void main(String[] args) { - int[] ar = new int[]{4, 5, 2, 25}; - nextGreaterElements(ar); - System.out.println("========="); - ar = new int[]{11, 13, 21, 3}; - nextGreaterElements(ar); - System.out.println("========="); - ar = new int[]{1, 5, 3, 4, 2, 0, 11}; - nextGreaterElements(ar); - System.out.println("========="); - ar = new int[]{3, 6, 8, 2, 1, 5, 12, 4, 9}; - nextGreaterElements(ar); - } -} diff --git a/src/main/java/com/rampatra/arrays/NextLargerNumber.java b/src/main/java/com/rampatra/arrays/NextLargerNumber.java deleted file mode 100644 index 00e00b78..00000000 --- a/src/main/java/com/rampatra/arrays/NextLargerNumber.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.rampatra.arrays; - -import com.rampatra.sorting.QuickSort; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 10/30/15 - * @time: 11:01 AM - * @see: http://www.geeksforgeeks.org/find-next-greater-number-set-digits/ - */ -public class NextLargerNumber { - - /** - * Finds the closest number which is larger - * than {@param n} by using only those digits - * present in {@param n} and using any digit - * only once. - * - * @param n - * @return - */ - public static int findNextLargerNumber(Integer n) { - - String str = n.toString(); - int len = str.length(); - int[] a = new int[len]; - int minIndex; - - // construct int array containing all - // digits in number {@param n} - for (int i = 0; i < len; i++) { - a[i] = Integer.parseInt(String.valueOf(str.charAt(i))); - } - - // find the index where a digit is greater than its previous - // digit (from left) - int i = len - 1; - while (i > 0) { - if (a[i] > a[i - 1]) break; - i--; - } - - // 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; - while (j >= i) { - if (a[j] < a[minIndex] && a[j] > a[i - 1]) { - minIndex = j; - } - j--; - } - - // swap a[i-1] with the smallest no. on the right - // of i-1 index which is larger than a[i-1] - swap(a, i - 1, minIndex); - - // sort all digits to the right of i-1 index - QuickSort.quickSort(a, i, len - 1); - - // construct the no. from the int array - StringBuilder builder = new StringBuilder(); - for (int k = 0; k < len; k++) { - builder.append(a[k]); - } - - return Integer.parseInt(builder.toString()); - } - - /** - * Swaps variables in {@param a} at {@param index1} with {@param index2}. - * - * @param a - * @param index1 - * @param index2 - */ - private static void swap(int[] a, int index1, int index2) { - int temp = a[index1]; - a[index1] = a[index2]; - a[index2] = temp; - } - - public static void main(String[] args) { - System.out.println(findNextLargerNumber(56)); - System.out.println(findNextLargerNumber(65)); - System.out.println(findNextLargerNumber(3451)); - System.out.println(findNextLargerNumber(534976)); - } -} diff --git a/src/main/java/com/rampatra/arrays/NthSmallestNumber.java b/src/main/java/com/rampatra/arrays/NthSmallestNumber.java deleted file mode 100644 index 8f7fbaf1..00000000 --- a/src/main/java/com/rampatra/arrays/NthSmallestNumber.java +++ /dev/null @@ -1,61 +0,0 @@ -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/main/java/com/rampatra/arrays/NumberOccurringOddTimes.java b/src/main/java/com/rampatra/arrays/NumberOccurringOddTimes.java deleted file mode 100644 index 81656dd1..00000000 --- a/src/main/java/com/rampatra/arrays/NumberOccurringOddTimes.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.rampatra.arrays; - -/** - * Created by IntelliJ IDEA. - * - * @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 TwoNonRepeatingElements} for a more - * complex problem which is solved in a similar approach. - */ -public class NumberOccurringOddTimes { - - public static int numberOccurringOddTimes(int a[]) { - int res = a[0]; - for (int i = 1; i < a.length; i++) { - res ^= a[i]; - } - return res; - } - - public static void main(String[] args) { - System.out.print(numberOccurringOddTimes(new int[]{2, 3, 3, 3, 1, 2, 1})); - } -} diff --git a/src/main/java/com/rampatra/arrays/OccurrencesInSortedArray.java b/src/main/java/com/rampatra/arrays/OccurrencesInSortedArray.java deleted file mode 100644 index fea37847..00000000 --- a/src/main/java/com/rampatra/arrays/OccurrencesInSortedArray.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.rampatra.arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 8/31/15 - * @time: 2:52 PM - */ -public class OccurrencesInSortedArray { - - /** - * Finds the occurrences of {@param k} in sorted array {@param a} in - * O(log n) time. - * - * @param a - * @param k - * @return - */ - public static int getOccurrencesInSortedArray(int[] a, int k) { - int firstIndex = getFirstIndexOf(a, k, 0, a.length - 1); - // element not found - if (firstIndex == -1) { - return 0; - } - return getLastIndexOf(a, k, firstIndex, a.length - 1) - firstIndex + 1; - } - - /** - * Returns the index of first occurrence of {@param n} in array {@param a}. - * - * @param a - * @param low - * @param high - * @param n - * @return - */ - public static int getFirstIndexOf(int[] a, int n, int low, int high) { - if (low <= high) { - int mid = (low + high) / 2; - if (a[mid] == n && (mid == 0 || a[mid - 1] < n)) { - return mid; - } else if (a[mid] < n) { - return getFirstIndexOf(a, n, mid + 1, high); - } else { - return getFirstIndexOf(a, n, low, mid - 1); - } - } else { - return -1; - } - } - - /** - * Returns the index of last occurrence of {@param n} in array {@param a}. - * - * @param a - * @param low - * @param high - * @param n - * @return - */ - public static int getLastIndexOf(int[] a, int n, int low, int high) { - if (low <= high) { - int mid = (low + high) / 2; - if (a[mid] == n && (mid == a.length - 1 || a[mid + 1] > n)) { - return mid; - } else if (a[mid] <= n) { - return getLastIndexOf(a, n, mid + 1, high); - } else { - return getLastIndexOf(a, n, low, mid - 1); - } - } else { - return -1; - } - } - - 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)); - System.out.println(getOccurrencesInSortedArray(new int[]{1, 1, 2, 2, 2, 2, 3}, 3)); - System.out.println(getOccurrencesInSortedArray(new int[]{1, 1, 2, 2, 2, 2, 3}, 0)); - System.out.println(getOccurrencesInSortedArray(new int[]{1, 1, 2, 2, 2, 2, 3}, 4)); - } -} diff --git a/src/main/java/com/rampatra/arrays/PairDiff.java b/src/main/java/com/rampatra/arrays/PairDiff.java deleted file mode 100644 index 8fce2367..00000000 --- a/src/main/java/com/rampatra/arrays/PairDiff.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.rampatra.arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 5/18/15 - * @time: 10:24 PM - */ - -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -/** - * 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 PairSum}. - */ -public class PairDiff { - - /** - * Using sorting. If we use Merge Sort or Heap Sort - * then (-)(nlogn) in worst case. If we use Quick Sort - * then O(n^2) in worst case. - * - * @param ar - * @param x - * @return - */ - static boolean pairDiff(int ar[], int x) { - Arrays.sort(ar); - - int len = ar.length; - - for (int i = 0, j = 1; i < len && j < len; ) { - if (i != j && ar[j] - ar[i] == x) { - return true; - } else if (ar[j] - ar[i] < x) { - j++; - } else { - i++; - } - } - return false; - } - - /** - * Using HashMap in O(n) time. - * - * @param ar - * @param x - * @param map - * @return - */ - static boolean pairDiff(int ar[], int x, Map map) { - for (int i = 0; i < ar.length; i++) { - if (map.containsKey(x + ar[i])) { - return true; - } - map.put(ar[i], 1); - } - return false; - } - - public static void main(String[] args) { - System.out.println(pairDiff(new int[]{-3, 4, -6, 1, 1}, -4)); - System.out.println(pairDiff(new int[]{3, 1}, 2)); - System.out.println(pairDiff(new int[]{-3, 4, -6, 1, 1}, -4, new HashMap())); - System.out.println(pairDiff(new int[]{3, 1}, 2, new HashMap())); - } -} diff --git a/src/main/java/com/rampatra/arrays/PairSum.java b/src/main/java/com/rampatra/arrays/PairSum.java deleted file mode 100644 index 75ce7d63..00000000 --- a/src/main/java/com/rampatra/arrays/PairSum.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.rampatra.arrays; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -/** - * Given an array ar[] of n numbers and - * another number x, determine whether or not there - * exists two elements in ar[] whose sum is exactly x. - * - * @author rampatra - * @since 5/18/15 - */ -public class PairSum { - - /** - * Using sorting. If we use Merge Sort or Heap Sort - * then (-)(nlogn) in worst case. If we use Quick Sort - * then O(n^2) in worst case. - * - * @param ar - * @param sum - * @return - */ - static boolean pairSum(int[] ar, int sum) { - Arrays.sort(ar); - - int len = ar.length; - - for (int i = 0, j = len - 1; i < j; ) { - if (ar[i] + ar[j] == sum) { - return true; - } else if (ar[i] + ar[j] < sum) { // approach towards larger elements - i++; - } else { // approach towards smaller elements - j--; - } - } - return false; - } - - /** - * Using hashmap in O(n) time. - * - * @param ar - * @param sum - * @param numSet - * @return - */ - static boolean pairSum(int[] ar, int sum, Set numSet) { - for (int i = 0; i < ar.length; i++) { - if (numSet.contains(sum - ar[i])) { - return true; - } - numSet.add(ar[i]); - } - return false; - } - - public static void main(String[] args) { - System.out.println(pairSum(new int[]{-3, 4, -6, 1, 1}, -2)); - System.out.println(pairSum(new int[]{-3, 4, -6, 1, 1}, 5)); - System.out.println(pairSum(new int[]{-3, 4, -6, 1, 1}, 0)); - System.out.println("--------"); - System.out.println(pairSum(new int[]{-3, 4, -6, 1, 1}, -2, new HashSet<>())); - System.out.println(pairSum(new int[]{-3, 4, -6, 1, 1}, 5, new HashSet<>())); - System.out.println(pairSum(new int[]{-3, 4, -6, 1, 1}, 0, new HashSet<>())); - } -} diff --git a/src/main/java/com/rampatra/arrays/PivotedBinarySearch.java b/src/main/java/com/rampatra/arrays/PivotedBinarySearch.java deleted file mode 100644 index 2f104e6f..00000000 --- a/src/main/java/com/rampatra/arrays/PivotedBinarySearch.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.rampatra.arrays; - -import com.rampatra.searching.BinarySearch; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 5/31/15 - */ -public class PivotedBinarySearch { - - /** - * Search an element in a sorted pivoted array {@code arr}. - *

- * Example, - * 1) For array [3,4,5,1,2] pivot is 5 - * 2) For array [6,7,8,5,4] pivot is 8 - * - * @param arr - * @param n - * @return - */ - public static int pivotedBinarySearch(int[] arr, int n) { - int pivot = findPivotIndex(arr, 0, arr.length - 1); - - if (pivot == -1 || arr[pivot] == n) { - return pivot; - } else if (n < arr[0]) { - return BinarySearch.binarySearch(arr, n, pivot + 1, arr.length - 1); - } else { - return BinarySearch.binarySearch(arr, n, 0, pivot - 1); - } - } - - /** - * Finds the pivot element in array {@code arr}. Pivot element is the only - * element for which next element to it is smaller than it. - * - * @param arr - * @param low - * @param high - * @return the index of the pivot element in the {@code arr}. - */ - public static int findPivotIndex(int[] arr, int low, int high) { - if (low > high) return -1; - - int mid = (low + high) / 2; - - if (mid == 0 || mid == arr.length - 1) return -1; - - if (arr[mid] > arr[mid + 1] && arr[mid] > arr[mid - 1]) { - return mid; - } else if (arr[mid] > arr[mid - 1] && arr[mid] < arr[mid + 1]) { - return findPivotIndex(arr, mid + 1, arr.length - 1); - } else { - return findPivotIndex(arr, 0, mid - 1); - } - } - - public static void main(String[] args) { - System.out.println("Pivot: " + findPivotIndex(new int[]{3, 4, 5, 1, 2}, 0, 4)); - System.out.println("Index: " + pivotedBinarySearch(new int[]{3, 4, 5, 1, 2}, 5)); - - System.out.println("Pivot: " + findPivotIndex(new int[]{1, 2, 3, 4, 5}, 0, 4)); - System.out.println("Index: " + pivotedBinarySearch(new int[]{1, 2, 3, 4, 5}, 4)); - - System.out.println("Pivot: " + findPivotIndex(new int[]{5, 4, 3, 2, 1}, 0, 4)); - System.out.println("Index: " + pivotedBinarySearch(new int[]{5, 4, 3, 2, 1}, 4)); - - System.out.println("Pivot: " + findPivotIndex(new int[]{5}, 0, -1)); - System.out.println("Index: " + pivotedBinarySearch(new int[]{5}, -1)); - } -} diff --git a/src/main/java/com/rampatra/arrays/ProductArrayPuzzle.java b/src/main/java/com/rampatra/arrays/ProductArrayPuzzle.java deleted file mode 100644 index 23de1acc..00000000 --- a/src/main/java/com/rampatra/arrays/ProductArrayPuzzle.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.rampatra.arrays; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 8/15/15 - * @time: 9:17 PM - */ -public class ProductArrayPuzzle { - - /** - * Construct a Product Array prod[] (of same size) such that prod[i] is - * equal to the product of all the elements of arr[] except arr[i]. Solve - * it without division operator and in O(n). - *

- * You can do this by taking two arrays one containing the products from - * left to right elements and other containing the products from right to - * left elements and then finally multiplying those two arrays gives you - * the answer. But the auxiliary space complexity of this method is O(n) - * as well as the space complexity is O(n). - *

- * The below method is the optimized way to do this in O(1) auxiliary space - * but the space complexity is O(n). - *

- * AUXILIARY SPACE is extra space or temporary space used by the algorithm, - * which is mostly used in algorithm where we use swapping or temporary variables. - *

- * SPACE COMPLEXITY means total space taken by the algorithm with respect to - * input size.Space complexity calculated by both auxiliary space and space used - * by the input. - *

- * For example - If we want to compare standard sorting algorithm on the basis of - * then auxiliary space would be better criteria than space complexity. Merge sort - * uses O(n) auxiliary space,where Insertion sort and Heap sort uses O(1) auxiliary - * space. Merge sort requires Ω(n) but Heap sort requires only a constant amount. - * Space complexity of all these sorting algorithm is O(n) though. - * - * @param a - * @return - */ - public static int[] getProductArray(int[] a) { - int[] prod = new int[a.length]; - - // prod array consists of products of the elements - prod[0] = 1; - - // fill prod with products of elements from left to right excluding current element - for (int i = 1; i < a.length; i++) { - prod[i] = a[i - 1] * prod[i - 1]; - } - - int temp = 1; - // fill prod with products of elements from right to left excluding current element - for (int i = a.length - 1; i >= 0; i--) { - prod[i] *= temp; - temp *= a[i]; - } - - // final prod array is the answer - return prod; - } - - public static void main(String[] args) { - System.out.println(Arrays.toString(getProductArray(new int[]{10, 3, 5, 6, 2}))); - System.out.println(Arrays.toString(getProductArray(new int[]{0, 0}))); - System.out.println(Arrays.toString(getProductArray(new int[]{1}))); - } -} diff --git a/src/main/java/com/rampatra/arrays/ReservoirSampling.java b/src/main/java/com/rampatra/arrays/ReservoirSampling.java deleted file mode 100644 index 050fb17f..00000000 --- a/src/main/java/com/rampatra/arrays/ReservoirSampling.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.rampatra.arrays; - -import java.util.Arrays; -import java.util.Random; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/21/15 - * @time: 2:52 PM - */ -public class ReservoirSampling { - - /** - * Returns {@param k} non-repeating random numbers from {@param stream} - * using reservoir sampling method. - *

- * Explanation: - * 1) Create an array reservoir[0..k-1] and copy first k items of stream[] to it. - * 2) Now one by one consider all items from (k+1)th item to nth item. - * a) Generate a random number from 0 to i where i is index of current item in - * stream[]. Let the generated random number is j. - * b) If j is in range 0 to k-1, replace reservoir[j] with arr[i]. - *

- * 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 - * put it in reservoir[]. To check if an item is previously selected or not, we - * need to search the item in reservoir[]. - * The time complexity of this algorithm will be O(k^2). This can be costly - * if k is big. Also, this is not efficient if the input is in the form of a stream. - * - * @param stream - * @param k - * @return - */ - public static int[] getKRandomNumbers(int[] stream, int k) { - int i; - int[] reservoir = new int[k]; - - for (i = 0; i < k; i++) { - reservoir[i] = stream[i]; - } - - for (; i < stream.length; i++) { - int rand = new Random().nextInt(i); - - if (rand < k) { - reservoir[rand] = stream[i]; - } - } - - return reservoir; - - } - - public static void main(String[] args) { - int[] stream = {1, 2, 3, 4, 5, 6, 7, 8, 9}; - System.out.println(Arrays.toString(getKRandomNumbers(stream, 4))); - } -} diff --git a/src/main/java/com/rampatra/arrays/ReverseArray.java b/src/main/java/com/rampatra/arrays/ReverseArray.java deleted file mode 100644 index 64550c58..00000000 --- a/src/main/java/com/rampatra/arrays/ReverseArray.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.rampatra.arrays; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/27/15 - * @time: 8:40 PM - */ -public class ReverseArray { - - /** - * Iterative method to reverse the entire array. - * - * @param a - */ - public static void reverse(int[] a) { - int temp; - for (int i = 0, j = a.length - 1; i < j; i++, j--) { - // swap elements - temp = a[i]; - a[i] = a[j]; - a[j] = temp; - } - } - - /** - * Recursive method to reverse the array elements from - * {@param i} index to {@param j} index (both inclusive). - * - * @param a - * @param i - * @param j - */ - public static void reverseRecursive(int[] a, int i, int j) { - if (i > j) return; - - int temp = a[i]; - a[i] = a[j]; - a[j] = temp; - reverseRecursive(a, ++i, --j); - } - - public static void main(String[] args) { - int[] ar = new int[]{1, 2, 3, 4, 5}; - System.out.println(Arrays.toString(ar)); - reverse(ar); - System.out.println(Arrays.toString(ar)); - reverseRecursive(ar, 0, ar.length - 1); - System.out.println(Arrays.toString(ar)); - } -} diff --git a/src/main/java/com/rampatra/arrays/RotateArray.java b/src/main/java/com/rampatra/arrays/RotateArray.java deleted file mode 100644 index f720dcf6..00000000 --- a/src/main/java/com/rampatra/arrays/RotateArray.java +++ /dev/null @@ -1,104 +0,0 @@ -package com.rampatra.arrays; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/28/15 - * @time: 10:53 AM - */ -public class RotateArray { - - /** - * Naive approach which stores the elements to be shifted in a temp array. - * Time complexity: O(n) - * Space complexity: O(k) - * - * @param a - * @param k - */ - public static void rotateNaiveApproach(int[] a, int k) { - int[] temp = new int[k]; - int i, j; - // store elements to be shifted in temp array - for (i = 0; i < k; i++) { - temp[i] = a[i]; - } - // shift elements to left - for (j = 0; i < a.length; i++, j++) { - a[j] = a[i]; - } - // move elements to end - for (i = 0; j < a.length; i++, j++) { - a[j] = temp[i]; - } - } - - /** - * Reversal algorithm for array rotation. - *

- * Example: - * For arr[] = [1, 2, 3, 4, 5, 6, 7], k = 2 and arr.length = 7 - * A = [1, 2] and B = [3, 4, 5, 6, 7] - * Reverse A, we get ArB = [2, 1, 3, 4, 5, 6, 7] - * 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 - */ - public static void rotateReversal(int[] a, int k) { - ReverseArray.reverseRecursive(a, 0, k - 1); - ReverseArray.reverseRecursive(a, k, a.length - 1); - ReverseArray.reverseRecursive(a, 0, a.length - 1); - } - - /** - * Juggling algorithm for array rotation. - * See: http://www.geeksforgeeks.org/array-rotation/ - * - * @param a - * @param k - */ - public static void rotateGCD(int[] a, int k) { - int gcd = gcd(a.length, k), temp, i, j, p; - - for (i = 0; i < gcd; i++) { - temp = a[i]; - j = i; - while (true) { - p = j + k; - if (p >= a.length) - p = p - a.length; - if (p == i) - break; - a[j] = a[p]; - j = p; - } - a[j] = temp; - } - } - - public static int gcd(int a, int b) { - if (b == 0) { - return a; - } else { - return gcd(b, a % b); - } - } - - public static void main(String[] args) { - int[] ar = {1, 2, 3, 4, 5, 6, 7}; - System.out.println(Arrays.toString(ar)); - rotateNaiveApproach(ar, 2); - System.out.println(Arrays.toString(ar)); - rotateGCD(ar, 2); - System.out.println(Arrays.toString(ar)); - rotateReversal(ar, 2); - System.out.println(Arrays.toString(ar)); - } -} diff --git a/src/main/java/com/rampatra/arrays/RotateMatrixBy90Degrees.java b/src/main/java/com/rampatra/arrays/RotateMatrixBy90Degrees.java deleted file mode 100644 index ccff75ca..00000000 --- a/src/main/java/com/rampatra/arrays/RotateMatrixBy90Degrees.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.rampatra.arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 8/22/15 - * @time: 4:03 PM - */ -public class RotateMatrixBy90Degrees { - - /** - * Rotates a 2-D array by 90 degrees clockwise. - *

- * The algorithm is simple: - * 1st row = last column - * 2nd row = 2nd last column - * and so on... - * - * @param a - * @return - */ - public static int[][] rotateMatrixBy90DegreesRight(int[][] a) { - int rows = a.length, columns = a[0].length; - int[][] rotatedMatrix = new int[columns][rows]; - - for (int i = 0; --rows >= 0 && i < a.length; i++) { - for (int j = 0; j < a[0].length; j++) { - rotatedMatrix[j][rows] = a[i][j]; - } - } - - return rotatedMatrix; - } - - private static void print2DMatrix(int[][] a) { - for (int i = 0; i < a.length; i++) { - for (int j = 0; j < a[0].length; j++) { - System.out.print(a[i][j]); - } - System.out.println(); - } - } - - public static void main(String[] args) { - int[][] ar = new int[][]{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; - print2DMatrix(ar); - System.out.println("--------"); - print2DMatrix(rotateMatrixBy90DegreesRight(ar)); - - System.out.println("========"); - - ar = new int[][]{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {0, 5, 7}}; - print2DMatrix(ar); - System.out.println("--------"); - print2DMatrix(rotateMatrixBy90DegreesRight(ar)); - } -} diff --git a/src/main/java/com/rampatra/arrays/RotatedIndex.java b/src/main/java/com/rampatra/arrays/RotatedIndex.java deleted file mode 100644 index 4478e5e3..00000000 --- a/src/main/java/com/rampatra/arrays/RotatedIndex.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.rampatra.arrays; - -/** - * @author rampatra - * @since 2019-04-04 - */ -public class RotatedIndex { - - private static int findIndexOfRotationPoint(String[] words) { - return findIndexOfRotationPoint(words, 0, words.length - 1); - } - - private static int findIndexOfRotationPoint(String[] words, int start, int end) { - if (start > end) return -1; - - int mid = (start + end) / 2; - - if (mid == 0 || mid == words.length - 1) return -1; - - if (words[mid].compareTo(words[mid - 1]) < 0 && words[mid].compareTo(words[mid + 1]) < 0) { - return mid; - } else if (words[mid].compareTo(words[mid - 1]) > 0 && words[mid].compareTo(words[mid + 1]) < 0) { - return findIndexOfRotationPoint(words, start, mid - 1); - } else { - return findIndexOfRotationPoint(words, mid + 1, end); - } - } - - public static void main(String[] args) { - System.out.println(findIndexOfRotationPoint(new String[]{ - "ptolemaic", - "retrograde", - "supplant", - "undulate", - "xenoepist", - "asymptote", // <-- rotates here! - "babka", - "banoffee", - "engender", - "karpatka", - "othellolagkage", - })); - - System.out.println(findIndexOfRotationPoint(new String[]{})); - - System.out.println(findIndexOfRotationPoint(new String[]{ - "asymptote", - "babka", - "banoffee", - "engender", - "karpatka", - "othellolagkage", - })); - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/arrays/SearchInSorted2DArray.java b/src/main/java/com/rampatra/arrays/SearchInSorted2DArray.java deleted file mode 100644 index 8ab14269..00000000 --- a/src/main/java/com/rampatra/arrays/SearchInSorted2DArray.java +++ /dev/null @@ -1,118 +0,0 @@ -package com.rampatra.arrays; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 8/23/15 - * @time: 10:31 PM - */ -public class SearchInSorted2DArray { - - /** - * Searches {@param value} in a SQUARE sized 2-D array {@param a} which is sorted - * both row wise and column wise. - *

- * Time complexity: - * T(n) = T(n) + T(n-1) + T(n-2) + .... + T(1) - * T(n) = n(n+1)/2 - * T(n) = O(n^2) where n is size of 2-D array. - *

- * Explanation: - * Linearly searches across rows and columns until the element is found or till the last element. If - * the element is not found in the 1st row or 1st column then we search in 2nd row and 2nd column - * and so on. - * - * @param a - * @param i - * @param j - * @param value - * @return an array consisting of co-ordinates if {@param value} is found otherwise {@code new int[]{-1, -1}}. - */ - public static int[] linearSearchNaive(int[][] a, int i, int j, int value) { - for (int x = i; x < a.length && (a[i][x] <= value || a[x][j] <= value); x++) { - if (a[i][x] == value) { - return new int[]{i, x}; - } else if (a[x][j] == value) { - return new int[]{x, j}; - } - } - - if (i < a.length - 1) { - return linearSearchNaive(a, i + 1, j + 1, value); - } else { - return new int[]{-1, -1}; - } - } - - /** - * More efficient way to search in a 2-D array sorted both row wise and column wise. - *

- * Explanation: - * We start from top right corner (we can also start from bottom left corner) and move left if current - * element is greater than the value to be searched and bottom if current element is - * smaller than the value to be searched. - *

- * Time complexity: O(m+n) where m = no. of rows, n = no. of columns - * - * @return - * @link http://articles.leetcode.com/2010/10/searching-2d-sorted-matrix-part-ii.html - */ - public static int[] linearSearch(int[][] a, int value) { - int i = 0, j = a[0].length - 1; // start from top right corner - - while (i < a.length && j >= 0) { - if (a[i][j] == value) { - return new int[]{i, j}; - } else if (a[i][j] > value) { - j--; // move left - } else { - i++; // move down - } - } - - return new int[]{-1, -1}; - - } - - private static void print2DMatrix(int[][] a) { - for (int i = 0; i < a.length; i++) { - for (int j = 0; j < a[0].length; j++) { - System.out.print(a[i][j]); - } - System.out.println(); - } - } - - 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))); - System.out.println(Arrays.toString(linearSearchNaive(ar, 0, 0, 2))); - System.out.println(Arrays.toString(linearSearchNaive(ar, 0, 0, 3))); - System.out.println(Arrays.toString(linearSearchNaive(ar, 0, 0, 4))); - System.out.println(Arrays.toString(linearSearchNaive(ar, 0, 0, 5))); - System.out.println(Arrays.toString(linearSearchNaive(ar, 0, 0, 6))); - System.out.println(Arrays.toString(linearSearchNaive(ar, 0, 0, 7))); - System.out.println(Arrays.toString(linearSearchNaive(ar, 0, 0, 8))); - System.out.println(Arrays.toString(linearSearchNaive(ar, 0, 0, 9))); - System.out.println(Arrays.toString(linearSearchNaive(ar, 0, 0, 10))); - System.out.println(Arrays.toString(linearSearchNaive(ar, 0, 0, 11))); - System.out.println(Arrays.toString(linearSearchNaive(ar, 0, 0, 12))); - System.out.println("============"); - System.out.println(Arrays.toString(linearSearch(ar, 1))); - System.out.println(Arrays.toString(linearSearch(ar, 2))); - System.out.println(Arrays.toString(linearSearch(ar, 3))); - System.out.println(Arrays.toString(linearSearch(ar, 4))); - System.out.println(Arrays.toString(linearSearch(ar, 5))); - System.out.println(Arrays.toString(linearSearch(ar, 6))); - System.out.println(Arrays.toString(linearSearch(ar, 7))); - System.out.println(Arrays.toString(linearSearch(ar, 8))); - System.out.println(Arrays.toString(linearSearch(ar, 9))); - System.out.println(Arrays.toString(linearSearch(ar, 10))); - System.out.println(Arrays.toString(linearSearch(ar, 11))); - System.out.println(Arrays.toString(linearSearch(ar, 12))); - } -} diff --git a/src/main/java/com/rampatra/arrays/Segregate0s1sAnd2s.java b/src/main/java/com/rampatra/arrays/Segregate0s1sAnd2s.java deleted file mode 100644 index e64929f8..00000000 --- a/src/main/java/com/rampatra/arrays/Segregate0s1sAnd2s.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.rampatra.arrays; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @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 - * 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 - swap(a, low, mid); - low++; - mid++; - break; - case 1: // mid points to 1 which is correct acc. to our assumption so proceed - mid++; - break; - case 2: // mid points to 2 instead of 1 so swap it with high - swap(a, mid, high); - high--; - break; - } - } - } - - private static void swap(int[] a, int index1, int index2) { - int temp = a[index1]; - a[index1] = a[index2]; - a[index2] = temp; - } - - public static void main(String[] args) { - int[] ar = new int[]{0, 1, 2, 0, 1, 2}; - segregate0s1sAnd2s(ar); - System.out.println(Arrays.toString(ar)); - - ar = new int[]{0, 2, 1, 1, 2, 0}; - segregate0s1sAnd2s(ar); - System.out.println(Arrays.toString(ar)); - - ar = new int[]{0, 1, 2}; - segregate0s1sAnd2s(ar); - System.out.println(Arrays.toString(ar)); - - ar = new int[]{2, 1, 0, 2, 1, 0}; - segregate0s1sAnd2s(ar); - System.out.println(Arrays.toString(ar)); - - ar = new int[]{1, 2, 1, 0, 2, 1, 0}; - segregate0s1sAnd2s(ar); - System.out.println(Arrays.toString(ar)); - } -} diff --git a/src/main/java/com/rampatra/arrays/Segregate0sAnd1s.java b/src/main/java/com/rampatra/arrays/Segregate0sAnd1s.java deleted file mode 100644 index e5f9634a..00000000 --- a/src/main/java/com/rampatra/arrays/Segregate0sAnd1s.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.rampatra.arrays; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/31/15 - * @time: 5:13 PM - */ -public class Segregate0sAnd1s { - - /** - * Segregate 0s and 1s by traversing the array only once. - * - * @param a - */ - public static void segregate0sAnd1s(int[] a) { - for (int i = 0, j = a.length - 1; i < j; i++, j--) { - if (a[i] > a[j]) { - // swap if a[i] > a[j] - a[i] = a[i] + a[j]; - a[j] = a[i] - a[j]; - a[i] = a[i] - a[j]; - } - } - } - - public static void main(String[] args) { - int[] ar = new int[]{0, 1, 1, 1, 0, 0, 1}; - segregate0sAnd1s(ar); - System.out.println(Arrays.toString(ar)); - } -} diff --git a/src/main/java/com/rampatra/arrays/SegregateEvenAndOddNos.java b/src/main/java/com/rampatra/arrays/SegregateEvenAndOddNos.java deleted file mode 100644 index 8cdaf6b6..00000000 --- a/src/main/java/com/rampatra/arrays/SegregateEvenAndOddNos.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.rampatra.arrays; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/31/15 - * @time: 5:13 PM - */ -public class SegregateEvenAndOddNos { - - /** - * Segregate even and odd numbers by traversing the - * array {@param a} only once. - *

- * This is similar to {@link Segregate0sAnd1s}. - * - * @param a - */ - public static void segregateEvenAndOddNos(int[] a) { - for (int i = 0, j = a.length - 1; i < j; ) { - if (a[i] % 2 != 0 && a[j] % 2 == 0) { - // swap - a[i] = a[i] + a[j]; - a[j] = a[i] - a[j]; - a[i] = a[i] - a[j]; - i++; - j--; - } else if (a[i] % 2 == 0 && a[j] % 2 == 0) { - i++; - } else if (a[i] % 2 != 0 && a[j] % 2 != 0) { - j--; - } else { - i++; - j--; - } - } - } - - public static void main(String[] args) { - int[] ar = new int[]{12, 34, 45, 9, 8, 90, 3}; - segregateEvenAndOddNos(ar); - System.out.println(Arrays.toString(ar)); - int[] ar1 = new int[]{34, 1, 45, 9, 8, 67, 3, 56, 78, 79, 101, 100}; - segregateEvenAndOddNos(ar1); - System.out.println(Arrays.toString(ar1)); - } -} diff --git a/src/main/java/com/rampatra/arrays/SmallestAndSecondSmallest.java b/src/main/java/com/rampatra/arrays/SmallestAndSecondSmallest.java deleted file mode 100644 index 9e683caf..00000000 --- a/src/main/java/com/rampatra/arrays/SmallestAndSecondSmallest.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.rampatra.arrays; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/30/15 - */ -public class SmallestAndSecondSmallest { - - private static int[] getSmallestAndSecondSmallest(int[] a) { - int smallest = Integer.MAX_VALUE, secondSmallest = Integer.MAX_VALUE; - - for (int i = 0; i < a.length; i++) { - if (a[i] < smallest) { - secondSmallest = smallest; - smallest = a[i]; - } else if (a[i] < secondSmallest && a[i] != smallest) { // a[i] != smallest; if numbers are repeated in array - secondSmallest = a[i]; - } - } - - return new int[]{smallest, secondSmallest}; - } - - public static void main(String[] args) { - System.out.println(Arrays.toString(getSmallestAndSecondSmallest(new int[]{100, 1, 60, -10, -80, 85, 70, -80}))); - System.out.println(Arrays.toString(getSmallestAndSecondSmallest(new int[]{100, 1, 60, 10, 80, 85, 70, 0}))); - } -} diff --git a/src/main/java/com/rampatra/arrays/SmallestMissingNumber.java b/src/main/java/com/rampatra/arrays/SmallestMissingNumber.java deleted file mode 100644 index 7b63a415..00000000 --- a/src/main/java/com/rampatra/arrays/SmallestMissingNumber.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.rampatra.arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 8/29/15 - * @time: 12:51 PM - */ -public class SmallestMissingNumber { - - /** - * Modified Binary Search to find the smallest missing number in an array - * {@param a} consisting of numbers between 0 to m - 1 and m > n where n is - * length of array. - *

- * Time complexity: O(log n) - * Con: Doesn't work if there are repetitive elements. - *

- * EXPLANATION: - * In standard Binary Search, the element to be searched is compared with - * the middle element and on the basis of comparison result, we decide whether - * to search is over or to go to left half or right half. - * In this method, we modify the standard Binary Search algorithm to compare the - * middle element with its index and make decision on the basis of this comparison. - * - * @param a - * @param low - * @param high - * @return - */ - public static int smallestMissingNumber(int[] a, int low, int high) { - if (low <= high) { - int mid = (low + high) / 2; - - if (a[mid] == mid) { - return smallestMissingNumber(a, mid + 1, high); - } else if (a[mid] > mid) { - return smallestMissingNumber(a, low, mid - 1); - } else { - return smallestMissingNumber(a, mid + 1, high); - } - } else { - return low; - } - } - - public static void main(String[] args) { - System.out.println(smallestMissingNumber(new int[]{0, 1}, 0, 1)); - System.out.println(smallestMissingNumber(new int[]{0, 1, 2, 6, 9}, 0, 4)); - System.out.println(smallestMissingNumber(new int[]{4, 5, 10, 11}, 0, 3)); - System.out.println(smallestMissingNumber(new int[]{0, 4, 5, 10, 56}, 0, 4)); - System.out.println(smallestMissingNumber(new int[]{0, 1, 2, 3, 4, 5, 6, 7, 10}, 0, 8)); - System.out.println(smallestMissingNumber(new int[]{0, 1, 2, 3, 3}, 0, 4)); // doesn't work - } -} diff --git a/src/main/java/com/rampatra/arrays/SortedSubSequence.java b/src/main/java/com/rampatra/arrays/SortedSubSequence.java deleted file mode 100644 index b6cd1b5c..00000000 --- a/src/main/java/com/rampatra/arrays/SortedSubSequence.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.rampatra.arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 10/12/15 - */ -public class SortedSubSequence { - - /** - * Finds 3 elements such that a[i] < a[j] < a[k] and i < j < k in O(n) time - * in an array of n integers. If there are multiple such triplets, then prints any - * one of them. - *

- * 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 arr - */ - 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 (arr[i] < min) { - smaller[i] = -1; - min = arr[i]; - } else { - smaller[i] = min; - } - } - - larger[len - 1] = -1; - for (int i = len - 2; i >= 0; i--) { - if (arr[i] > max) { - larger[i] = -1; - max = arr[i]; - } else { - larger[i] = max; - } - } - - for (int i = 0; i < len; i++) { - if (smaller[i] != -1 && larger[i] != -1) { - System.out.println(smaller[i] + "," + arr[i] + "," + larger[i]); - break; - } - } - - } - - public static void main(String[] args) { - printSortedSubSequenceOfSize3(new int[]{12, 11, 10, 5, 6, 2, 30}); - printSortedSubSequenceOfSize3(new int[]{1, 2, 3, 4}); - printSortedSubSequenceOfSize3(new int[]{4, 3, 2, 1}); - } -} diff --git a/src/main/java/com/rampatra/arrays/SubArrayOfSum.java b/src/main/java/com/rampatra/arrays/SubArrayOfSum.java deleted file mode 100644 index 4e4f5c2e..00000000 --- a/src/main/java/com/rampatra/arrays/SubArrayOfSum.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.rampatra.arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 9/27/15 - * @time: 7:32 PM - */ -public class SubArrayOfSum { - - /** - * Prints the sub-array in array {@param a} with sum {@param sum}. - *

- * Algorithm: Keep on adding the elements, once the sum is larger - * than the required sum start deleting the elements from the sum. - * (Google Interview Question) - * - * @param a - * @param sum - */ - public static void printSubArrayOfSum(int[] a, int sum) { - int currSum = 0, startIndex = 0; - for (int i = 0; i < a.length; i++) { - - currSum += a[i]; - - while (currSum > sum && startIndex < i) { - currSum -= a[startIndex++]; - } - - if (currSum == sum) { - System.out.println("Sub-array lies between indexes: " + startIndex + " and " + i); - return; - } - } - System.out.println("Sub-array with sum " + sum + " not found!"); - } - - 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); - printSubArrayOfSum(new int[]{1, 4, 0, 0, 3, 10, 5}, 0); - printSubArrayOfSum(new int[]{1, 4}, 0); - printSubArrayOfSum(new int[]{1, 4}, -4); - printSubArrayOfSum(new int[]{1, -4}, -3); - } -} diff --git a/src/main/java/com/rampatra/arrays/SubsetOfArray.java b/src/main/java/com/rampatra/arrays/SubsetOfArray.java deleted file mode 100644 index 21d5ff2c..00000000 --- a/src/main/java/com/rampatra/arrays/SubsetOfArray.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.rampatra.arrays; - -import com.rampatra.sorting.QuickSort; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 9/4/15 - * @time: 11:28 PM - */ -public class SubsetOfArray { - - /** - * Determines if array {@param b} is a subset of array {@param a}. - *

- * 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 - * complexity would be O(mlogm + nlogm). - * - * @param a - * @param b - * @return - */ - public static boolean isSubsetOfArray(int[] a, int[] b) { - - QuickSort.quickSort(a); - QuickSort.quickSort(b); - - int i, j; - for (i = 0, j = 0; i < a.length && j < b.length; ) { - if (a[i] > b[j]) { - return false; - } else if (a[i] == b[j]) { - i++; - j++; - } else { - i++; - } - } - - if (i < b.length) { - return false; - } else { - return true; - } - } - - 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})); - System.out.println(isSubsetOfArray(new int[]{1, 4, 2}, new int[]{1, 4, 4, 2})); - } -} diff --git a/src/main/java/com/rampatra/arrays/SymmetricDifference.java b/src/main/java/com/rampatra/arrays/SymmetricDifference.java deleted file mode 100644 index 9ae00478..00000000 --- a/src/main/java/com/rampatra/arrays/SymmetricDifference.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.rampatra.arrays; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 10/20/15 - * @time: 11:34 PM - */ -public class SymmetricDifference { - - /** - * Returns the symmetric difference between array {@param a1} - * and array {@param a2}. - *

- * SYMMETRIC DIFFERENCE refers to the numbers which are present in - * only one of the arrays and not both. - * - * @param a1 - * @param a2 - * @return - */ - public static int[] getSymmetricDifference(int[] a1, int[] a2) { - int index = 0; - int[] res = new int[a1.length + a2.length]; - - Arrays.sort(a1); - Arrays.sort(a2); - - for (int i = 0, j = 0; i < a1.length || j < a2.length; ) { - if (j >= a2.length) { - res[index++] = a1[i]; - i++; - } else if (i >= a1.length) { - res[index++] = a2[j]; - j++; - } else if (a1[i] < a2[j]) { - res[index++] = a1[i]; - i++; - } else if (a2[j] < a1[i]) { - res[index++] = a2[j]; - j++; - } else { - i++; - j++; - } - } - - return Arrays.copyOf(res, index); - } - - 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}))); - System.out.println(Arrays.toString(getSymmetricDifference(new int[]{1, 2, 3, 4}, new int[]{1, 2, 3, 4}))); - } -} diff --git a/src/main/java/com/rampatra/arrays/TripletOfSum.java b/src/main/java/com/rampatra/arrays/TripletOfSum.java deleted file mode 100644 index 91d47649..00000000 --- a/src/main/java/com/rampatra/arrays/TripletOfSum.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.rampatra.arrays; - -import com.rampatra.sorting.QuickSort; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 9/28/15 - * @time: 10:39 PM - */ -public class TripletOfSum { - - /** - * Finds any 3 numbers in array {@param a} - * whose sum is equal to {@param sum}. - *

- * Time complexity: O(n^2) - * - * @param a - * @param sum - * @return - */ - public static int[] getTripletOfSum(int[] a, int sum) { - - QuickSort.quickSort(a); - - int len = a.length; - for (int i = 0, j = i + 1, k = len - 1; i < len - 2; i++) { - while (j < k) { - if (a[i] + a[j] + a[k] == sum) { - return new int[]{a[i], a[j], a[k]}; - } else if (a[i] + a[j] + a[k] < sum) { - j++; - } else { - k--; - } - } - } - return new int[]{-1}; - } - - public static void main(String[] args) { - System.out.println(Arrays.toString(getTripletOfSum(new int[]{12, 3, 4, 5, 1, 6, 9}, 24))); - System.out.println(Arrays.toString(getTripletOfSum(new int[]{12, 3, 4, 5, 1, 6, 9}, 19))); - System.out.println(Arrays.toString(getTripletOfSum(new int[]{1, 2, 3}, 6))); - } -} diff --git a/src/main/java/com/rampatra/arrays/TwoElementsSumClosestToZero.java b/src/main/java/com/rampatra/arrays/TwoElementsSumClosestToZero.java deleted file mode 100644 index e41a0f92..00000000 --- a/src/main/java/com/rampatra/arrays/TwoElementsSumClosestToZero.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.rampatra.arrays; - -import com.rampatra.sorting.QuickSort; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/30/15 - * @time: 5:44 PM - */ -public class TwoElementsSumClosestToZero { - - /** - * An array of integers is given containing both +ve and -ve numbers. You - * need to find two elements such that their sum is closest to zero. - * - * @param a - * @return - */ - public static int[] getTwoElementsWhoseSumIsClosestToZero(int[] a) { - QuickSort.quickSort(a); - - int minDiff = Math.abs(0 - (a[0] + a[a.length - 1])), n1 = a[0], n2 = a[a.length - 1]; - - for (int i = 1, j = a.length - 2; i < j; ) { - if (Math.abs(0 - (a[i] + a[j])) < minDiff) { - minDiff = Math.abs(0 - (a[i] + a[j])); - n1 = a[i]; - n2 = a[j]; - i++; - } else { - j--; - } - } - - return new int[]{n1, n2}; - } - - public static void main(String[] args) { - System.out.println(Arrays.toString(getTwoElementsWhoseSumIsClosestToZero(new int[]{1, 60, -10, -80, 85, 70}))); - System.out.println(Arrays.toString(getTwoElementsWhoseSumIsClosestToZero(new int[]{-3, -100, -10, -80, 85, 70}))); - } -} diff --git a/src/main/java/com/rampatra/arrays/TwoRepeatingElements.java b/src/main/java/com/rampatra/arrays/TwoRepeatingElements.java deleted file mode 100644 index a943a532..00000000 --- a/src/main/java/com/rampatra/arrays/TwoRepeatingElements.java +++ /dev/null @@ -1,100 +0,0 @@ -package com.rampatra.arrays; - -import com.rampatra.bits.TwoNonRepeatingElements; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @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 TwoNonRepeatingElements}. - *

- * EXPLANATION: - * Let the repeating numbers be X and Y, if we xor all the elements in the array and all integers from 1 to n, - * then the result is X xor Y. - * The 1’s in binary representation of X xor Y is corresponding to the different bits between X and Y. - * Suppose that the kth bit of X xor Y is 1, we can xor all the elements in the array and all integers - * from 1 to n, whose kth bits are 1. The result will be one of X and Y. - * - * @param a - * @return - */ - public static int[] getTwoRepeatingElements(int[] a) { - int xor = a[0]; - int rightMostSetBit; - int x = 0, y = 0; - - for (int i = 1; i < a.length; i++) { - xor ^= a[i]; - } - - for (int i = 1; i <= a.length - 2; i++) { - xor ^= i; - } - - // now xor is X xor Y, therefore find any of its set bit - rightMostSetBit = xor & ~(xor - 1); - - for (int i = 0; i < a.length; i++) { - // one number will have a set bit at that position and other wouldn't - if ((a[i] & rightMostSetBit) == 0) { - x ^= a[i]; - } else { - y ^= a[i]; - } - } - - for (int i = 1; i <= a.length - 2; i++) { - // one number will have a set bit at that position and other wouldn't - if ((i & rightMostSetBit) == 0) { - x ^= i; - } else { - y ^= i; - } - } - - return new int[]{x, y}; - } - - /** - * The algorithm is simple. We use index of the array to track repeating elements. - * Once we encounter a element lets say 2 then we make the element in 2nd index -ve just - * to mark that we have encountered 2. When we encounter 2 again and see that 2nd index - * is already -ve we conclude that 2 is repeated. - *

- * Similar to {@link DuplicatesInArray#findDuplicatesInArray(int[])}. - * - * @param a - * @return - */ - public static int[] findTwoRepeatingElements(int[] a) { - int[] repeatingElements = new int[2]; - - for (int i = 0, j = 0; i < a.length; i++) { - if (a[Math.abs(a[i])] >= 0) { - a[Math.abs(a[i])] = -a[Math.abs(a[i])]; - } else { - repeatingElements[j++] = Math.abs(a[i]); - } - } - return repeatingElements; - } - - 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}))); - System.out.println("========"); - System.out.println(Arrays.toString(findTwoRepeatingElements(new int[]{4, 2, 4, 5, 2, 3, 1}))); - System.out.println(Arrays.toString(findTwoRepeatingElements(new int[]{2, 4, 5, 2, 3, 1, 6, 7, 7}))); - System.out.println(Arrays.toString(findTwoRepeatingElements(new int[]{1, 2, 1, 2}))); - } -} diff --git a/src/main/java/com/rampatra/arrays/TwoStacksInOneArray.java b/src/main/java/com/rampatra/arrays/TwoStacksInOneArray.java deleted file mode 100644 index b4e83806..00000000 --- a/src/main/java/com/rampatra/arrays/TwoStacksInOneArray.java +++ /dev/null @@ -1,93 +0,0 @@ -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 rampatra - * @since 9/21/15 - * @time: 6:18 PM - */ -public class TwoStacksInOneArray { - - int[] array; - int top1, top2, size; - - TwoStacksInOneArray(int size) { - array = new int[size]; - this.size = size; - top1 = -1; - top2 = size; - } - - void push(int stack, int item) { - if (top1 == top2 - 1) { - System.out.println("Stack is full"); - return; - } - - if (stack == 1) { - top1++; - array[top1] = item; - } else { - top2--; - array[top2] = item; - } - } - - int pop(int stack) { - if (stack == 1) { - if (top1 == -1) { - System.out.println("Stack 1 is empty"); - return -1; - } - int pop = array[top1]; - top1--; - return pop; - } else { - if (top2 == size) { - System.out.println("Stack 2 is empty"); - return -1; - } - int pop = array[top2]; - top2++; - return pop; - } - } - - void printStack(int stack) { - if (stack == 1) { - System.out.println(Arrays.toString(Arrays.copyOfRange(array, 0, top1 + 1))); - } else { - System.out.println(Arrays.toString(Arrays.copyOfRange(array, top2, size))); - } - } - - public static void main(String[] args) { - TwoStacksInOneArray twoStack = new TwoStacksInOneArray(5); - twoStack.push(1, 3); - twoStack.push(1, 4); - twoStack.push(1, 5); - twoStack.push(2, 1); - twoStack.push(1, 6); - twoStack.push(1, 7); - twoStack.printStack(1); - twoStack.pop(1); - twoStack.pop(1); - twoStack.pop(1); - twoStack.pop(1); - twoStack.pop(1); - twoStack.pop(1); - twoStack.printStack(2); - twoStack.pop(2); - twoStack.pop(2); - twoStack.printStack(2); - } -} diff --git a/src/main/java/com/rampatra/arrays/UnsortedSubArray.java b/src/main/java/com/rampatra/arrays/UnsortedSubArray.java deleted file mode 100644 index 36aa4e12..00000000 --- a/src/main/java/com/rampatra/arrays/UnsortedSubArray.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.rampatra.arrays; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 8/20/15 - * @time: 10:31 AM - */ -public class UnsortedSubArray { - - /** - * Finds the unsorted sub array in array {@param a} such that - * sorting this sub array makes the entire array sorted. - *

- * EXPLANATION: - * 1) Find the candidate unsorted subarray - * ...a) Scan from left to right and find the first element which is greater than the next element. Let s be the - * index of such an element. In the above example 1, s is 3 (index of 30). - * ...b) Scan from right to left and find the first element (first in right to left order) which is smaller than - * the next element (next in right to left order). Let e be the index of such an element. In the above example 1, - * e is 7 (index of 31). - * 2) Check whether sorting the candidate unsorted subarray makes the complete array sorted or not. If not, then - * include more elements in the subarray. - * ...a) Find the minimum and maximum values in arr[s..e]. Let minimum and maximum values be min and max. min and - * max for [30, 25, 40, 32, 31] are 25 and 40 respectively. - * ...b) Find the first element (if there is any) in arr[0..s-1] which is greater than min, change s to index of - * this element. There is no such element in above example 1. - * ...c) Find the last element (if there is any) in arr[e+1..n-1] which is smaller than max, change e to index of - * this element. In the above example 1, e is changed to 8 (index of 35) - * 3) Print s and e. - * - * @param a - * @return - */ - public static int[] getUnsortedSubArray(int[] a) { - int start = 0, end = a.length - 1, min = Integer.MAX_VALUE, max = Integer.MIN_VALUE; - int[] unsortedArray; - - // 1(a) - for (int i = 0; i < a.length - 1; i++) { - if (a[i] > a[i + 1]) { - start = i; - break; - } - } - - // 1(b) - for (int i = a.length - 1; i > 0; i--) { - if (a[i] < a[i - 1]) { - end = i; - break; - } - } - - // 2(a) - find min and max - for (int i = start; i <= end; i++) { - if (a[i] < min) { - min = a[i]; - } - if (a[i] > max) { - max = a[i]; - } - } - - // 2(b) - for (int i = 0; i < start; i++) { - if (a[i] > min) { - start = i; - break; - } - } - - // 2(c) - for (int i = end + 1; i < a.length; i++) { - if (a[i] < max) { - end = i; - break; - } - } - - unsortedArray = new int[end - start + 1]; - for (int i = start, j = 0; i <= end; i++, j++) { - unsortedArray[j] = a[i]; - } - - return unsortedArray; - } - - public static void main(String[] args) { - System.out.println(Arrays.toString(getUnsortedSubArray(new int[]{10, 12, 20, 30, 25, 40, 32, 31, 35, 50, 60}))); - System.out.println(Arrays.toString(getUnsortedSubArray(new int[]{0, 1, 15, 25, 6, 7, 30, 40, 50}))); - System.out.println(Arrays.toString(getUnsortedSubArray(new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8}))); // fully sorted already - } -} diff --git a/src/main/java/com/rampatra/backtracking/KnightTour.java b/src/main/java/com/rampatra/backtracking/KnightTour.java deleted file mode 100644 index 64b58918..00000000 --- a/src/main/java/com/rampatra/backtracking/KnightTour.java +++ /dev/null @@ -1,111 +0,0 @@ -package com.rampatra.backtracking; - -/** - * Created by IntelliJ IDEA. - *

- * A knight's tour is a sequence of moves of a knight on a chessboard such that the knight visits every square only - * 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 rampatra - * @since 10/15/15 - * @time: 11:56 PM - * @see: https://en.wikipedia.org/wiki/Knight%27s_tour - * @see: RatInAMaze for a simpler version of this problem - */ -public class KnightTour { - - /** - * Determines if a move is a valid move in the given chess board. - * - * @param i is the row of the new move - * @param j is the column of the new move - * @param tour - * @return - */ - public static boolean isValidMove(int i, int j, int[][] tour) { - if (i >= 0 && i < tour.length && j >= 0 && j < tour[0].length && tour[i][j] == 0) { - return true; - } else { - return false; - } - } - - /** - * Finds a valid knight's tour for a given chess board size if any - * with the use of backtracking. - * - * @param i - * @param j - * @param xMoves - * @param yMoves - * @param step - * @param tour - * @return - */ - public static boolean isValidKnightTour(int i, int j, int[] xMoves, int[] yMoves, int step, int[][] tour) { - - if (step > tour.length * tour[0].length) return true; - - int nextI, nextJ; - - for (int k = 0; k < xMoves.length; k++) { - // next move is calculated from all possible moves - nextI = i + xMoves[k]; - nextJ = j + yMoves[k]; - - // if the next move is valid then we proceed otherwise we - // try next set of moves - if (isValidMove(nextI, nextJ, tour)) { - tour[nextI][nextJ] = step; - if (isValidKnightTour(nextI, nextJ, xMoves, yMoves, step + 1, tour)) { - return true; - } else { - tour[nextI][nextJ] = 0; // backtrack - } - } - } - - return false; - } - - - /** - * Prints the knight's tour if any. - * - * @param i is the start row - * @param j is the start column - * @param boardSize is the size of the chess board - */ - public static void printKnightTour(int i, int j, int[] boardSize) { - if (boardSize.length < 2) return; - - // a 2D array for the knight's tour - int[][] tour = new int[boardSize[0]][boardSize[1]]; - // all possible relative moves that a knight can make - int[] xMoves = new int[]{1, 1, 2, 2, -1, -1, -2, -2}; - int[] yMoves = new int[]{-2, 2, -1, 1, -2, 2, -1, 1}; - - tour[0][0] = 1; - - if (isValidKnightTour(i, j, xMoves, yMoves, 2, tour)) { - print2DMatrix(tour); - } else { - System.out.println("Knight's tour doesn't exist for board size [" + boardSize[0] + "x" + boardSize[1] + "]"); - } - - } - - public static void print2DMatrix(int[][] array) { - for (int i = 0; i < array.length; i++) { - for (int j = 0; j < array[0].length; j++) { - System.out.print("[" + array[i][j] + "]"); - } - System.out.println(); - } - } - - public static void main(String[] args) { - printKnightTour(0, 0, new int[]{8, 8}); - } -} diff --git a/src/main/java/com/rampatra/backtracking/RatInAMaze.java b/src/main/java/com/rampatra/backtracking/RatInAMaze.java deleted file mode 100644 index bb8ea749..00000000 --- a/src/main/java/com/rampatra/backtracking/RatInAMaze.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.rampatra.backtracking; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 10/18/15 - * @time: 10:39 AM - */ -public class RatInAMaze { - - /** - * @param i - * @param j - * @param maze - * @return - */ - public static boolean isValidMove(int i, int j, int[][] maze) { - if (i >= 0 && i < maze.length && j >= 0 && j < maze[0].length && maze[i][j] == 1) { - return true; - } else { - return false; - } - } - - /** - * @param i - * @param j - * @param xMoves - * @param yMoves - * @param maze - * @param path - * @return - */ - public static boolean isValidPath(int i, int j, int[] xMoves, int[] yMoves, int[][] maze, int[][] path) { - - if (i == maze.length - 1 && j == maze[0].length - 1) return true; - - int nextI, nextJ; - - for (int k = 0; k < xMoves.length; k++) { - nextI = i + xMoves[k]; - nextJ = j + yMoves[k]; - if (isValidMove(nextI, nextJ, maze)) { - path[nextI][nextJ] = 1; - if (isValidPath(nextI, nextJ, xMoves, yMoves, maze, path)) { - return true; - } else { - path[nextI][nextJ] = 0; - } - } - } - return false; - } - - /** - * @param i is the start row - * @param j is the start column - * @param maze is the maze in which a path has to be found (1 denotes rat can traverse and 0 denotes it cannot) - */ - public static void printMazePath(int i, int j, int[][] maze) { - - int[] xMoves = {0, 1}; - int[] yMoves = {1, 0}; - - int[][] path = new int[maze.length][maze[0].length]; - - System.out.println("Maze"); - System.out.println("---------------"); - print2DMatrix(maze); - System.out.println("---------------"); - - if (isValidPath(i, j, xMoves, yMoves, maze, path)) { - print2DMatrix(path); - } else { - System.out.println("No escape path found!"); - } - } - - public static void print2DMatrix(int[][] array) { - for (int i = 0; i < array.length; i++) { - for (int j = 0; j < array[0].length; j++) { - System.out.print("[" + array[i][j] + "]"); - } - System.out.println(); - } - } - - public static void main(String[] args) { - printMazePath(0, 0, new int[][]{{1, 1, 1, 1}, {0, 0, 1, 1}}); - } -} diff --git a/src/main/java/com/rampatra/base/AVLTree.java b/src/main/java/com/rampatra/base/AVLTree.java deleted file mode 100644 index 61999cd0..00000000 --- a/src/main/java/com/rampatra/base/AVLTree.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.rampatra.base; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 4/25/15 - * @time: 10:25 AM - */ -public class AVLTree> extends Tree { - -} diff --git a/src/main/java/com/rampatra/base/BinaryNode.java b/src/main/java/com/rampatra/base/BinaryNode.java deleted file mode 100644 index 6e57530e..00000000 --- a/src/main/java/com/rampatra/base/BinaryNode.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.rampatra.base; - -/** - * Created by IntelliJ IDEA. - * User: rampatra - * Date: 4/11/15 - * Time: 7:11 PM - * To change this template go to Preferences | IDE Settings | File and Code Templates - */ -public class BinaryNode> { - - public E value; - public BinaryNode left; - public BinaryNode right; - - public BinaryNode(E value, BinaryNode left, BinaryNode right) { - this.value = value; - this.left = left; - this.right = right; - } - - public BinaryNode(BinaryNode node) { - if (node == null) return; - - this.value = node.value; - this.left = node.left; - this.right = node.right; - } -} diff --git a/src/main/java/com/rampatra/base/BinarySearchTree.java b/src/main/java/com/rampatra/base/BinarySearchTree.java deleted file mode 100644 index 644f1e7d..00000000 --- a/src/main/java/com/rampatra/base/BinarySearchTree.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.rampatra.base; - -import java.util.NoSuchElementException; - -import static java.lang.System.out; - -/** - * A binary search tree is a binary tree in which every node fits a specific ordering property: all left - * descendents <= n < all right descendents. This must be true for each node n. - *

- * Note: The definition of a binary search tree can vary slightly with respect to equality. Under some definitions, the - * tree cannot have duplicate values. In others, the duplicate values will be on the right or can be on either side. All - * are valid definitions, but you should clarify this with your interviewer - * - * @author rampatra - * @since 4/19/15 - * @param - */ -public class BinarySearchTree> extends BinaryTree { - - /** - * Inserts a node into the BST. - * - * @param value - */ - public BinaryNode put(E value) { - return put(root, value); - } - - public BinaryNode put(BinaryNode node, E value) { - BinaryNode newNode = new BinaryNode<>(value, null, null); - - if (node == null) { - return root = new BinaryNode<>(value, null, null); - } else { - if (value.compareTo(node.value) < 0) { - if (node.left == null) { - return node.left = newNode; - } else { - return put(node.left, value); - } - } else { - if (node.right == null) { - return node.right = newNode; - } else { - return put(node.right, value); - } - } - } - } - - - /** - * Returns the node with minimum value. - * - * @return - */ - public BinaryNode min() { - return min(root); - } - - public BinaryNode min(BinaryNode node) { - if (node == null) throw new NoSuchElementException(); - - if (node.left == null) { - return node; - } else { - return min(node.left); - } - } - - public void printList(BinaryNode node) { - BinaryNode current = node; - out.print("["); - if (current == null) { - out.println("]"); - return; - } - while (current.right != node) { - out.print(current.value + ","); - current = current.right; - } - out.println(current.value + "]"); - } -} diff --git a/src/main/java/com/rampatra/base/BinaryTree.java b/src/main/java/com/rampatra/base/BinaryTree.java deleted file mode 100644 index e420d7c0..00000000 --- a/src/main/java/com/rampatra/base/BinaryTree.java +++ /dev/null @@ -1,296 +0,0 @@ -package com.rampatra.base; - -import com.rampatra.trees.BFSUsingQueue; - -import static java.lang.System.out; - -/** - * Basic binary tree functions like put, delete, height, traversals, etc. - * An example of a binary tree: - * - * 5 ------> depth 0, level 1 (depth + 1) - * / \ - * 3 8 -----> depth 1, level 2 - * / \ / \ - * 2 4 9 7 ----> depth 2, level 3 - * - * Root of the tree: 5 - * Height: 2 - * - * @author rampatra - * @since 4/19/15 - * @link https://www.cs.cmu.edu/~adamchik/15-121/lectures/Trees/trees.html - * @link http://typeocaml.com/2014/11/26/height-depth-and-level-of-a-tree/ - */ -public class BinaryTree> extends Tree { - - public BinaryNode root; - Queue> queue = new LinkedQueue<>(); // needed for insertion - - /** - * Inserts a node into the binary tree such that - * it always forms a complete binary tree. - * - * @param value - */ - public BinaryNode put(E value) { - return put(root, value); - } - - public BinaryNode put(BinaryNode node, E value) { - // create a new node from the value - BinaryNode newNode = new BinaryNode<>(value, null, null); - - if (node == null) { - return root = queue.add(newNode); - } else { - BinaryNode parentNode = queue.element(); - if (parentNode.left == null) { - parentNode.left = newNode; - } else if (parentNode.right == null) { - parentNode.right = newNode; - queue.remove(); // parent node has both left and right child now, so dequeue it - } - queue.add(newNode); - } - return node; - } - - - /*********************************** - * - * Tree Traversals. - * - ***********************************/ - - /** - * Prints the pre-order traversal of the tree. - */ - public void preOrder() { - preOrder(root); - } - - public void preOrder(BinaryNode node) { - if (node == null) { - return; - } - out.print("->" + node.value); - preOrder(node.left); - preOrder(node.right); - } - - - /** - * Prints the in-order traversal of the tree. - */ - public void inOrder() { - inOrder(root); - } - - public void inOrder(BinaryNode node) { - if (node == null) { - return; - } - inOrder(node.left); - out.print("->" + node.value); - inOrder(node.right); - } - - - /** - * Prints the post-order traversal of the tree. - */ - public void postOrder() { - postOrder(root); - } - - public void postOrder(BinaryNode node) { - if (node == null) { - return; - } - postOrder(node.left); - postOrder(node.right); - out.print("->" + node.value); - } - - - /** - * Prints the node of the tree breadth-wise. - *

- * DEF: Breadth-first search (BFS) is an algorithm for traversing or searching tree - * or graph data structures. It starts at the tree root (or some arbitrary node of a - * graph, sometimes referred to as a `search key'[1]) and explores the neighboring nodes - * first, before moving to the next level neighbors. See {@link BFSUsingQueue} for a O(n) - * solution. - *

- * Time complexity: O(h^2) where, h is the height of the tree - */ - public void breadthFirstTraversal() { - int height = height(root); - // assuming level starts at one - for (int level = 1; level <= height + 1; level++) { - printLevel(root, level); - } - } - - public void printLevel(BinaryNode node, int level) { - if (node == null) return; - - // print the starting node - if (level == 1) { - printValue(node); - } else { // print the immediate child nodes - printLevel(node.left, level - 1); - printLevel(node.right, level - 1); - } - } - - /** - * Deletes the entire tree. - */ - public void delete() { - root = null; - } - - /** - * Deletes a particular node from the tree - * and rearranges the remaining nodes. - * - * @param value - */ - public void delete(E value) { - - } - - /** - * Deletes all child nodes of {@param node}. - * - * @param node - */ - public void deleteChildren(BinaryNode node) { - if (node == null) { - return; - } - node.left = null; - node.right = null; - } - - - /** - * Height of the tree is the number of edges from the root to its farthest leaf. - * Note: The height of binary tree with single node is taken as zero. - * - * @return the height of the tree. - */ - public int height() { - return height(root); - } - - public int height(BinaryNode node) { - if (node == null || (node.left == null && node.right == null)) { - return 0; - } - - return Math.max(height(node.left), height(node.right)) + 1; - } - - - /** - * Size of tree. - * - * @return the number of nodes currently in the tree. - */ - public int size() { - return size(root); - } - - public int size(BinaryNode node) { - if (node == null) { - return 0; - } else { - return size(node.left) + 1 + size(node.right); - } - } - - /** - * Tests if this tree is empty. - * - * @return - */ - public boolean isEmpty() { - return root == null; - } - - - /** - * The diameter of a tree (sometimes called the width) is the number - * of nodes on the longest path between two leaves in the tree. - * - * @return the diameter of the tree. - */ - public int diameter() { - return diameter(root); - } - - public int diameter(BinaryNode node) { - if (node == null) return 0; - - // diameter of current node - int diameter = height(node.left) + height(node.right) + 1; - - // return max diameters of current node, left sub-tree and right sub-tree - return Math.max(diameter, Math.max(diameter(node.left), diameter(node.right))); - } - - - /** - * Width is the number of nodes in a particular level. - * - * @return maximum width of the tree. - */ - public int width() { - return width(root, 0); - } - - public int width(BinaryNode node, int width) { - if (node == null) return 0; - - if (node.left == null && node.right == null) return 1; // for single/leaf node - - int levelWidth = width(node.left, width) + width(node.right, width); - - // to find max width - if (levelWidth > width) width = levelWidth; - - return width; - } - - public void printValue(BinaryNode node) { - if (node == null) return; - - out.print(node.value); - } - - // test cases - public static void main(String[] args) { - BinaryTree bt = new BinaryTree<>(); - bt.put(1); - bt.put(2); - bt.put(3); - bt.put(4); - bt.put(5); - bt.put(6); - bt.put(7); - bt.put(8); - - out.print("BFS: "); - bt.breadthFirstTraversal(); - out.print("\nPre Order: "); - bt.preOrder(); - out.print("\nIn Order: "); - bt.inOrder(); - out.print("\nPost Order: "); - bt.postOrder(); - out.println("\nHeight of tree: " + bt.height()); - } -} diff --git a/src/main/java/com/rampatra/base/CircularSingleLinkedList.java b/src/main/java/com/rampatra/base/CircularSingleLinkedList.java deleted file mode 100644 index cdf37470..00000000 --- a/src/main/java/com/rampatra/base/CircularSingleLinkedList.java +++ /dev/null @@ -1,297 +0,0 @@ -package com.rampatra.base; - -import java.util.NoSuchElementException; - -import static java.lang.System.out; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/16/15 - * @time: 1:00 PM - */ -public class CircularSingleLinkedList> implements LinkedList { - - public SingleLinkedNode head; - public int size; - - @Override - public boolean add(E item) { - SingleLinkedNode newNode = new SingleLinkedNode<>(item, head); - if (head == null) { // list empty - head = newNode; - newNode.next = head; - } else { // add to the end of list - SingleLinkedNode curr = head; - while (curr.next != head) { - curr = curr.next; - } - curr.next = newNode; - } - size++; - return true; - } - - @Override - public boolean add(int index, E item) { - isPositionIndex(index); - - if (index == 0) { // add at first - addFirst(item); - } else { // add at any other location - SingleLinkedNode nodeAtPrevIndex = getPredecessorNode(index); - SingleLinkedNode newNode = new SingleLinkedNode<>(item, nodeAtPrevIndex.next); - nodeAtPrevIndex.next = newNode; - size++; - } - return true; - } - - @Override - public void addFirst(E item) { - SingleLinkedNode newNode = new SingleLinkedNode<>(item, head), node; - if (head == null) { // empty linked list - newNode.next = newNode; - } else { - node = getNode(size - 1); - node.next = newNode; - } - head = newNode; - size++; - } - - @Override - public void addLast(E item) { - add(item); - } - - @Override - public void clear() { - // Clearing all of the links between nodes is "unnecessary", but: - // - helps a generational GC if the discarded nodes inhabit - // more than one generation - // - is sure to free memory even if there is a reachable Iterator - for (SingleLinkedNode node = head; node != null; ) { - SingleLinkedNode next = node.next; - node.item = null; - node.next = null; - node = next; - } - head = null; - size = 0; - } - - @Override - public LinkedList clone() { - return null; - } - - @Override - public boolean contains(E item) { - return getNode(item) != null; - } - - @Override - public E get(int index) { - return getNode(index).item; - } - - @Override - public E getFirst() { - isLinkedListEmpty(); - return head.item; - } - - @Override - public E getLast() { - return getNode(size - 1).item; - } - - @Override - public E remove() { - isLinkedListEmpty(); - - E item = head.item; - // last node should point to new head - SingleLinkedNode lastNode = getNode(size - 1); - lastNode.next = head.next; - head = (head.next != head) ? head.next : null; - size--; - return item; - } - - @Override - public E remove(int index) { - isLinkedListEmpty(); - - SingleLinkedNode prevNode = getPredecessorNode(index), - delNode, - lastNode; - if (prevNode == null) { // index = 0 - delNode = head; - head = (head.next != head) ? head.next : null; - size--; - return delNode.item; - } else { - delNode = prevNode.next; - prevNode.next = delNode.next; - // last node should point to new head - lastNode = getNode(size - 1); - lastNode.next = head.next; - head = head.next; - size--; - return delNode.item; - } - } - - @Override - public boolean removeItem(E item) { - isLinkedListEmpty(); - - if (!contains(item)) return false; - - SingleLinkedNode prevNode = getPredecessorNode(item), - lastNode; - if (prevNode == null) { // index = 0 - head = (head.next != head) ? head.next : null; - size--; - } else { - prevNode.next = prevNode.next.next; - // last node should point to new head - lastNode = getNode(size - 1); - lastNode.next = head.next; - head = head.next; - size--; - } - return true; - } - - @Override - public E set(int index, E item) { - SingleLinkedNode node = getNode(index); - node.item = item; - return node.item; - } - - @Override - public int size() { - return size; - } - - @Override - public void printList() { - printList(head); - } - - public void printList(SingleLinkedNode node) { - SingleLinkedNode curr = node; - out.print("["); - if (curr == null) { - out.println("]"); - return; - } - while (curr.next != head) { - out.print(curr.item + ","); - curr = curr.next; - } - out.println(curr.item + "]"); - } - - public static > CircularSingleLinkedList getLinkedList(SingleLinkedNode node) { - CircularSingleLinkedList linkedList = new CircularSingleLinkedList<>(); - // set head - linkedList.head = node; - // set size - SingleLinkedNode curr = node; - while (curr != linkedList.head) { - linkedList.size++; - curr = curr.next; - } - return linkedList; - } - - private SingleLinkedNode getPredecessorNode(int index) { - return index > 0 ? getNode(index - 1) : null; - } - - private SingleLinkedNode getPredecessorNode(E item) { - SingleLinkedNode prev = null; - SingleLinkedNode curr = head; - if (item == null) { - while (curr != head) { - if (curr.item == item) { // when item is null, use == rather than equals() - return prev; - } - prev = curr; - curr = curr.next; - } - } else { - while (curr != head) { - if (curr.item.equals(item)) { - return prev; - } - prev = curr; - curr = curr.next; - } - } - return null; - } - - public SingleLinkedNode getNode(int index) { - isElementIndex(index); - - SingleLinkedNode curr = head; - int i = 0; - while (i < index) { - curr = curr.next; - i++; - } - return curr; - } - - public SingleLinkedNode getNode(E item) { - SingleLinkedNode curr = head; - if (item == null) { - while (curr != head) { // when item is null, use == rather than equals() - if (curr.item == item) { - return curr; - } - curr = curr.next; - } - } else { - while (curr != head) { - if (curr.item.equals(item)) { - return curr; - } - curr = curr.next; - } - } - return null; - } - - private void isLinkedListEmpty() { - if (head == null) { - throw new NoSuchElementException("LinkedList empty"); - } - } - - /** - * Tells if the argument is the index of an existing element. - */ - private void isElementIndex(int index) { - if (index < 0 || index >= size) { - throw new IndexOutOfBoundsException("Index [" + index + "] must be less than size [" + size + "]"); - } - } - - /** - * Tells if the argument is the index of a valid position for an - * iterator or an add operation. - */ - private void isPositionIndex(int index) { - if (index < 0 || index > size) { - throw new IndexOutOfBoundsException("Index [" + index + "] must be less than or equal to size [" + size + "]"); - } - } -} diff --git a/src/main/java/com/rampatra/base/DoubleLinkedList.java b/src/main/java/com/rampatra/base/DoubleLinkedList.java deleted file mode 100644 index e905725c..00000000 --- a/src/main/java/com/rampatra/base/DoubleLinkedList.java +++ /dev/null @@ -1,280 +0,0 @@ -package com.rampatra.base; - -import java.util.NoSuchElementException; - -import static java.lang.System.out; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/16/15 - * @time: 1:00 PM - */ -public class DoubleLinkedList> implements LinkedList { - - public DoubleLinkedNode head; - public int size; - - @Override - public boolean add(E item) { - DoubleLinkedNode newNode = new DoubleLinkedNode<>(null, item, null); - if (head == null) { // list empty - head = newNode; - } else { // add to the end of list - DoubleLinkedNode curr = head; - while (curr.next != null) { - curr = curr.next; - } - curr.next = newNode; - newNode.prev = curr; - } - size++; - return true; - } - - @Override - public boolean add(int index, E item) { - isPositionIndex(index); - - if (index == 0) { // add at first - addFirst(item); - } else { // add at any other location - DoubleLinkedNode prevNode = getPredecessorNode(index); - DoubleLinkedNode nextNode = prevNode.next; - DoubleLinkedNode newNode = new DoubleLinkedNode<>(prevNode, item, prevNode.next); - prevNode.next = newNode; - if (nextNode != null) nextNode.prev = newNode; - size++; - } - return true; - } - - @Override - public void addFirst(E item) { - DoubleLinkedNode newNode = new DoubleLinkedNode<>(null, item, head); - if (head != null) head.prev = newNode; - head = newNode; - size++; - } - - @Override - public void addLast(E item) { - add(item); - } - - @Override - public void clear() { - // Clearing all of the links between nodes is "unnecessary", but: - // - helps a generational GC if the discarded nodes inhabit - // more than one generation - // - is sure to free memory even if there is a reachable Iterator - for (DoubleLinkedNode node = head; node != null; ) { - DoubleLinkedNode next = node.next; - node.item = null; - node.next = null; - node.prev = null; - node = next; - } - head = null; - size = 0; - } - - @Override - public LinkedList clone() { - return null; - } - - @Override - public boolean contains(E item) { - return getNode(item) != null; - } - - @Override - public E get(int index) { - return getNode(index).item; - } - - @Override - public E getFirst() { - isLinkedListEmpty(); - return head.item; - } - - @Override - public E getLast() { - return getNode(size - 1).item; - } - - @Override - public E remove() { - isLinkedListEmpty(); - - E item = head.item; - head = head.next; - if (head != null) head.prev = null; // check for linked list size = 1 - size--; - return item; - } - - @Override - public E remove(int index) { - isLinkedListEmpty(); - - DoubleLinkedNode prevNode = getPredecessorNode(index); - DoubleLinkedNode nextNode; - DoubleLinkedNode delNode; - if (prevNode == null) { // index = 0 - delNode = head; - head = head.next; - if (head != null) head.prev = null; // check for linked list size = 1 - size--; - return delNode.item; - } else { - delNode = prevNode.next; - nextNode = delNode.next; - prevNode.next = nextNode; - if (nextNode != null) nextNode.prev = prevNode; // check needed if node to be deleted is last node - size--; - return delNode.item; - } - } - - @Override - public boolean removeItem(E item) { - isLinkedListEmpty(); - - if (!contains(item)) return false; - - DoubleLinkedNode prevNode = getPredecessorNode(item); - DoubleLinkedNode nextNode; - if (prevNode == null) { // index = 0 - head = head.next; - if (head != null) head.prev = null; // condition for list size = 1 - size--; - } else { - nextNode = prevNode.next.next; - prevNode.next = nextNode; - if (nextNode != null) nextNode.prev = prevNode; - size--; - } - return true; - } - - @Override - public E set(int index, E item) { - DoubleLinkedNode node = getNode(index); - node.item = item; - return node.item; - } - - @Override - public int size() { - return size; - } - - @Override - public void printList() { - printList(head); - } - - public static > void printList(DoubleLinkedNode node) { - DoubleLinkedNode curr = node; - out.print("["); - if (curr == null) { - out.println("]"); - return; - } - // prints the list from first node - while (curr.next != null) { - out.print(curr.item.toString() + ","); - curr = curr.next; - } - out.println(curr.item.toString() + "]"); - // prints the list from last node - out.print("["); - while (curr.prev != null) { - out.print(curr.item.toString() + ","); - curr = curr.prev; - } - out.println(curr.item.toString() + "]"); - } - - public static > DoubleLinkedList getLinkedList(DoubleLinkedNode node) { - DoubleLinkedList linkedList = new DoubleLinkedList<>(); - // set head - linkedList.head = node; - // set size - DoubleLinkedNode curr = node; - while (curr != null) { - linkedList.size++; - curr = curr.next; - } - return linkedList; - } - - private DoubleLinkedNode getPredecessorNode(int index) { - return index > 0 ? getNode(index - 1) : null; - } - - private DoubleLinkedNode getPredecessorNode(E item) { - return getNode(item) != null ? getNode(item).prev : null; - } - - public DoubleLinkedNode getNode(int index) { - isElementIndex(index); - - DoubleLinkedNode curr = head; - int i = 0; - while (i < index) { - curr = curr.next; - i++; - } - return curr; - } - - public DoubleLinkedNode getNode(E item) { - DoubleLinkedNode curr = head; - if (item == null) { - while (curr != null) { // when item is null, use == rather than equals() - if (curr.item == item) { - return curr; - } - curr = curr.next; - } - } else { - while (curr != null) { - if (curr.item.equals(item)) { - return curr; - } - curr = curr.next; - } - } - return null; - } - - private void isLinkedListEmpty() { - if (head == null) { - throw new NoSuchElementException("LinkedList empty"); - } - } - - /** - * Tells if the argument is the index of an existing element. - */ - private void isElementIndex(int index) { - if (index < 0 || index >= size) { - throw new IndexOutOfBoundsException("Index [" + index + "] must be less than size [" + size + "]"); - } - } - - /** - * Tells if the argument is the index of a valid position for an - * iterator or an add operation. - */ - private void isPositionIndex(int index) { - if (index < 0 || index > size) { - throw new IndexOutOfBoundsException("Index [" + index + "] must be less than or equal to size [" + size + "]"); - } - } -} diff --git a/src/main/java/com/rampatra/base/DoubleLinkedNode.java b/src/main/java/com/rampatra/base/DoubleLinkedNode.java deleted file mode 100644 index 7da01c20..00000000 --- a/src/main/java/com/rampatra/base/DoubleLinkedNode.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.rampatra.base; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/18/15 - * @time: 2:42 PM - */ -public class DoubleLinkedNode> { - - public E item; - public DoubleLinkedNode next; - public DoubleLinkedNode prev; - - public DoubleLinkedNode(E item) { - this(null, item, null); - } - - public DoubleLinkedNode(DoubleLinkedNode prev, E item, DoubleLinkedNode next) { - this.item = item; - this.next = next; - this.prev = prev; - } -} diff --git a/src/main/java/com/rampatra/base/Graph.java b/src/main/java/com/rampatra/base/Graph.java deleted file mode 100644 index 0de77ba1..00000000 --- a/src/main/java/com/rampatra/base/Graph.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.rampatra.base; - -/** - * A rudimentary Graph having all the basic methods. - * - * @author rampatra - * @since 2019-02-10 - */ -public class Graph> { -} diff --git a/src/main/java/com/rampatra/base/GraphNode.java b/src/main/java/com/rampatra/base/GraphNode.java deleted file mode 100644 index 90f98478..00000000 --- a/src/main/java/com/rampatra/base/GraphNode.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.rampatra.base; - -import java.util.HashSet; -import java.util.Set; - -/** - * The class for a node in a graph. Ideally, you should make member variable {@code private} and have - * getters, setters, etc. but to keep it simple, I have omitted all those boilerplate code. - * - * @author rampatra - * @since 2019-02-10 - */ -public class GraphNode> { - public E value; - public Set> adjacentNodes = new HashSet<>(); - - public GraphNode(E value) { - this(value, null); - } - - public GraphNode(E value, Set> adjacentNodes) { - this.value = value; - if (adjacentNodes != null) { - this.adjacentNodes = adjacentNodes; - } - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - GraphNode graphNode = (GraphNode) o; - - return value.equals(graphNode.value); - } -} diff --git a/src/main/java/com/rampatra/base/LinkedList.java b/src/main/java/com/rampatra/base/LinkedList.java deleted file mode 100644 index cd45a2d5..00000000 --- a/src/main/java/com/rampatra/base/LinkedList.java +++ /dev/null @@ -1,135 +0,0 @@ -package com.rampatra.base; - -/** - * A generic interface for LinkedList. - * - * @author rampatra - * @since 6/16/15 - */ -public interface LinkedList> { - - /** - * Appends the specified element to the end of this list. - * - * @param item - * @return {@code true} (as specified by {@link java.util.Collection#add}) - */ - boolean add(E item); - - /** - * Inserts the specified element at the specified position in this list. - * - * @param index - * @param item - * @return - * @throws IndexOutOfBoundsException {@inheritDoc} - */ - boolean add(int index, E item); - - /** - * Inserts the specified element at the beginning of this list. - * - * @param item - */ - void addFirst(E item); - - /** - * Appends the specified element to the end of this list. - * - * @param item - */ - void addLast(E item); - - /** - * Removes all of the elements from this list. - */ - void clear(); - - /** - * Returns a shallow copy of this LinkedList. - * - * @return - */ - LinkedList clone(); - - /** - * Returns true if this list contains the specified element. - * - * @param item - * @return - */ - boolean contains(E item); - - /** - * Returns the element at the specified position in this list. - * - * @param index - * @return - * @throws IndexOutOfBoundsException {@inheritDoc} - */ - E get(int index); - - /** - * Returns the first element in this list. - * - * @return - * @throws java.util.NoSuchElementException if this list is empty - */ - E getFirst(); - - /** - * Returns the last element in this list. - * - * @return - * @throws java.util.NoSuchElementException if this list is empty - */ - E getLast(); - - /** - * Prints the contents of this list. - */ - void printList(); - - /** - * Retrieves and removes the head (first element) of this list. - * - * @return - * @throws java.util.NoSuchElementException if this list is empty - */ - E remove(); - - /** - * Removes the element at the specified position in this list. - * - * @param index - * @return - * @throws IndexOutOfBoundsException {@inheritDoc} - */ - E remove(int index); - - /** - * Removes the first occurrence of the specified element from this list, if it is present. - * - * @param item - * @return {@code true} if this list contained the specified element - */ - boolean removeItem(E item); - - /** - * Replaces the element at the specified position in this list with the specified element. - * - * @param index - * @param item - * @return - * @throws IndexOutOfBoundsException {@inheritDoc} - */ - E set(int index, E item); - - /** - * Returns the number of elements in this list. - * - * @return - */ - int size(); - -} diff --git a/src/main/java/com/rampatra/base/LinkedQueue.java b/src/main/java/com/rampatra/base/LinkedQueue.java deleted file mode 100644 index 3e4c472d..00000000 --- a/src/main/java/com/rampatra/base/LinkedQueue.java +++ /dev/null @@ -1,88 +0,0 @@ -package com.rampatra.base; - -import java.util.NoSuchElementException; - -/** - * Queue implementation using a singly linked list with two pointers. - * - * @author rampatra - * @since 4/12/15 - */ -public class LinkedQueue implements Queue { - - Node front; - Node rear; - - public LinkedQueue() { - front = null; - rear = null; - } - - @Override - public E add(E item) { - if (front == null || rear == null) { - front = rear = new Node<>(item, null); - } else { - rear.next = new Node<>(item, null); - rear = rear.next; - } - return item; - } - - @Override - public E remove() { - if (front == null) { - throw new NoSuchElementException(); - } - E item = element(); - front = front.next; - return item; - } - - @Override - public E element() { - if (front == null) { - throw new NoSuchElementException(); - } - return front.item; - } - - @Override - public int size() { - int count = 0; - if (front == null) return count; - for (Node node = front; node != rear; node = node.next) { - count++; - } - return count; - } - - @Override - public boolean isEmpty() { - return front == null; - } - - @Override - public void print() { - Node node; - System.out.print("["); - if (front == null) { - System.out.println("]"); - return; - } - for (node = front; node != rear; node = node.next) { - System.out.print(node.item + ","); - } - System.out.println(node.item + "]"); - } - - private class Node { - E item; - Node next; - - public Node(E item, Node next) { - this.item = item; - this.next = next; - } - } -} diff --git a/src/main/java/com/rampatra/base/LinkedStack.java b/src/main/java/com/rampatra/base/LinkedStack.java deleted file mode 100644 index d41c8945..00000000 --- a/src/main/java/com/rampatra/base/LinkedStack.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.rampatra.base; - -import java.util.EmptyStackException; - -/** - * Stack implementation using a singly linked list. - * - * @param the data type to be stored in the stack - * @author rampatra - * @since 3/24/15 - */ -public class LinkedStack implements Stack { - - private Node top; - - public LinkedStack() { - top = null; - } - - /** - * Pushes an item onto the top of this stack. - * - * @param item - */ - @Override - public E push(E item) { - top = new Node<>(item, top); - return item; - } - - /** - * Removes the object at the top of this stack and - * returns it. - * - * @return - */ - @Override - public E pop() { - E item = peek(); - top = top.next; - return item; - } - - /** - * Looks at the object at the top of this stack without removing it from the stack. - * - * @return - */ - @Override - public E peek() { - if (top == null) { - throw new EmptyStackException(); - } - return top.item; - } - - /** - * Returns the number of items currently in the stack. - * - * @return - */ - @Override - public int size() { - int count = 0; - for (Node node = top; node != null; node = node.next) { - count++; - } - return count; - } - - /** - * Prints the content of the stack. - */ - @Override - public void print() { - Node node; - System.out.print("["); - if (top == null) { - System.out.println("]"); - return; - } - for (node = top; node.next != null; node = node.next) { - System.out.print(node.item + ","); - } - System.out.println(node.item + "]"); - } - - /** - * Tests if this stack is empty. - * - * @return - */ - @Override - public boolean isEmpty() { - return top == null; - } - - private class Node { - E item; - Node next; - - Node(E item, Node next) { - this.item = item; - this.next = next; - } - } -} diff --git a/src/main/java/com/rampatra/base/MaxHeap.java b/src/main/java/com/rampatra/base/MaxHeap.java deleted file mode 100644 index 22b36cfa..00000000 --- a/src/main/java/com/rampatra/base/MaxHeap.java +++ /dev/null @@ -1,160 +0,0 @@ -package com.rampatra.base; - -import com.rampatra.sorting.HeapSort; - -import java.util.Arrays; - -/** - * A HEAP is a specialized tree-based ABSTRACT DATA TYPE that satisfies the heap property: - * min-heap: All non-leaf elements are either smaller than or equal to their left and right child. - * max-heap: All non-leaf elements are either greater than or equal to their left and right child. - *

- * Often implemented as an array, where the children of the element at index i are at index - * 2i+1 (left child) and 2i+2 (right child). - *

- * The first element (minimum or maximum, depending on chosen order) can be found in O(1). - * Each successor can be found in O(log n). The algorithm in maxHeapify() takes O(log n) time - * Therefore, buildMaxHeap() would take O(n log n) time BUT IF OBSERVED CAREFULLY IT TAKES 0(N) TIME. - *

- * Used in the HeapSort algorithm. Also can be used to implement a PriorityQueue. - * Learn more - * - * @author rampatra - * @since 8/2/15 - */ -public class MaxHeap { - - int[] heap; - int size; - - public MaxHeap(int[] heap) { - this.size = heap.length; - this.heap = Arrays.copyOf(heap, size); - } - - /** - * Makes the array {@param a} satisfy the max heap property starting from - * {@param index} till the end of array. - *

- * See {@link HeapSort#maxHeapify} for a modified - * version of maxHeapify. - *

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

- * Time complexity: O(n) and is not O(n log n). - */ - public void buildMaxHeap() { - for (int i = size / 2 - 1; i >= 0; i--) { - maxHeapify(i); - } - } - - /** - * Insert a new element into the heap satisfying - * the heap property. - *

- * 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) { - // increase heap size - heap = Arrays.copyOf(heap, size + 1); - int i = size; - int parentIndex = (int) Math.floor((i - 1) / 2); - // move up through the heap till you find the right position - while (i > 0 && elem > heap[parentIndex]) { - heap[i] = heap[parentIndex]; - i = parentIndex; - parentIndex = (int) Math.floor((i - 1) / 2); - } - heap[i] = elem; - size++; - } - - public int findMax() { - if (size == 0) { - return -1; - } else { - return heap[0]; - } - } - - public int extractMax() { - if (size == 0) return -1; - - int min = heap[0]; - heap[0] = heap[size - 1]; - size--; - maxHeapify(0); - return min; - } - - public int getSize() { - return size; - } - - public int[] getHeap() { - return heap; - } - - public void printHeap() { - if (heap == null) - System.out.print("null"); - int iMax = size - 1, i; - if (iMax == -1) - System.out.print("[]"); - - StringBuilder b = new StringBuilder(); - b.append('['); - for (i = 0; i < iMax; i++) { - b.append(heap[i]); - b.append(", "); - } - System.out.println(b.append(heap[i]).append(']').toString()); - } - - private void swap(int firstIndex, int secondIndex) { - int temp = heap[firstIndex]; - heap[firstIndex] = heap[secondIndex]; - heap[secondIndex] = temp; - } - - // test cases - public static void main(String[] args) { - int[] a = new int[]{2, 4, 5, 1, 6, 7, 8}; - MaxHeap maxHeap = new MaxHeap(a); - maxHeap.printHeap(); - maxHeap.buildMaxHeap(); - maxHeap.printHeap(); - maxHeap.extractMax(); - maxHeap.printHeap(); - maxHeap.insert(12); - maxHeap.printHeap(); - } -} diff --git a/src/main/java/com/rampatra/base/MinHeap.java b/src/main/java/com/rampatra/base/MinHeap.java deleted file mode 100644 index 6e7b7df1..00000000 --- a/src/main/java/com/rampatra/base/MinHeap.java +++ /dev/null @@ -1,143 +0,0 @@ -package com.rampatra.base; - -import java.util.Arrays; - -/** - * A HEAP is a specialized tree-based ABSTRACT DATA TYPE that satisfies the heap property: - * min-heap: All non-leaf elements are either smaller than or equal to their left and right child. - * max-heap: All non-leaf elements are either greater than or equal to their left and right child. - *

- * Often implemented as an array, where the children of the element at index i are at index - * 2i+1 (left child) and 2i+2 (right child). - *

- * The first element (minimum or maximum, depending on chosen order) can be found in O(1). - * Each successor can be found in O(log n). The algorithm in minHeapify() takes O(log n) time - * Therefore, buildMinHeap() would take O(n log n) time BUT IF OBSERVED CAREFULLY IT TAKES 0(N) TIME. - *

- * Used in the HeapSort algorithm. Also can be used to implement a PriorityQueue. - * Learn more - * - * @author rampatra - * @since 8/2/15 - */ -public class MinHeap { - - private int[] heap; - private int size; - - public MinHeap(int[] heap) { - this.size = heap.length; - this.heap = Arrays.copyOf(heap, size); - } - - /** - * Makes the array {@param a} satisfy the min heap property starting from - * {@param index} till the end of array. - *

- * Time complexity: O(log n). - * - * @param index - */ - public void minHeapify(int index) { - int minIndex = index; - int leftIndex = 2 * index + 1; - int rightIndex = 2 * index + 2; - - if (leftIndex < size && heap[index] > heap[leftIndex]) { - minIndex = leftIndex; - } - if (rightIndex < size && heap[minIndex] > heap[rightIndex]) { - minIndex = rightIndex; - } - - if (minIndex != index) { - swap(index, minIndex); - minHeapify(minIndex); - } - } - - /** - * Converts array {@param a} in to a min heap. - *

- * Time complexity: O(n) and is not O(n log n). - */ - public void buildMinHeap() { - for (int i = size / 2 - 1; i >= 0; i--) { - minHeapify(i); - } - } - - public void insert(int elem) { - heap = Arrays.copyOf(heap, size + 1); - int i = size; - int parentIndex = (int) Math.floor((i - 1) / 2); - while (i > 0 && elem < heap[parentIndex]) { - heap[i] = heap[parentIndex]; - i = parentIndex; - parentIndex = (int) Math.floor((i - 1) / 2); - } - heap[i] = elem; - size++; - } - - public int findMin() { - if (size == 0) { - return -1; - } else { - return heap[0]; - } - } - - public int extractMin() { - if (size == 0) return -1; - - int min = heap[0]; - heap[0] = heap[size - 1]; - size--; - minHeapify(0); - return min; - } - - public int getSize() { - return size; - } - - public int[] getHeap() { - return heap; - } - - public void printHeap() { - if (heap == null) - System.out.print("null"); - int iMax = size - 1, i; - if (iMax == -1) - System.out.print("[]"); - - StringBuilder b = new StringBuilder(); - b.append('['); - for (i = 0; i < iMax; i++) { - b.append(heap[i]); - b.append(", "); - } - System.out.println(b.append(heap[i]).append(']').toString()); - } - - private void swap(int firstIndex, int secondIndex) { - int temp = heap[firstIndex]; - heap[firstIndex] = heap[secondIndex]; - heap[secondIndex] = temp; - } - - // test cases - public static void main(String[] args) { - int[] a = new int[]{2, 4, 5, 1, 6, 7, 8}; - MinHeap minHeap = new MinHeap(a); - minHeap.printHeap(); - minHeap.buildMinHeap(); - minHeap.printHeap(); - minHeap.extractMin(); - minHeap.printHeap(); - minHeap.insert(0); - minHeap.printHeap(); - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/base/Queue.java b/src/main/java/com/rampatra/base/Queue.java deleted file mode 100644 index 660fcb90..00000000 --- a/src/main/java/com/rampatra/base/Queue.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.rampatra.base; - -/** - * A generic interface for a queue. - * - * @author rampatra - * @since 4/12/15 - */ -public interface Queue { - - - /** - * Inserts the specified element into this queue. - * - * @param item - * @return - */ - public E add(E item); - - - /** - * Retrieves and removes the head of this queue. This method throws an - * exception if this queue is empty. - * - * @return - */ - public E remove(); - - - /** - * Retrieves, but does not remove, the head of this queue. This method throws an - * exception if this queue is empty. - * - * @return - */ - public E element(); - - - /** - * Returns the size of this queue. - * - * @return - */ - public int size(); - - - /** - * Tests whether the queue is empty or not. - * - * @return - */ - public boolean isEmpty(); - - - /** - * Prints the content of the queue. - */ - public void print(); - - -} diff --git a/src/main/java/com/rampatra/base/SingleLinkedList.java b/src/main/java/com/rampatra/base/SingleLinkedList.java deleted file mode 100644 index d52484cb..00000000 --- a/src/main/java/com/rampatra/base/SingleLinkedList.java +++ /dev/null @@ -1,277 +0,0 @@ -package com.rampatra.base; - -import java.util.NoSuchElementException; - -import static java.lang.System.out; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/16/15 - * @time: 1:00 PM - */ -public class SingleLinkedList> implements LinkedList { - - public SingleLinkedNode head; - public int size; - - @Override - public boolean add(E item) { - SingleLinkedNode newNode = new SingleLinkedNode<>(item, null); - if (head == null) { // list empty - head = newNode; - } else { // add to the end of list - SingleLinkedNode curr = head; - while (curr.next != null) { - curr = curr.next; - } - curr.next = newNode; - } - size++; - return true; - } - - @Override - public boolean add(int index, E item) { - isPositionIndex(index); - - if (index == 0) { // add at first - addFirst(item); - } else { // add at any other location - SingleLinkedNode nodeAtPrevIndex = getPredecessorNode(index); - SingleLinkedNode newNode = new SingleLinkedNode<>(item, nodeAtPrevIndex.next); - nodeAtPrevIndex.next = newNode; - size++; - } - return true; - } - - @Override - public void addFirst(E item) { - SingleLinkedNode newNode = new SingleLinkedNode<>(item, head); - head = newNode; - size++; - } - - @Override - public void addLast(E item) { - add(item); - } - - @Override - public void clear() { - // Clearing all of the links between nodes is "unnecessary", but: - // - helps a generational GC if the discarded nodes inhabit - // more than one generation - // - is sure to free memory even if there is a reachable Iterator - for (SingleLinkedNode node = head; node != null; ) { - SingleLinkedNode next = node.next; - node.item = null; - node.next = null; - node = next; - } - head = null; - size = 0; - } - - @Override - public LinkedList clone() { - return null; - } - - @Override - public boolean contains(E item) { - return getNode(item) != null; - } - - @Override - public E get(int index) { - return getNode(index).item; - } - - @Override - public E getFirst() { - isLinkedListEmpty(); - return head.item; - } - - @Override - public E getLast() { - return getNode(size - 1).item; - } - - @Override - public E remove() { - isLinkedListEmpty(); - - E item = head.item; - head = head.next; - size--; - return item; - } - - @Override - public E remove(int index) { - isLinkedListEmpty(); - - SingleLinkedNode prevNode = getPredecessorNode(index); - SingleLinkedNode delNode; - if (prevNode == null) { // index = 0 - delNode = head; - head = head.next; - size--; - return delNode.item; - } else { - delNode = prevNode.next; - prevNode.next = delNode.next; - size--; - return delNode.item; - } - } - - @Override - public boolean removeItem(E item) { - isLinkedListEmpty(); - - if (!contains(item)) return false; - - SingleLinkedNode prevNode = getPredecessorNode(item); - if (prevNode == null) { // index = 0 - head = head.next; - size--; - } else { - prevNode.next = prevNode.next.next; - size--; - } - return true; - } - - @Override - public E set(int index, E item) { - SingleLinkedNode node = getNode(index); - node.item = item; - return node.item; - } - - @Override - public int size() { - return size; - } - - @Override - public void printList() { - printList(head); - } - - public static > void printList(SingleLinkedNode node) { - SingleLinkedNode curr = node; - out.print("["); - if (curr == null) { - out.println("]"); - return; - } - while (curr.next != null) { - out.print(curr.item.toString() + ","); - curr = curr.next; - } - out.println(curr.item.toString() + "]"); - } - - public static > SingleLinkedList getLinkedList(SingleLinkedNode node) { - SingleLinkedList linkedList = new SingleLinkedList<>(); - // set head - linkedList.head = node; - // set size - SingleLinkedNode curr = node; - while (curr != null) { - linkedList.size++; - curr = curr.next; - } - return linkedList; - } - - private SingleLinkedNode getPredecessorNode(int index) { - return index > 0 ? getNode(index - 1) : null; - } - - private SingleLinkedNode getPredecessorNode(E item) { - SingleLinkedNode prev = null; - SingleLinkedNode curr = head; - if (item == null) { - while (curr != null) { - if (curr.item == item) { // when item is null, use == rather than equals() - return prev; - } - prev = curr; - curr = curr.next; - } - } else { - while (curr != null) { - if (curr.item.equals(item)) { - return prev; - } - prev = curr; - curr = curr.next; - } - } - return null; - } - - public SingleLinkedNode getNode(int index) { - isElementIndex(index); - - SingleLinkedNode curr = head; - int i = 0; - while (i < index) { - curr = curr.next; - i++; - } - return curr; - } - - public SingleLinkedNode getNode(E item) { - SingleLinkedNode curr = head; - if (item == null) { - while (curr != null) { // when item is null, use == rather than equals() - if (curr.item == item) { - return curr; - } - curr = curr.next; - } - } else { - while (curr != null) { - if (curr.item.equals(item)) { - return curr; - } - curr = curr.next; - } - } - return null; - } - - private void isLinkedListEmpty() { - if (head == null) { - throw new NoSuchElementException("LinkedList empty"); - } - } - - /** - * Tells if the argument is the index of an existing element. - */ - private void isElementIndex(int index) { - if (index < 0 || index >= size) { - throw new IndexOutOfBoundsException("Index [" + index + "] must be less than size [" + size + "]"); - } - } - - /** - * Tells if the argument is the index of a valid position for an - * iterator or an add operation. - */ - private void isPositionIndex(int index) { - if (index < 0 || index > size) { - throw new IndexOutOfBoundsException("Index [" + index + "] must be less than or equal to size [" + size + "]"); - } - } -} diff --git a/src/main/java/com/rampatra/base/SingleLinkedNode.java b/src/main/java/com/rampatra/base/SingleLinkedNode.java deleted file mode 100644 index 97cd9a05..00000000 --- a/src/main/java/com/rampatra/base/SingleLinkedNode.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.rampatra.base; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/18/15 - * @time: 2:37 PM - */ -public class SingleLinkedNode> { - - public E item; - public SingleLinkedNode next; - - public SingleLinkedNode(E item) { - this(item, null); - } - - public SingleLinkedNode(E item, SingleLinkedNode next) { - this.item = item; - this.next = next; - } - -} diff --git a/src/main/java/com/rampatra/base/Stack.java b/src/main/java/com/rampatra/base/Stack.java deleted file mode 100644 index 3761052a..00000000 --- a/src/main/java/com/rampatra/base/Stack.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.rampatra.base; - -/** - * A generic interface for a stack. - * - * @author rampatra - * @since 4/3/15 - */ -public interface Stack { - /** - * Pushes an item onto the top of this stack. - * - * @param item - */ - public E push(E item); - - /** - * Removes the object at the top of this stack and returns it. - * This method throws an exception if this queue is empty. - * - * @return - */ - public E pop(); - - /** - * Looks at the object at the top of this stack without - * removing it from the stack. This method throws an - * exception if this queue is empty. - * - * @return - */ - public E peek(); - - /** - * Returns the number of items currently in the stack. - * - * @return - */ - public int size(); - - /** - * Tests if this stack is empty. - * - * @return - */ - public boolean isEmpty(); - - /** - * Prints the content of the stack. - */ - public void print(); -} diff --git a/src/main/java/com/rampatra/base/Tree.java b/src/main/java/com/rampatra/base/Tree.java deleted file mode 100644 index 56c8b338..00000000 --- a/src/main/java/com/rampatra/base/Tree.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.rampatra.base; - -/** - * Created by IntelliJ IDEA. - * User: rampatra - * Date: 4/19/15 - * Time: 6:30 PM - * To change this template go to Preferences | IDE Settings | File and Code Templates - */ -public class Tree> { - -} diff --git a/src/main/java/com/rampatra/base/Trie.java b/src/main/java/com/rampatra/base/Trie.java deleted file mode 100644 index 65cb7cbb..00000000 --- a/src/main/java/com/rampatra/base/Trie.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.rampatra.base; - -import java.util.HashMap; - -/** - * Trie also called digital tree and sometimes radix tree or prefix tree (as they can be - * searched by prefixes), is an ordered tree data structure that is used to store a dynamic - * set or associative array where the keys are usually strings. - *

- * You can think it as HashMap of HashMap of HashMap and so on. Each key in the HashMap is a - * single digit/letter of the data you want to store and {@code data} is the final full word - * you want to save in trie. - *

- * Some resources: - * Trie Data Structure - * More about Tries - * Video explanation from Gayle McDowell - * - * @author rampatra - * @since 9/22/15 - */ -public class Trie { - - private class TrieNode { - char ch; - HashMap> children = new HashMap<>(); - boolean isCompleteWord; // to mark a complete word in the tri data structure - - TrieNode(char ch) { - this.ch = ch; - } - } - - private TrieNode root; - - Trie() { - root = new TrieNode<>('0'); - } - - /** - * Inserts {@code data} in trie. - * - * @param str - */ - public void insert(String str) { - char c; - TrieNode curr = root; - - for (int i = 0; i < str.length(); i++) { - c = str.charAt(i); - curr.children.putIfAbsent(c, new TrieNode<>(c)); - curr = curr.children.get(c); - } - - curr.isCompleteWord = true; - } - - /** - * Searches {@code data} in trie. - * - * @param str the value to search. - * @return {@code true} if {@code str} is present, {@code false} otherwise. - */ - public boolean search(String str) { - - TrieNode curr = root; - - for (int i = 0; i < str.length(); i++) { - if (curr.children.get(str.charAt(i)) == null) { - return false; - } - curr = curr.children.get(str.charAt(i)); - } - - return curr.isCompleteWord; - } - - // unit testing - public static void main(String[] args) { - Trie trie = new Trie(); - trie.insert("ram"); - trie.insert("r"); - trie.insert("rama"); - trie.insert("rampatra"); - System.out.println(trie.search("ram")); - System.out.println(trie.search("r")); - System.out.println(trie.search("ra")); - System.out.println(trie.search("raz")); - System.out.println(trie.search("rampatra")); - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/base/UndirectedGraph.java b/src/main/java/com/rampatra/base/UndirectedGraph.java deleted file mode 100644 index 661fa45a..00000000 --- a/src/main/java/com/rampatra/base/UndirectedGraph.java +++ /dev/null @@ -1,166 +0,0 @@ -package com.rampatra.base; - -import java.util.ArrayDeque; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Queue; -import java.util.Set; -import java.util.stream.Collectors; - -/** - * @author rampatra - * @since 2019-02-14 - */ -public class UndirectedGraph> extends Graph { - // map for a fast lookup - private Map> nodes = new HashMap<>(); - - /** - * Adds an edge between a node with value {@code value} and another node with value {@code adjacentValue}. As the - * graph is undirected, the edges are added in both the nodes. If nodes with respective values are not present in - * the graph then this method creates the nodes. - * - * @param value refers to the value for first node - * @param adjacentValue refers to the value for the second node - * @return the node with value {@code value}, or the first node - */ - public GraphNode addEdge(E value, E adjacentValue) { - GraphNode node = nodes.get(value); - GraphNode adjNode = nodes.get(adjacentValue); - if (node == null && value != null) { - node = new GraphNode<>(value); - nodes.put(value, node); - } - if (adjNode == null && adjacentValue != null) { - adjNode = new GraphNode<>(adjacentValue); - nodes.put(adjacentValue, adjNode); - } - if (node != null && adjNode != null) { - node.adjacentNodes.add(adjNode); - adjNode.adjacentNodes.add(node); // as this is an undirected graph - } - return node; - } - - /** - * Method to check whether {@code src} and {@code dest} nodes are connected by depth first search (DFS). - * - * @param src source node in graph - * @param dest destination node in graph - * @return {@code true} if there is a path from {@code src} to {@code dest}, {@code false} otherwise - */ - public boolean hasPathDFS(E src, E dest) { - GraphNode s = nodes.get(src); - GraphNode d = nodes.get(dest); - Set> visited = new HashSet<>(); // to save all visited nodes so that we do not visit them again - return hasPathDFS(s, d, visited); - } - - private boolean hasPathDFS(GraphNode src, GraphNode dest, Set> visited) { - if (src == null || dest == null) { - return false; - } - if (src.value.compareTo(dest.value) == 0) { - return true; - } else if (!visited.contains(src)) { - visited.add(src); - for (GraphNode node : src.adjacentNodes) { - if (hasPathDFS(node, dest, visited)) { - return true; - } - } - } - return false; - } - - /** - * Method to check whether {@code src} and {@code dest} nodes are connected by breadth first search (BFS). - * - * @param src source node in graph - * @param dest destination node in graph - * @return {@code true} if there is a path from {@code src} to {@code dest}, {@code false} otherwise - */ - public boolean hasPathBFS(E src, E dest) { - GraphNode s = nodes.get(src); - GraphNode d = nodes.get(dest); - if (s == null || d == null) { - return false; - } - Set> visited = new HashSet<>(); - Queue> toVisit = new ArrayDeque<>(); - toVisit.add(s); - return hasPathBFS(d, visited, toVisit); - } - - private boolean hasPathBFS(GraphNode dest, Set> visited, Queue> toVisit) { - while (!toVisit.isEmpty()) { - GraphNode node = toVisit.poll(); - if (visited.contains(node)) { - continue; - } else { - visited.add(node); - } - toVisit.addAll(node.adjacentNodes.stream().filter(n -> !visited.contains(n)).collect(Collectors.toList())); - if (node.value.compareTo(dest.value) == 0) { - return true; - } - } - return false; - } - - - /** - * Prints the node values in the graph. - */ - public void print() { - Set visited = new HashSet<>(); - System.out.print("["); - Iterator iterator = nodes.keySet().iterator(); - while (iterator.hasNext()) { - E node = iterator.next(); - if (!visited.contains(node)) { - visited.add(node); - System.out.print(node); - if (iterator.hasNext()) { - System.out.print(", "); - } - } - } - System.out.println("]"); - } - - public static void main(String[] args) { - UndirectedGraph graph = new UndirectedGraph<>(); - graph.addEdge(1, 4); - graph.addEdge(4, 5); - graph.addEdge(4, 6); - graph.addEdge(4, 7); - graph.addEdge(5, 1); - graph.addEdge(5, 6); - graph.addEdge(8, null); - graph.addEdge(null, 9); - graph.print(); - - System.out.println("----"); - - // has path DFS - System.out.println(graph.hasPathDFS(1, 5)); - System.out.println(graph.hasPathDFS(1, 6)); - System.out.println(graph.hasPathDFS(1, 8)); - System.out.println(graph.hasPathDFS(4, 8)); - System.out.println(graph.hasPathDFS(4, 9)); - System.out.println(graph.hasPathDFS(4, 100)); - - System.out.println("----"); - - // has path BFS - System.out.println(graph.hasPathBFS(1, 5)); - System.out.println(graph.hasPathBFS(1, 6)); - System.out.println(graph.hasPathBFS(1, 8)); - System.out.println(graph.hasPathBFS(4, 8)); - System.out.println(graph.hasPathBFS(4, 9)); - System.out.println(graph.hasPathBFS(4, 100)); - } -} diff --git a/src/main/java/com/rampatra/bits/AbsWithoutBranching.java b/src/main/java/com/rampatra/bits/AbsWithoutBranching.java deleted file mode 100644 index 53973b6a..00000000 --- a/src/main/java/com/rampatra/bits/AbsWithoutBranching.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.rampatra.bits; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/9/15 - * @time: 12:26 PM - */ -public class AbsWithoutBranching { - - /** - * Returns the absolute value of any integer. - *

- * EXPLANATION: - * For example, consider int takes 4 bits: - * So for input = -5, we have - * -5 = 1011 - * mask = 1111 - * mask + n = 1010 - * (mask + n)^mask = 0101 (which is 5) - * - * @param n - * @return - */ - public static int abs(int n) { - int mask = n >> 31; - return (mask + n) ^ mask; - } - - public static void main(String[] args) { - System.out.println(abs(-5)); - System.out.println(abs(5)); - System.out.println(abs(0)); - System.out.println(abs(-0)); - } -} diff --git a/src/main/java/com/rampatra/bits/Addition.java b/src/main/java/com/rampatra/bits/Addition.java deleted file mode 100644 index c120ecaa..00000000 --- a/src/main/java/com/rampatra/bits/Addition.java +++ /dev/null @@ -1,130 +0,0 @@ -package com.rampatra.bits; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/10/15 - * @time: 12:55 PM - */ -public class Addition { - - /** - * Best method. - *

- * -n = ~n + 1. - * ~n = -(n+1). Therefore, n+1 = -(~n). - *

- * Works for -ve numbers. - *

- * Note: This method works only if the numbers - * are stored in 2’s complement form. - * - * @param n - * @return - */ - public static int add(int n) { - return -(~n); - } - - /** - * Good solution. - *

- * Adds two numbers without using any - * arithmetic operators. - * - * @param x - * @param y - * @return sum of {@param x} and {@param y} - */ - public static int add(int x, int y) { - int carry; - while (y != 0) { - carry = x & y; - x = x ^ y; - y = carry << 1; - } - return x; - } - - /** - * Naive approach. - *

- * Adds two numbers without using any - * arithmetic operators. - * - * @param x - * @param y - * @return sum of {@param x} and {@param y} - */ - public static int addNaive(int x, int y) { - int carry = 0, sum = 0, c = 0, xLSB, yLSB; - while (c < 32) { - xLSB = x & 1; - yLSB = y & 1; - sum |= (xLSB ^ yLSB ^ carry) << c; - if ((xLSB & yLSB) == 1 || (xLSB & carry) == 1 || (yLSB & carry) == 1) { - carry = 1; - } else { - carry = 0; - } - x >>= 1; - y >>= 1; - c++; - } - return sum; - } - - /** - * Idea is to flip all the bits of {@param n} till - * rightmost 0 bit (inclusive). - *

- * Doesn't work for -ve numbers. - * - * @param n - * @return - */ - public static int addByFlip(int n) { - int mask = 1; - // flip all bits in n until rightmost 0 bit - while ((n & mask) != 0) { - n ^= mask; - mask <<= 1; - } - // flip the rightmost 0 bit - return n ^ mask; - } - - public static void main(String[] args) { - System.out.println(add(0, 0)); //0 - System.out.println(add(12, 12)); //24 - System.out.println(add(12, 5)); //17 - System.out.println(add(3, 5)); //8 - System.out.println(add(8, 5)); //13 - System.out.println(add(13, 256)); // 269 - System.out.println(add(456, 982348234)); // 982348690 - System.out.println(add(1, 0xffffffff)); // 0 - System.out.println("------"); - System.out.println(addNaive(0, 0)); //0 - System.out.println(addNaive(12, 12)); //24 - System.out.println(addNaive(12, 5)); //17 - System.out.println(addNaive(3, 5)); //8 - System.out.println(addNaive(8, 5)); //13 - System.out.println(addNaive(13, 256)); // 269 - System.out.println(addNaive(456, 982348234)); // 982348690 - System.out.println(addNaive(1, 0xffffffff)); // 0 - System.out.println("------"); - System.out.println(addByFlip(0)); - System.out.println(addByFlip(1)); - System.out.println(addByFlip(2)); - System.out.println(addByFlip(3)); - System.out.println(addByFlip(4)); - System.out.println(addByFlip(5)); - System.out.println(addByFlip(7)); - System.out.println("------"); - System.out.println(add(1)); - System.out.println(add(5)); - System.out.println(add(-0)); - System.out.println(add(-5)); - } -} diff --git a/src/main/java/com/rampatra/bits/BinaryGap.java b/src/main/java/com/rampatra/bits/BinaryGap.java deleted file mode 100644 index a89c1a29..00000000 --- a/src/main/java/com/rampatra/bits/BinaryGap.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.rampatra.bits; - -/** - * Created by rampatra on 30/05/2016. - */ -public class BinaryGap { - - /** - * A binary gap of a positive integer N is any maximal - * sequence of consecutive zeros that is surrounded by ones - * at both ends in the binary representation of N. - * - * @param n - * @return - */ - public static int findBinaryGap(long n) { - int gap = 0; - int maxGap = 0; - while (n > 0) { - if ((n & 1) == 1) { - while (n >>> 1 > 0 && (n >>> 1 & 1) == 0) { - gap++; - n = n >>> 1; - } - if (gap > maxGap) { - maxGap = gap; - } - gap = 0; - } - n = n >>> 1; - } - - return maxGap; - } - - public static int findMaxNoOf0sBetweenTwo1s(long n) { - return findBinaryGap(n); - } - - public static void main(String[] args) { - System.out.println(findBinaryGap(2)); - System.out.println(findBinaryGap(8)); - System.out.println(findBinaryGap(9)); - System.out.println(findBinaryGap(16)); - System.out.println(findBinaryGap(17)); - System.out.println(findMaxNoOf0sBetweenTwo1s(121)); - System.out.println(findMaxNoOf0sBetweenTwo1s(1041)); - System.out.println(findMaxNoOf0sBetweenTwo1s(2_147_483_64889L)); - } -} diff --git a/src/main/java/com/rampatra/bits/BinaryString.java b/src/main/java/com/rampatra/bits/BinaryString.java deleted file mode 100644 index ad0ffb84..00000000 --- a/src/main/java/com/rampatra/bits/BinaryString.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.rampatra.bits; - -/** - * @author rampatra - * @since 2019-03-21 - */ -public class BinaryString { - - /** - * Returns the binary representation of a {@code byte}. - * - * @param b a byte. - * @return the binary representation of the input byte. - */ - private static String toBinaryString(byte b) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < Byte.SIZE; i++) { - sb.append(b & (byte) 1); - b >>= 1; - } - return sb.reverse().toString(); - } - - public static void main(String[] args) { - System.out.println(toBinaryString((byte) 0xff)); - System.out.println(toBinaryString((byte) (0xff >> 3))); - } -} diff --git a/src/main/java/com/rampatra/bits/BooleanArrayPuzzle.java b/src/main/java/com/rampatra/bits/BooleanArrayPuzzle.java deleted file mode 100644 index d3d87feb..00000000 --- a/src/main/java/com/rampatra/bits/BooleanArrayPuzzle.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.rampatra.bits; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/12/15 - * @time: 3:31 PM - */ -public class BooleanArrayPuzzle { - - /** - * Change 1 to 0 in an array of length 2 containing - * one 0 and the other either 1 or 0. - * - * @param a - * @return - */ - public static int[] change1To0InArray(int a[]) { - a[a[1]] = a[a[0]]; - return a; - } - - public static void main(String[] args) { - System.out.println(Arrays.toString(change1To0InArray(new int[]{0, 0}))); - System.out.println(Arrays.toString(change1To0InArray(new int[]{0, 1}))); - System.out.println(Arrays.toString(change1To0InArray(new int[]{1, 0}))); - } -} diff --git a/src/main/java/com/rampatra/bits/ConvertAToB.java b/src/main/java/com/rampatra/bits/ConvertAToB.java deleted file mode 100644 index 07c162b8..00000000 --- a/src/main/java/com/rampatra/bits/ConvertAToB.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.rampatra.bits; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/7/15 - * @time: 1:53 PM - */ -public class ConvertAToB { - - /** - * Returns the number of bits required to be - * flipped to convert {@param a} to {@param b}. - * - * @param a - * @param b - * @return - */ - public static int getBitsToConvertAToB(int a, int b) { - return CountSetBits.countSetBits(a ^ b); - } - - public static void main(String[] args) { - System.out.println(getBitsToConvertAToB(3, 4)); - System.out.println(getBitsToConvertAToB(3, 5)); - System.out.println(getBitsToConvertAToB(5, 3)); - } -} diff --git a/src/main/java/com/rampatra/bits/CountSetBits.java b/src/main/java/com/rampatra/bits/CountSetBits.java deleted file mode 100644 index a2296e6e..00000000 --- a/src/main/java/com/rampatra/bits/CountSetBits.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.rampatra.bits; - -import java.util.Scanner; - -/** - * Created by IntelliJ IDEA. - * User: rampatra - * Date: 4/4/15 - * Time: 8:52 PM - * To change this template go to Preferences | IDE Settings | File and Code Templates - */ -public class CountSetBits { - - /** - * Unoptimized version. Works for -ve numbers as well. - * - * @param number - * @return - */ - static int countSetBits(int number) { - int count = 0; - for (int i = 0; i < 32; i++) { - if ((number & 1) == 1) { - count++; - } - number = number >>> 1; - } - return count; - } - - /** - * Optimized version. Works for -ve numbers as well. - *

- * Uses BRIAN KERNIGAN'S bit counting. Acc. to this, the right most/least significant set bit is unset - * in each iteration. The time complexity is proportional to the number of bits set. - * - * @param n - * @return - * @link http://stackoverflow.com/questions/12380478/bits-counting-algorithm-brian-kernighan-in-an-integer-time-complexity - * @link http://graphics.stanford.edu/~seander/bithacks.html#ParityNaive - */ - static int countSetBits(long n) { - int count = 0; - while (n != 0) { - n &= n - 1; // right most set bit in n is unset - count++; - } - return count; - } - - public static void main(String[] args) { - Scanner in = new Scanner(System.in); - - long n = Long.parseLong(in.nextLine()); - System.out.println(countSetBits(n)); - System.out.println(Integer.toBinaryString((int) -n)); - System.out.println(countSetBits((int) -n)); - - - } -} - -/** - * Learn more: - * http://javarevisited.blogspot.in/2014/06/how-to-count-number-of-set-bits-or-1s.html - */ \ No newline at end of file diff --git a/src/main/java/com/rampatra/bits/CountSetBitsFromMinusNtoN.java b/src/main/java/com/rampatra/bits/CountSetBitsFromMinusNtoN.java deleted file mode 100644 index a0aeb5e0..00000000 --- a/src/main/java/com/rampatra/bits/CountSetBitsFromMinusNtoN.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.rampatra.bits; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/22/15 - * @time: 12:42 PM - */ -public class CountSetBitsFromMinusNtoN { - - /** - * Explanation: - *

- * -3: 101 - * -2: 110 - * -1: 111 - * 0: 000 - * 1: 001 - * 2: 010 - * 3: 110 - *

- * If you fold the above representation between -1 and 0, the total no. of set bits from -3 to 2 - * will be equal to the total no. of bits in nos. from -3 to 2. - * - * @param n - * @return - */ - public static int countSetBitsFromMinusNtoN(int n) { - return n * 32 + CountSetBits.countSetBits((long) n); // 32 because int is of 32 bits in java - } - - public static void main(String[] args) { - System.out.println(countSetBitsFromMinusNtoN(3)); - System.out.println(countSetBitsFromMinusNtoN(0)); - System.out.println(countSetBitsFromMinusNtoN(9)); - } -} diff --git a/src/main/java/com/rampatra/bits/ElementOccurringOnce.java b/src/main/java/com/rampatra/bits/ElementOccurringOnce.java deleted file mode 100644 index 4621209c..00000000 --- a/src/main/java/com/rampatra/bits/ElementOccurringOnce.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.rampatra.bits; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/14/15 - * @time: 12:37 AM - */ -public class ElementOccurringOnce { - - /** - * Returns the element occurring once in {@param a} having - * other elements repeating thrice. - * - * @param a - * @return - */ - public static int getElementOccurringOnceInElementsRepeatedThreeTimes(int a[]) { - int result = 0; - for (int i = 0; i < 32; i++) { - int sum = 0; - // sum of all bits at ith position for all elements in a[] - for (int j = 0; j < a.length; j++) { - sum += (a[j] >>> i) & 1; - } - // bit will be set in result if sum mod 3 isn't 0 - result |= (sum % 3) << i; - } - return result; - } - - public static void main(String[] args) { - System.out.println(getElementOccurringOnceInElementsRepeatedThreeTimes(new int[]{12, 12, 6, 6, 2, 12, 6})); - System.out.println(getElementOccurringOnceInElementsRepeatedThreeTimes(new int[]{5, 5, 45, 45, 456, 5, 45})); - System.out.println(getElementOccurringOnceInElementsRepeatedThreeTimes(new int[]{12, 12, 34, 34, 6, 12, 34})); - } -} - -/** - * EXPLANATION: - * 12 = 1100 - * 12 = 1100 - * 6 = 0110 - * 6 = 0110 - * 2 = 0010 - * 12 = 1100 - * 6 = 0110 - * ------------- - * res = 0010 - *

- * 1st bit of res = (0+0+0+0+0+0+0) % 3 = 0 - * 2nd bit of res = (0+0+1+1+1+0+1) % 3 = 1 - * 3rd bit of res = (1+1+1+1+0+1+1) % 3 = 0 - * 4th bit of res = (1+1+0+0+0+1+0) % 3 = 0 - *

- * NOTE: Sum of bits at a particular position will not be divisible - * by 3 if the no. occurring once has a set bit at that position. - */ diff --git a/src/main/java/com/rampatra/bits/FlippingBits.java b/src/main/java/com/rampatra/bits/FlippingBits.java deleted file mode 100644 index 48c891ad..00000000 --- a/src/main/java/com/rampatra/bits/FlippingBits.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.rampatra.bits; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/5/15 - * @time: 3:50 PM - */ -public class FlippingBits { - - /** - * Returns the number by flipping/inverting its bits using - * XOR operation with 1......11 (size of int i.e, 32 1's). - * - * @param n - * @return - */ - public static int getNumberByFlippingBits(int n) { - return n ^ 0xffffffff; // equivalent to 11....1 (32 times) in binary - } - - /** - * Returns the number by flipping/inverting its bits using - * the NOT operator. - * - * @param n - * @return - */ - public static int getNumberByFlippingBits_V1(int n) { - return ~n; - } - - public static void main(String[] args) { - System.out.println(getNumberByFlippingBits(5)); - System.out.println(getNumberByFlippingBits_V1(5)); - } -} - -/** - * EXPLANATION: - *

- * For input: 5 - *

- * Binary: 000.....101 - * Inverted: 111.....010 (which is the 2's compliment of -6) - *

- * Therefore, result is -6. - */ diff --git a/src/main/java/com/rampatra/bits/IntegerOverflow.java b/src/main/java/com/rampatra/bits/IntegerOverflow.java deleted file mode 100644 index 6d214ac8..00000000 --- a/src/main/java/com/rampatra/bits/IntegerOverflow.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.rampatra.bits; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/4/15 - * @time: 4:28 PM - */ -public class IntegerOverflow { - - /** - * Adds {@param a} and {@param b} and if the result can't - * be stored as an integer it throws an exception - * - * @param a - * @param b - * @return - */ - public static int add(int a, int b) throws Exception { - - if (a > Integer.MAX_VALUE - b) { - throw new Exception("Integer Overflow"); - } else { - return a + b; - } - } - - /** - * Adds {@param a} and {@param b} and if the result can't - * be stored as an integer it throws an exception - * - * @param a - * @param b - * @return - */ - public static int add_V1(int a, int b) throws Exception { - - if ((a > 0 && b > 0 && a + b < 0) || (a < 0 && b < 0 && a + b > 0)) { - throw new Exception("Integer Overflow"); - } else { - return a + b; - } - } - - public static void main(String[] args) { - try { - System.out.println(add(2, 3)); - System.out.println(add(2147483647, 999999999)); - System.out.println(add(-2147483647, -999999999)); - System.out.println(add_V1(2, 3)); - System.out.println(add_V1(2147483647, 999999999)); - System.out.println(add_V1(-2147483647, -999999999)); - } catch (Exception e) { - e.printStackTrace(); - } - } -} diff --git a/src/main/java/com/rampatra/bits/LittleAndBigEndian.java b/src/main/java/com/rampatra/bits/LittleAndBigEndian.java deleted file mode 100644 index 86ca46e9..00000000 --- a/src/main/java/com/rampatra/bits/LittleAndBigEndian.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.rampatra.bits; - -import java.nio.ByteOrder; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/5/15 - * @time: 3:10 PM - * @link http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/Data/endian.html - */ -public class LittleAndBigEndian { - - public static boolean isLittleEndian() { - return ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN); - } - - public static void main(String[] args) { - System.out.println(isLittleEndian()); - } -} diff --git a/src/main/java/com/rampatra/bits/MaxWithoutBranching.java b/src/main/java/com/rampatra/bits/MaxWithoutBranching.java deleted file mode 100644 index f2669829..00000000 --- a/src/main/java/com/rampatra/bits/MaxWithoutBranching.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.rampatra.bits; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/8/15 - * @time: 5:41 PM - * @link: http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax - */ -public class MaxWithoutBranching { - - public static int getMinWithoutBranching(int a, int b) { - return b ^ ((a ^ b) & -((a < b) ? 1 : 0)); - } - - public static int getMaxWithoutBranching(int a, int b) { - return a ^ ((a ^ b) & -((a < b) ? 1 : 0)); - } - - public static void main(String[] args) { - System.out.println(getMinWithoutBranching(5, 6)); - System.out.println(getMinWithoutBranching(-5, -6)); - System.out.println(getMinWithoutBranching(-5, 6)); - System.out.println(getMinWithoutBranching(5, -6)); - System.out.println(getMinWithoutBranching(0, 0)); - - System.out.println(getMaxWithoutBranching(5, 6)); - System.out.println(getMaxWithoutBranching(-5, -6)); - System.out.println(getMaxWithoutBranching(-5, 6)); - System.out.println(getMaxWithoutBranching(5, -6)); - System.out.println(getMaxWithoutBranching(0, 0)); - } -} - -/** - * EXPLANATION: - * On some rare machines where branching is very expensive and no condition move - * instructions exist, the above expression might be faster than the obvious - * approach, r = (x < y) ? x : y, even though it involves two more instructions. - * (Typically, the obvious approach is best, though.) It works because if x < y, - * then -(x < y) will be all ones, so r = y ^ (x ^ y) & ~0 = y ^ x ^ y = x. - * Otherwise, if x >= y, then -(x < y) will be all zeros, so r = y ^ ((x ^ y) & 0) = y. - * On some machines, evaluating (x < y) as 0 or 1 requires a branch instruction, - * so there may be no advantage. - */ diff --git a/src/main/java/com/rampatra/bits/Modulo.java b/src/main/java/com/rampatra/bits/Modulo.java deleted file mode 100644 index d220f3a8..00000000 --- a/src/main/java/com/rampatra/bits/Modulo.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.rampatra.bits; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/8/15 - * @time: 11:28 PM - */ -public class Modulo { - - /** - * Returns {@param n} modulo {@param d} provided - * {@param d} is a power of 2. - * - * @param n - * @param d - * @return - */ - public static int getNmoduloD(int n, int d) { - return n & (d - 1); - } - - public static void main(String[] args) { - System.out.println(getNmoduloD(18, 8)); - System.out.println(getNmoduloD(18, 4)); - System.out.println(getNmoduloD(13, 4)); - System.out.println(getNmoduloD(13, 1)); - System.out.println(getNmoduloD(2, 2)); - System.out.println(getNmoduloD(13, 16)); - } -} - -/** - * Consider example, for 18 % 8 - *

- * 18 = 10010 - * 7 = 00111 (8 = 2 ^ 3, therefore mask has to have three 1's) - * 2 = 00010 (remainder = 18 & (8-1)) - */ diff --git a/src/main/java/com/rampatra/bits/MultipleOf3.java b/src/main/java/com/rampatra/bits/MultipleOf3.java deleted file mode 100644 index 87af5c1d..00000000 --- a/src/main/java/com/rampatra/bits/MultipleOf3.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.rampatra.bits; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/3/15 - * @time: 1:18 PM - */ -public class MultipleOf3 { - - /** - * 1) Get count of all set bits at odd positions (For 23 it’s 3). - * 2) Get count of all set bits at even positions (For 23 it’s 1). - * 3) If difference of above two counts is a multiple of 3 then number is also a multiple of 3. - *

- * NOTE: Binary representation of 23 is 00..10111 - * - * @param n - * @return - */ - public static boolean isMultipleOf3(long n) { - int oddCount = 0, evenCount = 0; - - n = Math.abs(n); - - if (n == 0) return true; - if (n == 1) return false; - - while (n > 0) { - if ((n & 1) == 1) oddCount++; - n >>= 1; - - if ((n & 1) == 1) evenCount++; - n >>= 1; - } - - return isMultipleOf3(oddCount - evenCount); - - } - - public static void main(String[] args) { - System.out.println(isMultipleOf3(0)); - System.out.println(isMultipleOf3(1)); - System.out.println(isMultipleOf3(2)); - System.out.println(isMultipleOf3(3)); - System.out.println(isMultipleOf3(18)); - System.out.println(isMultipleOf3(-18)); // works for -ve numbers as well - System.out.println(isMultipleOf3(-17)); - } -} - -/** - * Old School Method: - *

- * If sum of digits in a number is multiple of 3 then number is multiple of - * 3 e.g., for 612 sum of digits is 9 so it’s a multiple of 3. But this solution - * is not efficient. You have to get all decimal digits one by one, add them and - * then check if sum is multiple of 3. - */ \ No newline at end of file diff --git a/src/main/java/com/rampatra/bits/Multiply.java b/src/main/java/com/rampatra/bits/Multiply.java deleted file mode 100644 index edc2e421..00000000 --- a/src/main/java/com/rampatra/bits/Multiply.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.rampatra.bits; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/3/15 - * @time: 11:35 PM - */ - -/** - * Time Complexity: O(1) - * Space Complexity: O(1) - *

- * Note: Works only for positive integers. - */ -public class Multiply { - - /** - * Multiplies {@param n} with 3.5 and returns only the - * integral part of the number and omits the fractional part. - * - * @param n - * @return - */ - public static long multiplyWith3point5(long n) { - return ((n << 3) - n) >> 1; // (8n-n)/2 = 7n/2 = 3.5n - } - - /** - * Multiplies {@param n} with 3.5 and returns only the - * integral part of the number and omits the fractional part. - * - * @param n - * @return - */ - public static long multiplyWith3point5_V1(long n) { - return (n << 1) + n + (n >> 1); // n*2 + n + n/2 = 7n/2 = 3.5n - } - - /** - * 3 left shifts gives us 8n but we want 7n, so we subtract - * 1n from it. Similarly we can do any multiplication by shifting - * and then adding/subtracting. - * - * @param n - * @return - */ - public static long multiplyWith7(long n) { - return (n << 3) - n; - } - - /** - * Multiplies a number with 8 by performing 3 left shifts. - * - * @param n - * @return - */ - public static long multiplyWith8(long n) { - return (n << 3); - } - - public static void main(String[] args) { - System.out.println(multiplyWith3point5(3)); - System.out.println(multiplyWith3point5(4)); - System.out.println(multiplyWith3point5(6)); - System.out.println(multiplyWith3point5(-7)); - - System.out.println(multiplyWith7(6)); - System.out.println(multiplyWith7(7)); - - System.out.println(multiplyWith8(4)); - System.out.println(multiplyWith8(6)); - System.out.println(multiplyWith8(7)); - } -} diff --git a/src/main/java/com/rampatra/bits/NextHigherNumber.java b/src/main/java/com/rampatra/bits/NextHigherNumber.java deleted file mode 100644 index 444dcf99..00000000 --- a/src/main/java/com/rampatra/bits/NextHigherNumber.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.rampatra.bits; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/10/15 - * @time: 6:08 PM - */ -public class NextHigherNumber { - - /** - * The main logic is to flip the bits in the first '01' bit pattern - * of {@param n} from the right and then push all 1 bits to the right - * of '01' to the extreme right. - *

- *

- * For example, - *

- * 3 (0000011) = 5 (0000101) - * 6 (0000110) = 9 (0001001) - * 23 (0010111) = 27 (0011011) - * 24 (0011000) = 33 (0100001) - * 46 (0101110) = 51 (0110011) - * - * @param n - * @return - */ - public static int getNextHigherNumberWithSameSetBits(int n) { - int leftPattern = 1, rightPattern = 0, count = 0; - - while (n > 0) { - count++; - if (((n & 1) == 1)) { - - rightPattern <<= 1; - rightPattern |= 1; - - if (((n >> 1) & 1) == 0) { - n >>>= 1; - break; - } - } - n >>>= 1; - } - - return (n << count) | (leftPattern << count) | (rightPattern >> 1); - } - - public static void main(String[] args) { - System.out.println(getNextHigherNumberWithSameSetBits(0));//doesn't work for 0 - System.out.println(getNextHigherNumberWithSameSetBits(4));//8 - System.out.println(getNextHigherNumberWithSameSetBits(5));//6 - System.out.println(getNextHigherNumberWithSameSetBits(6));//9 - System.out.println(getNextHigherNumberWithSameSetBits(23));//27 - System.out.println(getNextHigherNumberWithSameSetBits(24));//33 - System.out.println(getNextHigherNumberWithSameSetBits(44));//49 - System.out.println(getNextHigherNumberWithSameSetBits(46));//51 - } -} diff --git a/src/main/java/com/rampatra/bits/NextPowerOf2.java b/src/main/java/com/rampatra/bits/NextPowerOf2.java deleted file mode 100644 index 44c04491..00000000 --- a/src/main/java/com/rampatra/bits/NextPowerOf2.java +++ /dev/null @@ -1,143 +0,0 @@ -package com.rampatra.bits; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/2/15 - * @time: 5:08 PM - */ -public class NextPowerOf2 { - - /** - * Returns a power of 2 number which is larger - * than {@param n} but if {@param n} is already - * a power of 2 then it simply returns it. - *

- * Left shifts 1 number of times equal to the - * leftmost set bit position in n. - * - * @param n - * @return - */ - public static long nextHigherPowerOf2(long n) { - // if n is already a power of 2 then return n - if (n != 0 && ((n & (n - 1)) == 0)) return n; - - long p = 1; - while (p < n) { - p <<= 1; - } - return p; - } - - /** - * Returns a power of 2 number which is larger - * than {@param n} but if {@param n} is already - * a power of 2 then it simply returns it. - *

- * Finds the leftmost set bit position and - * left shifts 1 that many times. - * - * @param n - * @return - */ - public static long nextHigherPowerOf2_V2(long n) { - // if n is already a power of 2 then return n - if (n != 0 && ((n & (n - 1)) == 0)) return n; - - long c = 0; - // finds the position of the leftmost set bit - while (n > 0) { - n >>= 1; - c++; - } - - return 1 << c; - } - - /** - * Returns a power of 2 number which is larger - * than {@param n} but if {@param n} is already - * a power of 2 then it simply returns it. - *

- * Finds the leftmost set bit position and - * left shifts 1 that many times. - * - * @param n - * @return - */ - public static long nextHigherPowerOf2_V1(long n) { - if (PowerOf2.isPowerOf2(n)) { - return n; - } - - int c = 0; - // finds the position of leftmost set bit - for (int i = 1; i <= 64; i++) { - if ((n & 1) == 1) { - c = i; - } - n >>= 1; - } - - return 1 << c; - } - - - /** - * Returns a power of 2 number which is smaller - * than {@param n}. - * - * @param n - * @return - */ - public static long nextLowerPowerOf2(long n) { - long p = 1; - while (p < n) { - p <<= 1; - } - return (n > 1) ? p >> 1 : n; // check for n = 0 or 1; - } - - public static void main(String[] args) { - - System.out.println(nextHigherPowerOf2(2)); - System.out.println(nextHigherPowerOf2(3)); - System.out.println(nextHigherPowerOf2(18)); - System.out.println(nextHigherPowerOf2(6)); - System.out.println(nextHigherPowerOf2(7)); - System.out.println(nextHigherPowerOf2(1)); - System.out.println(nextHigherPowerOf2(0)); - - System.out.println("================="); - - System.out.println(nextHigherPowerOf2_V2(2)); - System.out.println(nextHigherPowerOf2_V2(3)); - System.out.println(nextHigherPowerOf2_V2(18)); - System.out.println(nextHigherPowerOf2_V2(6)); - System.out.println(nextHigherPowerOf2_V2(7)); - System.out.println(nextHigherPowerOf2_V2(1)); - System.out.println(nextHigherPowerOf2_V2(0)); - - System.out.println("================="); - - System.out.println(nextHigherPowerOf2_V1(2)); - System.out.println(nextHigherPowerOf2_V1(3)); - System.out.println(nextHigherPowerOf2_V1(18)); - System.out.println(nextHigherPowerOf2_V1(6)); - System.out.println(nextHigherPowerOf2_V1(7)); - System.out.println(nextHigherPowerOf2_V1(1)); - System.out.println(nextHigherPowerOf2_V1(0)); - - System.out.println("================="); - - System.out.println(nextLowerPowerOf2(2)); - System.out.println(nextLowerPowerOf2(3)); - System.out.println(nextLowerPowerOf2(18)); - System.out.println(nextLowerPowerOf2(6)); - System.out.println(nextLowerPowerOf2(7)); - System.out.println(nextLowerPowerOf2(1)); - System.out.println(nextLowerPowerOf2(0)); - } -} diff --git a/src/main/java/com/rampatra/bits/OppositeSign.java b/src/main/java/com/rampatra/bits/OppositeSign.java deleted file mode 100644 index 919d2137..00000000 --- a/src/main/java/com/rampatra/bits/OppositeSign.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.rampatra.bits; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/14/15 - * @time: 12:24 AM - */ -public class OppositeSign { - - public static int isOppositeSign(int a, int b) { - return (a ^ b) >>> 31; - } - - public static void main(String[] args) { - System.out.println(isOppositeSign(-5, -3)); - System.out.println(isOppositeSign(-5, 3)); - System.out.println(isOppositeSign(5, -3)); - } -} diff --git a/src/main/java/com/rampatra/bits/Parity.java b/src/main/java/com/rampatra/bits/Parity.java deleted file mode 100644 index 673ba5b3..00000000 --- a/src/main/java/com/rampatra/bits/Parity.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.rampatra.bits; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/3/15 - * @time: 3:50 PM - */ - -/** - * PARITY: Parity of a number refers to whether it - * contains an odd or even number of 1-bits. The number - * has “odd parity”, if it contains odd number of 1-bits - * and is “even parity” if it contains even number of 1-bits. - */ -public class Parity { - - /** - * Uses BRIAN KERNIGAN'S bit counting. Acc. to this, the right most/least significant set bit is unset - * in each iteration. The time complexity is proportional to the number of bits set. - *

- * {@see http://stackoverflow.com/questions/12380478/bits-counting-algorithm-brian-kernighan-in-an-integer-time-complexity} - * {@see http://graphics.stanford.edu/~seander/bithacks.html#ParityNaive} - * - * @param n - * @return - */ - public static boolean isEvenParity(long n) { - boolean parity = true; - - while (n > 0) { - parity = !parity; - n = n & (n - 1); - } - return parity; - } - - - /** - * Old school method - * - * @param n - * @return true if {@param n} has even number of 1-bits - */ - public static boolean isEvenParityByCountingSetBits(long n) { - int setBitsCount = 0; - - while (n > 0) { - if ((n & 1) == 1) setBitsCount++; - n >>= 1; - } - - return setBitsCount % 2 == 0; - } - - public static void main(String[] args) { - System.out.println(isEvenParity(0)); - System.out.println(isEvenParity(1)); - System.out.println(isEvenParity(5)); - System.out.println(isEvenParity(6)); - System.out.println(isEvenParity(7)); - System.out.println(isEvenParity(12)); - System.out.println("=========================="); - System.out.println(isEvenParityByCountingSetBits(0)); - System.out.println(isEvenParityByCountingSetBits(1)); - System.out.println(isEvenParityByCountingSetBits(5)); - System.out.println(isEvenParityByCountingSetBits(6)); - System.out.println(isEvenParityByCountingSetBits(7)); - System.out.println(isEvenParityByCountingSetBits(12)); - } -} diff --git a/src/main/java/com/rampatra/bits/PowerOf2.java b/src/main/java/com/rampatra/bits/PowerOf2.java deleted file mode 100644 index 04a1d9dd..00000000 --- a/src/main/java/com/rampatra/bits/PowerOf2.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.rampatra.bits; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/2/15 - * @time: 12:18 PM - */ -public class PowerOf2 { - - /** - * Power of 2 no. always has only one set bit. - * - * @param n - * @return - */ - public static boolean isPowerOf2(long n) { - return CountSetBits.countSetBits(n) == 1; - } - - /** - * AND operation of power of 2 no.s and the no. minus 1 is always 0. - * ex: 100 & 011 is 000 - * - * @param n - * @return - */ - public static boolean isPowerOf2UsingANDoperator(long n) { - return n != 0 && (n & (n - 1)) == 0; // n != 0 check added for input 0 - } - - /** - * The following code can be found in {@link java.util.Random#nextInt(int)}. - * - * @param n - * @return - */ - public static boolean isPowerOf2FromRandomClass(long n) { - return n != 0 && (n & -n) == n; - } - - public static void main(String[] args) { - System.out.println(isPowerOf2(18)); - System.out.println(isPowerOf2UsingANDoperator(18)); - System.out.println(isPowerOf2FromRandomClass(18)); - - System.out.println(isPowerOf2(16)); - System.out.println(isPowerOf2UsingANDoperator(16)); - System.out.println(isPowerOf2FromRandomClass(16)); - - System.out.println(isPowerOf2(0)); // works for 0 - System.out.println(isPowerOf2UsingANDoperator(0)); // works for 0 with a check - System.out.println(isPowerOf2FromRandomClass(0)); // works for 0 with a check - - System.out.println(isPowerOf2(-2)); // doesn't work for -ve no.s - System.out.println(isPowerOf2UsingANDoperator(-2)); // doesn't work for -ve no.s - System.out.println(isPowerOf2FromRandomClass(-2)); // doesn't work for -ve no.s - } -} diff --git a/src/main/java/com/rampatra/bits/PowerOf4.java b/src/main/java/com/rampatra/bits/PowerOf4.java deleted file mode 100644 index 5b75c4a2..00000000 --- a/src/main/java/com/rampatra/bits/PowerOf4.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.rampatra.bits; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/9/15 - * @time: 12:56 PM - */ -public class PowerOf4 { - - /** - * Determines whether any +ve number - * is power of 4 or not. - * - * @param n - * @return - */ - public static boolean isPowerOf4(int n) { - int zeroBitCount = 0; - // first check whether only 1 bit is set - if (n > 0 && (n & (n - 1)) == 0) { - // count no. of unset bits after the set bit - while (n > 1) { - zeroBitCount++; - n >>= 1; - } - // if no. of unset bits are even then its a power of 4 - return zeroBitCount % 2 == 0; - } - return false; - } - - public static void main(String[] args) { - System.out.println(isPowerOf4(0)); - System.out.println(isPowerOf4(1)); - System.out.println(isPowerOf4(4)); - System.out.println(isPowerOf4(16)); - System.out.println(isPowerOf4(18)); - System.out.println(isPowerOf4(64)); - } -} diff --git a/src/main/java/com/rampatra/bits/README.md b/src/main/java/com/rampatra/bits/README.md deleted file mode 100644 index 30119f20..00000000 --- a/src/main/java/com/rampatra/bits/README.md +++ /dev/null @@ -1,122 +0,0 @@ -# Bits - -## Basic Operators - -#### AND: - -| x | y | x `&` y | -----|---|:-------:| -| 0 | 0 | 0 | -| 0 | 1 | 0 | -| 1 | 0 | 0 | -| 1 | 1 | 1 | - -#### OR: - -| x | y | x `\|` y | -|---|---|:--------:| -| 0 | 0 | 0 | -| 0 | 1 | 1 | -| 1 | 0 | 1 | -| 1 | 1 | 1 | - -#### XOR: - -| x | y | x `^` y | -|---|---|:-------:| -| 0 | 0 | 0 | -| 0 | 1 | 1 | -| 1 | 0 | 1 | -| 1 | 1 | 0 | - - -## Shifts - -_Disclaimer: We are taking `byte` (8 bits) as our datatype to explain the - concepts instead of the usual integer._ - -#### 1. Left Shift (<<): - -1 << 3 = 8 - -> 00000001 << 3 = 00001000 - -#### 2. Right Shift: - -**Two types:** - -**a. Signed Right Shift (>>):** - -64 >> 2 = 16 - -> 001000000 >> 2 = 00010000 - --64 >> 2 = -16 - -> 111000000 >> 2 = 11110000 - -**b. Unsigned Right Shift (>>>):** - -64 >>> 2 = 16 - -> 001000000 >>> 2 = 00010000 - --64 >>> 2 = 56 - -> 111000000 >>> 2 = 00111000 - -## Helpful Masks - -#### 1. Set the 4th bit from right: - -```java -byte mask = 1 << 3; -``` - -Explanation, - -``` -00000001 << 3 = 00001000 -``` - -#### 2. Set the first 3 bits from right: - -```java -byte mask = (1 << 3) - 1; -``` - -Explanation, - -``` -00000001 << 3 = 00001000 - -00001000 - 00000001 = 00000111 -``` - -#### 3. Mask with alternating 1010...10 - -```java -byte mask = 0x55; -``` - -#### 4. Mask with alternating 0101...01 - -```java -byte mask = 0xaa; -``` - -#### 5. Unset the 4th bit - -```java -byte mask = 1 << 3; - -byte num = num & ~mask; -``` - -Explanation, - -``` -00000001 << 3 = 00001000 - -~(00001000) = 11110111 -``` \ No newline at end of file diff --git a/src/main/java/com/rampatra/bits/ReverseBits.java b/src/main/java/com/rampatra/bits/ReverseBits.java deleted file mode 100644 index 04f8cc3b..00000000 --- a/src/main/java/com/rampatra/bits/ReverseBits.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.rampatra.bits; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/5/15 - * @time: 4:26 PM - * @link: http://stackoverflow.com/questions/746171/best-algorithm-for-bit-reversal-from-msb-lsb-to-lsb-msb-in-c - * @link: http://graphics.stanford.edu/~seander/bithacks.html#BitReverseObvious - */ -public class ReverseBits { - - public static int getNumberByReversingBits(int n) { - - int m; - // assume 32-bit number - m = 0x55555555; // 1-bit swap - n = ((n & m) << 1) | ((n & ~m) >>> 1); - - m = 0x33333333; // 2-bits swap - n = ((n & m) << 2) | ((n & ~m) >>> 2); - - m = 0x0f0f0f0f; // 4-bits swap - n = ((n & m) << 4) | ((n & ~m) >>> 4); - - m = 0x00ff00ff; // 8-bits swap - n = ((n & m) << 8) | ((n & ~m) >>> 8); - - n = (n << 16) | (n >>> 16); // 16-bits swap - - return n; - } - - /** - * Checks for set bits in {@param n} and sets them - * from the left end in {@code reverseNum}. - *

- * Time Complexity: O(log n) - * Space Complexity: O(1) - * - * @param n - * @return - */ - public static int getNumberByReversingBitsV1(int n) { - - int reverseNum = 0, i = 0; - while (n > 0) { - if ((n & 1) == 1) { - reverseNum |= 1 << 31 - i; - } - n >>>= 1; - i++; - } - - return reverseNum; - } - - /** - * This method is similar to {@link #getNumberByReversingBitsV1(int)} but here we put - * the set bits of {@param n} in {@code reverse number} and keep on shifting the reverse number - * left until {@param n} becomes {@code zero} and finally shift left for the remaining number of - * bits used to represent the number. - *

- * Time complexity: O(log n) (as we are dividing 'n' by 2 in each iteration) - * Space Complexity: O(1) - * - * @param n - * @return - */ - public static int getNumberByReversingBitsV2(int n) { - int noOfBits = 32; - int reverse = 0; - - while (n > 0) { - reverse <<= 1; - reverse |= n & 1; - n >>>= 1; - noOfBits--; - } - reverse <<= noOfBits; - return reverse; - } - - public static void main(String[] args) { - System.out.println(getNumberByReversingBits(79876)); - System.out.println(getNumberByReversingBitsV1(79876)); - System.out.println(getNumberByReversingBitsV2(79876)); - System.out.println(getNumberByReversingBitsV2(5)); - } -} diff --git a/src/main/java/com/rampatra/bits/RightShiftOperator.java b/src/main/java/com/rampatra/bits/RightShiftOperator.java deleted file mode 100644 index 3eafd7b6..00000000 --- a/src/main/java/com/rampatra/bits/RightShiftOperator.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.rampatra.bits; - -/** - * {@code >>} shifts bits to right filling left bits with the left most - * bit (most significant bit). Also called signed right shift. - * {@code >>>} shifts bits to the right filling left bits - * with 0. Also called unsigned right shift. - * - * @author rampatra - * @since 6/2/15 - */ -public class RightShiftOperator { - - public static void main(String[] args) { - int n = -4; - System.out.printf("n: %32d\n", n); - System.out.printf("n: %32s\n", Integer.toBinaryString(n)); - System.out.printf("n>>1: %32s\n", Integer.toBinaryString(n >> 1)); - System.out.printf("n>>1: %32d\n", n >> 1); - System.out.printf("n>>>1: %32s\n", Integer.toBinaryString(n >>> 1)); - System.out.printf("n>>>1: %32d\n", n >>> 1); - - System.out.println("======================================="); - - n = -235034334; - System.out.printf("n: %32d\n", n); - System.out.printf("n: %32s\n", Integer.toBinaryString(n)); - System.out.printf("n>>1: %32s\n", Integer.toBinaryString(n >> 1)); - System.out.printf("n>>1: %32d\n", n >> 1); - System.out.printf("n>>>1: %32s\n", Integer.toBinaryString(n >>> 1)); - System.out.printf("n>>>1: %32d\n", n >>> 1); - System.out.printf("n>>2: %32s\n", Integer.toBinaryString(n >> 2)); - System.out.printf("n>>>2: %32s\n", Integer.toBinaryString(n >>> 2)); - - System.out.println("======================================="); - - n = 235034334; - System.out.printf("n: %32d\n", n); - System.out.printf("n: %32s\n", Integer.toBinaryString(n)); - System.out.printf("n>>1: %32s\n", Integer.toBinaryString(n >> 1)); - System.out.printf("n>>1: %32d\n", n >> 1); - System.out.printf("n>>>1: %32s\n", Integer.toBinaryString(n >>> 1)); - System.out.printf("n>>>1: %32d\n", n >>> 1); - System.out.printf("n>>2: %32s\n", Integer.toBinaryString(n >> 2)); - System.out.printf("n>>>2: %32s\n", Integer.toBinaryString(n >>> 2)); - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/bits/RightmostSetBit.java b/src/main/java/com/rampatra/bits/RightmostSetBit.java deleted file mode 100644 index 1916ed64..00000000 --- a/src/main/java/com/rampatra/bits/RightmostSetBit.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.rampatra.bits; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/3/15 - * @time: 11:56 PM - */ -public class RightmostSetBit { - - /** - * Returns the position of the rightmost set bit - * in {@param n} where the position starts from 1. - *

- * Works for -ve no.s as well. - * - * @param n - * @return - */ - public static int getRightmostSetBitPosition(long n) { - int position = 0; - while (n != 0) { - position++; - if ((n & 1) == 1) { - break; - } - n >>= 1; - } - return position; - } - - public static long unsetRightmostSetBit(long n) { - return n & (n - 1); // brian kerningham's algorithm - } - - public static void main(String[] args) { - System.out.println(getRightmostSetBitPosition(0)); - System.out.println(getRightmostSetBitPosition(1)); - System.out.println(getRightmostSetBitPosition(2)); - System.out.println(getRightmostSetBitPosition(5)); - System.out.println(getRightmostSetBitPosition(18)); - System.out.println(getRightmostSetBitPosition(19)); - System.out.println(getRightmostSetBitPosition(-1)); - System.out.println(getRightmostSetBitPosition(-2)); - System.out.println(getRightmostSetBitPosition(-4)); - - System.out.println("========================"); - - System.out.println(unsetRightmostSetBit(0)); - System.out.println(unsetRightmostSetBit(2)); - System.out.println(unsetRightmostSetBit(12)); - System.out.println(unsetRightmostSetBit(16)); - System.out.println(unsetRightmostSetBit(18)); - System.out.println(unsetRightmostSetBit(-1)); - } -} diff --git a/src/main/java/com/rampatra/bits/RotateBits.java b/src/main/java/com/rampatra/bits/RotateBits.java deleted file mode 100644 index 9712b028..00000000 --- a/src/main/java/com/rampatra/bits/RotateBits.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.rampatra.bits; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/8/15 - * @time: 5:12 PM - *

- * A ROTATION (OR CIRCULAR SHIFT) is an operation similar to - * shift except that the bits that fall off at one end are put - * back to the other end. - *

- * For example, 000…11100101 becomes 00..0011100101000 if the number - * is rotated 3 times towards left and becomes 101000..0011100 if the - * number is rotated 3 times towards right. - */ -public class RotateBits { - - public static int leftRotateBits(int n, int times) { - return n << times | n >>> (32 - times); - } - - public static int rightRotateBits(int n, int times) { - return n >>> times | n << (32 - times); - } - - public static void main(String[] args) { - System.out.println(leftRotateBits(5, 3)); - System.out.println(leftRotateBits(234324, 3)); - System.out.println(rightRotateBits(5, 3)); - System.out.println(rightRotateBits(234324, 3)); - } -} diff --git a/src/main/java/com/rampatra/bits/ShiftByNegativeNumber.java b/src/main/java/com/rampatra/bits/ShiftByNegativeNumber.java deleted file mode 100644 index 4acd83b3..00000000 --- a/src/main/java/com/rampatra/bits/ShiftByNegativeNumber.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.rampatra.bits; - -/** - * Understanding shifting in Java. What happens when you shift a number by a negative number. - * - * @author rampatra - * @link https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.19 - * @link https://stackoverflow.com/a/10516830/1385441 - * @since 18/11/2018 - */ -public class ShiftByNegativeNumber { - /** - * These both are the same as in java if the left operand is int only the low five bits are considered - * for shifting and if the left operand is a long then the low six bits are considered. - * Binary representation of -2 is 11.....11110. The last 5 bits are 11110 which is 30. - * - * @param args - */ - public static void main(String[] args) { - int v1 = 1 << -2; - int v2 = 1 << 30; - System.out.println(v1); - System.out.println(v2); - } -} diff --git a/src/main/java/com/rampatra/bits/SmallestOf3Integers.java b/src/main/java/com/rampatra/bits/SmallestOf3Integers.java deleted file mode 100644 index 63e542a9..00000000 --- a/src/main/java/com/rampatra/bits/SmallestOf3Integers.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.rampatra.bits; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/12/15 - * @time: 6:18 PM - */ -public class SmallestOf3Integers { - - /** - * Returns min of 2 numbers without using - * any comparison operators. - * - * @param x - * @param y - * @return - */ - private static int min(int x, int y) { - return y + ((x - y) & ((x - y) >> 31)); - } - - /** - * Returns the smallest element in an - * array of length 3. - * - * @param a - * @return - */ - public static int getSmallest(int a[]) { - return min(a[0], min(a[1], a[2])); - } - - /** - * This method uses repeated subtraction to - * find the smallest element in an array. - * - * @param a - * @return - */ - public static int getSmallest_V1(int a[]) { - int c = 0; - while (a[0] > 0 && a[1] > 0 && a[2] > 0) { - a[0]--; - a[1]--; - a[2]--; - c++; - } - return c; - } - - public static void main(String[] args) { - System.out.println(getSmallest(new int[]{4, 5, 6})); - System.out.println(getSmallest_V1(new int[]{4, 5, 6})); - } -} diff --git a/src/main/java/com/rampatra/bits/StrCmp.java b/src/main/java/com/rampatra/bits/StrCmp.java deleted file mode 100644 index 4b1be36f..00000000 --- a/src/main/java/com/rampatra/bits/StrCmp.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.rampatra.bits; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/15/15 - * @time: 10:38 AM - */ -public class StrCmp { - - /** - * Compares two strings {@param s1} and {@param s2} lexicographically ignoring case. - * If both are equal it returns 0 otherwise their lexicographic differences. - * - * @param s1 - * @param s2 - * @return - */ - public static int compareStringIgnoreCase(String s1, String s2) { - int n1 = s1.length(); - int n2 = s2.length(); - int min = Math.min(n1, n2); - for (int i = 0; i < min; i++) { - char c1 = s1.charAt(i); - char c2 = s2.charAt(i); - if (c1 != c2) { - // If characters don't match but case may be ignored, - // try converting both characters to uppercase. - // If the results match, then the comparison scan should - // continue. - c1 = Character.toUpperCase(c1); - c2 = Character.toUpperCase(c2); - if (c1 != c2) { - // Unfortunately, conversion to uppercase does not work properly - // for the Georgian alphabet, which has strange rules about case - // conversion. So we need to make one last check before - // exiting. - c1 = Character.toUpperCase(c1); - c2 = Character.toUpperCase(c2); - if (c1 != c2) { - // No overflow because of numeric promotion - return c1 - c2; - } - } - } - } - return n1 - n2; - } - - public static void main(String[] args) { - System.out.println(compareStringIgnoreCase("ram", "ram")); - System.out.println(compareStringIgnoreCase("ram", "Ram")); - System.out.println(compareStringIgnoreCase("", "")); - System.out.println(compareStringIgnoreCase("", " ")); - System.out.println(compareStringIgnoreCase(" ", " ")); - System.out.println(compareStringIgnoreCase(" ", "")); - System.out.println(compareStringIgnoreCase("Geeks", "apple")); - System.out.println(compareStringIgnoreCase("", "ABCD")); - System.out.println(compareStringIgnoreCase("ABCD", "z")); - System.out.println(compareStringIgnoreCase("ABCD", "abcdEghe")); - System.out.println(compareStringIgnoreCase("GeeksForGeeks", "gEEksFORGeEKs")); - System.out.println(compareStringIgnoreCase("GeeksForGeeks", "geeksForGeeks")); - System.out.println("--------------------"); - System.out.println("ram".compareToIgnoreCase("ram")); - System.out.println("ram".compareToIgnoreCase("Ram")); - System.out.println("".compareToIgnoreCase("")); - System.out.println("".compareToIgnoreCase(" ")); - System.out.println(" ".compareToIgnoreCase(" ")); - System.out.println(" ".compareToIgnoreCase("")); - System.out.println("Geeks".compareToIgnoreCase("apple")); - System.out.println("".compareToIgnoreCase("ABCD")); - System.out.println("ABCD".compareToIgnoreCase("z")); - System.out.println("ABCD".compareToIgnoreCase("abcdEghe")); - System.out.println("GeeksForGeeks".compareToIgnoreCase("gEEksFORGeEKs")); - System.out.println("GeeksForGeeks".compareToIgnoreCase("geeksForGeeks")); - } -} diff --git a/src/main/java/com/rampatra/bits/SubBit.java b/src/main/java/com/rampatra/bits/SubBit.java deleted file mode 100644 index f91a4dd8..00000000 --- a/src/main/java/com/rampatra/bits/SubBit.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.rampatra.bits; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/4/15 - * @time: 10:54 PM - */ -public class SubBit { - - /** - * Returns the number formed with the bits from {@param start} - * and {@param end} of {@param num} (both inclusive). - * - * @param num - * @param start > 0 and <= 32 - * @param end > 0 and <= 32 - * @return - */ - public static int getNumberFromSubBits(int num, int start, int end) { - return num << (32 - end) >>> (start - end + 31); // more intuitive (start - 1 + 32 - end) - } - - public static void main(String[] args) { - System.out.println(getNumberFromSubBits(5, 1, 2)); - } -} diff --git a/src/main/java/com/rampatra/bits/SwapBits.java b/src/main/java/com/rampatra/bits/SwapBits.java deleted file mode 100644 index 40fbb613..00000000 --- a/src/main/java/com/rampatra/bits/SwapBits.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.rampatra.bits; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/13/15 - * @time: 4:45 PM - */ -public class SwapBits { - - /** - * Swaps bits at even position with bits - * at odd position in {@param n}. - * - * @param n - * @return - */ - public static int swapEvenOddBits(int n) { - int evenBits = n & 0x55555555; - int oddBits = n & 0xaaaaaaaa; - - return evenBits << 1 | oddBits >> 1; - } - - /** - * Swaps bits at even position with bits - * at odd position in {@param n}. - * - * @param n - * @return - */ - public static int swapEvenOddBits_V1(int n) { - for (int i = 0; i < 32; i += 2) { - int evenBit = (n >> i) & 1; - int oddBit = (n >> (i + 1)) & 1; - int xor = evenBit ^ oddBit; - - n ^= xor << i; - n ^= xor << (i + 1); - } - return n; - } - - - /** - * Swaps {@param length} bits in {@param n} starting from - * {@param pos1} with bits starting from {@param pos2}. - *

- * For example, - * x = 28 (11100) - * p1 = 0 (Start from first bit from right side) - * p2 = 3 (Start from 4th bit from right side) - * l = 2 (No of bits to be swapped) - * Output: - * 7 (00111) - * - * @param n - * @param pos1 starts from 0 - * @param pos2 starts from 0 - * @param length - * @return - */ - public static int swapBitRangeInNumber(int n, int pos1, int pos2, int length) { - int set1 = (n >> pos1) & ((1 << length) - 1); // 1st set of bits to be swapped - int set2 = (n >> pos2) & ((1 << length) - 1); // 2nd set of bits to be swapped - int xor = set1 ^ set2; // difference pattern between the bits to be swapped - - return n ^ (xor << pos1) ^ (xor << pos2); // XORing the difference pattern at the appropriate - // position of the bits to be swapped gives us the result - // (this logic is similar to swapping bits using XOR) - } - - public static void main(String[] args) { - System.out.println(swapEvenOddBits(23)); - System.out.println(swapEvenOddBits(0)); - System.out.println(swapEvenOddBits(5)); - System.out.println(swapEvenOddBits(6)); - System.out.println("-------------------------------"); - System.out.println(swapEvenOddBits_V1(23)); - System.out.println(swapEvenOddBits_V1(0)); - System.out.println(swapEvenOddBits_V1(5)); - System.out.println(swapEvenOddBits_V1(6)); - System.out.println("-------------------------------"); - System.out.println(swapBitRangeInNumber(47, 1, 5, 3)); - System.out.println(swapBitRangeInNumber(28, 0, 3, 2)); - System.out.println(swapBitRangeInNumber(269, 1, 3, 2)); - } -} diff --git a/src/main/java/com/rampatra/bits/TwoNonRepeatingElements.java b/src/main/java/com/rampatra/bits/TwoNonRepeatingElements.java deleted file mode 100644 index a3b47f08..00000000 --- a/src/main/java/com/rampatra/bits/TwoNonRepeatingElements.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.rampatra.bits; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/7/15 - * @time: 2:46 PM - * @link: http://www.geeksforgeeks.org/find-two-non-repeating-elements-in-an-array-of-repeating-elements/ - */ -public class TwoNonRepeatingElements { - - /** - * Finds the 2 non-repeating elements in an array of - * repeating elements (all elements repeated twice - * except 2 elements). - * - * @param a - * @return - */ - public static int[] getTwoNonRepeatingElementsInArray(int a[]) { - int xor = 0, setBit, x = 0, y = 0; - for (int i = 0; i < a.length; i++) { - xor ^= a[i]; // XOR all array elements - } - setBit = xor & ~(xor - 1); // get the rightmost set bit in XOR - for (int i = 0; i < a.length; i++) { - if ((a[i] & setBit) == 0) { - x ^= a[i]; // one non-repeating element - } else { - y ^= a[i]; // other non-repeating element - } - } - return new int[]{x, y}; - } - - public static void main(String[] args) { - System.out.println(Arrays.toString(getTwoNonRepeatingElementsInArray(new int[]{2, 3, 4, 2, 3, 4, 5, 6}))); - } -} - -/** - * EXPLANATION: - * Consider input arr[] = {2, 4, 7, 9, 2, 4} - * 1) Get the XOR of all the elements. - * xor = 2^4^7^9^2^4 = 14 (1110) - * 2) Get a number which has only one set bit of the xor. - * Since we can easily get the rightmost set bit, let us use it. - * set_bit_no = xor & ~(xor-1) = (1110) & ~(1101) = 0010 - * Now set_bit_no will have only set as rightmost set bit of xor. - * 3) Now divide the elements in two sets and do xor of - * elements in each set, and we get the non-repeating - * elements 7 and 9. Please see implementation for this - * step. - */ diff --git a/src/main/java/com/rampatra/blockchain/Block.java b/src/main/java/com/rampatra/blockchain/Block.java deleted file mode 100644 index 8ba8eab5..00000000 --- a/src/main/java/com/rampatra/blockchain/Block.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.rampatra.blockchain; - -import java.io.Serializable; - -/** - * @author rampatra - * @since 2019-03-05 - */ -public class Block implements Serializable { - - private int index; - private String previousHash; - private long timestamp; - private String data; - private String hash; - private int nonce; - - public Block(int index, String previousHash, long timestamp, String data, String hash, int nonce) { - this.index = index; - this.previousHash = previousHash; - this.timestamp = timestamp; - this.data = data; - this.hash = hash; - this.nonce = nonce; - } - - public int getIndex() { - return index; - } - - public void setIndex(int index) { - this.index = index; - } - - public String getPreviousHash() { - return previousHash; - } - - public void setPreviousHash(String previousHash) { - this.previousHash = previousHash; - } - - public long getTimestamp() { - return timestamp; - } - - public void setTimestamp(long timestamp) { - this.timestamp = timestamp; - } - - public String getData() { - return data; - } - - public void setData(String data) { - this.data = data; - } - - public String getHash() { - return hash; - } - - public void setHash(String hash) { - this.hash = hash; - } - - public int getNonce() { - return nonce; - } - - public void setNonce(int nonce) { - this.nonce = nonce; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("Block{"); - sb.append("index=").append(index); - sb.append(", previousHash='").append(previousHash).append('\''); - sb.append(", timestamp=").append(timestamp); - sb.append(", data='").append(data).append('\''); - sb.append(", hash='").append(hash).append('\''); - sb.append(", nonce=").append(nonce); - sb.append('}'); - return sb.toString(); - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/blockchain/Blockchain.java b/src/main/java/com/rampatra/blockchain/Blockchain.java deleted file mode 100644 index 58fe7813..00000000 --- a/src/main/java/com/rampatra/blockchain/Blockchain.java +++ /dev/null @@ -1,182 +0,0 @@ -package com.rampatra.blockchain; - -import java.nio.charset.StandardCharsets; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Date; -import java.util.List; -import java.util.ListIterator; - -/** - * @author rampatra - * @since 2019-03-05 - */ -public class Blockchain { - - private List blocks; - private int difficulty; - - public Blockchain(List blocks, int difficulty) { - this.blocks = blocks; - this.difficulty = difficulty; - this.blocks.add(getGenesisBlock()); - } - - public List getBlocks() { - return blocks; - } - - public int getSize() { - return blocks.size(); - } - - public Block getLatestBlock() { - if (blocks.isEmpty()) return null; - - return blocks.get(blocks.size() - 1); - } - - public void addBlock(Block block) { - blocks.add(block); - } - - /** - * Mine, create a new block with the {@code data}, and finally, add it to the blockchain. - *

- * Mining is nothing but the process of calculating a hash of a {@link Block} with {@code data} such - * that the hash starts with a specific number of zeros equal to the difficulty of the blockchain. - * - * @param data - * @return - */ - public Block mine(String data) { - Block previousBlock = getLatestBlock(); - Block nextBlock = getNextBlock(previousBlock, data); - - if (isValidNextBlock(previousBlock, nextBlock)) { - blocks.add(nextBlock); - return nextBlock; - } else { - throw new RuntimeException("Invalid block"); - } - } - - /** - * Executes the {@link Blockchain#isValidNextBlock(Block, Block)} on the entire blockchain. - * - * @return {@code false} if at least one block in the blockchain is invalid, {@code true} otherwise. - */ - public boolean isValidChain() { - ListIterator listIterator = blocks.listIterator(); - listIterator.next(); - while (listIterator.hasPrevious() && listIterator.hasNext()) { - if (!isValidNextBlock(listIterator.previous(), listIterator.next())) { - return false; - } - } - return true; - } - - /** - * Creates the Genesis Block for the blockchain. The Genesis Block is the first block in the blockchain. - * - * @return the genesis block - */ - private Block getGenesisBlock() { - final long timestamp = new Date().getTime(); - int nonce = 0; - String data = "Blockchain in Java"; - String hash; - while (!isValidHashDifficulty(hash = calculateHashForBlock(0, "0", timestamp, data, nonce))) { - nonce++; - } - - return new Block(0, "0", timestamp, data, hash, nonce); - } - - private Block getNextBlock(Block previousBlock, String data) { - final int index = previousBlock.getIndex() + 1; - final long timestamp = new Date().getTime(); - int nonce = 0; - String hash; - while (!isValidHashDifficulty( - hash = calculateHashForBlock(index, previousBlock.getHash(), timestamp, data, nonce))) { - nonce++; - } - return new Block(index, previousBlock.getHash(), timestamp, data, hash, nonce); - } - - private boolean isValidNextBlock(Block previousBlock, Block nextBlock) { - - String nextBlockHash = calculateHashForBlock(nextBlock.getIndex(), previousBlock.getHash(), - nextBlock.getTimestamp(), nextBlock.getData(), nextBlock.getNonce()); - - if (previousBlock.getIndex() + 1 != nextBlock.getIndex()) { - return false; - } else if (!previousBlock.getHash().equals(nextBlock.getPreviousHash())) { - return false; - } else if (!this.isValidHashDifficulty(nextBlockHash)) { - return false; - } else if (!nextBlockHash.equals(nextBlock.getHash())) { - return false; - } else { - return true; - } - } - - /** - * Checks if the hash respects the difficulty of the blockchain, i.e, if the hash - * begins with a number of zeros equal to the difficulty of the blockchain. - * - * @param hash the SHA256 hash of the block. - * @return {@code true} if hash obeys difficulty, {@code false} otherwise. - */ - private boolean isValidHashDifficulty(String hash) { - for (int i = 0; i < difficulty; i++) { - if (hash.charAt(i) != '0') { - return false; - } - } - return true; - } - - /** - * Calculates the SHA256 hash of the block. - * - * @param index - * @param previousHash - * @param timestamp - * @param data - * @param nonce - * @return the SHA256 hash of the block. - */ - private String calculateHashForBlock(final int index, final String previousHash, final long timestamp, - final String data, final int nonce) { - try { - MessageDigest digest = MessageDigest.getInstance("SHA-256"); - byte[] encodedhash = digest.digest( - (index + previousHash + timestamp + data + nonce).getBytes(StandardCharsets.UTF_8)); - return bytesToHex(encodedhash); - } catch (NoSuchAlgorithmException e) { - throw new RuntimeException("Encryption Error: {}", e); - } - } - - private static String bytesToHex(byte[] hash) { - StringBuilder hexString = new StringBuilder(); - for (int i = 0; i < hash.length; i++) { - String hex = Integer.toHexString(0xff & hash[i]); - if (hex.length() == 1) hexString.append('0'); - hexString.append(hex); - } - return hexString.toString(); - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("Blockchain{"); - sb.append("blocks=").append(blocks); - sb.append('}'); - return sb.toString(); - } -} diff --git a/src/main/java/com/rampatra/blockchain/Message.java b/src/main/java/com/rampatra/blockchain/Message.java deleted file mode 100644 index 9bebbae5..00000000 --- a/src/main/java/com/rampatra/blockchain/Message.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.rampatra.blockchain; - -import java.io.Serializable; - -/** - * @author rampatra - * @since 2019-03-10 - */ -public class Message implements Serializable { - - enum MessageType { - REQUEST_LATEST_BLOCK, - RECEIVE_LATEST_BLOCK, - REQUEST_BLOCKCHAIN, - RECEIVE_BLOCKCHAIN - } - - private MessageType messageType; - private Block latestBlock; - private Blockchain blockchain; - - - public MessageType getMessageType() { - return messageType; - } - - public Block getLatestBlock() { - return latestBlock; - } - - public Blockchain getBlockchain() { - return blockchain; - } - - public static final class MessageBuilder { - private MessageType messageType; - private Block latestBlock; - private Blockchain blockchain; - - private MessageBuilder() { - } - - public static MessageBuilder aMessage() { - return new MessageBuilder(); - } - - public MessageBuilder withMessageType(MessageType messageType) { - this.messageType = messageType; - return this; - } - - public MessageBuilder withLatestBlock(Block latestBlock) { - this.latestBlock = latestBlock; - return this; - } - - public MessageBuilder withBlockchain(Blockchain blockchain) { - this.blockchain = blockchain; - return this; - } - - public Message build() { - Message message = new Message(); - message.latestBlock = this.latestBlock; - message.blockchain = this.blockchain; - message.messageType = this.messageType; - return message; - } - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/blockchain/MessageHandler.java b/src/main/java/com/rampatra/blockchain/MessageHandler.java deleted file mode 100644 index 52aaf328..00000000 --- a/src/main/java/com/rampatra/blockchain/MessageHandler.java +++ /dev/null @@ -1,123 +0,0 @@ -package com.rampatra.blockchain; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.net.Socket; -import java.net.SocketException; - -/** - * @author rampatra - * @since 2019-03-10 - */ -public class MessageHandler implements Runnable { - - private ObjectInputStream in; - private ObjectOutputStream out; - private Peer peer; - - MessageHandler(Socket client, Peer peer) { - try { - in = new ObjectInputStream(client.getInputStream()); - out = new ObjectOutputStream(client.getOutputStream()); - this.peer = peer; - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - @Override - public void run() { - Message message; - try { - while ((message = (Message) in.readObject()) != null) { - handleMessage(message); - } - } catch (Exception e) { - if (!(e instanceof SocketException)) { - throw new RuntimeException(e); - } - } finally { - try { - in.close(); - out.close(); - } catch (Exception e) { - // do nothing - } - } - } - - /** - * Handle messages accordingly. - * - * @param message is the message object from the peer. - */ - private void handleMessage(Message message) { - Message.MessageType type = message.getMessageType(); - switch (type) { - case REQUEST_LATEST_BLOCK: - sendMessage(Message.MessageBuilder - .aMessage() - .withMessageType(Message.MessageType.RECEIVE_LATEST_BLOCK) - .withLatestBlock(peer.getBlockchain().getLatestBlock()) - .build()); - break; - case RECEIVE_LATEST_BLOCK: - handleLatestBlock(message.getLatestBlock()); - break; - case REQUEST_BLOCKCHAIN: - sendMessage(Message.MessageBuilder - .aMessage() - .withMessageType(Message.MessageType.RECEIVE_BLOCKCHAIN) - .withBlockchain(peer.getBlockchain()) - .build()); - break; - case RECEIVE_BLOCKCHAIN: - handleBlockchain(message.getBlockchain()); - break; - default: - throw new RuntimeException("Unknown message type"); - } - } - - private void sendMessage(Message message) { - try { - out.writeObject(message); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - /** - * If the latest block received from the peer has {@code previousHash} equal to the hash of the - * latest block in the current user's blockchain then add the latest block received to the - * current user's blockchain, or else, if the latest block received has a larger index then - * request the entire blockchain from the peer. - * - * @param latestBlock the block received from the peer - */ - private void handleLatestBlock(Block latestBlock) { - Block latestBlockWithCurrentPeer = peer.getBlockchain().getLatestBlock(); - - if (latestBlock.getPreviousHash().equals(latestBlockWithCurrentPeer.getHash())) { - peer.getBlockchain().addBlock(latestBlock); - } else if (latestBlock.getIndex() > latestBlockWithCurrentPeer.getIndex()) { - sendMessage(Message.MessageBuilder - .aMessage() - .withMessageType(Message.MessageType.REQUEST_BLOCKCHAIN) - .build()); - } - } - - /** - * If the blockchain received from the peer is valid and longer then replace current user's - * blockchain with the received blockchain. - * - * @param blockchain the entire blockchain received from the peer - */ - private void handleBlockchain(Blockchain blockchain) { - if (blockchain.isValidChain() && blockchain.getSize() > peer.getBlockchain().getSize()) { - peer.setBlockchain(blockchain); - } - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/blockchain/P2P.java b/src/main/java/com/rampatra/blockchain/P2P.java deleted file mode 100644 index c8c65ac6..00000000 --- a/src/main/java/com/rampatra/blockchain/P2P.java +++ /dev/null @@ -1,135 +0,0 @@ -package com.rampatra.blockchain; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Scanner; - -/** - * @author rampatra - * @since 2019-03-09 - */ -public class P2P { - - private static List peers = new ArrayList<>(); - private static int lastUsedPort = 4000; - - public static Peer addPeer(Blockchain blockchain) { - Peer peer = new Peer(blockchain, lastUsedPort++); - peers.add(peer); - return peer; - } - - public static void removePeer(int index) { - Peer peer = peers.get(index); - peer.stopServer(); - peers.remove(index); - } - - public static void removePeer(Peer peer) { - Iterator iterator = peers.iterator(); - while (iterator.hasNext()) { - if (iterator.next().equals(peer)) { - peer.stopServer(); - iterator.remove(); - break; - } - } - } - - public static void removeAllPeers() { - Iterator iterator = peers.iterator(); - while (iterator.hasNext()) { - Peer peer = iterator.next(); - peer.stopServer(); - iterator.remove(); - } - } - - public static Peer getPeer(int index) { - return peers.get(index); - } - - public static List getPeers() { - return peers; - } - - public static void showPeers() { - for (int i = 0; i < peers.size(); i++) { - System.out.println("Peer " + (i + 1) + ": " + peers.get(i).getPort()); - } - } - - public static void showPeersWithBlockchain() { - for (int i = 0; i < peers.size(); i++) { - System.out.println("Peer " + (i + 1) + " (" + peers.get(i).getPort() + "): " + peers.get(i).getBlockchain()); - } - } - - /** - * The main starting point of the blockchain demo. At first, add some peers (option 1) and mine some data - * by choosing a particular peer (option 2). You would soon see that the newly mined block is broadcast to - * all the peers. - * - * @param args - */ - public static void main(String[] args) { - try { - int menuChoice; - int peerIndex; - String data; - Scanner s = new Scanner(System.in); - Blockchain blockchain = new Blockchain(new ArrayList<>(), 3); - - while (true) { - - System.out.println("\n======= Welcome to Blockchain in Java ======="); - System.out.println("1. Add Peer"); - System.out.println("2. Mine data in peer"); - System.out.println("3. Remove peer"); - System.out.println("4. Show peers"); - System.out.println("5. Exit"); - - menuChoice = s.nextInt(); - - switch (menuChoice) { - case 1: - P2P.addPeer(blockchain); - System.out.println("New peer added!"); - P2P.showPeersWithBlockchain(); - break; - case 2: - System.out.println("Choose peer: (a number for ex. 1, 2, etc.)"); - P2P.showPeers(); - peerIndex = s.nextInt(); - Peer p = P2P.getPeer(peerIndex - 1); - System.out.println("Enter data: (a string with no spaces)"); - data = s.next(); - p.mine(data); - System.out.println("Data mined!"); - P2P.showPeersWithBlockchain(); - break; - case 3: - System.out.println("Choose peer: (a number for ex. 1, 2, etc.)"); - P2P.showPeers(); - peerIndex = s.nextInt(); - P2P.removePeer(peerIndex - 1); - System.out.println("Peer " + peerIndex + " removed!"); - P2P.showPeersWithBlockchain(); - break; - case 4: - P2P.showPeersWithBlockchain(); - break; - case 5: - P2P.removeAllPeers(); - System.out.println("Bye, see you soon!"); - System.exit(0); - default: - System.out.println("Wrong choice!"); - } - } - } catch (Exception e) { - throw new RuntimeException(e); - } - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/blockchain/Peer.java b/src/main/java/com/rampatra/blockchain/Peer.java deleted file mode 100644 index fcb34632..00000000 --- a/src/main/java/com/rampatra/blockchain/Peer.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.rampatra.blockchain; - -import java.io.ObjectOutputStream; -import java.net.ServerSocket; -import java.net.Socket; -import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.stream.Collectors; - -/** - * @author rampatra - * @since 2019-03-09 - */ -public class Peer { - - private Blockchain blockchain; - private int port; - private ServerSocket server; - private ExecutorService executor = Executors.newSingleThreadExecutor(); - - Peer(Blockchain blockchain, int port) { - this.blockchain = blockchain; - this.port = port; - startServer(); - getLatestBlockFromPeers(); - } - - /** - * Once a new peer is created, we start the socket server to receive messages from the peers. - */ - private void startServer() { - try { - executor.submit(() -> { - server = new ServerSocket(port); - while (true) { - // we create a new thread for each new client thereby supporting multiple client simultaneously - new Thread(new MessageHandler(server.accept(), this)).start(); - } - }); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - /** - * Stop the server once a peer is removed from the network. - */ - public void stopServer() { - try { - if (!server.isClosed()) { - server.close(); - } - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - /** - * Once a new peer is created and added to the network, it requests the latest block from - * all the peers and updates its blockchain if it is outdated. - */ - private void getLatestBlockFromPeers() { - sendMessageToPeers(Message.MessageBuilder - .aMessage() - .withMessageType(Message.MessageType.REQUEST_LATEST_BLOCK) - .build()); - } - - private void sendMessageToPeers(Message message) { - try { - // send to all peers except itself - List peers = P2P.getPeers() - .stream() - .filter(peer -> !(peer.port == this.port)) - .collect(Collectors.toList()); - for (Peer peer : peers) { - Socket client = new Socket("127.0.0.1", peer.port); - ObjectOutputStream out = new ObjectOutputStream(client.getOutputStream()); - out.writeObject(message); - } - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - /** - * Mine, create a new block with the {@code data}, and finally, add it to the blockchain. - * - * @param data - */ - public void mine(String data) { - Block latestBlock = this.blockchain.mine(data); - sendMessageToPeers(Message.MessageBuilder - .aMessage().withMessageType(Message.MessageType.RECEIVE_LATEST_BLOCK) - .withLatestBlock(latestBlock) - .build()); - } - - public Blockchain getBlockchain() { - return blockchain; - } - - public void setBlockchain(Blockchain blockchain) { - this.blockchain = blockchain; - } - - public int getPort() { - return port; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("Peer{"); - sb.append("blockchain=").append(blockchain); - sb.append(", port=").append(port); - sb.append('}'); - return sb.toString(); - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/database/README.md b/src/main/java/com/rampatra/database/README.md deleted file mode 100644 index 0ea2737c..00000000 --- a/src/main/java/com/rampatra/database/README.md +++ /dev/null @@ -1,76 +0,0 @@ -# Relational Database (WIP) - -A __relational database__ is a digital database based on -the [relational model](https://en.wikipedia.org/wiki/Relational_model) of -data. In simple words, it is a collection of data items with pre-defined -relationships between them. These items are organized as a set of tables, -with columns and rows. Each column stores some specific attribute of an object/entity and the -row represents a specific object/entity. - -A software system used to maintain relational databases is a __relational -database management system (RDBMS)__, for e.g., MySQL, Oracle DB, PostgreSQL, etc. -Virtually all relational database systems use __SQL (Structured Query Language)__ -for querying and maintaining the database. - -## Basic Definitions - -1. Primary Key - -2. Candidate Key - -3. Composite Key - -4. Prime/Non-prime attribute - -## Types of SQL commands - -1. DDL -2. DML -3. DCL -4. TCL - -| Type | Command List | -|-------|-------------------| -| DDL | CREATE | -| | DROP | -| | ALTER | -| | RENAME | -| | TRUNCATE | -| | | -| DML | SELECT | -| | INSERT | -| | UPDATE | -| | DELETE | -| | | -| DCL | GRANT | -| | REVOKE | -| | | -| TCL | START TRANSACTION | -| | COMMIT | -| | ROLLBACK | - -## Types of Joins - -1. Inner Join -2. Left Outer Join -3. Right Outer Join -4. Full Join -5. Self Join - -## Normalization Forms - -1. 1NF -2. 2NF -3. 3NF -4. BCNF -5. 4NF -6. 5NF - -#### 1NF - -Required conditions: - -a. All values should be atomic (non-breakable). -b. There should be a candidate key or a composite key (basically you should be able to uniquely identify all records in the table). - - \ No newline at end of file diff --git a/src/main/java/com/rampatra/dynamicprogramming/FibonacciNumbers.java b/src/main/java/com/rampatra/dynamicprogramming/FibonacciNumbers.java deleted file mode 100644 index 8d102ef7..00000000 --- a/src/main/java/com/rampatra/dynamicprogramming/FibonacciNumbers.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.rampatra.dynamicprogramming; - -import java.util.Arrays; - -import static java.lang.System.out; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 9/10/15 - */ -public class FibonacciNumbers { - - /** - * Computes first {@code k} fibonacci numbers using - * bottom-up DP approach. - *

- * Time complexity: O(k) - * - * @param k - */ - public static int[] getFirstKFibonacciNumbers(int k) { - int[] fib = new int[k]; - int i = 1; - while (i < k) { - if (i == 1 || i == 2) { - fib[i] = 1; - } else { - fib[i] = fib[i - 1] + fib[i - 2]; - } - i++; - } - return fib; - } - - public static void main(String[] args) { - out.println(Arrays.toString(getFirstKFibonacciNumbers(0))); - out.println(Arrays.toString(getFirstKFibonacciNumbers(10))); - out.println(Arrays.toString(getFirstKFibonacciNumbers(46))); - } -} diff --git a/src/main/java/com/rampatra/dynamicprogramming/LongestIncreasingSubSequence.java b/src/main/java/com/rampatra/dynamicprogramming/LongestIncreasingSubSequence.java deleted file mode 100644 index 7372a9a8..00000000 --- a/src/main/java/com/rampatra/dynamicprogramming/LongestIncreasingSubSequence.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.rampatra.dynamicprogramming; - -/** - * @author rampatra - * @since 9/29/15 - */ -public class LongestIncreasingSubSequence { - - /** - * TODO: Properly document and understand - * The Longest Increasing SubSequence (LIS) problem is to find the length of - * the longest sub-sequence of a given sequence such that all elements of the - * sub-sequence are sorted in increasing order. - *

- * For example, - * Length of LIS for { 10, 22, 9, 33, 21, 50, 41, 60, 80 } is 6 and LIS - * is {10, 22, 33, 50, 60, 80}. - *

- * Optimal Substructure: - * Let arr[0..n-1] be the input array and L(i) be the length of the LIS till index i such that arr[i] is part - * of LIS and arr[i] is the last element in LIS, then L(i) can be recursively written as. - * L(i) = { 1 + Max ( L(j) ) } where j < i and arr[j] < arr[i] and if there is no such j then L(i) = 1 - * To get LIS of a given array, we need to return max(L(i)) where 0 < i < n So the LIS problem has optimal - * substructure property as the main problem can be solved using solutions to sub-problems. - * - * @param arr - * @return - */ - public static int getLongestIncreasingSubSequenceLength(int[] arr) { - int len = arr.length, maxLisLength = 0; - int[] lis = new int[len]; - - for (int i = 0; i < len; i++) { - lis[i] = 1; - } - - for (int i = 1; i < len; i++) { - for (int j = 0; j < i; j++) { - if (arr[i] > arr[j] && lis[i] < lis[j] + 1) - lis[i] = lis[j] + 1; - } - } - - for (int i = 0; i < len; i++) { - if (lis[i] > maxLisLength) { - maxLisLength = lis[i]; - } - } - - return maxLisLength; - } - - public static void main(String[] args) { - System.out.println(getLongestIncreasingSubSequenceLength(new int[]{2, 3, 7, 8, 15})); - System.out.println(getLongestIncreasingSubSequenceLength(new int[]{2, 20, 7, 8, 1})); - System.out.println(getLongestIncreasingSubSequenceLength(new int[]{20, 10, 5})); - } -} diff --git a/src/main/java/com/rampatra/dynamicprogramming/MaximumRectangleOf1sInMatrix.java b/src/main/java/com/rampatra/dynamicprogramming/MaximumRectangleOf1sInMatrix.java deleted file mode 100644 index b49f55b6..00000000 --- a/src/main/java/com/rampatra/dynamicprogramming/MaximumRectangleOf1sInMatrix.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.rampatra.dynamicprogramming; - -import com.rampatra.stacks.MaxRectangleAreaInHistogram; - -/** - * Given a 2D matrix of 0s and 1s. Find the largest rectangle of all 1s in this matrix. - *

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

- * Note: If the number of cols is too large as compared to rows then you can process the matrix column-wise and create - * the histogram for each column. In this way the hist[] array will be of size = number of rows in the matrix. - * - * @author rampatra - * @since 2019-04-05 - */ -public class MaximumRectangleOf1sInMatrix { - - private static int getMaxRectangleSizeOf1s(int[][] binaryMatrix) { - int area; - int maxArea = 0; - int[] hist = new int[binaryMatrix[0].length]; - - /* - Create a histogram with the rows. Start with the first row, create a histogram and then extend this - histogram based on the elements in the next rows. If the element in the row is a 0 then make the bar in - the histogram 0 or else just increase the bar in the histogram. - - Basically, we are creating a histogram with all the 1s in the matrix and then finding the maximum - rectangle size of this histogram. - */ - for (int row = 0; row < binaryMatrix.length; row++) { - for (int col = 0; col < binaryMatrix[0].length; col++) { - if (binaryMatrix[row][col] == 0) { - hist[col] = 0; - } else { - hist[col] += binaryMatrix[row][col]; - } - } - area = MaxRectangleAreaInHistogram.getMaxRectangleArea(hist); - maxArea = Math.max(maxArea, area); - } - return maxArea; - } - - public static void main(String[] args) { - System.out.println(getMaxRectangleSizeOf1s( - new int[][]{{0, 1, 1}, - {0, 0, 1}, - {0, 1, 1}})); - - System.out.println(getMaxRectangleSizeOf1s( - new int[][]{{0, 1, 1, 1, 0}, - {0, 0, 1, 1, 0}, - {0, 1, 1, 1, 0}})); - - System.out.println(getMaxRectangleSizeOf1s( - new int[][]{{1, 1, 1, 0}, - {1, 1, 1, 1}, - {0, 1, 1, 0}, - {0, 1, 1, 1}, - {1, 0, 0, 1}, - {1, 1, 1, 1}})); - - // edge cases - System.out.println(getMaxRectangleSizeOf1s( - new int[][]{{}})); - - System.out.println(getMaxRectangleSizeOf1s( - new int[][]{{0}})); - - System.out.println(getMaxRectangleSizeOf1s( - new int[][]{{0, 0, 0}})); - - System.out.println(getMaxRectangleSizeOf1s( - new int[][]{{1}})); - } -} diff --git a/src/main/java/com/rampatra/dynamicprogramming/MinimumJumpsToReachEnd.java b/src/main/java/com/rampatra/dynamicprogramming/MinimumJumpsToReachEnd.java deleted file mode 100644 index bbc6a40f..00000000 --- a/src/main/java/com/rampatra/dynamicprogramming/MinimumJumpsToReachEnd.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.rampatra.dynamicprogramming; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 9/20/15 - * @time: 1:18 PM - */ -public class MinimumJumpsToReachEnd { - - /** - * Given an array of integers where each element represents the max number of steps that - * can be made forward from that element. Write a function to return the minimum number - * of jumps to reach the end of the array (starting from the first element). If an element - * is 0, then we cannot move through that element. - *

- * A naive approach is to start from the first element and recursively call for all the elements - * reachable from first element. The minimum number of jumps to reach end from first can be calculated - * using minimum number of jumps needed to reach end from the elements reachable from first. - *

- * minJumps(start, end) = Min ( minJumps(k, end) ) for all k reachable from start - * - * @param a - * @param l - * @param h - * @return - */ - public static int getMinimumJumpsToReachEndNaive(int[] a, int l, int h) { - // base cases - if (l == h) return 0; - if (a[l] == 0) return Integer.MAX_VALUE; - - int minJumps = Integer.MAX_VALUE; - for (int i = l + 1; i <= h && i <= a[l] + l; i++) { - int jumps = getMinimumJumpsToReachEndNaive(a, i, h); - if (jumps + 1 < minJumps) { - minJumps = jumps + 1; - } - } - return minJumps; - } - - // TODO dp approach - - public static void main(String[] args) { - int[] ar = new int[]{1, 3, 5, 8, 9, 2, 6, 7, 6, 8, 9}; - System.out.println(getMinimumJumpsToReachEndNaive(ar, 0, ar.length - 1)); - ar = new int[]{5, 4, 3, 2, 1}; - System.out.println(getMinimumJumpsToReachEndNaive(ar, 0, ar.length - 1)); - ar = new int[]{1, 2, 3, 4, 5}; - System.out.println(getMinimumJumpsToReachEndNaive(ar, 0, ar.length - 1)); - ar = new int[]{1, 2}; - System.out.println(getMinimumJumpsToReachEndNaive(ar, 0, ar.length - 1)); - ar = new int[]{1, 1, 1, 1, 1}; - System.out.println(getMinimumJumpsToReachEndNaive(ar, 0, ar.length - 1)); - } -} diff --git a/src/main/java/com/rampatra/java8/DateTime.java b/src/main/java/com/rampatra/java8/DateTime.java deleted file mode 100644 index c564b7b4..00000000 --- a/src/main/java/com/rampatra/java8/DateTime.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.rampatra.java8; - -import java.time.Instant; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.util.Date; - -/** - * @author rampatra - * @since 2019-05-15 - */ -public class DateTime { - - private static long getCurrentTimestampFromInstant() { - return Instant.now().toEpochMilli(); - } - - private static String addTwoDays() { - LocalDateTime now = LocalDateTime.ofInstant(Instant.now(), ZoneId.of("UTC")); - LocalDateTime afterTwoDays = now.plusDays(2); - return afterTwoDays.getDayOfMonth() + "-" + afterTwoDays.getMonthValue() + "-" + afterTwoDays.getYear(); - } - - public static void main(String[] args) { - System.out.println("Timestamp from Instant: " + getCurrentTimestampFromInstant() + - "\nTimestamp from Legacy Date: " + new Date().getTime()); - System.out.println("Add Two days: " + addTwoDays()); - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/java8/FlatMapInStreams.java b/src/main/java/com/rampatra/java8/FlatMapInStreams.java deleted file mode 100644 index e5258deb..00000000 --- a/src/main/java/com/rampatra/java8/FlatMapInStreams.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.rampatra.java8; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * @author rampatra - * @version 17/02/2017 - */ -public class FlatMapInStreams { - - public static long countTotalIngredientsInAllDishes(List dishes) { - return dishes.stream() - .map(Dish::getIngredients) - .flatMap(List::stream) - .count(); - } - - public static void main(String[] args) { - List ingredients = new ArrayList<>(); - ingredients.add("rice"); - ingredients.add("chicken"); - ingredients.add("haldi"); - List dishes = Arrays.asList( - new Dish("biriyani", 600, ingredients), - new Dish("pulao", 600, new ArrayList<>())); - // to show whether empty List is counted in flatMap - System.out.println(countTotalIngredientsInAllDishes(dishes)); - } -} - -class Dish { - private String name; - private int calories; - private List ingredients; - - public Dish(String name, int calories, List ingredients) { - this.name = name; - this.calories = calories; - this.ingredients = ingredients; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public int getCalories() { - return calories; - } - - public void setCalories(int calories) { - this.calories = calories; - } - - public List getIngredients() { - return ingredients; - } - - public void setIngredients(List ingredients) { - this.ingredients = ingredients; - } -} diff --git a/src/main/java/com/rampatra/java8/Lambdas.java b/src/main/java/com/rampatra/java8/Lambdas.java deleted file mode 100644 index 2450d80c..00000000 --- a/src/main/java/com/rampatra/java8/Lambdas.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.rampatra.java8; - -import java.util.function.Consumer; - -/** - * @author rampatra - * @version 21/02/2017 - */ -public class Lambdas { - - private int a = 1; - - public void testScopeOfLambda(Consumer consumer) { - consumer.accept("Lambda"); - } - - public static void main(String[] args) { - Lambdas l = new Lambdas(); - l.testScopeOfLambda(x -> System.out.println(x)); - l.testScopeOfLambda(x -> System.out.println(x + l.a)); - l.a = 2; - l.testScopeOfLambda(x -> System.out.println(x + l.a)); - /*for (int i = 0; i < 10; i++) { - l.testScopeOfLambda(x -> System.out.println(x + i)); - }*/ - /*l.testScopeOfLambda(x -> { - int a = 2; - System.out.println(x + l.a); - });*/ - l.testScopeOfLambda(new Consumer() { - int a = 2; - - @Override - public void accept(String s) { - - } - }); - } -} diff --git a/src/main/java/com/rampatra/java8/Streams.java b/src/main/java/com/rampatra/java8/Streams.java deleted file mode 100644 index 86cd0336..00000000 --- a/src/main/java/com/rampatra/java8/Streams.java +++ /dev/null @@ -1,153 +0,0 @@ -package com.rampatra.java8; - -import java.util.Arrays; -import java.util.List; - -import static java.util.Comparator.comparing; -import static java.util.stream.Collectors.toList; - -/** - * @author rampatra - * @version 02/02/2017 - */ -class Trader { - - private final String name; - private final String city; - - public Trader(String n, String c) { - this.name = n; - this.city = c; - } - - public String getName() { - return this.name; - } - - public String getCity() { - return this.city; - } - - public String toString() { - return "Trader:" + this.name + " in " + this.city; - } -} - -class Transaction { - private final Trader trader; - private final int year; - private final int value; - - public Transaction(Trader trader, int year, int value) { - this.trader = trader; - this.year = year; - this.value = value; - } - - public Trader getTrader() { - return this.trader; - } - - public int getYear() { - return this.year; - } - - public int getValue() { - return this.value; - } - - public String toString() { - return "{" + this.trader + ", " + - "year: " + this.year + ", " + - "value:" + this.value + "}"; - } -} - -public class Streams { - - static final Trader raoul = new Trader("Raoul", "Cambridge"); - static final Trader mario = new Trader("Mario", "Milan"); - static final Trader alan = new Trader("Alan", "Cambridge"); - static final Trader brian = new Trader("Brian", "Cambridge"); - - static final List transactions = Arrays.asList( - new Transaction(brian, 2011, 300), - new Transaction(raoul, 2012, 1000), - new Transaction(raoul, 2011, 400), - new Transaction(mario, 2012, 710), - new Transaction(mario, 2012, 700), - new Transaction(alan, 2012, 950) - ); - - public static List getTransactionsIn2011SortedByValue() { - return transactions.stream() - .filter(t -> t.getYear() == 2011) - .sorted(comparing(Transaction::getValue)) - .collect(toList()); - } - - public static List findUniqueCities() { - return transactions.stream() - .map(t -> t.getTrader().getCity()) - .distinct() - .collect(toList()); - } - - public static List getAllTradersFromCambridgeAndSortByName() { - return transactions.stream() - .map(Transaction::getTrader) - .filter(traders -> traders.getCity().equals("Cambridge")) - .distinct() - .sorted(comparing(Trader::getName)) - .collect(toList()); - } - - public static List getAllTraderNamesAndSortByName() { - return transactions.stream() - .map(t -> t.getTrader().getName()) - .distinct() - .sorted() - .collect(toList()); - } - - public static boolean areAnyTradersFromMilan() { - return transactions.stream() - .anyMatch(t -> "Milan".equals(t.getTrader().getCity())); - } - - public static Integer[] getAllTransValuesFromTradersInCambridge() { - return transactions.stream() - .filter(t -> "Cambridge".equals(t.getTrader().getCity())) - .map(Transaction::getValue) - .toArray(Integer[]::new); - } - - public static int findHighestTransactionValue() { - return transactions.stream() - .mapToInt(Transaction::getValue) - .max().getAsInt(); - - /* this is another solution - return transactions.stream() - .map(Transaction::getValue) - .reduce((t1, t2) -> (t1 > t2) ? t1 : t2) // you can replace with .reduce(Integer::max) - .get();*/ - } - - public static Transaction getSmallestTransaction() { - return transactions.stream() - .reduce((t1, t2) -> t1.getValue() < t2.getValue() ? t1 : t2) - .get(); - } - - public static void main(String[] args) { - System.out.println("1: " + getTransactionsIn2011SortedByValue()); - System.out.println("2: " + findUniqueCities()); - System.out.println("3: " + getAllTradersFromCambridgeAndSortByName()); - System.out.println("4: " + getAllTraderNamesAndSortByName()); - System.out.println("5: " + areAnyTradersFromMilan()); - System.out.println("6: " + Arrays.asList(getAllTransValuesFromTradersInCambridge())); - System.out.println("7: " + findHighestTransactionValue()); - System.out.println("8: " + getSmallestTransaction()); - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/linkedlists/AddNumbersInTwoLists.java b/src/main/java/com/rampatra/linkedlists/AddNumbersInTwoLists.java deleted file mode 100644 index e32e3336..00000000 --- a/src/main/java/com/rampatra/linkedlists/AddNumbersInTwoLists.java +++ /dev/null @@ -1,150 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/2/15 - * @time: 1:20 PM - */ -public class AddNumbersInTwoLists { - - /** - * Adds two numbers represented by two linked lists {@param list1} - * and {@param list2} (where first node is the least significant - * digit) and stores them in another list. - *

- * Example: - *

- * Input: - * First List: 5->6->3 // represents number 365 - * Second List: 8->4->2 // represents number 248 - * Output: - * Resultant list: 3->1->6 // represents number 613 - *

- * Input: - * First List: 7->5->9->4->6 // represents number 64957 - * Second List: 8->4 // represents number 48 - * Output: - * Resultant list: 5->0->0->5->6 // represents number 65005 - * - * @param list1 - * @param list2 - * @return list containing the sum of numbers in {@param list1} and {@param list2}. - */ - public static SingleLinkedList addWithNode1LSD(SingleLinkedList list1, - SingleLinkedList list2) { - - int sum, carry = 0; - SingleLinkedNode curr1 = list1.head, curr2 = list2.head; - SingleLinkedList resultList = new SingleLinkedList<>(); - - // loop till both of the list runs out - while (curr1 != null || curr2 != null) { - - // if either of the list runs out first - int a = (curr1 != null) ? curr1.item : 0; - int b = (curr2 != null) ? curr2.item : 0; - - sum = (a + b + carry) % 10; - carry = (a + b + carry) / 10; - resultList.add(sum); - - if (curr1 != null) curr1 = curr1.next; - if (curr2 != null) curr2 = curr2.next; - } - - // if there is any carry left over, add it to the result - if (carry != 0) resultList.addFirst(carry); - - return resultList; - } - - /** - * Adds two numbers represented by two linked lists {@param list1} - * and {@param list2} (where first node is the most significant - * digit) and stores them in another list. - *

- * Example: - *

- * Input: - * First List: 5->6->3 // represents number 563 - * Second List: 8->4->2 // represents number 842 - * Output: - * Resultant list: 1->4->0->5 // represents number 1405 - *

- * Input: - * First List: 7->5->9->4->6 // represents number 75946 - * Second List: 8->4 // represents number 84 - * Output: - * Resultant list: 7->6->0->3->0 // represents number 76030 - * - * @param list1 - * @param list2 - * @return - */ - public static SingleLinkedList addWithNode1MSD(SingleLinkedList list1, - SingleLinkedList list2) { - ReverseSingleLinkedList.reverseList(list1); - ReverseSingleLinkedList.reverseList(list2); - - SingleLinkedList resultList = addWithNode1LSD(list1, list2); - - ReverseSingleLinkedList.reverseList(resultList); - - return resultList; - } - - /** - * Adds the numbers in two lists (where first node is the least significant - * digit) and prints the sum. - *

- * Example: - *

- * Input: - * First List: 5->6->3 // represents number 365 - * Second List: 8->4->2 // represents number 248 - * Output: - * 613 // represents number 613 - * - * @param l1 - * @param l2 - */ - private static void printSumWithNode1LSD(SingleLinkedList l1, SingleLinkedList l2) { - System.out.println(convertToInt(l1) + convertToInt(l2)); - } - - private static int convertToInt(SingleLinkedList list) { - int num = 0; - int baseValue = 1; - SingleLinkedNode temp = list.head; - while (temp != null) { - num += (temp.item * baseValue); - baseValue *= 10; - temp = temp.next; - } - return num; - } - - public static void main(String[] args) { - SingleLinkedList linkedList1 = new SingleLinkedList<>(); - linkedList1.add(7); - linkedList1.add(5); - linkedList1.add(9); - linkedList1.add(4); - linkedList1.add(6); - linkedList1.printList(); - SingleLinkedList linkedList2 = new SingleLinkedList<>(); - linkedList2.add(8); - linkedList2.add(4); - linkedList2.printList(); - addWithNode1LSD(linkedList1, linkedList2).printList(); - System.out.println("--------------"); - addWithNode1MSD(linkedList1, linkedList2).printList(); - System.out.println("--------------"); - printSumWithNode1LSD(linkedList1, linkedList2); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/CloneWithRandPointers.java b/src/main/java/com/rampatra/linkedlists/CloneWithRandPointers.java deleted file mode 100644 index 53795113..00000000 --- a/src/main/java/com/rampatra/linkedlists/CloneWithRandPointers.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.DoubleLinkedList; -import com.rampatra.base.DoubleLinkedNode; - -/** - * Find the question here. - * - * @author rampatra - * @since 6/20/15 - */ -public class CloneWithRandPointers { - - /** - * Clones a linked list with next pointer pointing to the - * next node and prev pointer pointing to any random node. - * - * @param list - * @param - * @return - */ - public static > DoubleLinkedList clone(DoubleLinkedList list) { - DoubleLinkedNode firstNode = list.getNode(0); - DoubleLinkedNode curr = firstNode; - - // copy each node and insert after it - while (curr != null) { - curr.next = new DoubleLinkedNode<>(null, curr.item, curr.next); - curr = curr.next.next; - } - - // copy all random pointers from original node to the copied node - curr = firstNode; - while (curr != null && curr.next != null) { - curr.next.prev = (curr.prev != null) ? curr.prev.next : null; - curr = curr.next.next; - } - - // separate the copied nodes into a different linked list - curr = firstNode; - DoubleLinkedNode cloneHead = firstNode.next; - DoubleLinkedNode dupNode; - while (curr != null && curr.next != null) { - dupNode = curr.next; - curr.next = dupNode.next; - dupNode.next = (curr.next != null) ? curr.next.next : null; - curr = curr.next; - } - - return DoubleLinkedList.getLinkedList(cloneHead); - } - - public static void main(String[] args) { - DoubleLinkedList linkedList = new DoubleLinkedList<>(); - linkedList.add(0); - linkedList.add(1); - linkedList.add(2); - linkedList.add(3); - linkedList.getNode(0).prev = null; - linkedList.getNode(1).prev = linkedList.getNode(2); - linkedList.getNode(2).prev = linkedList.getNode(0); - linkedList.getNode(3).prev = linkedList.getNode(1); - System.out.println("======Original======"); - linkedList.printList(); - DoubleLinkedList clonedList = clone(linkedList); - System.out.println("======Cloned======"); - clonedList.printList(); - System.out.println("======Cloned (Modified)======"); - clonedList.set(0, 234); - clonedList.set(1, 567); - clonedList.printList(); - System.out.println("======Original======"); - linkedList.printList(); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/DeleteAlternateNodes.java b/src/main/java/com/rampatra/linkedlists/DeleteAlternateNodes.java deleted file mode 100644 index 45670941..00000000 --- a/src/main/java/com/rampatra/linkedlists/DeleteAlternateNodes.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Delete alternate nodes in a single linked list. - * - * @author rampatra - * @since 6/27/15 - */ -public class DeleteAlternateNodes { - - public static > void deleteAlternateNodes(SingleLinkedList list) { - deleteAlternateNodes(list.head); - } - - public static > void deleteAlternateNodes(SingleLinkedNode node) { - if (node == null || node.next == null) return; - - node.next = node.next.next; - - deleteAlternateNodes(node.next); - } - - public static void main(String[] args) { - SingleLinkedList linkedList = new SingleLinkedList<>(); - linkedList.add(0); - linkedList.add(1); - linkedList.add(2); - linkedList.add(3); - linkedList.add(4); - linkedList.add(5); - linkedList.printList(); - deleteAlternateNodes(linkedList); - linkedList.printList(); - - } -} diff --git a/src/main/java/com/rampatra/linkedlists/DeleteLesserNodes.java b/src/main/java/com/rampatra/linkedlists/DeleteLesserNodes.java deleted file mode 100644 index 0dbc734a..00000000 --- a/src/main/java/com/rampatra/linkedlists/DeleteLesserNodes.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/30/15 - * @time: 5:13 PM - */ -public class DeleteLesserNodes { - - /** - * Delete a node from {@param list} if there are any nodes - * with values greater than node on the right hand side of the list. - *

- * Example: - *

- * Input: 12->15->10->11->5->6->2->3->NULL - * Output: 15->11->6->3->NULL - *

- * Input: 10->20->30->40->50->60->NULL - * Output: 60->NULL - *

- * Input: 60->50->40->30->20->10->NULL - * Output: 60->50->40->30->20->10->NULL - * - * @param list - * @param - */ - public static > void deleteLesserNodes(SingleLinkedList list) { - - // reverse the list - ReverseSingleLinkedList.reverseList(list); - - E max; - SingleLinkedNode curr = list.getNode(0), prev = curr; - - max = curr.item; - - while (curr != null) { - if (curr.item.compareTo(max) >= 0) { - max = curr.item; - prev = curr; - } else { - prev.next = curr.next; - } - - curr = curr.next; - } - - // reverse the list - ReverseSingleLinkedList.reverseList(list); - } - - - /** - * Recursive version of {@link #deleteLesserNodes(SingleLinkedList)}. - * - * @param node - * @param - * @return - */ - public static > SingleLinkedNode deleteLesserNodes(SingleLinkedNode node) { - if (node == null) return null; - - SingleLinkedNode next = deleteLesserNodes(node.next); - node.next = next; - - if (next != null && node.item.compareTo(next.item) < 0) { - return next; - } else { - return node; - } - } - - public static void main(String[] args) { - SingleLinkedList linkedList = new SingleLinkedList<>(); - linkedList.add(00); - linkedList.add(11); - linkedList.add(22); - linkedList.add(33); - linkedList.add(44); - linkedList.add(55); - linkedList.add(66); - linkedList.printList(); - deleteLesserNodes(linkedList); - linkedList.printList(); - // for recursive version - linkedList.add(00); - linkedList.add(11); - linkedList.add(22); - linkedList.add(33); - linkedList.add(44); - linkedList.add(55); - linkedList.printList(); - linkedList.printList(deleteLesserNodes(linkedList.head)); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/DeleteMnodesAfterNnodes.java b/src/main/java/com/rampatra/linkedlists/DeleteMnodesAfterNnodes.java deleted file mode 100644 index 005aef06..00000000 --- a/src/main/java/com/rampatra/linkedlists/DeleteMnodesAfterNnodes.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/6/15 - * @time: 7:43 PM - */ -public class DeleteMnodesAfterNnodes { - - /** - * Deletes {@param n} nodes after every {@param m} nodes in {@param list} - * till it reaches the end of {@param list}. - * - * @param list - * @param m - * @param n - * @param - */ - public static > void deleteMnodesAfterNnodes(SingleLinkedList list, - int m, int n) { - - SingleLinkedNode curr1 = list.head, curr2; - - while (curr1 != null) { - - // skip m nodes - for (int i = 1; curr1.next != null && i < m; i++) { - curr1 = curr1.next; - } - - // delete n nodes - curr2 = curr1; - for (int i = 0; curr2 != null && i <= n; i++) { - curr2 = curr2.next; - } - curr1.next = curr2; - - curr1 = curr1.next; - } - } - - public static void main(String[] args) { - SingleLinkedList linkedList = new SingleLinkedList<>(); - linkedList.add(7); - linkedList.add(5); - linkedList.add(9); - linkedList.add(4); - linkedList.add(6); - linkedList.add(1); - linkedList.add(2); - linkedList.add(7); - linkedList.add(5); - linkedList.add(9); - linkedList.add(4); - linkedList.add(6); - linkedList.add(1); - linkedList.add(2); - linkedList.printList(); - deleteMnodesAfterNnodes(linkedList, 3, 2); - linkedList.printList(); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/DeleteNode.java b/src/main/java/com/rampatra/linkedlists/DeleteNode.java deleted file mode 100644 index 82d8c3d7..00000000 --- a/src/main/java/com/rampatra/linkedlists/DeleteNode.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/18/15 - * @time: 2:35 PM - */ -public class DeleteNode { - - /** - * Given a pointer to a node, delete it. - * - * @param node - * @param - */ - public static > void deleteNode(SingleLinkedNode node) { - // assert node isn't the last node in the linked list - node.item = node.next.item; - node.next = node.next.next; - } - - public static void main(String[] args) { - SingleLinkedList linkedList = new SingleLinkedList<>(); - linkedList.add(0); - linkedList.add(1); - linkedList.add(2); - linkedList.printList(); - deleteNode(linkedList.getNode(1)); - linkedList.printList(); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/DetectAndRemoveLoop.java b/src/main/java/com/rampatra/linkedlists/DetectAndRemoveLoop.java deleted file mode 100644 index 5ad549d4..00000000 --- a/src/main/java/com/rampatra/linkedlists/DetectAndRemoveLoop.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * See this Stackoverflow post to understand - * how to find the starting node of the loop. - *

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

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

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

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

- * Approach: - * 1) Use Floyd's cycle detection algorithm to detect loop. - * 2) Acc. to FCD, once the fast pointer meets the slow pointer we conclude that there is a loop. - * 4) Now that we have concluded there is a loop, let's detect the starting node and remove the loop: - * i. Move the slow pointer to head. - * ii. Now, move both slow and fast pointer at same pace and where they meet is the starting point of the loop. - * iii. Lastly, to remove the loop make the next of the node (before the starting point of loop) to null. - * - * Proof for Floyd's Cycle Detection: Consider a cyclic list and imagine the slow and fast pointers are two runners - * racing around a circle track. The fast runner will eventually meet the slow runner. Why? Consider this case - - * The fast runner is just one step behind the slow runner. In the next iteration, they both increment one and two - * steps respectively and meet each other. - * - * @param list - * @param - * @return {@code true} if loop exists {@code false} otherwise. - */ - public static > boolean detectAndRemoveLoop(SingleLinkedList list) { - boolean isLoopPresent = false; - SingleLinkedNode slow = list.head, fast = list.head; - - while (fast != null && fast.next != null) { - slow = slow.next; - fast = fast.next.next; - if (slow == fast) { - isLoopPresent = true; - break; - } - } - - if (!isLoopPresent) return false; - - slow = list.head; - // move both pointers at same pace to determine the starting node of loop - while (true) { - slow = slow.next; - fast = fast.next; - if (slow == fast) { - fast.next = null; - break; - } - } - - return isLoopPresent; - } - - public static void main(String[] args) { - SingleLinkedList linkedList = new SingleLinkedList<>(); - linkedList.add(0); - linkedList.add(1); - linkedList.add(2); - linkedList.add(3); - linkedList.add(4); - linkedList.add(5); - linkedList.getNode(4).next = linkedList.getNode(2); - System.out.println(detectAndRemoveLoop(linkedList)); - linkedList.printList(); - - linkedList = new SingleLinkedList<>(); - linkedList.add(0); - linkedList.add(1); - linkedList.getNode(1).next = linkedList.getNode(0); - System.out.println(detectAndRemoveLoop(linkedList)); - linkedList.printList(); - - linkedList = new SingleLinkedList<>(); - linkedList.add(0); - System.out.println(detectAndRemoveLoop(linkedList)); - linkedList.printList(); - - linkedList = new SingleLinkedList<>(); - linkedList.add(0); - linkedList.getNode(0).next = linkedList.getNode(0); - System.out.println(detectAndRemoveLoop(linkedList)); - linkedList.printList(); - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/linkedlists/DetectLoop.java b/src/main/java/com/rampatra/linkedlists/DetectLoop.java deleted file mode 100644 index 45bd6b6f..00000000 --- a/src/main/java/com/rampatra/linkedlists/DetectLoop.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -import java.util.HashMap; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/19/15 - */ -public class DetectLoop { - - /** - * Uses Flyod's Cycle Finding algorithm. - *

- * This is the fastest method. Traverse - * linked list using two pointers. Move one - * pointer by one and other pointer by two. - * If these pointers meet at some node then - * there is a loop. If pointers do not meet - * then linked list does not have loop. - *

- * Level: Easy - * Time Complexity: O(n) - * Space Complexity: O(1) - * - * @param list - * @return - */ - public static > boolean isLoopPresent(SingleLinkedList list) { - SingleLinkedNode slow = list.head, fast = list.head; - while (fast != null && fast.next != null) { - slow = slow.next; - fast = fast.next.next; - if (slow == fast) { - return true; - } - } - return false; - } - - /** - * Uses HashMap to store visited nodes. - *

- * Time Complexity: O(n) - * Space Complexity: O(n) - * - * @param node - * @return - */ - public static > boolean isLoopPresentUsingHashMap(SingleLinkedNode node) { - HashMap, Boolean> map = new HashMap<>(); - SingleLinkedNode curr = node; - while (curr != null) { - if (map.get(curr) != null && map.get(curr)) { - return true; - } - map.put(curr, true); - curr = curr.next; - } - return false; - } - - public static void main(String[] args) { - SingleLinkedList linkedList = new SingleLinkedList<>(); - linkedList.add(0); - linkedList.add(1); - linkedList.add(2); - linkedList.add(3); - linkedList.add(4); - linkedList.add(5); - linkedList.getNode(4).next = linkedList.getNode(3); - System.out.println(isLoopPresent(linkedList)); - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/linkedlists/DivideCircularListIntoTwo.java b/src/main/java/com/rampatra/linkedlists/DivideCircularListIntoTwo.java deleted file mode 100644 index b19af007..00000000 --- a/src/main/java/com/rampatra/linkedlists/DivideCircularListIntoTwo.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.CircularSingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/23/15 - * @time: 6:01 PM - */ -public class DivideCircularListIntoTwo> extends CircularSingleLinkedList { - - public static > CircularSingleLinkedList[] divideIntoTwoHalves(CircularSingleLinkedList list) { - SingleLinkedNode middleNode = list.getNode(list.size - 1 >> 1), - lastNode = list.getNode(list.size - 1), - secondHead = middleNode.next; - // make the 2nd half circular first - lastNode.next = middleNode.next; - // then make the 1st half circular - middleNode.next = list.head; - - return new CircularSingleLinkedList[]{getLinkedList(list.head), getLinkedList(secondHead)}; - } - - public static void main(String[] args) { - CircularSingleLinkedList linkedList = new CircularSingleLinkedList<>(); - linkedList.add(00); - linkedList.add(11); - linkedList.add(22); - linkedList.add(33); - linkedList.add(44); - CircularSingleLinkedList linkedLists[] = divideIntoTwoHalves(linkedList); - linkedLists[0].printList(); - linkedLists[1].printList(); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/FlattenMultiLevelLinkedList.java b/src/main/java/com/rampatra/linkedlists/FlattenMultiLevelLinkedList.java deleted file mode 100644 index 5f9434ed..00000000 --- a/src/main/java/com/rampatra/linkedlists/FlattenMultiLevelLinkedList.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.DoubleLinkedNode; - -import static java.lang.System.out; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/26/15 - */ -public class FlattenMultiLevelLinkedList { - - /** - * Flattens a multilevel linked list into a single level linked list. You can - * {@see http://www.geeksforgeeks.org/flatten-a-linked-list-with-next-and-child-pointers/} for - * clarity on question. - *

- * Solution: - * 1) Take "cur" pointer, which will point to head of the fist level of the list - * 2) Take "tail" pointer, which will point to end of the first level of the list - * 3) Repeat the below procedure while "curr" is not NULL. - * I) if current node has a child then - * a) append this new child list to the "tail" - * tail->next = cur->child - * b) find the last node of new child list and update "tail" - * while (tail->next != null) { - * tail = tail->next; - * } - * II) move to the next node. i.e. cur = cur->next - * - * @param node - * @param - * @return - */ - public static > DoubleLinkedNode flatten(DoubleLinkedNode node) { - DoubleLinkedNode curr = node, tail; - - // set tail to last node in 1st level - while (curr.next != null) { - curr = curr.next; - } - tail = curr; - - curr = node; - while (curr != null) { - if (curr.prev != null) { - // append child to tail - tail.next = curr.prev; - // update tail - while (tail.next != null) { - tail = tail.next; - } - } - curr = curr.next; - } - return node; - } - - /** - * Prints the list. - * - * @param node - * @param - */ - public static > void printList(DoubleLinkedNode node) { - DoubleLinkedNode curr = node; - out.print("["); - if (curr == null) { - out.println("]"); - return; - } - while (curr.next != null) { - out.print(curr.item.toString() + ","); - curr = curr.next; - } - out.println(curr.item.toString() + "]"); - } - - public static void main(String[] args) { - // 1st level - DoubleLinkedNode head = new DoubleLinkedNode<>(1); - head.next = new DoubleLinkedNode<>(5); - head.next.next = new DoubleLinkedNode<>(4); - head.next.next.next = new DoubleLinkedNode<>(8); - head.next.next.next.next = new DoubleLinkedNode<>(9); - // 2nd level under node 1 - head.prev = new DoubleLinkedNode<>(10); - head.prev.next = new DoubleLinkedNode<>(10); - head.prev.next.next = new DoubleLinkedNode<>(12); - head.prev.next.next.next = new DoubleLinkedNode<>(14); - // 2nd level under node 2 - head.next.prev = new DoubleLinkedNode<>(16); - head.next.prev.next = new DoubleLinkedNode<>(17); - head.next.prev.next.next = new DoubleLinkedNode<>(18); - head.next.prev.next.next.next = new DoubleLinkedNode<>(20); - // 3rd level under node 2 - head.next.prev.prev = new DoubleLinkedNode<>(22); - head.next.prev.prev.next = new DoubleLinkedNode<>(24); - head.next.prev.prev.next.next = new DoubleLinkedNode<>(26); - head.next.prev.prev.next.next.next = new DoubleLinkedNode<>(28); - // after flattening - printList(flatten(head)); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/Identical.java b/src/main/java/com/rampatra/linkedlists/Identical.java deleted file mode 100644 index a4aa0d1c..00000000 --- a/src/main/java/com/rampatra/linkedlists/Identical.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/29/15 - */ -public class Identical { - - /** - * Returns {@code true} if linked list {@param list1} and {@param list2} - * are identical i.e, the data in the nodes as well as their arrangements are - * similar. Ex: 1->2->3 and 1->2->3 are identical. - * - * @param list1 - * @param list2 - * @param - * @return - */ - private static > boolean isIdentical(SingleLinkedList list1, - SingleLinkedList list2) { - - // base cases - if (list1.size != list2.size) { - return false; - } else if (list1.size == 0) { - return true; - } - - SingleLinkedNode curr1 = list1.getNode(0), curr2 = list2.getNode(0); - - while (curr1 != null && curr2 != null) { - if (!curr1.item.equals(curr2.item)) { - return false; - } - curr1 = curr1.next; - curr2 = curr2.next; - } - - return true; - } - - public static void main(String[] args) { - SingleLinkedList linkedList1 = new SingleLinkedList<>(); - linkedList1.add(0); - linkedList1.add(1); - linkedList1.add(2); - linkedList1.add(3); - linkedList1.add(4); - linkedList1.add(5); - linkedList1.add(6); - linkedList1.printList(); - SingleLinkedList linkedList2 = new SingleLinkedList<>(); - linkedList2.add(0); - linkedList2.add(1); - linkedList2.add(2); - linkedList2.add(3); - linkedList2.add(4); - linkedList2.add(5); - linkedList2.add(6); - linkedList2.printList(); - System.out.println(isIdentical(linkedList1, linkedList2)); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/InsertInSortedCircularLinkedList.java b/src/main/java/com/rampatra/linkedlists/InsertInSortedCircularLinkedList.java deleted file mode 100644 index a04b48bc..00000000 --- a/src/main/java/com/rampatra/linkedlists/InsertInSortedCircularLinkedList.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.CircularSingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/29/15 - * @time: 6:16 PM - */ -public class InsertInSortedCircularLinkedList> extends CircularSingleLinkedList { - - /** - * Inserts an element in the sorted circular - * linked list maintaining the sorted property. - * - * @param item - */ - public void insert(E item) { - SingleLinkedNode node = head, curr = node; - - do { - if (node.item.compareTo(item) > 0) { // new node is to be inserted before head - // last node should now point to the new head - while (curr.next != head) { - curr = curr.next; - } - head = new SingleLinkedNode<>(item, node); - curr.next = head; - return; - } else if (node.next.item.compareTo(item) > 0) { - node.next = new SingleLinkedNode<>(item, node.next); - return; - } else if (node.next == head) { - node.next = new SingleLinkedNode<>(item, head); - return; - } - node = node.next; - } while (node != head); - } - - public static void main(String[] args) { - InsertInSortedCircularLinkedList linkedList = new InsertInSortedCircularLinkedList<>(); - linkedList.add(00); - linkedList.add(11); - linkedList.add(22); - linkedList.add(33); - linkedList.printList(); - linkedList.insert(-2); - linkedList.insert(9); - linkedList.insert(44); - linkedList.printList(); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/InsertInSortedList.java b/src/main/java/com/rampatra/linkedlists/InsertInSortedList.java deleted file mode 100644 index fc0bd2b1..00000000 --- a/src/main/java/com/rampatra/linkedlists/InsertInSortedList.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/21/15 - * @time: 10:20 PM - */ -public class InsertInSortedList> extends SingleLinkedList { - - /** - * Inserts an element in the sorted linked - * list maintaining the sorted property. - * - * @param item - */ - public void insert(E item) { - SingleLinkedNode node = head; - - while (node != null) { - if (node.item.compareTo(item) > 0) { // new node is to be inserted before head - head = new SingleLinkedNode<>(item, node); - return; - } else if (node.next == null || node.next.item.compareTo(item) > 0) { // new node to be inserted anywhere else - node.next = new SingleLinkedNode<>(item, node.next); - return; - } - node = node.next; - } - } - - public static void main(String[] args) { - InsertInSortedList linkedList = new InsertInSortedList<>(); - linkedList.add(00); - linkedList.add(11); - linkedList.add(22); - linkedList.add(33); - linkedList.printList(); - linkedList.insert(-2); - linkedList.insert(9); - linkedList.insert(44); - linkedList.printList(); - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/linkedlists/IntersectionAndUnionOf2Lists.java b/src/main/java/com/rampatra/linkedlists/IntersectionAndUnionOf2Lists.java deleted file mode 100644 index f8fd3a79..00000000 --- a/src/main/java/com/rampatra/linkedlists/IntersectionAndUnionOf2Lists.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/7/15 - * @time: 1:04 PM - */ -public class IntersectionAndUnionOf2Lists { - - /** - * @param list1 - * @param list2 - * @param - * @return an array of list consisting of intersection and union of two sorted - * list {@param list1} and {@param list2} respectively. - */ - public static > SingleLinkedList[] getIntersectionAndUnion(SingleLinkedList list1, - SingleLinkedList list2) { - - SingleLinkedNode curr1 = list1.head, curr2 = list2.head; - SingleLinkedList intersectionList = new SingleLinkedList<>(), - unionList = new SingleLinkedList<>(); - - MergeSort.mergeSort(curr1); - MergeSort.mergeSort(curr2); - - while (curr1 != null || curr2 != null) { - if (curr1 == null) { - unionList.add(curr2.item); - curr2 = curr2.next; - } else if (curr2 == null) { - unionList.add(curr1.item); - curr1 = curr1.next; - } else if (curr1.item.compareTo(curr2.item) < 0) { - unionList.add(curr1.item); - curr1 = curr1.next; - } else if (curr1.item.compareTo(curr2.item) > 0) { - unionList.add(curr2.item); - curr2 = curr2.next; - } else { - unionList.add(curr1.item); - intersectionList.add(curr1.item); - curr1 = curr1.next; - curr2 = curr2.next; - } - } - - return new SingleLinkedList[]{intersectionList, unionList}; - } - - public static void main(String[] args) { - SingleLinkedList linkedList1 = new SingleLinkedList<>(); - linkedList1.add(00); - linkedList1.add(11); - linkedList1.add(22); - linkedList1.add(33); - linkedList1.add(44); - linkedList1.add(55); - linkedList1.printList(); - SingleLinkedList linkedList2 = new SingleLinkedList<>(); - linkedList2.add(21); - linkedList2.add(33); - linkedList2.add(44); - linkedList2.add(55); - linkedList2.add(67); - linkedList2.add(89); - linkedList2.printList(); - System.out.println("Intersection:"); - getIntersectionAndUnion(linkedList1, linkedList2)[0].printList(); - System.out.println("Union:"); - getIntersectionAndUnion(linkedList1, linkedList2)[1].printList(); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/IntersectionOf2SortedLists.java b/src/main/java/com/rampatra/linkedlists/IntersectionOf2SortedLists.java deleted file mode 100644 index 0213a3b9..00000000 --- a/src/main/java/com/rampatra/linkedlists/IntersectionOf2SortedLists.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/27/15 - * @time: 11:13 AM - */ -public class IntersectionOf2SortedLists { - - /** - * Returns a linked list with elements common in - * both {@param list1} and {@param list2}. - * - * @param list1 - * @param list2 - * @param - * @return - */ - public static > SingleLinkedList getIntersectionList(SingleLinkedList list1, - SingleLinkedList list2) { - - SingleLinkedNode curr1 = list1.getNode(0), curr2 = list2.getNode(0); - SingleLinkedList intersectedList = new SingleLinkedList<>(); - while (curr1 != null && curr2 != null) { - // advance the current pointer of the list having smaller {@code item} - if (curr1.item.compareTo(curr2.item) < 0) { - curr1 = curr1.next; - } else if (curr1.item.compareTo(curr2.item) > 0) { - curr2 = curr2.next; - } else { // both nodes are equal so add it to the result - intersectedList.add(curr1.item); - curr1 = curr1.next; - curr2 = curr2.next; - } - } - - return intersectedList; - } - - public static void main(String[] args) { - SingleLinkedList linkedList1 = new SingleLinkedList<>(); - linkedList1.add(00); - linkedList1.add(11); - linkedList1.add(22); - linkedList1.add(33); - linkedList1.add(44); - linkedList1.add(55); - linkedList1.printList(); - SingleLinkedList linkedList2 = new SingleLinkedList<>(); - linkedList2.add(21); - linkedList2.add(33); - linkedList2.add(44); - linkedList2.add(55); - linkedList2.add(67); - linkedList2.add(89); - linkedList2.printList(); - getIntersectionList(linkedList1, linkedList2).printList(); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/IntersectionPointOfTwoLists.java b/src/main/java/com/rampatra/linkedlists/IntersectionPointOfTwoLists.java deleted file mode 100644 index 705da489..00000000 --- a/src/main/java/com/rampatra/linkedlists/IntersectionPointOfTwoLists.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/18/15 - */ -public class IntersectionPointOfTwoLists { - - - /** - * Returns the node at which {@param list1} and {@param list2} intersect. - * - * @param list1 - * @param list2 - * @param - * @return - */ - public static > SingleLinkedNode getIntersectionNode(SingleLinkedList list1, - SingleLinkedList list2) { - - SingleLinkedNode curr1, curr2; - int diffLength = Math.abs(list1.size - list2.size); - - // forward the pointer in the longer list by their diff. in length - if (list1.size > list2.size) { - curr1 = list1.head; - curr2 = list2.head; - } else { - curr1 = list2.head; - curr2 = list1.head; - } - while (diffLength > 0) { - curr1 = curr1.next; - diffLength--; - } - - // now compare both lists node by node - while (curr1 != null) { - if (curr1 == curr2) return curr1; - curr1 = curr1.next; - curr2 = curr2.next; - } - - // lists do not intersect - return null; - } - - public static void main(String[] args) { - SingleLinkedList linkedList1 = new SingleLinkedList<>(); - linkedList1.add(0); - linkedList1.add(1); - linkedList1.add(2); - linkedList1.add(3); - linkedList1.add(4); - linkedList1.add(5); - linkedList1.add(6); - linkedList1.add(7); - linkedList1.add(8); - SingleLinkedList linkedList2 = new SingleLinkedList<>(); - linkedList2.add(56); - linkedList2.add(78); - linkedList2.add(45); - linkedList2.add(23); - linkedList2.getNode(3).next = linkedList1.getNode(5); // join 2 lists at some point - linkedList2.size = 8; // IMP: update size after joining - System.out.println(getIntersectionNode(linkedList1, linkedList2) != null ? - getIntersectionNode(linkedList1, linkedList2).item : "List don't intersect!"); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/LRUCache.java b/src/main/java/com/rampatra/linkedlists/LRUCache.java deleted file mode 100644 index ed046035..00000000 --- a/src/main/java/com/rampatra/linkedlists/LRUCache.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.rampatra.linkedlists; - -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.Map; - -/** - * A simple LRU cache using {@link LinkedHashMap}. A special - * LinkedHashMap(capacity, loadFactor, accessOrderBoolean) constructor is - * provided to create a linked hash map whose order of iteration is the - * order in which its entries were last accessed, from least-recently - * accessed to most-recently. Invoking the put or get method results - * in an access to the corresponding entry. If the enclosing Map is - * access-ordered, it moves the entry to the end of the list; otherwise, - * it does nothing. - * See Javarticles.com. - * - * @author rampatra - * @since 7/8/15 - */ -public class LRUCache { - - private LinkedHashMap linkedHashMap; - - // initialize cache - LRUCache(final int size) { - this.linkedHashMap = new LinkedHashMap(size, .75f, true) { - @Override - protected boolean removeEldestEntry(Map.Entry eldest) { - return size() > size; - } - }; - } - - V add(E key, V value) { - return linkedHashMap.put(key, value); - } - - V get(E key) { - return linkedHashMap.get(key); - } - - private void print() { - Iterator iterator = linkedHashMap.keySet().iterator(); - while (iterator.hasNext()) { - System.out.print(iterator.next() + ((iterator.hasNext()) ? "," : "\n")); - } - } - - public static void main(String[] args) { - LRUCache cache = new LRUCache<>(3); - cache.add(1, 1); - cache.add(2, 2); - cache.add(3, 3); - cache.print(); // initial cache contents - - cache.add(4, 4); // should remove 1 as it was accessed last - cache.print(); - - cache.get(2); - cache.add(5, 5); // should remove 3 as 2 was recently accessed - cache.print(); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/MaximumSumLinkedList.java b/src/main/java/com/rampatra/linkedlists/MaximumSumLinkedList.java deleted file mode 100644 index cb51fe73..00000000 --- a/src/main/java/com/rampatra/linkedlists/MaximumSumLinkedList.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/15/15 - * @time: 12:12 AM - */ -public class MaximumSumLinkedList { - - /** - * Constructs a linked list that contains maximum sum path from start to end - * from two linked lists starting at {@param node1} and {@param node2}. - *

- * Example, - * Input: - * List1 = 1->3->30->90->120->240->511 - * List2 = 0->3->12->32->90->125->240->249 - *

- * Output: Following is maximum sum linked list out of two input lists - * List = 1->3->12->32->90->125->240->511 - *

- * NOTE: We switch at 3 and 240 to get above maximum sum linked list - * - * @param node1 - * @param node2 - * @param - * @return - */ - public static > SingleLinkedNode maximumSumLinkedList(SingleLinkedNode node1, - SingleLinkedNode node2) { - - boolean isList1 = true; - SingleLinkedNode head = node1, node = node1, curr1 = node1.next, curr2 = node2.next; - - while (curr1 != null || curr2 != null) { - // if either of the list runs out first - if (curr1 == null) { - // check whether we are in list 1 currently - if (isList1) break; - - node.next = curr2; - node = node.next; - curr2 = curr2.next; - continue; - } - if (curr2 == null) { - // check whether we are in list 2 currently - if (!isList1) break; - - node.next = curr1; - node = node.next; - curr1 = curr1.next; - continue; - } - - // switch lists once both node values match - if (curr1.item.compareTo(curr2.item) == 0) { - isList1 = !isList1; - } - if (isList1) { - node.next = curr1; - } else { - node.next = curr2; - } - node = node.next; - curr1 = curr1.next; - curr2 = curr2.next; - } - - return head; - } - - public static void main(String[] args) { - SingleLinkedList linkedList1 = new SingleLinkedList<>(); - linkedList1.add(00); - linkedList1.add(11); - linkedList1.add(22); - linkedList1.add(33); - linkedList1.add(44); - linkedList1.add(55); - linkedList1.add(88); - linkedList1.add(90); - linkedList1.printList(); - SingleLinkedList linkedList2 = new SingleLinkedList<>(); - linkedList2.add(12); - linkedList2.add(21); - linkedList2.add(26); - linkedList2.add(33); - linkedList2.add(34); - linkedList2.add(67); - linkedList2.printList(); - SingleLinkedList.printList(maximumSumLinkedList(linkedList1.head, linkedList2.head)); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/MergeSort.java b/src/main/java/com/rampatra/linkedlists/MergeSort.java deleted file mode 100644 index 3ad4ad65..00000000 --- a/src/main/java/com/rampatra/linkedlists/MergeSort.java +++ /dev/null @@ -1,125 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/7/15 - * @time: 4:34 PM - */ -public class MergeSort { - - /** - * Merge sort for linked list starting at {@param node}. - *

- * Time complexity: O(n log n) - * Space complexity: O(log n) stack space as it is recursive - * - * @param node - * @param - * @return - */ - public static > SingleLinkedNode mergeSort(SingleLinkedNode node) { - if (node == null || node.next == null) return node; - - SingleLinkedNode middleNode, head1, head2; - - middleNode = divideInTwoHalves(node); - - head1 = mergeSort(node); - head2 = mergeSort(middleNode); - - return mergeTwoSortedLists(head1, head2); - - } - - - /** - * Divides a linked list starting from {@param node} into 2 halves - * and returns the starting {@code node} of the second half. - * - * @param node - * @param - * @return - */ - public static > SingleLinkedNode divideInTwoHalves(SingleLinkedNode node) { - SingleLinkedNode slow = node, fast = node, prev = slow; - - if (node == null || node.next == null) { - return null; - } - - while (fast != null && fast.next != null) { - prev = slow; - slow = slow.next; - fast = fast.next.next; - } - prev.next = null; - return slow; - } - - - /** - * Merges two sorted lists starting at {@param node1} and {@param node2} - * into one and returns its starting node. - *

- * This method is similar to {@link MergeTwoSortedLists#mergeTwoSortedLists} - * - * @param node1 - * @param node2 - * @param - * @return - */ - public static > SingleLinkedNode mergeTwoSortedLists(SingleLinkedNode node1, - SingleLinkedNode node2) { - SingleLinkedNode curr1 = node1, curr2 = node2, head, curr; - - if (node1 == null && node2 == null) return null; - - head = curr = new SingleLinkedNode<>(null); // dummy node - - while (curr1 != null || curr2 != null) { - // handle cases where either of the list run out first - if (curr1 == null) { - curr.next = curr2; - curr2 = curr2.next; - } else if (curr2 == null) { - curr.next = curr1; - curr1 = curr1.next; - } else if (curr1.item.compareTo(curr2.item) < 0) { // advance the current pointer of the - // list having smaller {@code item} - curr.next = curr1; - curr1 = curr1.next; - } else if (curr1.item.compareTo(curr2.item) > 0) { - curr.next = curr2; - curr2 = curr2.next; - } else { // both nodes are equal so add both to the result - curr.next = curr1; - curr = curr.next; - curr1 = curr1.next; - curr.next = curr2; - curr2 = curr2.next; - } - - curr = curr.next; - } - - // return the node next to the dummy node - return head.next; - } - - public static void main(String[] args) { - SingleLinkedList linkedList = new SingleLinkedList<>(); - linkedList.add(21); - linkedList.add(33); - linkedList.add(89); - linkedList.add(21); - linkedList.add(44); - linkedList.add(67); - linkedList.printList(); - linkedList.printList(mergeSort(linkedList.head)); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/MergeSortDoubleLinkedList.java b/src/main/java/com/rampatra/linkedlists/MergeSortDoubleLinkedList.java deleted file mode 100644 index 1adab868..00000000 --- a/src/main/java/com/rampatra/linkedlists/MergeSortDoubleLinkedList.java +++ /dev/null @@ -1,131 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.DoubleLinkedList; -import com.rampatra.base.DoubleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/7/15 - * @time: 4:34 PM - */ -public class MergeSortDoubleLinkedList { - - /** - * Merge sort for linked list starting at {@param node}. - * - * @param node - * @param - * @return - */ - public static > DoubleLinkedNode mergeSort(DoubleLinkedNode node) { - if (node == null || node.next == null) return node; - - DoubleLinkedNode middleNode, head1, head2; - - middleNode = divideInTwoHalves(node); - - head1 = mergeSort(node); - head2 = mergeSort(middleNode); - - return mergeTwoSortedLists(head1, head2); - - } - - - /** - * Divides a linked list starting from {@param node} into 2 halves - * and returns the starting {@code node} of the second half. - * - * @param node - * @param - * @return - */ - public static > DoubleLinkedNode divideInTwoHalves(DoubleLinkedNode node) { - DoubleLinkedNode slow = node, fast = node, prev = slow; - - if (node == null || node.next == null) { - return null; - } - - while (fast != null && fast.next != null) { - prev = slow; - slow = slow.next; - fast = fast.next.next; - } - prev.next = null; - return slow; - } - - - /** - * Merges two sorted lists starting at {@param node1} and {@param node2} - * into one and returns its starting node. - *

- * This method is similar to {@link MergeTwoSortedLists#mergeTwoSortedLists} - * - * @param node1 - * @param node2 - * @param - * @return - */ - public static > DoubleLinkedNode mergeTwoSortedLists(DoubleLinkedNode node1, - DoubleLinkedNode node2) { - DoubleLinkedNode curr1 = node1, curr2 = node2, head, curr; - - if (node1 == null && node2 == null) return null; - - head = curr = new DoubleLinkedNode<>(null); // dummy node - - while (curr1 != null || curr2 != null) { - // handle cases where either of the list run out first - if (curr1 == null) { - curr.next = curr2; - curr2.prev = curr; - curr2 = curr2.next; - } else if (curr2 == null) { - curr.next = curr1; - curr1.prev = curr; - curr1 = curr1.next; - } else if (curr1.item.compareTo(curr2.item) < 0) { // advance the current pointer of the - // list having smaller {@code item} - curr.next = curr1; - curr1.prev = curr; - curr1 = curr1.next; - } else if (curr1.item.compareTo(curr2.item) > 0) { - curr.next = curr2; - curr2.prev = curr; - curr2 = curr2.next; - } else { // both nodes are equal so add both to the result - curr.next = curr1; - curr = curr.next; - curr1 = curr1.next; - curr1.prev = curr; - curr.next = curr2; - curr2.prev = curr; - curr2 = curr2.next; - } - - curr = curr.next; - } - - // the dummy node should be unlinked - head.next.prev = null; - - // return the node next to the dummy node - return head.next; - } - - public static void main(String[] args) { - DoubleLinkedList linkedList = new DoubleLinkedList<>(); - linkedList.add(21); - linkedList.add(33); - linkedList.add(89); - linkedList.add(21); - linkedList.add(44); - linkedList.add(67); - linkedList.printList(); - linkedList.printList(mergeSort(linkedList.head)); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/MergeTwoLinkedListAlternatively.java b/src/main/java/com/rampatra/linkedlists/MergeTwoLinkedListAlternatively.java deleted file mode 100644 index e94c08e8..00000000 --- a/src/main/java/com/rampatra/linkedlists/MergeTwoLinkedListAlternatively.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/13/15 - * @time: 12:54 PM - */ -public class MergeTwoLinkedListAlternatively { - - /** - * Given two linked lists, insert nodes of second list into first list at - * alternate positions of first list till there are no more positions to - * insert in first list. - *

- * Example, - * Input: L1: 5->7->17->13->11 and L2: 12->10->2->4->6 - * Output: L1: 5->12->7->10->17->2->13->4->11->6 and L2: empty - *

- * Input: L1: 1->2->3 and L2: 4->5->6->7->8 - * Output: L1: 1->4->2->5->3->6 and L2: 7->8 - * - * @param node1 - * @param node2 - * @param - * @return - */ - public static > SingleLinkedNode mergeTwoLinkedListAlternatively(SingleLinkedNode node1, - SingleLinkedNode node2) { - - SingleLinkedNode curr1 = node1, curr2 = node2, temp1, temp2; - - while (curr1 != null && curr2 != null) { - temp1 = curr1.next; - temp2 = curr2.next; - - curr1.next = curr2; - curr2.next = temp1; - - curr1 = temp1; - curr2 = temp2; - } - - return curr2; - - } - - public static void main(String[] args) { - SingleLinkedList linkedList1 = new SingleLinkedList<>(); - linkedList1.add(00); - linkedList1.add(11); - linkedList1.add(22); - linkedList1.add(33); - linkedList1.add(44); - linkedList1.add(55); - linkedList1.printList(); - SingleLinkedList linkedList2 = new SingleLinkedList<>(); - linkedList2.add(21); - linkedList2.add(33); - linkedList2.add(44); - linkedList2.add(55); - linkedList2.add(67); - linkedList2.add(89); - linkedList2.add(99); - linkedList2.printList(); - SingleLinkedNode list2 = mergeTwoLinkedListAlternatively(linkedList1.head, linkedList2.head); - linkedList1.printList(); - SingleLinkedList.printList(list2); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/MergeTwoSortedLists.java b/src/main/java/com/rampatra/linkedlists/MergeTwoSortedLists.java deleted file mode 100644 index 1c4eaf93..00000000 --- a/src/main/java/com/rampatra/linkedlists/MergeTwoSortedLists.java +++ /dev/null @@ -1,124 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/27/15 - * @time: 8:47 PM - */ -public class MergeTwoSortedLists { - - /** - * Merges two sorted list {@param list1} and {@param list2} into - * a list with values in ascending order. - * - * @param list1 - * @param list2 - * @param - * @return - */ - public static > SingleLinkedList mergeTwoSortedLists(SingleLinkedList list1, - SingleLinkedList list2) { - SingleLinkedNode curr1 = list1.head, curr2 = list2.head; - SingleLinkedList intersectedList = new SingleLinkedList<>(); - while (curr1 != null || curr2 != null) { - // handle cases where either of the list run out first - if (curr1 == null) { - intersectedList.add(curr2.item); - curr2 = curr2.next; - } else if (curr2 == null) { - intersectedList.add(curr1.item); - curr1 = curr1.next; - } else if (curr1.item.compareTo(curr2.item) < 0) { // advance the current pointer of - // the list having smaller {@code item} - intersectedList.add(curr1.item); - curr1 = curr1.next; - } else if (curr1.item.compareTo(curr2.item) > 0) { - intersectedList.add(curr2.item); - curr2 = curr2.next; - } else { // both nodes are equal so add both to the result - intersectedList.add(curr1.item); - intersectedList.add(curr1.item); - curr1 = curr1.next; - curr2 = curr2.next; - } - } - - return intersectedList; - } - - /** - * Recursive method to merge two sorted lists into one sorted list. - *

- * NOTE: You can make {@param mergedList} as static and not pass as params - * to this method. - * - * @param node1 - * @param node2 - * @param - */ - public static > SingleLinkedNode mergeTwoSortedLists(SingleLinkedList mergedList, - SingleLinkedNode node1, - SingleLinkedNode node2) { - - if (node1 == null && node2 == null) return null; - - // if either of the list runs out first - if (node1 == null) { - mergeTwoSortedLists(mergedList, node1, node2.next); - mergedList.addFirst(node2.item); - return node2; - } - if (node2 == null) { - mergeTwoSortedLists(mergedList, node1.next, node2); - mergedList.addFirst(node1.item); - return node1; - } - - if (node1.item.compareTo(node2.item) < 0) { // node1 is smaller, so add it and advance the pointer - mergeTwoSortedLists(mergedList, node1.next, node2); - mergedList.addFirst(node1.item); - return node1; - } else if (node1.item.compareTo(node2.item) > 0) { - mergeTwoSortedLists(mergedList, node1, node2.next); - mergedList.addFirst(node2.item); - return node2; - } else { // both nodes are equal so add both - mergeTwoSortedLists(mergedList, node1.next, node2.next); - mergedList.addFirst(node1.item); - mergedList.addFirst(node2.item); - return node1; - } - } - - public static void main(String[] args) { - SingleLinkedList linkedList1 = new SingleLinkedList<>(); - linkedList1.add(00); - linkedList1.add(11); - linkedList1.add(22); - linkedList1.add(33); - linkedList1.add(44); - linkedList1.add(55); - linkedList1.printList(); - SingleLinkedList linkedList2 = new SingleLinkedList<>(); - linkedList2.add(21); - linkedList2.add(33); - linkedList2.add(44); - linkedList2.add(55); - linkedList2.add(67); - linkedList2.add(89); - linkedList2.add(99); - linkedList2.printList(); - mergeTwoSortedLists(linkedList1, linkedList2).printList(); - System.out.println("===================="); - linkedList1.printList(); - linkedList2.printList(); - SingleLinkedList mergedList = new SingleLinkedList<>(); - mergeTwoSortedLists(mergedList, linkedList1.head, linkedList2.head); - mergedList.printList(); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/MiddleNode.java b/src/main/java/com/rampatra/linkedlists/MiddleNode.java deleted file mode 100644 index 72318998..00000000 --- a/src/main/java/com/rampatra/linkedlists/MiddleNode.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/18/15 - */ -public class MiddleNode { - - public static > SingleLinkedNode getMiddleNode(SingleLinkedList list) { - SingleLinkedNode slow = list.head, fast = list.head; - while (fast != null && fast.next != null) { - slow = slow.next; - fast = fast.next.next; - } - return slow; - } - - public static void main(String[] args) { - SingleLinkedList linkedList = new SingleLinkedList<>(); - linkedList.add(00); - linkedList.add(11); - linkedList.add(22); - linkedList.add(33); - linkedList.add(44); - linkedList.add(55); - linkedList.add(66); - linkedList.add(77); - linkedList.add(88); - System.out.println(getMiddleNode(linkedList).item); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/MoveLastNodeToFirst.java b/src/main/java/com/rampatra/linkedlists/MoveLastNodeToFirst.java deleted file mode 100644 index 5f79e936..00000000 --- a/src/main/java/com/rampatra/linkedlists/MoveLastNodeToFirst.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/23/15 - * @time: 7:52 PM - */ -public class MoveLastNodeToFirst { - - public static > void moveLastNodeToFirst(SingleLinkedList list) { - if (list.size <= 1) return; - - SingleLinkedNode curr = list.getNode(0), prev = curr; - while (curr.next != null) { - prev = curr; - curr = curr.next; - } - prev.next = null; - curr.next = list.head; - list.head = curr; - } - - public static void main(String[] args) { - SingleLinkedList linkedList = new SingleLinkedList<>(); - linkedList.add(00); - linkedList.add(11); - linkedList.add(22); - linkedList.add(33); - linkedList.printList(); - moveLastNodeToFirst(linkedList); - linkedList.printList(); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/NthNodeFromLast.java b/src/main/java/com/rampatra/linkedlists/NthNodeFromLast.java deleted file mode 100644 index 871af6cf..00000000 --- a/src/main/java/com/rampatra/linkedlists/NthNodeFromLast.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/18/15 - */ -public class NthNodeFromLast { - - /** - * @param list - * @param n - * @param - * @return - */ - public static > SingleLinkedNode getNthNodeFromLast(SingleLinkedList list, int n) { - SingleLinkedNode slow = list.getNode(0); - SingleLinkedNode fast = list.getNode(0); - // move the fast reference ahead of slow reference by 'n' nodes - for (int i = 0; i < n; i++) { - // assert length of linkedlist > n - fast = fast.next; - } - while (fast != null) { - slow = slow.next; - fast = fast.next; - } - return slow; - } - - public static void main(String[] args) { - SingleLinkedList linkedList = new SingleLinkedList<>(); - linkedList.add(0); - linkedList.add(1); - linkedList.add(2); - linkedList.add(3); - linkedList.add(4); - linkedList.add(5); - linkedList.add(6); - linkedList.add(7); - linkedList.add(8); - linkedList.printList(); - System.out.println("n=3: " + getNthNodeFromLast(linkedList, 3).item); - - SingleLinkedList linkedList2 = new SingleLinkedList<>(); - linkedList2.add(0); - linkedList2.add(1); - linkedList2.add(2); - linkedList2.add(3); - linkedList2.add(4); - linkedList2.add(5); - linkedList2.add(6); - linkedList2.add(7); - linkedList2.add(8); - linkedList2.printList(); - System.out.println("n=1: " + getNthNodeFromLast(linkedList2, 1).item); - - SingleLinkedList linkedList3 = new SingleLinkedList<>(); - linkedList3.add(0); - linkedList3.add(1); - linkedList3.add(2); - linkedList3.add(3); - linkedList3.add(4); - linkedList3.add(5); - linkedList3.add(6); - linkedList3.add(7); - linkedList3.add(8); - linkedList3.printList(); - System.out.println("n=9: " + getNthNodeFromLast(linkedList3, 9).item); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/PairWiseSwap.java b/src/main/java/com/rampatra/linkedlists/PairWiseSwap.java deleted file mode 100644 index 3adc98b5..00000000 --- a/src/main/java/com/rampatra/linkedlists/PairWiseSwap.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/24/15 - * @time: 3:48 PM - */ -public class PairWiseSwap { - - /** - * Recursively swaps adjacent nodes of a linked list. - *

- * Example: - * Input: 11->22->33->44->55 - * Output: 22->11->44->33->55 - * - * @param node - * @return new starting node after swapping adjacent nodes. - */ - public static > SingleLinkedNode pairWiseSwap(SingleLinkedNode node) { - if (node == null || node.next == null) return node; - - SingleLinkedNode nextNode = node.next, nextOfNextNode = nextNode.next; - - nextNode.next = node; - node.next = pairWiseSwap(nextOfNextNode); - - return nextNode; - } - - public static void main(String[] args) { - SingleLinkedList linkedList = new SingleLinkedList<>(); - linkedList.add(11); - linkedList.add(22); - linkedList.add(33); - linkedList.add(44); - linkedList.add(55); - linkedList.add(66); - linkedList.add(77); - linkedList.printList(); - linkedList.printList(pairWiseSwap(linkedList.head)); - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/linkedlists/Palindrome.java b/src/main/java/com/rampatra/linkedlists/Palindrome.java deleted file mode 100644 index 1f85b35d..00000000 --- a/src/main/java/com/rampatra/linkedlists/Palindrome.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.LinkedStack; -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; -import com.rampatra.base.Stack; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/18/15 - */ -public class Palindrome> extends SingleLinkedList { - - /** - * Uses Stack to test whether a linked list starting - * from {@param node} is palindrome or not. - * - * @param list - * @return {@code true} if linked list palindrome, {@code false} otherwise. - */ - private static > boolean isPalindrome(SingleLinkedList list) { - SingleLinkedNode head = list.getNode(0); - SingleLinkedNode curr = head; - Stack> stack = new LinkedStack<>(); - - while (curr != null) { - stack.push(curr); - curr = curr.next; - } - - curr = head; - - while (curr != null) { - if (curr.item != stack.pop().item) { - return false; - } - curr = curr.next; - } - - return true; - } - - /** - * Recursive function to test whether a linked list - * starting from {@param node} is palindrome or not. - *

- * NOTE: This method moves the head reference. (disadvantage) - * - * @param node - * @return - */ - private boolean isPalindromeRecursive(SingleLinkedNode node) { - if (node == null) return true; - - boolean isPalindrome = isPalindromeRecursive(node.next); - - if (head.item == node.item) { - head = head.next; - return isPalindrome; - } else { - return false; - } - } - - public static void main(String[] args) { - Palindrome linkedList = new Palindrome<>(); - linkedList.add(0); - linkedList.add(1); - linkedList.add(2); - linkedList.add(1); - linkedList.add(0); - linkedList.printList(); - System.out.println(isPalindrome(linkedList)); - linkedList.printList(); - System.out.println(linkedList.isPalindromeRecursive(linkedList.getNode(0))); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/QuickSort.java b/src/main/java/com/rampatra/linkedlists/QuickSort.java deleted file mode 100644 index 5808fdcb..00000000 --- a/src/main/java/com/rampatra/linkedlists/QuickSort.java +++ /dev/null @@ -1,88 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/21/15 - * @time: 11:43 PM - */ -public class QuickSort { - - public static > SingleLinkedNode[] partition(SingleLinkedNode firstNode, - SingleLinkedNode lastNode) { - - SingleLinkedNode[] partition = new SingleLinkedNode[4]; - SingleLinkedNode pivot = lastNode, curr = new SingleLinkedNode<>(null, firstNode), currNext, pivotNext; - - while (curr.next != null && curr.next != lastNode) { - if (curr.next.item.compareTo(pivot.item) > 0) { - currNext = curr.next; - curr.next = currNext.next; - pivotNext = pivot.next; - pivot.next = currNext; - currNext.next = pivotNext; - continue; - } - curr = curr.next; - } - - partition[0] = curr; - - while (curr.next != pivot) { - curr = curr.next; - } - partition[1] = curr; - - partition[2] = pivot.next; - - while (curr.next != null) { - curr = curr.next; - } - partition[3] = curr; - - return partition; - - } - - public static > SingleLinkedNode quickSort(SingleLinkedNode firstNode, - SingleLinkedNode lastNode) { - - SingleLinkedNode head = firstNode; - if (firstNode != lastNode) { - SingleLinkedNode partition[] = partition(firstNode, lastNode); - head = quickSort(partition[0], partition[1]); - quickSort(partition[2], partition[3]); - } - - return head; - } - - public static > SingleLinkedNode quickSort(SingleLinkedNode node) { - return quickSort(node, getLastNode(node)); - } - - public static > SingleLinkedNode getLastNode(SingleLinkedNode node) { - SingleLinkedNode curr = node; - - while (curr != null && curr.next != null) { - curr = curr.next; - } - - return curr; - } - - public static void main(String[] args) { - SingleLinkedList linkedList = new SingleLinkedList<>(); - linkedList.add(23); - linkedList.add(4); - linkedList.add(45); - linkedList.add(11); - linkedList.add(7); - linkedList.printList(); - linkedList.printList(quickSort(linkedList.head)); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/RandomNode.java b/src/main/java/com/rampatra/linkedlists/RandomNode.java deleted file mode 100644 index 97aafdec..00000000 --- a/src/main/java/com/rampatra/linkedlists/RandomNode.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.arrays.ReservoirSampling; -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -import java.util.Random; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/21/15 - * @time: 12:57 PM - */ -public class RandomNode { - - /** - * Returns a random node from linked list with each node having an equal probability. - *

- * This method uses the simplified version of Reservoir Sampling ({@link ReservoirSampling}) - * where k = 1. - * - * @param node - * @param - * @return - */ - public static > SingleLinkedNode getRandomNode(SingleLinkedNode node) { - SingleLinkedNode result = node, curr = node; - for (int i = 2; curr != null; i++) { - - int rand = new Random().nextInt(i); - - if (rand % i == 0) result = curr; - - curr = curr.next; - } - - return result; - } - - public static void main(String[] args) { - SingleLinkedList linkedList = new SingleLinkedList<>(); - linkedList.add(00); - linkedList.add(11); - linkedList.add(22); - linkedList.add(33); - linkedList.add(44); - linkedList.add(55); - linkedList.add(66); - linkedList.add(77); - linkedList.add(88); - System.out.println(getRandomNode(linkedList.head).item); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/RemoveDuplicates.java b/src/main/java/com/rampatra/linkedlists/RemoveDuplicates.java deleted file mode 100644 index 7471f231..00000000 --- a/src/main/java/com/rampatra/linkedlists/RemoveDuplicates.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -import java.util.HashSet; -import java.util.Set; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/18/15 - * @time: 2:35 PM - */ -public class RemoveDuplicates { - - /** - * Removes duplicates from a sorted linked list - * by traversing it once. - * - * @param list - * @param - */ - public static > void removeDuplicates(SingleLinkedList list) { - SingleLinkedNode curr = list.getNode(0); - while (curr != null) { - // inner while loop for removing multiple duplicates - while (curr.next != null && curr.item == curr.next.item) { - curr.next = curr.next.next; - } - curr = curr.next; - } - } - - /** - * Removes duplicates from an unsorted linked list. - *

- * This method uses {@link HashSet}, another - * way is that you can sort it using merge sort and then - * call {@link #removeDuplicates}. - * - * @param list - * @param - */ - public static > void removeDuplicatesFromUnsortedList(SingleLinkedList list) { - SingleLinkedNode curr = list.getNode(0); - SingleLinkedNode prev = curr; - Set itemsInList = new HashSet<>(); - while (curr != null) { - if (itemsInList.contains(curr.item)) { - itemsInList.add(curr.item); - } else { // delete duplicate element - prev.next = curr.next; - } - prev = curr; - curr = curr.next; - } - } - - public static void main(String[] args) { - SingleLinkedList linkedList = new SingleLinkedList<>(); - linkedList.add(0); - linkedList.add(0); - linkedList.add(0); - linkedList.add(1); - linkedList.add(1); - linkedList.add(2); - linkedList.add(2); - linkedList.add(2); - linkedList.add(2); - linkedList.add(3); - linkedList.add(3); - linkedList.add(3); - linkedList.add(3); - linkedList.printList(); - removeDuplicates(linkedList); - linkedList.printList(); - - SingleLinkedList linkedList2 = new SingleLinkedList<>(); - linkedList2.add(0); - linkedList2.add(0); - linkedList2.add(2); - linkedList2.add(1); - linkedList2.add(4); - linkedList2.add(2); - linkedList2.add(6); - linkedList2.add(7); - linkedList2.add(6); - linkedList2.printList(); - removeDuplicatesFromUnsortedList(linkedList2); - linkedList2.printList(); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/RemoveMiddlePointsFromLineSegments.java b/src/main/java/com/rampatra/linkedlists/RemoveMiddlePointsFromLineSegments.java deleted file mode 100644 index d4099eed..00000000 --- a/src/main/java/com/rampatra/linkedlists/RemoveMiddlePointsFromLineSegments.java +++ /dev/null @@ -1,102 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/23/15 - * @time: 11:18 PM - */ -public class RemoveMiddlePointsFromLineSegments { - - /** - * Given a linked list of co-ordinates representing line segments, we have - * to remove those nodes which represent the middle points. - *

- * Example: - * Input: - * (0,10)-> (1,10)-> (3,10)-> (10,10)-> (10,8)-> (10,5)-> (20,5)-> (40,5) - * Output: - * (0,10)-> (10,10)-> (10,5)-> (40,5) - *

- * Input: - * (2,3)->(4,3)->(6,3)->(10,3)->(12,3) - * Output: - * (2,3)->(12,3) - * - * @param node - */ - public static void removeMiddlePointsFromLineSegments(SingleLinkedNode node) { - - SingleLinkedNode curr1 = node, curr2 = node; - - while (curr1 != null && curr1.next != null) { - // vertical line - if (curr1.item.x == curr1.next.item.x) { - while (curr2.next != null && curr2.next.item.x == curr1.item.x) { - curr2 = curr2.next; - } - curr1.next = curr2; - } else if (curr1.item.y == curr1.next.item.y) { // horizontal line - while (curr2.next != null && curr2.next.item.y == curr1.item.y) { - curr2 = curr2.next; - } - curr1.next = curr2; - } else { - System.out.println("Linked list doesn't represent line segments!"); - return; - } - curr1 = curr1.next; - } - } - - public static void main(String[] args) { - // test case 1 - SingleLinkedList linkedList = new SingleLinkedList<>(); - linkedList.add(new Point(0, 10)); - linkedList.add(new Point(1, 10)); - linkedList.add(new Point(3, 10)); - linkedList.add(new Point(10, 10)); - linkedList.add(new Point(10, 8)); - linkedList.add(new Point(10, 5)); - linkedList.add(new Point(20, 5)); - linkedList.add(new Point(40, 5)); - linkedList.printList(); - removeMiddlePointsFromLineSegments(linkedList.head); - linkedList.printList(); - - // test case 2 - SingleLinkedList linkedList2 = new SingleLinkedList<>(); - linkedList2.add(new Point(2, 3)); - linkedList2.add(new Point(4, 3)); - linkedList2.add(new Point(6, 3)); - linkedList2.add(new Point(10, 3)); - linkedList2.add(new Point(12, 3)); - linkedList2.printList(); - removeMiddlePointsFromLineSegments(linkedList2.head); - linkedList2.printList(); - } -} - -class Point implements Comparable { - - int x, y; - - Point(int x, int y) { - this.x = x; - this.y = y; - } - - @Override - public String toString() { - return "(" + x + "," + y + ")"; - } - - @Override - public int compareTo(Point o) { - return 0; - } -} diff --git a/src/main/java/com/rampatra/linkedlists/ReverseAlternateNodesAndAppendAtEnd.java b/src/main/java/com/rampatra/linkedlists/ReverseAlternateNodesAndAppendAtEnd.java deleted file mode 100644 index 70b005d2..00000000 --- a/src/main/java/com/rampatra/linkedlists/ReverseAlternateNodesAndAppendAtEnd.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/14/15 - * @time: 12:16 PM - */ -public class ReverseAlternateNodesAndAppendAtEnd { - - /** - * Reverse alternate nodes and append them to end of the list. - *

- * Example, - *

- * Input List: 1->2->3->4->5->6 - * Output List: 1->3->5->6->4->2 - *

- * Input List: 12->14->16->18->20 - * Output List: 12->16->20->18->14 - * - * @param node - * @param - * @return - */ - public static > SingleLinkedNode reverseAlternateNodesAndAppendAtEnd(SingleLinkedNode node) { - SingleLinkedNode curr = node, end = node, currNext, endNext; - - while (end.next != null) { - end = end.next; - } - - while (curr != end && curr.next != end) { - - currNext = curr.next.next; - endNext = end.next; - - end.next = curr.next; - end.next.next = endNext; - - curr.next = currNext; - curr = curr.next; - } - - return node; - } - - public static void main(String[] args) { - SingleLinkedList linkedList = new SingleLinkedList<>(); - linkedList.add(11); - linkedList.add(22); - linkedList.add(33); - linkedList.add(44); - linkedList.add(55); - linkedList.add(66); - linkedList.printList(); - SingleLinkedList.printList(reverseAlternateNodesAndAppendAtEnd(linkedList.head)); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/ReverseDoubleLinkedList.java b/src/main/java/com/rampatra/linkedlists/ReverseDoubleLinkedList.java deleted file mode 100644 index 466c6ac4..00000000 --- a/src/main/java/com/rampatra/linkedlists/ReverseDoubleLinkedList.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.DoubleLinkedList; -import com.rampatra.base.DoubleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/19/15 - * @time: 9:24 AM - */ -public class ReverseDoubleLinkedList { - - /** - * Reverses the doubly linked list. - * - * @param list - */ - public static > void reverseList(DoubleLinkedList list) { - - DoubleLinkedNode curr = list.getNode(0); - DoubleLinkedNode temp = curr; - - while (curr != null) { - temp = curr.prev; - curr.prev = curr.next; - curr.next = temp; - curr = curr.prev; - } - - // temp will be null if linked list has only one node - if (temp != null) { - list.head = temp.prev; - } - } - - public static void main(String[] args) { - DoubleLinkedList linkedList = new DoubleLinkedList<>(); - linkedList.add(11); - linkedList.add(22); - linkedList.add(33); - linkedList.add(44); - linkedList.add(55); - linkedList.add(66); - linkedList.printList(); - reverseList(linkedList); - linkedList.printList(); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/ReverseLinkedListInAlternateGroups.java b/src/main/java/com/rampatra/linkedlists/ReverseLinkedListInAlternateGroups.java deleted file mode 100644 index 68a3b81f..00000000 --- a/src/main/java/com/rampatra/linkedlists/ReverseLinkedListInAlternateGroups.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/30/15 - * @time: 9:33 AM - */ -public class ReverseLinkedListInAlternateGroups> extends SingleLinkedList { - - /** - * Reverses the linked list in groups alternatively. - *

- * It is similar to {@link ReverseLinkedListInGroups} but - * does alternatively. - *

- * Example: - * Inputs: 1->2->3->4->5->6->7->8->9 and k = 3 - * Output: 3->2->1->4->5->6->9->8->7 - * - * @param node - * @param k - * @return - */ - public SingleLinkedNode reverseLinkedListInAltGroups(SingleLinkedNode node, int k) { - int i = 0; - SingleLinkedNode curr = node, prev = null, next = null; - - // reverse the 'next' pointer of nodes with help of 3 pointers - while (curr != null && i < k) { - next = curr.next; - curr.next = prev; - prev = curr; - curr = next; - i++; - } - - // update the head - if (node == head) { - head = prev; - } - - if (node != null) node.next = next; - - // move the pointer k steps ahead - i = 1; - while (curr != null && i < k) { - curr = curr.next; - i++; - } - - // recursively call on the next set of nodes - if (curr != null) { - curr.next = reverseLinkedListInAltGroups(curr.next, k); - } - - return prev; - } - - public static void main(String[] args) { - ReverseLinkedListInAlternateGroups linkedList = new ReverseLinkedListInAlternateGroups<>(); - linkedList.add(00); - linkedList.add(11); - linkedList.add(22); - linkedList.add(33); - linkedList.add(44); - linkedList.add(55); - linkedList.add(66); - linkedList.add(77); - linkedList.add(88); - linkedList.add(99); - linkedList.printList(); - linkedList.reverseLinkedListInAltGroups(linkedList.head, 2); - linkedList.printList(); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/ReverseLinkedListInGroups.java b/src/main/java/com/rampatra/linkedlists/ReverseLinkedListInGroups.java deleted file mode 100644 index 1935356e..00000000 --- a/src/main/java/com/rampatra/linkedlists/ReverseLinkedListInGroups.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/29/15 - * @time: 2:32 PM - */ -public class ReverseLinkedListInGroups { - - /** - * Reverses the linked list in groups. - *

- * Example: - *

- * Inputs: 1->2->3->4->5->6->7->8 and k = 3 - * Output: 3->2->1->6->5->4->8->7. - *

- * Inputs: 1->2->3->4->5->6->7->8 and k = 5 - * Output: 5->4->3->2->1->8->7->6. - * - * @param node - * @param k - * @return - */ - public static > SingleLinkedNode reverseLinkedListInGroups(SingleLinkedNode node, int k) { - - SingleLinkedNode curr = node, prev = null, next = null; - int i = 0; - - // reverse the 'next' pointer of nodes with help of 3 pointers - while (curr != null && i < k) { - next = curr.next; - curr.next = prev; - prev = curr; - curr = next; - i++; - } - - // recursively call for the rest of the nodes in the linked list - if (next != null) { - node.next = reverseLinkedListInGroups(curr, k); - } - - return prev; - } - - public static void main(String[] args) { - SingleLinkedList linkedList = new SingleLinkedList<>(); - linkedList.add(0); - linkedList.add(1); - linkedList.add(2); - linkedList.add(3); - linkedList.add(4); - linkedList.add(5); - linkedList.add(6); - linkedList.add(7); - linkedList.add(8); - linkedList.add(9); - linkedList.add(10); - linkedList.printList(); - SingleLinkedList.printList(reverseLinkedListInGroups(linkedList.head, 3)); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/ReverseSingleLinkedList.java b/src/main/java/com/rampatra/linkedlists/ReverseSingleLinkedList.java deleted file mode 100644 index de474417..00000000 --- a/src/main/java/com/rampatra/linkedlists/ReverseSingleLinkedList.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * This is for reversing a linked list, both iteratively and recursively. If you - * want to reverse linked list in groups then see {@link ReverseLinkedListInGroups}. - * - * @author rampatra - * @since 6/19/15 - * @time: 9:24 AM - */ -public class ReverseSingleLinkedList { - - /** - * Reverses the linked list using 3 references prev, curr and next. - * - * @param list - */ - public static > void reverseList(SingleLinkedList list) { - SingleLinkedNode curr = list.getNode(0), prev = null, next; - while (curr != null) { - next = curr.next; - curr.next = prev; - prev = curr; - curr = next; - } - list.head = prev; - } - - /** - * Recursive method to reverse a linked list. - * - * @param node - * @return - */ - public static > SingleLinkedNode recursiveReverseList(SingleLinkedNode node) { - if (node == null || node.next == null) return node; - - SingleLinkedNode nextNode = node.next; - - node.next = null; - - SingleLinkedNode newHead = recursiveReverseList(nextNode); - - nextNode.next = node; - - return newHead; - } - - /** - * Recursive method to PRINT the linked list in reverse. - *

- * NOTE: It doesn't reverse the linked list but just PRINTS - * them in reverse. - * - * @param node - * @param - */ - public static > void printListInReverse(SingleLinkedNode node) { - if (node == null) return; - - printListInReverse(node.next); - - System.out.print(node.item + ","); - } - - public static void main(String[] args) { - SingleLinkedList linkedList = new SingleLinkedList<>(); - linkedList.add(11); - linkedList.add(22); - linkedList.add(33); - linkedList.add(44); - linkedList.add(55); - linkedList.printList(); - reverseList(linkedList); - linkedList.printList(); - printListInReverse(linkedList.head); - System.out.println(); - SingleLinkedList.printList(recursiveReverseList(linkedList.head)); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/RotateLinkedList.java b/src/main/java/com/rampatra/linkedlists/RotateLinkedList.java deleted file mode 100644 index 15d28211..00000000 --- a/src/main/java/com/rampatra/linkedlists/RotateLinkedList.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/3/15 - * @time: 3:07 PM - */ -public class RotateLinkedList { - - /** - * Rotates the {@param list} anti-clockwise by {@param k} nodes. - * - * @param list - * @param k - * @param - */ - public static > void rotateCounterClockwise(SingleLinkedList list, int k) { - int clockwiseK = list.size - k; - rotateClockwise(list, clockwiseK); - } - - - /** - * Rotates the {@param list} clockwise by {@param k} nodes. - *

- * Example, - *

- * Input: [0,11,22,33,44,55] and k = 2 - * Output: [22,33,44,55,0,11] - * - * @param list - * @param k - * @param - */ - public static > void rotateClockwise(SingleLinkedList list, int k) { - int i = 0; - SingleLinkedNode curr = list.head, end = curr; - - // get a pointer to the last node - while (end.next != null) { - end = end.next; - } - - // start moving first k nodes from start to end - while (i < k && k < list.size) { - end.next = curr; - end = end.next; - curr = curr.next; - i++; - } - - // change head to k+1 node - list.head = curr; - end.next = null; - - } - - public static void main(String[] args) { - SingleLinkedList linkedList = new SingleLinkedList<>(); - linkedList.add(00); - linkedList.add(11); - linkedList.add(22); - linkedList.add(33); - linkedList.add(44); - linkedList.add(55); - linkedList.printList(); - rotateClockwise(linkedList, 2); - linkedList.printList(); - rotateCounterClockwise(linkedList, 2); - linkedList.printList(); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/SegregateEvenOddNumbers.java b/src/main/java/com/rampatra/linkedlists/SegregateEvenOddNumbers.java deleted file mode 100644 index 1bdcb4db..00000000 --- a/src/main/java/com/rampatra/linkedlists/SegregateEvenOddNumbers.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/30/15 - * @time: 10:32 PM - */ -public class SegregateEvenOddNumbers { - - /** - * Modifies the linked list such that all even numbers appear - * before all the odd numbers in the linked list. - *

- * Algorithm: - * ---------- - * 1) Make a pointer point the last node of the list. - *

- * 2) Traverse the linked list from start and append all odd values - * nodes to the end of the above pointer. - *

- * 3) If the pointer in step 1 points to a odd valued node then move it - * to the end so that the relative order of nodes remains unchanged. - * - * @param list - * @param - */ - public static > void segregateEvenOddNumbers(SingleLinkedList list) { - SingleLinkedNode curr = list.head, prev = null, end = curr, separator; - - // a pointer to the last node - while (end.next != null) { - end = end.next; - } - separator = end; - - // move all odd valued nodes after the end node - while (curr != separator) { - if (Integer.parseInt(curr.item.toString()) % 2 != 0) { - end.next = curr; - curr = curr.next; - end = end.next; - end.next = null; - if (curr == list.head) { - list.head = curr; - } else { - prev.next = curr; - } - } else { - prev = curr; - curr = curr.next; - } - } - - // if separator is odd valued then move it to the end (if its not already in the end) - if (Integer.parseInt(separator.item.toString()) % 2 != 0 && separator.next != null) { - prev.next = curr.next; - while (curr.next != null) { - curr = curr.next; - } - curr.next = separator; - separator.next = null; - } - - } - - public static void main(String[] args) { - SingleLinkedList linkedList = new SingleLinkedList<>(); - linkedList.add(00); - linkedList.add(11); - linkedList.add(22); - linkedList.add(33); - linkedList.add(44); - linkedList.add(55); - linkedList.add(66); - linkedList.add(77); - linkedList.printList(); - segregateEvenOddNumbers(linkedList); - linkedList.printList(); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/SortAlternativelySortedLinkedList.java b/src/main/java/com/rampatra/linkedlists/SortAlternativelySortedLinkedList.java deleted file mode 100644 index 79842cc4..00000000 --- a/src/main/java/com/rampatra/linkedlists/SortAlternativelySortedLinkedList.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/20/15 - * @time: 3:03 PM - */ -public class SortAlternativelySortedLinkedList { - - /** - * Given a Linked List which is in alternating ascending and descending orders. In other words, nodes - * at even indexes are in ascending order whereas the nodes at odd indexes are in descending order. - * Sort the list efficiently in O(n) time complexity. - *

- * Example: - *

- * Input List: 10->40->53->30->67->12->89->NULL - * Output List: 10->12->30->43->53->67->89->NULL - * - * @param node - * @param - * @return - */ - public static > SingleLinkedNode sort(SingleLinkedNode node) { - SingleLinkedNode secondList = node.next, curr = node, next; - - // separate even and odd nodes into two separate lists - while (curr != null && curr.next != null) { - next = curr.next; - curr.next = next.next; - next.next = (curr.next == null) ? null : curr.next.next; - curr = curr.next; - } - - // reverse the descending ordered list - secondList = ReverseSingleLinkedList.recursiveReverseList(secondList); - - // now merge two sorted lists - return MergeSort.mergeTwoSortedLists(node, secondList); - } - - public static void main(String[] args) { - SingleLinkedList linkedList = new SingleLinkedList<>(); - linkedList.add(21); - linkedList.add(67); - linkedList.add(44); - linkedList.add(33); - linkedList.add(89); - linkedList.printList(); - linkedList.printList(sort(linkedList.head)); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/SortLinkedListOf0s1s2s.java b/src/main/java/com/rampatra/linkedlists/SortLinkedListOf0s1s2s.java deleted file mode 100644 index 6b5c08c1..00000000 --- a/src/main/java/com/rampatra/linkedlists/SortLinkedListOf0s1s2s.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/5/15 - * @time: 1:47 PM - */ -public class SortLinkedListOf0s1s2s { - - /** - * Sorts {@param list} consisting of only 0s, 1s and 2s as their node values. - *

- * Time complexity: O(n) - * Space complexity: O(1) - * - * @param list - */ - public static void sort(SingleLinkedList list) { - int[] count = new int[3]; - SingleLinkedNode curr = list.head; - - // keep count of 0s, 1s and 2s - while (curr != null) { - count[curr.item]++; - curr = curr.next; - } - - // make a linked list of that many 0s, 1s and 2s - list.clear(); - for (int i = 0; i < count.length; i++) { - for (int j = 0; j < count[i]; j++) { - list.add(i); - } - } - } - - public static void main(String[] args) { - SingleLinkedList linkedList = new SingleLinkedList<>(); - linkedList.add(0); - linkedList.add(1); - linkedList.add(2); - linkedList.add(0); - linkedList.add(1); - linkedList.add(2); - linkedList.add(1); - linkedList.printList(); - sort(linkedList); - linkedList.printList(); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/SortedDLLToBBST.java b/src/main/java/com/rampatra/linkedlists/SortedDLLToBBST.java deleted file mode 100644 index 6b050d0c..00000000 --- a/src/main/java/com/rampatra/linkedlists/SortedDLLToBBST.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.DoubleLinkedList; -import com.rampatra.base.DoubleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/24/15 - * @time: 3:16 PM - */ -public class SortedDLLToBBST { - - /** - * Returns the number of nodes in the doubly linked list. - * - * @param node - * @param - * @return - */ - static > int getLength(DoubleLinkedNode node) { - int l = 0; - DoubleLinkedNode curr = node; - while (curr != null) { - curr = curr.next; - l++; - } - return l; - } - - /** - * @param node - * @param - */ - static > void inOrder(DoubleLinkedNode node) { - if (node == null) return; - inOrder(node.prev); - System.out.print(node.item.toString()); - inOrder(node.next); - } - - /** - * Converts a sorted doubly linked list to a balanced binary tree in-place. - * - * @param node - * @param - * @return - */ - public static > DoubleLinkedNode sortedDLLToBBST(DoubleLinkedNode node) { - return sortedDLLToBBST(node, getLength(node)); - } - - public static > DoubleLinkedNode sortedDLLToBBST(DoubleLinkedNode node, int n) { - if (n <= 0) { - return null; - } - - DoubleLinkedNode left = sortedDLLToBBST(node, n / 2); - - DoubleLinkedNode root = node; - root.prev = left; - - node = node.next; - - DoubleLinkedNode right = sortedDLLToBBST(node, n - n / 2 - 1); - root.next = right; - - return root; - } - - public static void main(String[] args) { - DoubleLinkedList linkedList = new DoubleLinkedList<>(); - linkedList.add(11); - linkedList.add(22); - linkedList.add(33); - linkedList.add(44); - linkedList.add(55); - linkedList.add(66); - linkedList.add(77); - linkedList.printList(); - inOrder(sortedDLLToBBST(linkedList.head)); - System.out.println(); - linkedList.printList(); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/StackWithOperationOnMiddleElement.java b/src/main/java/com/rampatra/linkedlists/StackWithOperationOnMiddleElement.java deleted file mode 100644 index bbcc4193..00000000 --- a/src/main/java/com/rampatra/linkedlists/StackWithOperationOnMiddleElement.java +++ /dev/null @@ -1,118 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.DoubleLinkedNode; - -import java.util.EmptyStackException; - -import static java.lang.System.out; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/24/15 - * @time: 1:06 PM - *

- *

- * Implement a stack with below operations in O(1) time complexity: - * 1) push() which adds an element to the top of stack. - * 2) pop() which removes an element from top of stack. - * 3) findMiddle() which will return middle element of the stack. - * 4) deleteMiddle() which will delete the middle element. - * Push and pop are standard stack operations. - *

- * The idea is to use a double linked list to represent a stack with pointer pointing to the middle node. - */ -public class StackWithOperationOnMiddleElement> { - - int i = -1; - DoubleLinkedNode top, mid; - - public void push(E item) { - - top = new DoubleLinkedNode<>(null, item, top); - if (top.next != null) { - top.next.prev = top; - } else { - mid = top; - } - - if (i % 2 == 0) { - mid = mid.prev; - } - i++; - } - - public E pop() { - if (top == null) { - throw new EmptyStackException(); - } - - DoubleLinkedNode topNode = top; - if (top.next != null) { - top.next.prev = null; - } - top = top.next; - - i++; - if (i % 2 == 0) { - mid = mid.next; - } - - return topNode.item; - } - - public E getMiddleElement() { - if (mid == null) { - throw new EmptyStackException(); - } - return mid.item; - } - - /** - * Prints the content of the stack. - */ - public void print() { - DoubleLinkedNode curr = top; - out.print("["); - if (curr == null) { - out.println("]"); - return; - } - // prints the list from first node - while (curr.next != null) { - out.print(curr.item.toString() + ","); - curr = curr.next; - } - out.println(curr.item.toString() + "]"); - // prints the list from last node - out.print("["); - while (curr.prev != null) { - out.print(curr.item.toString() + ","); - curr = curr.prev; - } - out.println(curr.item.toString() + "]"); - } - - public static void main(String[] args) { - StackWithOperationOnMiddleElement stack = new StackWithOperationOnMiddleElement<>(); - stack.push(2); - stack.push(3); - stack.push(4); - stack.push(5); - stack.push(6); - stack.print(); - System.out.println("Mid: " + stack.getMiddleElement()); - stack.pop(); - stack.print(); - System.out.println("Mid: " + stack.getMiddleElement()); - stack.push(7); - stack.print(); - System.out.println("Mid: " + stack.getMiddleElement()); - stack.pop(); - stack.pop(); - stack.pop(); - stack.print(); - System.out.println("Mid: " + stack.getMiddleElement()); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/SwapKthNode.java b/src/main/java/com/rampatra/linkedlists/SwapKthNode.java deleted file mode 100644 index 44f12da7..00000000 --- a/src/main/java/com/rampatra/linkedlists/SwapKthNode.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/13/15 - * @time: 12:25 PM - */ -public class SwapKthNode { - - public static > SingleLinkedNode swapKthNodeFromStartWithKthNodeFromEnd(SingleLinkedNode node, - int k) { - - - int i = 1; - - // dummy node needed to swap the very first node - SingleLinkedNode head = new SingleLinkedNode<>(null), - curr = head, - slow = head, - fast = head, - temp; - - head.next = node; - - // find kth node from start - while (i < k && curr.next != null) { - curr = curr.next; - fast = fast.next; - i++; - } - - // move the fast pointer k steps ahead of slow - fast = fast.next; - - // find kth node from end - while (fast.next != null) { - slow = slow.next; - fast = fast.next; - } - - // if either of the node isn't present in the list then do nothing - if (curr.next == null || slow.next == null) return head.next; - - // swap nodes - temp = curr.next; - curr.next = slow.next; - slow.next = temp; - - // update their next nodes - temp = curr.next.next; - curr.next.next = slow.next.next; - slow.next.next = temp; - - return head.next; - - } - - public static void main(String[] args) { - SingleLinkedList linkedList = new SingleLinkedList<>(); - linkedList.add(11); - linkedList.add(22); - linkedList.add(33); - linkedList.add(44); - linkedList.add(55); - linkedList.add(66); - linkedList.add(77); - linkedList.printList(); - linkedList.printList(swapKthNodeFromStartWithKthNodeFromEnd(linkedList.head, 2)); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/SwapNodes.java b/src/main/java/com/rampatra/linkedlists/SwapNodes.java deleted file mode 100644 index ffb50332..00000000 --- a/src/main/java/com/rampatra/linkedlists/SwapNodes.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/12/15 - * @time: 1:23 PM - */ -public class SwapNodes { - - /** - * Swap nodes with value {@param item1} with {@param item2} in linked list - * starting at {@param node}. - * - * @param node - * @param item1 - * @param item2 - * @param - * @return - */ - public static > SingleLinkedNode swap(SingleLinkedNode node, - E item1, - E item2) { - - // dummy node needed to swap the very first node - SingleLinkedNode head = new SingleLinkedNode<>(null), - curr1 = head, - curr2 = head, - temp; - - head.next = node; - - while (curr1.next != null && curr1.next.item != item1) { - curr1 = curr1.next; - } - - while (curr2.next != null && curr2.next.item != item2) { - curr2 = curr2.next; - } - - // if either of the node isn't present in the list then do nothing - if (curr1.next == null || curr2.next == null) return head.next; - - // swap nodes - temp = curr1.next; - curr1.next = curr2.next; - curr2.next = temp; - - // update their next nodes - temp = curr1.next.next; - curr1.next.next = curr2.next.next; - curr2.next.next = temp; - - return head.next; - } - - public static void main(String[] args) { - SingleLinkedList linkedList = new SingleLinkedList<>(); - linkedList.add(11); - linkedList.add(22); - linkedList.add(33); - linkedList.add(44); - linkedList.add(55); - linkedList.add(66); - linkedList.add(77); - linkedList.printList(); - linkedList.printList(swap(linkedList.head, 111, 77)); - } -} diff --git a/src/main/java/com/rampatra/linkedlists/TripletFromThreeLinkedLists.java b/src/main/java/com/rampatra/linkedlists/TripletFromThreeLinkedLists.java deleted file mode 100644 index 1addeb69..00000000 --- a/src/main/java/com/rampatra/linkedlists/TripletFromThreeLinkedLists.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.rampatra.linkedlists; - -import com.rampatra.base.SingleLinkedList; -import com.rampatra.base.SingleLinkedNode; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/9/15 - * @time: 4:00 PM - */ -public class TripletFromThreeLinkedLists { - - public static SingleLinkedNode findTripletWithSumEqualsTo(SingleLinkedNode node1, - SingleLinkedNode node2, - SingleLinkedNode node3, - int sum) { - node2 = MergeSort.mergeSort(node2); - node3 = MergeSort.mergeSort(node3); - node3 = ReverseSingleLinkedList.recursiveReverseList(node3); - - SingleLinkedNode curr1 = node1, curr2, curr3; - int s; - - while (curr1 != null) { - - curr2 = node2; - curr3 = node3; - - while (curr2 != null && curr3 != null) { - s = curr1.item + curr2.item + curr3.item; - - if (s == sum) { - curr1.next = curr2; - curr2.next = curr3; - curr3.next = null; - return curr1; - } - - if (s < sum) { - curr2 = curr2.next; - } else { - curr3 = curr3.next; - } - } - - curr1 = curr1.next; - - } - - return null; - - } - - public static void main(String[] args) { - SingleLinkedList linkedList1 = new SingleLinkedList<>(); - linkedList1.add(2); - SingleLinkedList linkedList2 = new SingleLinkedList<>(); - linkedList2.add(6); - linkedList2.add(8); - linkedList2.add(7); - SingleLinkedList linkedList3 = new SingleLinkedList<>(); - linkedList3.add(9); - linkedList3.add(6); - linkedList3.add(12); - linkedList1.printList(); - linkedList2.printList(); - linkedList3.printList(); - SingleLinkedList.printList(findTripletWithSumEqualsTo(linkedList1.head, - linkedList2.head, - linkedList3.head, - 18)); - } -} diff --git a/src/main/java/com/rampatra/misc/BotTesting.java b/src/main/java/com/rampatra/misc/BotTesting.java deleted file mode 100644 index 398e60b6..00000000 --- a/src/main/java/com/rampatra/misc/BotTesting.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.rampatra.misc; - -/** - * Created by IntelliJ IDEA. - * User: rampatra - * Date: 2/26/15 - * Time: 4:16 PM - * To change this template go to Preferences | IDE Settings | File and Code Templates - */ - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -public class BotTesting { - public static void main(String args[]) throws MalformedURLException { - final URL myURL = new URL("http://localhost:8080/ifb.html"); - ExecutorService executorService = Executors.newFixedThreadPool(20); - Long start = System.currentTimeMillis(); - - for (int i = 0; i <= 50; i++) { - executorService.execute(new Runnable() { - - @Override - public void run() { - - try { - HttpURLConnection myURLConnection = (HttpURLConnection) myURL.openConnection(); - - myURLConnection.setRequestProperty("x-msisdn", "919871296875"); - myURLConnection.setRequestProperty("x-rat", "1"); - myURLConnection.setRequestProperty("X-Forwarded-For", "171.48.0.1"); - String userAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 " + Math.random(); - myURLConnection.setRequestProperty("user-agent", userAgent); - myURLConnection.setRequestMethod("GET"); - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(myURLConnection.getInputStream())); - String line; - StringBuffer content = new StringBuffer(""); - - - bufferedReader.close(); - - } catch (IOException e) { - e.printStackTrace(); - } - } - }); - } - Long diff = System.currentTimeMillis() - start; - System.out.println("Difference: " + diff + "ms"); - executorService.shutdown(); - } -} diff --git a/src/main/java/com/rampatra/misc/BreakParagraph.java b/src/main/java/com/rampatra/misc/BreakParagraph.java deleted file mode 100644 index fc63912c..00000000 --- a/src/main/java/com/rampatra/misc/BreakParagraph.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.rampatra.misc; - -import java.text.BreakIterator; -import java.util.Locale; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 9/22/15 - * @time: 10:02 AM - */ -public class BreakParagraph { - public static void main(String[] args) { - String paragraph = - "Line boundary analysis determines where a text " + - "string can be broken when line-wrapping. The " + - "mechanism correctly handles punctuation and " + - "hyphenated words. Mr.Ram is a good boy. Actual line breaking needs to " + - "also consider the available line width and is " + - "handled by higher-level software. "; - - BreakIterator iterator = - BreakIterator.getSentenceInstance(Locale.US); - - int sentences = count(iterator, paragraph); - System.out.println("Number of sentences: " + sentences); - } - - private static int count(BreakIterator bi, String source) { - int counter = 0; - bi.setText(source); - - int lastIndex = bi.first(); - while (lastIndex != BreakIterator.DONE) { - int firstIndex = lastIndex; - lastIndex = bi.next(); - - if (lastIndex != BreakIterator.DONE) { - String sentence = source.substring(firstIndex, lastIndex); - System.out.println("sentence = " + sentence); - counter++; - } - } - return counter; - } -} diff --git a/src/main/java/com/rampatra/misc/CollectionIteration.java b/src/main/java/com/rampatra/misc/CollectionIteration.java deleted file mode 100644 index 54edc937..00000000 --- a/src/main/java/com/rampatra/misc/CollectionIteration.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.rampatra.misc; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import static java.lang.System.out; - -/** - * Created by IntelliJ IDEA. - *

- * All possible ways of iterating different collections in Java. - * Level: Basics - * - * @author rampatra - * @since 10/16/15 - * @time: 9:24 AM - */ -public class CollectionIteration { - - public static void main(String[] args) { - List list = new ArrayList<>(); - list.add(1); - list.add(2); - list.add(3); - // 1st way - Iterator iterator = list.iterator(); - while (iterator.hasNext()) { - out.println("List: " + iterator.next()); - } - // 2nd way - for (int i = 0; i < list.size(); i++) { - out.println("List: " + list.get(i)); - } - - Map hashMap = new HashMap<>(); - hashMap.put("one", 1); - hashMap.put("two", 2); - hashMap.put("three", 3); - // 1st way - Iterator> iterator1 = hashMap.entrySet().iterator(); // iterator only iterates on - // lists or set and not on maps - while (iterator1.hasNext()) { - Map.Entry entry = iterator1.next(); - out.println("HashMap: " + entry.getKey() + "->" + entry.getValue()); - } - // 2nd way - for (Map.Entry entry : hashMap.entrySet()) { // entrySet() returns a Set of Entry objects - // stored in HashMap - out.println("HashMap: " + entry.getKey() + "->" + entry.getValue()); - } - } -} diff --git a/src/main/java/com/rampatra/misc/DivideByZero.java b/src/main/java/com/rampatra/misc/DivideByZero.java deleted file mode 100644 index e879a783..00000000 --- a/src/main/java/com/rampatra/misc/DivideByZero.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.rampatra.misc; - -/** - * Created by IntelliJ IDEA. - * User: rampatra - * Date: 4/18/15 - * Time: 2:50 PM - * To change this template go to Preferences | IDE Settings | File and Code Templates - */ -public class DivideByZero { - public static void main(String[] args) { - System.out.println(5.0 / 0); // doesn't throw any exception - System.out.println(5 / 0); // throws runtime exception or unchecked exception (does NOT need explicit handling). To be specific, throws an arithmetic exception. - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/misc/Equals.java b/src/main/java/com/rampatra/misc/Equals.java deleted file mode 100644 index 9987a957..00000000 --- a/src/main/java/com/rampatra/misc/Equals.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.rampatra.misc; - -/** - * Created by IntelliJ IDEA. - * User: rampatra - * Date: 3/14/15 - * Time: 4:38 PM - * To change this template go to Preferences | IDE Settings | File and Code Templates - */ -public class Equals { - public static void main(String[] args) { - Short i = new Short((short) 12); - Short j = new Short((short) 12); - System.out.print(j == i); // prints false as compiler compares 2 references instead of their values - System.out.print(12 == i); // prints true as the compiler unboxes "i" and then compares the value - } -} diff --git a/src/main/java/com/rampatra/misc/GarbageCollection.java b/src/main/java/com/rampatra/misc/GarbageCollection.java deleted file mode 100644 index 1ed15635..00000000 --- a/src/main/java/com/rampatra/misc/GarbageCollection.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.rampatra.misc; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 10/2/15 - * @time: 12:44 AM - */ -public class GarbageCollection { - public void finalize() { - System.out.println("object is garbage collected"); - } - - public static void main(String args[]) { - GarbageCollection s1 = new GarbageCollection(); - GarbageCollection s2 = new GarbageCollection(); - s1 = null; - s2 = null; - System.gc(); - } -} diff --git a/src/main/java/com/rampatra/misc/GenericNonGenericMix.java b/src/main/java/com/rampatra/misc/GenericNonGenericMix.java deleted file mode 100644 index b13b0392..00000000 --- a/src/main/java/com/rampatra/misc/GenericNonGenericMix.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.rampatra.misc; - -import java.util.ArrayList; -import java.util.List; - -/** - * Created by IntelliJ IDEA. - * User: rampatra - * Date: 3/26/15 - * Time: 3:06 PM - * To change this template go to Preferences | IDE Settings | File and Code Templates - */ -public class GenericNonGenericMix { - static List add(ArrayList list) { - list.add(new String("100")); - list.add(new Integer(10)); // will throw exception at runtime - return list; - } - - public static void main(String[] args) { - ArrayList stringArrayList = new ArrayList<>(); - stringArrayList.add("ram"); - add(stringArrayList); - for (String s : stringArrayList) { - System.out.println(s); - } - } -} diff --git a/src/main/java/com/rampatra/misc/HitCount.java b/src/main/java/com/rampatra/misc/HitCount.java deleted file mode 100644 index 97f946ec..00000000 --- a/src/main/java/com/rampatra/misc/HitCount.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.rampatra.misc; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 10/16/15 - * @time: 8:40 AM - */ -public class HitCount { - - public static String getIPWithMaxHitCount(List inputList) { - HashMap hashMap = new HashMap<>(); - - for (int i = 0; i < inputList.size(); i++) { - String input = inputList.get(i); - String ip = input.substring(0, input.indexOf(" ")); - if (hashMap.get(ip) == null) { - hashMap.put(ip, 1); - } else { - hashMap.put(ip, hashMap.get(ip) + 1); - } - } - - List> list = new ArrayList<>(hashMap.entrySet()); - Collections.sort(list, new Comparator>() { - @Override - public int compare(Map.Entry o1, Map.Entry o2) { - return o2.getValue().compareTo(o1.getValue()); // desc order - } - }); - - return list.get(0).getKey(); - } - - public static void main(String[] args) { - List inputList = new ArrayList<>(); - inputList.add("10.1.2.23 http://we.sdfdsf.sdf"); - inputList.add("10.1.2.24 http://we.sdfdsf.sdf"); - inputList.add("10.1.2.24 http://we.sdfdsf.sdf"); - inputList.add("10.1.2.24 http://we.sdfdsf.sdf"); - inputList.add("10.1.2.24 http://we.sdfdsf.sdf"); - inputList.add("10.1.2.23 http://we.sdfdsf.sdf"); - inputList.add("10.1.2.23 http://we.sdfdsf.sdf"); - System.out.println(getIPWithMaxHitCount(inputList)); - } -} diff --git a/src/main/java/com/rampatra/misc/MapReduce.java b/src/main/java/com/rampatra/misc/MapReduce.java deleted file mode 100644 index a69df528..00000000 --- a/src/main/java/com/rampatra/misc/MapReduce.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.rampatra.misc; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -/** - * A rudimentary example explaining the concept of Map/Reduce paradigm. The question is, provided a list of Person - * objects from various countries, compute the total population in each country. - * - * @author rampatra - * @since 2019-02-26 - */ -public class MapReduce { - - private static class Person { - String name; - int age; - String country; - - Person(String country) { - this.country = country; - } - } - - /** - * The mapper function will take all the data and output only the information which we need, and in this - * case, it is just the country name to which a person belongs. - * - * @param personList a list of all persons - * @return a list of country names - */ - private static List mapper(List personList) { - return personList.stream().map(person -> person.country).collect(Collectors.toList()); - } - - /** - * The reducer function will take all the useful information from the mapper function and then compute the result - * we need. In this case, it is to count the number of persons in each country. - * - * @param countryNamesOfAllPersons a list of country names taken out of all {@code Person} objects - * @return a map containing country names as the keys and their resp. population as values - */ - private static Map reducer(List countryNamesOfAllPersons) { - Map countryToPopulationMap = new HashMap<>(); - - countryNamesOfAllPersons.forEach(countryName -> { - countryToPopulationMap.computeIfPresent(countryName, (country, population) -> population + 1); - countryToPopulationMap.computeIfAbsent(countryName, country -> countryToPopulationMap.put(country, 1)); - }); - - return countryToPopulationMap; - } - - /** - * Just to print the output. - * - * @param countryToPopulationMap a map containing country names as the keys and their resp. population as values - */ - private static void printPopulation(Map countryToPopulationMap) { - countryToPopulationMap.forEach((k, v) -> System.out.println(k + ": " + v)); - } - - public static void main(String[] args) { - - Person[] persons = new Person[]{new Person("India"), new Person("Ireland"), - new Person("Sweden"), new Person("United States"), new Person("India"), - new Person("Ireland"), new Person("India")}; - - printPopulation(reducer(mapper(Arrays.asList(persons)))); - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/misc/MapWithTimestamp.java b/src/main/java/com/rampatra/misc/MapWithTimestamp.java deleted file mode 100644 index 184656a7..00000000 --- a/src/main/java/com/rampatra/misc/MapWithTimestamp.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.rampatra.misc; - -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - -/** - * @author rampatra - * @since 2019-05-15 - */ -public class MapWithTimestamp { - - private final Map> map = new HashMap<>(); - - public V get(K key, Long timestamp) { - Map entry = map.get(key); - - return entry != null ? entry.get(timestamp) : null; - } - - public void put(K key, Long timestamp, V value) { - Map entry = map.get(key); - - if (entry == null) { - map.put(key, new HashMap() {{ - put(timestamp, value); - }}); - } else { - entry.put(timestamp, value); - } - } - - public static void main(String[] args) throws Exception { - MapWithTimestamp mapWithTimestamp = new MapWithTimestamp<>(); - long timestamp1; - long timestamp2; - long timestamp3; - - mapWithTimestamp.put(1, timestamp1 = new Date().getTime(), 10_0); - mapWithTimestamp.put(2, timestamp2 = new Date().getTime(), 20_0); - Thread.sleep(100); - mapWithTimestamp.put(2, new Date().getTime(), 20_1); - Thread.sleep(100); - mapWithTimestamp.put(2, new Date().getTime(), 20_2); - mapWithTimestamp.put(3, timestamp3 = new Date().getTime(), 30_0); - System.out.println(mapWithTimestamp.get(2, timestamp2)); - System.out.println(mapWithTimestamp.get(3, timestamp2)); - System.out.println(mapWithTimestamp.get(3, timestamp3)); - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/misc/MethodLocalVSInner.java b/src/main/java/com/rampatra/misc/MethodLocalVSInner.java deleted file mode 100644 index 6eebd6c6..00000000 --- a/src/main/java/com/rampatra/misc/MethodLocalVSInner.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.rampatra.misc; - -/** - * Created by IntelliJ IDEA. - * User: rampatra - * Date: 4/14/15 - * Time: 11:39 AM - * To change this template go to Preferences | IDE Settings | File and Code Templates - */ -class A { - void m() { - System.out.println("outer"); - } -} - -public class MethodLocalVSInner { - - public static void main(String[] args) { - new MethodLocalVSInner().go(); - } - - void go() { - new A().m(); - class A { - void m() { - System.out.println("inner"); - } - } - } - - class A { - void m() { - System.out.println("middle"); - } - } -} diff --git a/src/main/java/com/rampatra/misc/MethodOverloading.java b/src/main/java/com/rampatra/misc/MethodOverloading.java deleted file mode 100644 index bdd30522..00000000 --- a/src/main/java/com/rampatra/misc/MethodOverloading.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.rampatra.misc; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 5/8/15 - * @time: 12:08 PM - */ -class MethodOverloading { - - static void go(float x) { - System.out.print("float "); - } - - static void go(Long x) { - System.out.print("Long "); - } - - static void go(double x) { - System.out.print("double "); - } - - static void go(Double x) { - System.out.print("Double "); - } - - static void go(int x, int y) { - System.out.print("int,int "); - } - - static void go(byte... x) { - System.out.print("byte... "); - } - - static void go(Long x, Long y) { - System.out.print("Long,Long "); - } - - static void go(long... x) { - System.out.print("long... "); - } - - public static void main(String[] args) { - byte b = 5; - short s = 5; - long l = 5; - float f = 5.0f; - // widening beats autoboxing - go(b); - go(s); - go(l); - go(f); - // widening beats var-args - go(b, b); - // auto-boxing beats var-args - go(l, l); - } -} diff --git a/src/main/java/com/rampatra/misc/Outer.java b/src/main/java/com/rampatra/misc/Outer.java deleted file mode 100644 index b767e2b7..00000000 --- a/src/main/java/com/rampatra/misc/Outer.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.rampatra.misc; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 9/30/15 - * @time: 9:37 AM - */ -class BigOuter { - static class Nest { - void go() { - System.out.println("hi"); - } - } -} - -public class Outer { - static class B2 { - void goB2() { - System.out.println("hi 2"); - } - } - - public static void main(String[] args) { - BigOuter.Nest n = new BigOuter.Nest(); - n.go(); - B2 b2 = new B2(); - b2.goB2(); - //B2.goB2(); not possible - } -} diff --git a/src/main/java/com/rampatra/misc/OuterClassAccess.java b/src/main/java/com/rampatra/misc/OuterClassAccess.java deleted file mode 100644 index 6c6f53ed..00000000 --- a/src/main/java/com/rampatra/misc/OuterClassAccess.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.rampatra.misc; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 11/13/15 - * @time: 11:39 AM - */ -public class OuterClassAccess { - private int size = 7; - private static int length = 3; - - public static void main(String[] args) { - new OuterClassAccess().go(); - } - - void go() { - int size = 5; - System.out.println(new Inner().adder()); - } - - class Inner { - int adder() { - return size * length; // inner class can access static members of outer class - } - } -} diff --git a/src/main/java/com/rampatra/misc/RandomTest.java b/src/main/java/com/rampatra/misc/RandomTest.java deleted file mode 100644 index 5c9590cc..00000000 --- a/src/main/java/com/rampatra/misc/RandomTest.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.rampatra.misc; - -import java.util.Random; - -/** - * @author rampatra - * @since 2/23/15 - */ -public class RandomTest { - public static void main(String[] args) { - Random r = new Random(); - System.out.println(r.nextInt(1)); - System.out.println(randInt(0, 1, false)); - //System.out.print(randInts(1, 0)); - } - - public static int randInt(int start, int end, boolean startInclusive) { - int diff = end - start; - if (start < 0 || end < 0 || diff <= 0) return -1; - - Random random = new Random(); - if (startInclusive) { - return random.nextInt(diff + 1) + start; - } else { - return random.nextInt(diff) + start + 1; - } - } - - public static int randInt(int max, int exclude) { - // some validation - if (max <= 0) return -1; - Random random = new Random(); - int randInt = random.nextInt(max); - if (randInt == exclude) { - return (randInt == max) ? randInt - 1 : randInt + 1; - } else { - return randInt; - } - } - - public static int[] randInts(int max, int exclude) { - int[] randInts = new int[2]; - randInts[0] = randInt(max, exclude); - do { - randInts[1] = randInt(max, exclude); - } while ((randInts[0] != -1 & randInts[1] != -1) && (randInts[0] == randInts[1])); - - return randInts; - } -} diff --git a/src/main/java/com/rampatra/misc/ReadFile.java b/src/main/java/com/rampatra/misc/ReadFile.java deleted file mode 100644 index c5c64540..00000000 --- a/src/main/java/com/rampatra/misc/ReadFile.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.rampatra.misc; - -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; - - -/** - * Various ways to read a file in Java. - * - * @author rampatra - * @since 2019-06-03 - */ -public class ReadFile { - - private static Stream readFile(String filePath) throws IOException { - return Files.lines(Paths.get(filePath)); // use Files.readAllLines() to return a List instead of Stream - } - - private static String readFile(Path filePath) throws IOException { - Stream lines = Files.lines(filePath); - String data = lines.collect(Collectors.joining("\n")); - lines.close(); - return data; - } - - private static List readLargeFile(Path filePath) throws IOException { - try (BufferedReader reader = Files.newBufferedReader(filePath)) { - List result = new ArrayList<>(); - for (; ; ) { - String line = reader.readLine(); - if (line == null) - break; - result.add(line); - } - return result; - } - } - - private static String readFileOldWay(String filePath) throws IOException { - try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) { - StringBuilder builder = new StringBuilder(); - String currentLine = reader.readLine(); - while (currentLine != null) { - builder.append(currentLine); - builder.append("\n"); - currentLine = reader.readLine(); - } - // reader.close(); not required as try-with-resources is used - - return builder.toString(); - } - } - - public static void main(String[] args) throws IOException { - readFile("src/main/java/com/rampatra/misc/reverseandadd.txt").forEach(System.out::println); - System.out.println("=================="); - System.out.println(readFile(Paths.get("src/main/java/com/rampatra/misc/reverseandadd.txt"))); - System.out.println("=================="); - System.out.println(readLargeFile(Paths.get("src/main/java/com/rampatra/misc/reverseandadd.txt"))); - System.out.println("=================="); - System.out.println(readFileOldWay("src/main/java/com/rampatra/misc/reverseandadd.txt")); - } -} diff --git a/src/main/java/com/rampatra/misc/RecursiveWarmup.java b/src/main/java/com/rampatra/misc/RecursiveWarmup.java deleted file mode 100644 index ad99d0c3..00000000 --- a/src/main/java/com/rampatra/misc/RecursiveWarmup.java +++ /dev/null @@ -1,118 +0,0 @@ -package com.rampatra.misc; - -import java.util.ArrayList; -import java.util.List; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 9/28/15 - * @time: 8:37 PM - */ -public class RecursiveWarmup { - - /** - * Reverses the string {@param input} iteratively. - * - * @param input - * @return the reversed {@code String}. - */ - public String reverse(String input) { - - int len = input.length(); - char[] charArray = input.toCharArray(); - char[] revCharArray = new char[len]; - - for (int i = 0; i < len; i++) { - revCharArray[len - i - 1] = charArray[i]; - } - - return String.valueOf(revCharArray); - } - - /** - * Reverses the string {@param input} recursively. - * NOTE: This is BAD programming practice. - * - * @param input - * @return the reversed {@code String}. - */ - public String reverseRecursive(String input) { - if (input.length() > 1) { - char c = input.charAt(0); - String rev = reverseRecursive(input.substring(1)); - input = rev + c; - } - return input; - } - - - /** - * Reverses a list {@param input}. - * - * @param input - * @return reversed {@code List}. - */ - public List reverse(List input) { - - List revList = new ArrayList<>(); - - for (int i = input.size() - 1; i >= 0; i--) { - revList.add(input.get(i)); - } - - return revList; - } - - /** - * Reverses a list {@param input} recursively. - * NOTE: This is BAD programming practice. - * - * @param input - * @return reversed {@code List}. - */ - public List reverseRecursive(List input) { - - if (!input.isEmpty()) { - Integer item = input.remove(0); - reverseRecursive(input); - input.add(item); - } - return input; - } - - /** - * Starting point of the program. - * - * @param a - */ - public static void main(String[] args) { - RecursiveWarmup RecursiveWarmup = new RecursiveWarmup(); - List list1 = new ArrayList<>(); - list1.add(1); - list1.add(2); - list1.add(3); - list1.add(4); - List list2 = new ArrayList<>(); - list2.add(1); - List list3 = new ArrayList<>(); - System.out.println("========= String reverse test cases ========="); - System.out.println(RecursiveWarmup.reverse("apple")); - System.out.println(RecursiveWarmup.reverse("a")); - System.out.println(RecursiveWarmup.reverse("")); - System.out.println("========= String reverse recursive test cases ========="); - System.out.println(RecursiveWarmup.reverseRecursive("apple")); - System.out.println(RecursiveWarmup.reverseRecursive("a")); - System.out.println(RecursiveWarmup.reverseRecursive("")); - System.out.println("========== List reverse test cases =========="); - System.out.println(RecursiveWarmup.reverse(list1)); - System.out.println(RecursiveWarmup.reverse(list2)); - System.out.println(RecursiveWarmup.reverse(list3)); - System.out.println("========== List reverse recursive test cases =========="); - System.out.println(RecursiveWarmup.reverseRecursive(list1)); - System.out.println(RecursiveWarmup.reverseRecursive(list2)); - System.out.println(RecursiveWarmup.reverseRecursive(list3)); - System.exit(0); - } -} diff --git a/src/main/java/com/rampatra/misc/RegexReplaceAllSpaces.java b/src/main/java/com/rampatra/misc/RegexReplaceAllSpaces.java deleted file mode 100644 index 04b33db6..00000000 --- a/src/main/java/com/rampatra/misc/RegexReplaceAllSpaces.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.rampatra.misc; - -/** - * @author rampatra - * @since 11/3/15 - */ -public class RegexReplaceAllSpaces { - - public static String replaceAll(String str, String regex, String replacement) { - return str.replaceAll(regex, replacement); - } - - public static void main(String[] args) { - System.out.println(replaceAll("ram s", "\\s+", "")); - } -} - - diff --git a/src/main/java/com/rampatra/misc/RegexValidateLatLong.java b/src/main/java/com/rampatra/misc/RegexValidateLatLong.java deleted file mode 100644 index e8d8d2d6..00000000 --- a/src/main/java/com/rampatra/misc/RegexValidateLatLong.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.rampatra.misc; - -import java.util.Scanner; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * @author rampatra - * @since 9/12/15 - */ -public class RegexValidateLatLong { - - /** - * Validates latitude/longitude in the form (+75, 180) etc. - * - * @param s - * @return - */ - public static String validateLatLong(String s) { - String regex_coords = "^(\\(\\-?\\d+(\\.\\d+)?),\\s*(\\-?\\d+(\\.\\d+)?\\))$"; - Pattern compiledPattern2 = Pattern.compile(regex_coords, Pattern.CASE_INSENSITIVE); - Matcher matcher2 = compiledPattern2.matcher(s); - while (matcher2.find()) { - return "Valid"; - } - return "Invalid"; - } - - public static void main(String[] args) { - Scanner in = new Scanner(System.in); - - int t = Integer.parseInt(in.nextLine()); - String[] in_ar = new String[t]; - - for (int i = 0; i < t; i++) { - in_ar[i] = in.nextLine(); - } - - for (String i : in_ar) { - System.out.println(validateLatLong(i)); - } - } -} diff --git a/src/main/java/com/rampatra/misc/ReverseAndAdd.java b/src/main/java/com/rampatra/misc/ReverseAndAdd.java deleted file mode 100644 index 56713796..00000000 --- a/src/main/java/com/rampatra/misc/ReverseAndAdd.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.rampatra.misc; - -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; -import java.math.BigInteger; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 9/16/15 - * @time: 10:53 PM - */ -public class ReverseAndAdd { - - /** - * Reverses the number {@param n}. - * - * @param n - * @return the reverse of the number {@param n}. - */ - public static BigInteger getReverse(BigInteger n) { - return new BigInteger(new StringBuilder().append(n).reverse().toString()); - } - - /** - * Checks if {@param n} is palindrome. - * - * @param n - * @return {@code true} if {@param n} is palindrome. - */ - public static boolean isPalindrome(BigInteger n) { - return n.compareTo(getReverse(n)) == 0; - } - - /** - * Checks if {@param n} is negative. - * - * @param n - * @return {@code true} if {@param n} is negative, {@code false} otherwise. - */ - public static boolean isNegative(BigInteger n) { - return n.compareTo(new BigInteger("0")) == -1; - } - - /** - * Reverses the number {@param n}, adds to itself and then checks - * for palindrome. - * - * @param n - * @return an array of {@code BigInteger} with number of additions and final palindrome number respectively. - */ - public static BigInteger[] reverseAddAndCheck(String n) { - BigInteger additions = new BigInteger("1"); - BigInteger original = new BigInteger(n); - - boolean isNegative = isNegative(original); - if (isNegative) original = original.multiply(new BigInteger("-1")); - - BigInteger reverse; - - while (!isPalindrome(original.add(reverse = getReverse(original)))) { - original = original.add(reverse); - additions = additions.add(new BigInteger("1")); - } - - original = original.add(reverse); - if (isNegative) original = original.multiply(new BigInteger("-1")); - - return new BigInteger[]{additions, original}; - } - - /** - * Reads the input file mentioned in {@param filePath} line by line - * and calls {@code reverseAddAndCheck()} for every line. - * - * @param filePath - */ - public static void readFile(String filePath) { - - try (BufferedReader br = new BufferedReader(new FileReader(filePath))) { - - String line; - - while ((line = br.readLine()) != null) { - BigInteger[] result = reverseAddAndCheck(line); - System.out.println(result[0] + " " + result[1]); - } - - } catch (IOException e) { - e.printStackTrace(); - } - } - - /** - * Starting point of the program. - * - * @param args - */ - public static void main(String[] args) { - readFile(args[0]); - System.exit(0); - } -} diff --git a/src/main/java/com/rampatra/misc/TreeList.java b/src/main/java/com/rampatra/misc/TreeList.java deleted file mode 100644 index fd9059f4..00000000 --- a/src/main/java/com/rampatra/misc/TreeList.java +++ /dev/null @@ -1,174 +0,0 @@ -package com.rampatra.misc; - -/** - * Created by IntelliJ IDEA. - * - * @since 5/4/15 - * @time: 8:17 PM - */ -// TreeList.java -/* - Demonstrates the greatest recursive pointer problem ever -- - recursively changing an ordered binary tree into a circular - doubly linked list. - See http://cslibrary.stanford.edu/109/ - - This code is not especially OOP. - - This code is free for any purpose. - Feb 22, 2000 - Nick Parlante nick.parlante@cs.stanford.edu -*/ - - - -/* - This is the simple Node class from which the tree and list - are built. This does not have any methods -- it's just used - as dumb storage by TreeList. - The code below tries to be clear where it treats a Node pointer - as a tree vs. where it is treated as a list. -*/ -class Node { - int data; - Node small; - Node large; - - public Node(int data) { - this.data = data; - small = null; - large = null; - } -} - - -/* - TreeList main methods: - -join() -- utility to connect two list nodes - -append() -- utility to append two lists - -treeToList() -- the core recursive function - -treeInsert() -- used to build the tree -*/ -class TreeList { - /* - helper function -- given two list nodes, join them - together so the second immediately follow the first. - Sets the .next of the first and the .previous of the second. - */ - public static void join(Node a, Node b) { - a.large = b; - b.small = a; - } - - - /* - helper function -- given two circular doubly linked - lists, append them and return the new list. - */ - public static Node append(Node a, Node b) { - // if either is null, return the other - if (a == null) return (b); - if (b == null) return (a); - - // find the last node in each using the .previous pointer - Node aLast = a.small; - Node bLast = b.small; - - // join the two together to make it connected and circular - join(aLast, b); - join(bLast, a); - - return (a); - } - - - /* - --Recursion-- - Given an ordered binary tree, recursively change it into - a circular doubly linked list which is returned. - */ - public static Node treeToList(Node root) { - // base case: empty tree -> empty list - if (root == null) return (null); - - // Recursively do the subtrees (leap of faith!) - Node aList = treeToList(root.small); - Node bList = treeToList(root.large); - - // Make the single root node into a list length-1 - // in preparation for the appending - root.small = root; - root.large = root; - - // At this point we have three lists, and it's - // just a matter of appending them together - // in the right order (aList, root, bList) - aList = append(aList, root); - aList = append(aList, bList); - - return (aList); - } - - - /* - Given a non-empty tree, insert a new node in the proper - place. The tree must be non-empty because Java's lack - of reference variables makes that case and this - method messier than they should be. - */ - public static void treeInsert(Node root, int newData) { - if (newData <= root.data) { - if (root.small != null) treeInsert(root.small, newData); - else root.small = new Node(newData); - } else { - if (root.large != null) treeInsert(root.large, newData); - else root.large = new Node(newData); - } - } - - - // Do an inorder traversal to print a tree - // Does not print the ending "\n" - public static void printTree(Node root) { - if (root == null) return; - printTree(root.small); - System.out.print(Integer.toString(root.data) + " "); - printTree(root.large); - } - - - // Do a traversal of the list and print it out - public static void printList(Node head) { - Node current = head; - - while (current != null) { - System.out.print(Integer.toString(current.data) + " "); - current = current.large; - if (current == head) break; - } - - System.out.println(); - } - - - // Demonstrate tree->list with the list 1..5 - public static void main(String[] args) { - - // first build the tree shown in the problem document - // http://cslibrary.stanford.edu/109/ - Node root = new Node(6); - treeInsert(root, 3); - treeInsert(root, 5); - treeInsert(root, 7); - treeInsert(root, 8); - treeInsert(root, 9); - - System.out.println("tree:"); - printTree(root); // 1 2 3 4 5 - System.out.println(); - - System.out.println("list:"); - Node head = treeToList(root); - printList(head); // 1 2 3 4 5 yay! - } -} diff --git a/src/main/java/com/rampatra/misc/parenthesis.txt b/src/main/java/com/rampatra/misc/parenthesis.txt deleted file mode 100644 index 077f4ab6..00000000 --- a/src/main/java/com/rampatra/misc/parenthesis.txt +++ /dev/null @@ -1,1587 +0,0 @@ -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{{{{}}}} -{[]}{[]} -{[()]} -{[] -{{]][[}} -{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]{]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]}{[]} -{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} \ No newline at end of file diff --git a/src/main/java/com/rampatra/misc/reverseandadd.txt b/src/main/java/com/rampatra/misc/reverseandadd.txt deleted file mode 100644 index 9e1727db..00000000 --- a/src/main/java/com/rampatra/misc/reverseandadd.txt +++ /dev/null @@ -1,225 +0,0 @@ -1 -5 -59 -69 -79 -89 -166 -188 -193 -829 -167 -849 -177 -999 -739 -989 -869 -187 -1397 -2069 -1797 -1798 -6999 -1297 -10797 -10853 -10921 -10971 -13297 -10548 -13293 -17793 -20889 -80359 -13697 -10794 -15891 -70759 -70269 -10677 -10833 -10911 -700269 -106977 -108933 -600259 -131996 -600279 -141996 -600579 -147996 -178992 -190890 -600589 -150296 -1009227 -1007619 -1009246 -1008628 -1007377 -1001699 -1009150 -1058921 -1050995 -1003569 -1036974 -1490991 -3009179 -1008595 -1064912 -1998999 -7008429 -1000689 -1005744 -1007601 -7008899 -9008299 -10905963 -10069785 -10089342 -11979990 -10029372 -10029826 -16207990 -90000589 -10309988 -100389898 -100055896 -110909992 -160009490 -800067199 -151033997 -100093573 -103249931 -107025910 -180005498 -100239862 -140669390 -1090001921 -7007009909 -1009049407 -9000046899 -1050027948 -1304199693 -5020089949 -1005499526 -10000505448 -10000922347 -10000696511 -10701592943 -10018999583 -10000442119 -10000761554 -10084899970 -10006198250 -18060009890 -11400245996 -16002897892 -18317699990 -37000488999 -10050289485 -90000626389 -10000853648 -13003696093 -10050859271 -10287799930 -10000973037 -10600713933 -10942399911 -60000180709 -11009599796 -16000097392 -10031199494 -10306095991 -10087799570 -100900509906 -100000055859 -104000146950 -180005998298 -300000185539 -100001987765 -1000007614641 -1000043902320 -1000006653746 -1000005469548 -4000096953659 -1332003929995 -1000201995662 -6000008476379 -1200004031698 -1631002019993 -1000006412206 -1090604591930 -1600005969190 -10090899969901 -40000004480279 -14104229999995 -100000109584608 -100000098743648 -100004789906151 -100079239995161 -100389619999030 -200000729975309 -107045067996994 -105420999199982 -101000269830970 -104000047066970 -700000001839569 -100000050469737 -101000789812993 -100907098999571 -100017449991820 -890000023937399 -100009989989199 -101507024989944 -107405139999943 -100057569996821 -103500369729970 -900000076152049 -100000439071028 -120000046510993 -103000015331997 -100617081999573 -100009029910821 -107000020928910 -100000090745299 -102000149322944 -130000074931591 -100120849299260 --1 --5 --59 --69 --79 --89 --166 --188 --193 --829 --167 --849 --177 --999 --739 --989 --869 --187 --1397 --2069 --1797 --1798 --6999 --1297 --103500369729970 --900000076152049 --100000439071028 --120000046510993 --103000015331997 --100617081999573 --100009029910821 --107000020928910 --100000090745299 --102000149322944 --130000074931591 --100120849299260 \ No newline at end of file diff --git a/src/main/java/com/rampatra/permutations/StringPermutations.java b/src/main/java/com/rampatra/permutations/StringPermutations.java deleted file mode 100644 index 302d14f9..00000000 --- a/src/main/java/com/rampatra/permutations/StringPermutations.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.rampatra.permutations; - -/** - * Prints all the permutations of a string by using the characters in the - * input only once. - * - * @author rampatra - * @link http://www.ericleschinski.com/c/java_permutations_recursion/ - * @link http://introcs.cs.princeton.edu/java/23recursion/Permutations.java.html - * @link me.rampatra.strings.StringPermutationCount for a modification of this problem - * @since 9/24/15 - */ -public class StringPermutations { - - /** - * Generates and prints all possible permutations (in order) - * of string {@param s}. - * - * @param prefix empty string, needed for the recursive method - * @param s input string with no repeated characters - */ - public static void printAllPermutations(String prefix, String s) { - int len = s.length(); - if (len == 0) { - System.out.println(prefix); - } else { - for (int i = 0; i < len; i++) { - printAllPermutations(prefix + s.charAt(i), s.substring(0, i) + s.substring(i + 1)); - } - } - } - - public static void main(String[] args) { - printAllPermutations("", "a"); - System.out.println("-------"); - printAllPermutations("", "ab"); - System.out.println("-------"); - printAllPermutations("", "abc"); - } -} diff --git a/src/main/java/com/rampatra/permutations/StringPermutationsCount.java b/src/main/java/com/rampatra/permutations/StringPermutationsCount.java deleted file mode 100644 index c5916a07..00000000 --- a/src/main/java/com/rampatra/permutations/StringPermutationsCount.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.rampatra.permutations; - -/** - * Created by IntelliJ IDEA. - *

- * You have 2 string, one smaller, one larger. Write an algorithm to figure out how many permutations of the - * smaller string exist in the bigger string. - * - * @author rampatra - * @since 10/15/15 - * @time: 10:32 AM - * @see: StringPermutations for a simpler version - */ -public class StringPermutationsCount { - - /** - * Finds the number of permutations of string {@param s1} that exists in string {@param s2}. - * - * @param prefix - * @param s1 - * @param s2 - * @param count - * @return - */ - public static int getStringPermutationsCount(String prefix, String s1, String s2, int count) { - if (s1.isEmpty()) { - if (s2.indexOf(prefix) != -1) count++; - } - - for (int i = 0; i < s1.length(); i++) { - count = getStringPermutationsCount(prefix + s1.substring(i, i + 1), s1.substring(0, i) + s1.substring(i + 1), s2, count); - } - - return count; - } - - public static void main(String[] args) { - System.out.println(getStringPermutationsCount("", "abc", "abcba", 0)); - System.out.println(getStringPermutationsCount("", "abc", "abcbacb", 0)); - } -} diff --git a/src/main/java/com/rampatra/permutations/StringPermutationsWithDuplicates.java b/src/main/java/com/rampatra/permutations/StringPermutationsWithDuplicates.java deleted file mode 100644 index 21d31cb3..00000000 --- a/src/main/java/com/rampatra/permutations/StringPermutationsWithDuplicates.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.rampatra.permutations; - -/** - * A slight variation of {@link StringPermutations} where the input may - * contain repeated characters. - * - * @author rampatra - * @since 16/11/2018 - */ -public class StringPermutationsWithDuplicates { - - /** - * Generates and prints all possible permutations (in order) - * of string {@param s}. - * - * @param prefix empty string, needed for the recursive method - * @param s input string with repeated characters - */ - public static void printAllPermutations(String prefix, String s) { - // TODO - } - - public static void main(String[] args) { - printAllPermutations("", "aba"); - } -} - diff --git a/src/main/java/com/rampatra/permutations/UppercaseLowercasePermutations.java b/src/main/java/com/rampatra/permutations/UppercaseLowercasePermutations.java deleted file mode 100644 index fec104a6..00000000 --- a/src/main/java/com/rampatra/permutations/UppercaseLowercasePermutations.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.rampatra.permutations; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 9/26/15 - * @time: 4:43 PM - */ -public class UppercaseLowercasePermutations { - - /** - * Generates all possible case combinations for string {@param s}. - *

- * For example, - * Input: 0ab - * Output: ["0ab","0AB","0aB","0Ab"] - * - * @param prefix - * @param s - */ - public static void printUppercaseLowercasePermutations(String prefix, String s) { - - if (s.isEmpty()) { - System.out.println(prefix); - return; - } - - if (isNumber(s.charAt(0))) { - printUppercaseLowercasePermutations(prefix + s.charAt(0), s.substring(1)); - } else { - printUppercaseLowercasePermutations(prefix + Character.toUpperCase(s.charAt(0)), s.substring(1)); - printUppercaseLowercasePermutations(prefix + Character.toLowerCase(s.charAt(0)), s.substring(1)); - } - } - - public static boolean isNumber(char s) { - try { - Integer.parseInt(String.valueOf(s)); - } catch (Exception e) { - return false; - } - return true; - } - - public static void main(String[] args) { - printUppercaseLowercasePermutations("", "0ab"); - System.out.println("========"); - printUppercaseLowercasePermutations("", "01"); - System.out.println("========"); - printUppercaseLowercasePermutations("", "0a1"); - System.out.println("========"); - printUppercaseLowercasePermutations("", "0ab1c"); - } -} diff --git a/src/main/java/com/rampatra/searching/BinarySearch.java b/src/main/java/com/rampatra/searching/BinarySearch.java deleted file mode 100644 index 26997658..00000000 --- a/src/main/java/com/rampatra/searching/BinarySearch.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.rampatra.searching; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @version 9/1/15 - */ -public class BinarySearch { - - /** - * Searches an element {@param n} in a sorted array {@param a} - * and returns its index in O(log n) time. The Index may not - * correspond to the first occurrence of the element. - * - * @param a sorted array to be searched - * @param n number to be searched in the array - * @return index of {@param n} or {@code -1} if not present - */ - private static int binarySearch(int[] a, int n) { - return binarySearch(a, n, 0, a.length - 1); - } - - public static int binarySearch(int[] a, int n, int low, int high) { - - if (low <= high) { - int mid = (low + high) / 2; // to prevent overflow you can instead do: mid = low + (high - low) / 2 - - if (n == a[mid]) { - return mid; - } else if (n < a[mid]) { - return binarySearch(a, n, 0, mid - 1); - } else { - return binarySearch(a, n, mid + 1, high); - } - } else { - return -1; - } - } - - /** - * Non-recursive version of binary search. - * - * @param a sorted array to be searched - * @param n number to be searched in the array - * @return index of {@param n} or {@code -1} if not present - */ - private static int binarySearchNonRecursive(int[] a, int n) { - int low = 0, high = a.length, mid; - while (low <= high) { - mid = (low + high) / 2; // to prevent overflow you can instead do: mid = low + (high - low) / 2 - if (n == a[mid]) { - return mid; - } else if (n < a[mid]) { - high = mid - 1; - } else { - low = mid + 1; - } - } - return -1; - } - - /** - * Driver for testing. - * - * @param a - */ - public static void main(String[] args) { - System.out.println(binarySearch(new int[]{0, 2}, 2)); - System.out.println(binarySearch(new int[]{0, 1, 2, 3}, 2)); - System.out.println(binarySearch(new int[]{0, 1, 2, 3}, 3)); - System.out.println(binarySearch(new int[]{0, 2}, 0)); - System.out.println(binarySearch(new int[]{0, 1, 2, 2, 2, 3, 3}, 2)); // doesn't return index of first occurrence - System.out.println("---------"); - System.out.println(binarySearchNonRecursive(new int[]{0, 2}, 2)); - System.out.println(binarySearchNonRecursive(new int[]{0, 1, 2, 3}, 2)); - System.out.println(binarySearchNonRecursive(new int[]{0, 1, 2, 3}, 3)); - System.out.println(binarySearchNonRecursive(new int[]{0, 2}, 0)); - System.out.println(binarySearchNonRecursive(new int[]{0, 1, 2, 2, 2, 3, 3}, 2)); - } -} diff --git a/src/main/java/com/rampatra/searching/InterpolationSearch.java b/src/main/java/com/rampatra/searching/InterpolationSearch.java deleted file mode 100644 index 20f76665..00000000 --- a/src/main/java/com/rampatra/searching/InterpolationSearch.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.rampatra.searching; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 9/1/15 - * @time: 4:57 PM - */ -public class InterpolationSearch { - - /** - * @param a - * @param k - * @return - */ - public static int search(int[] a, int k) { - int low = 0, high = a.length - 1, mid; - - while (a[low] != a[high] && k >= a[low] && k <= a[high]) { - mid = low + (k - a[low]) * (high - low) / a[high] - a[low]; - - if (k < a[mid]) { - high = mid - 1; - } else if (k > a[mid]) { - low = mid + 1; - } else { - return mid; - } - } - - if (k == a[low]) { - return low; - } else { - return -1; - } - } - - public static void main(String[] args) { - System.out.println(search(new int[]{0, 2}, 2)); - System.out.println(search(new int[]{0, 1}, 2)); - System.out.println(search(new int[]{0, 1, 2, 3}, 2)); - System.out.println(search(new int[]{0, 1, 2, 3}, 3)); - System.out.println(search(new int[]{0, 2}, 0)); - System.out.println(search(new int[]{0, 1, 2, 2, 2, 3, 3}, 2)); - } -} diff --git a/src/main/java/com/rampatra/sorting/BubbleSort.java b/src/main/java/com/rampatra/sorting/BubbleSort.java deleted file mode 100644 index 8560319b..00000000 --- a/src/main/java/com/rampatra/sorting/BubbleSort.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.rampatra.sorting; - -import java.util.Arrays; - -/** - * @author rpatra16 - * @since 03/11/2018 - */ -public class BubbleSort { - - /** - * In bubble sort, we start at the beginning of the array and swap - * the first two elements if the first is greater than the second. - * Then, we go to the next pair, and so on, continuously making sweeps - * of the array until it is sorted. In doing so, the smaller items - * slowly "bubble" up to the beginning of the list and in each inner - * iteration the largest element is sorted. Ergo, the inner loop runs - * until {@code length - i - 1} times. Time complexity: O(n^2). Space - * complexity: O(1), in place. To learn more: {@see https://youtu.be/6Gv8vg0kcHc} - * - * @param ar to be sorted - */ - private static void bubbleSort(int[] ar) { - for (int i = 0; i < ar.length - 1; i++) { - for (int j = 0; j < ar.length - i - 1; j++) { - if (ar[j] > ar[j + 1]) { - swap(ar, j, j + 1); - } - } - } - } - - private static void swap(int[] ar, int i, int j) { - int temp = ar[i]; - ar[i] = ar[j]; - ar[j] = temp; - } - - public static void main(String[] args) { - int[] ar = {2, 5, 1, 7, 8}; - System.out.println(Arrays.toString(ar)); - bubbleSort(ar); - System.out.println(Arrays.toString(ar)); - ar = new int[]{7, 5, 1, 7, 8, 0, 23}; - System.out.println(Arrays.toString(ar)); - bubbleSort(ar); - System.out.println(Arrays.toString(ar)); - } -} diff --git a/src/main/java/com/rampatra/sorting/CheckSorted.java b/src/main/java/com/rampatra/sorting/CheckSorted.java deleted file mode 100644 index 0b9b6c3f..00000000 --- a/src/main/java/com/rampatra/sorting/CheckSorted.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.rampatra.sorting; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 10/23/15 - * @time: 8:30 AM - */ -public class CheckSorted { - - /** - * Determines whether array {@param a} is sorted or not. - * Sort order can be either ascending or descending. - * - * @param a - * @return - */ - public static boolean isSorted(int[] a) { - - if (a.length == 0) return true; - - int i; - boolean isAscending; - - // go to index where you find a number different from - // previous number (req. to determine sort order) - for (i = 1; i < a.length; i++) { - if (a[i] != a[i - 1]) break; - } - - // all elements equal or only a single element - if (i == a.length) { - return true; - } - - // determine sort order of array - if (a[i] > a[i - 1]) { - isAscending = true; - } else { - isAscending = false; - } - - // check if appropriate sort property is hold for rest of array - if (isAscending) { - for (; i < a.length; i++) { - if (a[i] < a[i - 1]) return false; - } - } else { - for (; i < a.length; i++) { - if (a[i] > a[i - 1]) return false; - } - } - - return true; - } - - public static void main(String[] args) { - System.out.println(isSorted(new int[]{1, 2, 3, 4, 5})); - System.out.println(isSorted(new int[]{5, 4, 3, 2, 1})); - System.out.println(isSorted(new int[]{})); - System.out.println(isSorted(new int[]{0})); - System.out.println(isSorted(new int[]{0, 0, 0, 0, 0, 0})); - System.out.println(isSorted(new int[]{4, 7, 9, 1, 0})); - } -} diff --git a/src/main/java/com/rampatra/sorting/HeapSort.java b/src/main/java/com/rampatra/sorting/HeapSort.java deleted file mode 100644 index 61f03802..00000000 --- a/src/main/java/com/rampatra/sorting/HeapSort.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.rampatra.sorting; - -import com.rampatra.base.MaxHeap; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 8/3/15 - */ -public class HeapSort { - - /** - * Heapsort. - *

- * Time complexity: O(n log n) as maxHeapify has complexity O(log n), buildMaxHeap has complexity O(n) and we - * run maxHeapify n-1 times in heapSort function, therefore time complexity of heapSort function is O(n log n). - * - * @param a - */ - public static void heapSort(int[] a) { - buildMaxHeap(a); - - for (int i = a.length - 1; i > 0; i--) { - swap(a, 0, i); - maxHeapify(a, 0, i); - } - } - - /** - * Makes the array {@param a} satisfy the max heap property starting from - * {@param index} till {@param end} position in array. - *

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

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

- * Time complexity: O(n) and is not O(n log n). - */ - private static void buildMaxHeap(int[] a) { - for (int i = a.length / 2 - 1; i >= 0; i--) { - maxHeapify(a, i, a.length); - } - } - - private static void swap(int[] a, int firstIndex, int secondIndex) { - a[firstIndex] = a[firstIndex] + a[secondIndex]; - a[secondIndex] = a[firstIndex] - a[secondIndex]; - a[firstIndex] = a[firstIndex] - a[secondIndex]; - } - - public static void main(String[] args) { - int[] ar = new int[]{2, 5, 1, 7, 9, 4}; - System.out.println(Arrays.toString(ar)); - heapSort(ar); - System.out.println(Arrays.toString(ar)); - } -} diff --git a/src/main/java/com/rampatra/sorting/MergeSort.java b/src/main/java/com/rampatra/sorting/MergeSort.java deleted file mode 100644 index eb95cf79..00000000 --- a/src/main/java/com/rampatra/sorting/MergeSort.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.rampatra.sorting; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 7/29/15 - * @time: 8:47 PM - */ -public class MergeSort { - - /** - * Merge sort. Note that we are creating unnecessary arrays in each recursive - * call. This makes the algorithm simple but it occupies more space. Look at - * {@link MergeSortSpaceOptimized} instead. - *

- * Time complexity: O(n log n) - * Space complexity: O(n) (also needs O(log n) stack space as it is recursive) - * - * @param arr - * @return - */ - public static int[] mergeSort(int[] arr) { - if (arr.length == 1) return arr; - - int[] x = mergeSort(Arrays.copyOfRange(arr, 0, arr.length / 2)); - int[] y = mergeSort(Arrays.copyOfRange(arr, arr.length / 2, arr.length)); - - return merge(x, y); - } - - /** - * Merges two sorted arrays {@code a} and {@code b}. - * - * @param a - * @param b - * @return - */ - public static int[] merge(int[] a, int[] b) { - int lenA = a.length, lenB = b.length, k = 0; - int[] sortedArray = new int[lenA + lenB]; - - for (int i = 0, j = 0; i < lenA || j < lenB; ) { - if (j == lenB || (i < lenA && a[i] < b[j])) { - sortedArray[k++] = a[i++]; - } else { - sortedArray[k++] = b[j++]; - } - } - - return sortedArray; - } - - public static void main(String[] args) { - int[] ar = new int[]{3, 5, 1, 6, 9, 8}; - System.out.println(Arrays.toString(ar)); - System.out.println(Arrays.toString(mergeSort(ar))); - } -} diff --git a/src/main/java/com/rampatra/sorting/MergeSortSpaceOptimized.java b/src/main/java/com/rampatra/sorting/MergeSortSpaceOptimized.java deleted file mode 100644 index 1b80caf8..00000000 --- a/src/main/java/com/rampatra/sorting/MergeSortSpaceOptimized.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.rampatra.sorting; - -import java.util.Arrays; - -/** - * @author rampatra - * @since 13/11/2018 - */ -public class MergeSortSpaceOptimized { - - /** - * This is entry point. You can call this method to sort - * an array {@code arr}. - * - * @param arr array to be sorted - */ - public static void mergeSort(int[] arr) { - mergeSort(arr, new int[arr.length], 0, arr.length - 1); - } - - private static void mergeSort(int[] arr, int[] helper, int low, int high) { - if (low < high) { - int mid = (low + high) / 2; // to prevent overflow you can instead do: mid = low + (high - low) / 2 - - mergeSort(arr, helper, low, mid); - mergeSort(arr, helper, mid + 1, high); - - merge(arr, helper, low, mid, high); - } - } - - private static void merge(int[] arr, int[] helper, int low, int mid, int high) { - int k = low; - - /* - Similar to merging two sorted arrays, i.e, merge two parts of arr[], arr[low..mid] and arr[mid+1..high], - and store in helper[] - */ - for (int i = low, j = mid + 1; i <= mid || j <= high; ) { - if (i > mid) { - helper[k++] = arr[j++]; - } else if (j > high) { - helper[k++] = arr[i++]; - } else if (arr[i] <= arr[j]) { - helper[k++] = arr[i++]; - } else if (arr[i] > arr[j]) { - helper[k++] = arr[j++]; - } - } - - // finally copy the sorted result from helper[] to arr[] - for (int i = low; i <= high; i++) { // note: we can use System.arraycopy() for better performance - arr[i] = helper[i]; - } - } - - public static void main(String[] args) { - int[] arr = {3, 6, 8, 9, 1, 2, 4}; - System.out.println(Arrays.toString(arr)); - mergeSort(arr); - System.out.println(Arrays.toString(arr)); - arr = new int[]{5, 8, 1, 2, 5, 3, 0, 1, 2, 4}; - System.out.println(Arrays.toString(arr)); - mergeSort(arr); - System.out.println(Arrays.toString(arr)); - } -} diff --git a/src/main/java/com/rampatra/sorting/PancakeSort.java b/src/main/java/com/rampatra/sorting/PancakeSort.java deleted file mode 100644 index 81cd9943..00000000 --- a/src/main/java/com/rampatra/sorting/PancakeSort.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.rampatra.sorting; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 10/26/15 - * @time: 9:20 PM - */ -public class PancakeSort { - - /** - * Sorts the array {@param a} in-place in O(n^2) time complexity. - *

- * This can also be seen as: Sort the array {@param a} using a method - * {@code reverse(int[] a, int end)} which reverses array {@code int[] a} - * from {@code 0} index till {@code end} index (both inclusive). - * - * @param a - */ - public static void sort(int[] a) { - - int maxIndex; // max element's index - int unsortedIndex = a.length - 1; // index till which elements are unsorted - - while (unsortedIndex > 0) { - maxIndex = 0; - // find max element's index - for (int j = 1; j <= unsortedIndex; j++) { - if (a[j] > a[maxIndex]) { - maxIndex = j; - } - } - // move the max element to its appropriate index if its not already in its correct index - if (maxIndex != unsortedIndex) { - reverse(a, maxIndex); // bring the max element to the front - reverse(a, unsortedIndex); // move the max element to its appropriate index - } - unsortedIndex--; - } - } - - /** - * Reverses array {@param a} from {@code 0} index - * till {@code end} index. - * - * @param a - * @param end - */ - public static void reverse(int[] a, int end) { - int temp; - for (int i = 0; i <= end / 2; i++) { - temp = a[i]; - a[i] = a[end - i]; - a[end - i] = temp; - } - } - - public static void main(String[] args) { - int[] ar = {1, 2, 3, 4, 5, 6}; - System.out.println(Arrays.toString(ar)); - sort(ar); - System.out.println(Arrays.toString(ar)); - ar = new int[]{3, 4, 7, 1, 9, 0}; - System.out.println(Arrays.toString(ar)); - sort(ar); - System.out.println(Arrays.toString(ar)); - ar = new int[]{6, 5, 4, 3, 2, 1}; - System.out.println(Arrays.toString(ar)); - sort(ar); - System.out.println(Arrays.toString(ar)); - ar = new int[]{}; - System.out.println(Arrays.toString(ar)); - sort(ar); - System.out.println(Arrays.toString(ar)); - ar = new int[]{1}; - System.out.println(Arrays.toString(ar)); - sort(ar); - System.out.println(Arrays.toString(ar)); - } -} diff --git a/src/main/java/com/rampatra/sorting/QuickSort.java b/src/main/java/com/rampatra/sorting/QuickSort.java deleted file mode 100644 index 48744ddc..00000000 --- a/src/main/java/com/rampatra/sorting/QuickSort.java +++ /dev/null @@ -1,104 +0,0 @@ -package com.rampatra.sorting; - -import java.util.Arrays; - -/** - * The basic Quick Sort. See http://www.csanimated.com/animation.php?t=Quicksort to learn more. - * - * @author rampatra - * @since 7/21/15 - */ -public class QuickSort { - - /** - * In-place partition method which moves all elements smaller than - * the pivot element to its left and all elements larger than the - * pivot element to its right and finally places the pivot element - * at its correct position. - * - * @param arr - * @param startIndex - * @param endIndex - * @return position of the pivot element - */ - public static int partition(int[] arr, int startIndex, int endIndex) { - int pivot = endIndex, temp; - - for (int i = startIndex; i < endIndex; i++) { - // if ith element is smaller than pivot element then - // swap it with the last larger element known - if (arr[i] < arr[pivot]) { - // swap a[startIndex] with a[i] - temp = arr[startIndex]; - arr[startIndex] = arr[i]; - arr[i] = temp; - startIndex++; - } - } - - // place the pivot element in its correct position - temp = arr[startIndex]; - arr[startIndex] = arr[pivot]; - arr[pivot] = temp; - - return startIndex; - } - - /** - * Recursive Quick sort. - * NOTE: This function is tail-recursive (doesn't use extra stack space per recursive call in many - * programming languages but not in Java as it doesn't support tail-recursive optimization). - *

- * Time complexity: - * Best Case: O(nlogn) - * Worst Case: O(n*n) - * - * @param arr - * @param startIndex - * @param endIndex - */ - public static void quickSort(int[] arr, int startIndex, int endIndex) { - if (startIndex < endIndex) { - int partition = partition(arr, startIndex, endIndex); - quickSort(arr, startIndex, partition - 1); - quickSort(arr, partition + 1, endIndex); - } - } - - /** - * Wrapper method to quick sort the entire array. - * - * @param arr the input array to sort - */ - public static void quickSort(int[] arr) { - quickSort(arr, 0, arr.length - 1); - } - - public static void main(String[] args) { - int[] ar = {3, 2, 1, 6, 4, 9, 7, 8}; - System.out.println(Arrays.toString(ar)); - quickSort(ar); - System.out.println(Arrays.toString(ar)); - - System.out.println("------"); - - ar = new int[]{3, 2, 6, 8, 4, 3, 7, 8}; - System.out.println(Arrays.toString(ar)); - quickSort(ar); - System.out.println(Arrays.toString(ar)); - - System.out.println("------"); - - ar = new int[]{4, 4, 4, 4, 4, 4, 4}; - System.out.println(Arrays.toString(ar)); - quickSort(ar); - System.out.println(Arrays.toString(ar)); - - System.out.println("------"); - - ar = new int[]{}; - System.out.println(Arrays.toString(ar)); - quickSort(ar); - System.out.println(Arrays.toString(ar)); - } -} diff --git a/src/main/java/com/rampatra/sorting/SelectionSort.java b/src/main/java/com/rampatra/sorting/SelectionSort.java deleted file mode 100644 index fb1e2b0e..00000000 --- a/src/main/java/com/rampatra/sorting/SelectionSort.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.rampatra.sorting; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 8/22/15 - * @time: 12:28 PM - */ -public class SelectionSort { - - /** - * Selection Sort. - *

- * Explanation: - * This is one of the simplest algorithm where each time the smallest/largest - * element is chosen and placed at the appropriate position and then again the - * logic is applied on rest of the elements till the entire array is sorted. - *

- * Time complexity: O(n^2) for all cases. Space complexity: O(1). - *

- * NOTE: Advantage of this sort is that it requires minimum number of memory writes - * like Cycle sort. - * - * @param a - */ - public static void selectionSort(int[] a) { - int minIndex; - - for (int i = 0; i < a.length - 1; i++) { - minIndex = i; - for (int j = i + 1; j < a.length; j++) { - if (a[j] < a[minIndex]) { - minIndex = j; - } - } - swap(a, i, minIndex); - } - } - - /** - * Swaps variables in {@param a} at {@param index1} with {@param index2}. - * - * @param a - * @param index1 - * @param index2 - */ - private static void swap(int[] a, int index1, int index2) { - int temp = a[index1]; - a[index1] = a[index2]; - a[index2] = temp; - } - - public static void main(String[] args) { - int[] ar = new int[]{3, 2, 1, 5, 6, 9, 7, 10}; - selectionSort(ar); - System.out.println(Arrays.toString(ar)); - - ar = new int[]{3, 2, 1, 5, 5, 6, 9, 7, 6, 10}; - selectionSort(ar); - System.out.println(Arrays.toString(ar)); - } -} diff --git a/src/main/java/com/rampatra/sorting/WiggleSort.java b/src/main/java/com/rampatra/sorting/WiggleSort.java deleted file mode 100644 index 51ef266a..00000000 --- a/src/main/java/com/rampatra/sorting/WiggleSort.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.rampatra.sorting; - -import java.util.Arrays; - -/** - * Wiggle Sort: Arrange the elements in the array such that elements in - * even indices are greater than or equal to its neighbouring elements - * and elements in odd indices are less than or equal to its neighbouring - * elements. In other words, all elements in array {@code a} are arranged - * such that, a[i-1] <= a[i] => a[i+1] - *

- * Ex: {1, 3, 2, 5, 4, 6} - * - * @author rampatra - * @version 01/09/2016 - */ -public class WiggleSort { - - public static int[] wiggleSortEasyWay(int[] a) { - a = MergeSort.mergeSort(a); - for (int i = 1; i < a.length; i += 2) { - swap(a, i, i + 1); - } - return a; - } - - private static void swap(int[] a, int index1, int index2) { - if (index2 >= a.length) return; - - a[index1] = a[index1] + a[index2]; - a[index2] = a[index1] - a[index2]; - a[index1] = a[index1] - a[index2]; - } - - public static void main(String[] args) { - int[] ar = {3, 5, 6, 7, 8, 1, 2}; - System.out.println(Arrays.toString(wiggleSortEasyWay(ar))); - int[] ar1 = {3, 5, 6, 7, 2, 1}; - System.out.println(Arrays.toString(wiggleSortEasyWay(ar1))); - int[] ar2 = {3, 5, 6, 7, 8, 1}; - System.out.println(Arrays.toString(wiggleSortEasyWay(ar2))); - int[] ar3 = {3, 5, 6, 5, 8, 1}; - System.out.println(Arrays.toString(wiggleSortEasyWay(ar3))); - } -} diff --git a/src/main/java/com/rampatra/stacks/BalancingParenthesis.java b/src/main/java/com/rampatra/stacks/BalancingParenthesis.java deleted file mode 100644 index c6e2851d..00000000 --- a/src/main/java/com/rampatra/stacks/BalancingParenthesis.java +++ /dev/null @@ -1,160 +0,0 @@ -package com.rampatra.stacks; - -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; -import java.util.EmptyStackException; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 9/15/15 - */ -public class BalancingParenthesis { - - private static final char L_PAREN = '('; - private static final char R_PAREN = ')'; - private static final char L_BRACE = '{'; - private static final char R_BRACE = '}'; - private static final char L_BRACKET = '['; - private static final char R_BRACKET = ']'; - - /** - * Checks if the parenthesis are well-formed in string {@param input}. - *

- * For example, - * {[()]} : true - * {[]()[]} : true - * {[)} : false - * {(} : false - * - * @param input - * @return {@code true} if parenthesis are well-formed, {@code false} otherwise. - */ - public static boolean isWellFormed(String input) { - int len = input.length(); - Stack stack = new Stack<>(); - - // obvious check as the i/p only consists of parenthesis - if (len % 2 != 0) return false; - - for (int i = 0; i < len; i++) { - char charAtI = input.charAt(i); - if (charAtI == L_PAREN || charAtI == L_BRACE || charAtI == L_BRACKET) { - stack.push(charAtI); - } else if (charAtI == R_PAREN) { - if (stack.isEmpty() || stack.pop() != L_PAREN) return false; - } else if (charAtI == R_BRACE) { - if (stack.isEmpty() || stack.pop() != L_BRACE) return false; - } else if (charAtI == R_BRACKET) { - if (stack.isEmpty() || stack.pop() != L_BRACKET) return false; - } - } - - return stack.isEmpty(); - } - - /** - * Reads the file specified in {@param filePath} line by line - * and checks if parenthesis are well-formed or not. - * - * @param filePath - */ - public static void readFile(String filePath) { - - try (BufferedReader br = new BufferedReader(new FileReader(filePath))) { - - String line; - - while ((line = br.readLine()) != null) { - System.out.println(isWellFormed(line) ? "True" : "False"); - } - - } catch (IOException e) { - e.printStackTrace(); - } - } - - /** - * Starting point of the program. - * - * @param args - */ - public static void main(String[] args) { - readFile(args[0]); - } -} - -/** - * Stack implementation using - * a singly linked list. - * - * @param - */ -class Stack { - - private Node top; - - public Stack() { - top = null; - } - - /** - * Pushes an item onto the top of this stack. - * - * @param item - */ - public E push(E item) { - top = new Node<>(item, top); - return item; - } - - /** - * Removes the object at the top of this stack and - * returns it. - * - * @return - */ - public E pop() { - E item = peek(); - top = top.next; - return item; - } - - /** - * Looks at the object at the top of this stack without removing it from the stack. - * - * @return - */ - public E peek() { - if (top == null) { - throw new EmptyStackException(); - } - return top.item; - } - - /** - * Tests if this stack is empty. - * - * @return - */ - public boolean isEmpty() { - return top == null; - } - - /** - * Generic node for holding values of any object type. - * - * @param - */ - private class Node { - E item; - Node next; - - Node(E item, Node next) { - this.item = item; - this.next = next; - } - } -} diff --git a/src/main/java/com/rampatra/stacks/MaxRectangleAreaInHistogram.java b/src/main/java/com/rampatra/stacks/MaxRectangleAreaInHistogram.java deleted file mode 100644 index 8494b0e7..00000000 --- a/src/main/java/com/rampatra/stacks/MaxRectangleAreaInHistogram.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.rampatra.stacks; - -/** - * Given a bar histogram, calculate the maximum possible rectangle area in the histogram. Consider each bar is 1 unit - * wide. - *

- * Level: Hard - * Time Complexity: O(n) - * Space Complexity: O(n) - * - * @author rampatra - * @since 2019-04-04 - */ -public class MaxRectangleAreaInHistogram { - - public static int getMaxRectangleArea(int[] hist) { - Stack stack = new Stack<>(); - int area; - int maxArea = 0; - int currMaxIndex; - int i = 0; - - while (i < hist.length) { - // keep adding indexes of bars which are equal to or larger than what's there in stack currently - if (stack.isEmpty() || hist[i] >= hist[stack.peek()]) { - stack.push(i); - i++; - } else { - /* - Whenever we encounter a bar smaller than what is there in the stack, we pop the topmost - element and compute the area. - */ - currMaxIndex = stack.pop(); - /* - Compute area from stack.peek() to (i - 1), - - Why (i - 1)? Because i has been incremented and is now pointing to the next bar in the - histogram - - Why stack.peak()? Because hist[stack.peek() + 1] is the last bar in the histogram with height more - than or equal to the current bar height - */ - area = hist[currMaxIndex] * (i - (stack.isEmpty() ? 0 : stack.peek() + 1)); - maxArea = Math.max(maxArea, area); - } - } - - /* - Process the left over elements in the stack. Note: the below code can also be merged with the loop - above but I have separated it out for simplicity. - */ - while (!stack.isEmpty()) { - currMaxIndex = stack.pop(); - area = hist[currMaxIndex] * (i - (stack.isEmpty() ? 0 : stack.peek() + 1)); - maxArea = Math.max(maxArea, area); - } - - return maxArea; - } - - public static void main(String[] args) { - /* - ___ - ___ | | ___ - | |__| |__| | - | | | | | | - 2 1 3 1 2 - - Max. area in this histogram is 5, which is the bottom horizontal rectangle. - */ - System.out.println(getMaxRectangleArea(new int[]{2, 1, 3, 1, 2})); // maxArea = 5 - System.out.println(getMaxRectangleArea(new int[]{2, 1, 5, 6, 2, 3})); // maxArea = 10 - System.out.println(getMaxRectangleArea(new int[]{2, 2, 2, 6, 1, 5, 4, 2, 2, 2, 2})); // maxArea = 12 - - // edge cases - System.out.println(getMaxRectangleArea(new int[]{})); // maxArea = 0 - System.out.println(getMaxRectangleArea(new int[]{1})); // maxArea = 1 - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/strings/AnagramsTogether.java b/src/main/java/com/rampatra/strings/AnagramsTogether.java deleted file mode 100644 index 87ee6569..00000000 --- a/src/main/java/com/rampatra/strings/AnagramsTogether.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.rampatra.strings; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 9/23/15 - */ -public class AnagramsTogether { - - /** - * Prints all the anagrams together from the string array {@code strings}. - *

- * Anagrams are words consisting of the same letters but in the same or different - * order. For example, "cat" and "tac" are anagrams. Same as "god" and "dog". - * - * @param strings - */ - private static void printAnagramsTogether(String[] strings) { - - // each key holds all the indexes of a anagram - HashMap> hashMap = new HashMap<>(); - - for (int i = 0; i < strings.length; i++) { - char[] chars = strings[i].toCharArray(); - Arrays.sort(chars); - - List indexes = hashMap.get(String.valueOf(chars)); - if (indexes == null) { - indexes = new ArrayList<>(); - } - indexes.add(i); - hashMap.put(String.valueOf(chars), indexes); - } - - for (Map.Entry> entry : hashMap.entrySet()) { - for (int i = 0; i < entry.getValue().size(); i++) { - System.out.println(strings[entry.getValue().get(i)]); - } - System.out.println("------"); - } - } - - public static void main(String[] args) { - printAnagramsTogether(new String[]{"cat", "dog", "tac", "god", "act"}); - printAnagramsTogether(new String[]{"cat", "tac", "act", "god", "dog"}); - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/strings/AnagramsTogetherLexicographically.java b/src/main/java/com/rampatra/strings/AnagramsTogetherLexicographically.java deleted file mode 100644 index c1390646..00000000 --- a/src/main/java/com/rampatra/strings/AnagramsTogetherLexicographically.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.rampatra.strings; - -import java.util.*; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 10/11/15 - */ -public class AnagramsTogetherLexicographically { - - /** - * Takes an array of String {@code strings} and prints anagrams in groups where the groups - * are arranged lexicographically and the strings within each group are also arranged - * lexicographically. - * - * @param strings - */ - public static void printAnagramsTogether(String[] strings) { - - HashMap> hashMap = new HashMap<>(); - TreeSet> treeSet = new TreeSet<>((Comparator) (o1, o2) -> { - if (o1 instanceof List && o2 instanceof List) { - return ((List) o1).get(0).compareTo(((List) o2).get(0)); - } else { - return 0; - } - }); - - for (int i = 0; i < strings.length; i++) { - String spaceRemovedStr = strings[i].replaceAll("\\s+", ""); - char[] chars = spaceRemovedStr.toCharArray(); - Arrays.sort(chars); - - List indexes = hashMap.get(String.valueOf(chars)); - if (indexes == null) { - indexes = new ArrayList<>(); - } - indexes.add(i); - hashMap.put(String.valueOf(chars), indexes); - } - - for (Map.Entry> entry : hashMap.entrySet()) { - - List anagrams = new ArrayList<>(); - - for (int i = 0; i < entry.getValue().size(); i++) { - anagrams.add(strings[entry.getValue().get(i)]); - } - - Collections.sort(anagrams); // arrange anagrams lexicographically within a single line - treeSet.add(anagrams); // sort the entire output lexicographically - } - - treeSet.stream().flatMap(Collection::stream).forEach(System.out::println); - } - - /** - * Take list of strings from console and print anagrams in groups. - * - * @param args - */ - public static void main(String[] args) { - Scanner in = new Scanner(System.in); - List strings = new ArrayList<>(); - String s; - System.out.println("Input string in separate lines (blank string to stop):"); - // you should use in.hasNextLine() - while (!(s = in.nextLine()).trim().equals("")) { - strings.add(s); - } - printAnagramsTogether(strings.toArray(new String[0])); - } -} diff --git a/src/main/java/com/rampatra/strings/BasicRegexParser.java b/src/main/java/com/rampatra/strings/BasicRegexParser.java deleted file mode 100644 index faf47331..00000000 --- a/src/main/java/com/rampatra/strings/BasicRegexParser.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.rampatra.strings; - -/** - * @author rampatra - * @since 25/11/2018 - */ -public class BasicRegexParser { - - /** - * Implement a regular expression function isMatch that supports the '.' and '*' symbols. - * The function receives two strings - text and pattern - and should return true if the - * text matches the pattern as a regular expression. For simplicity, assume that the actual - * symbols '.' and '*' do not appear in the text string and are used as special symbols only - * in the pattern string. - * - * @param text - * @param pattern - * @return - */ - private static boolean isMatch(String text, String pattern) { - int textIndex = 0; - int patternIndex = 0; - - while (textIndex < text.length()) { - if (patternIndex >= pattern.length()) return false; - - if (pattern.charAt(patternIndex) == '.' || text.charAt(textIndex) == pattern.charAt(patternIndex)) { - // if the next character in the pattern is a '*' then forward the text pointer - if (patternIndex < pattern.length() - 1 && pattern.charAt(patternIndex + 1) == '*') { - while (textIndex < text.length() - 1 && text.charAt(textIndex + 1) == text.charAt(textIndex)) { - textIndex++; - } - patternIndex++; // for the '*' in the pattern - } - } else if (patternIndex < pattern.length() - 1 && pattern.charAt(patternIndex + 1) == '*') { // if the text - // and pattern are not equal at the index but the pattern has a '*' after then increment the pattern pointer - textIndex--; // as we incrementing the text pointer outside but we should, in fact, stay at the current text index - patternIndex++; - } else { - return false; - } - textIndex++; - patternIndex++; - } - return true; - } - - public static void main(String[] args) { - System.out.println(isMatch("aa", "a")); // output: false - System.out.println(isMatch("aa", "aa")); // output: true - System.out.println(isMatch("abc", "a.c")); // output: true - System.out.println(isMatch("abbb", "ab*")); // output: true - System.out.println(isMatch("acd", "ab*c.")); // output: true - System.out.println(isMatch("abbdbb", "ab*d")); // output: false - System.out.println(isMatch("aba", "a.a")); // output: true - System.out.println(isMatch("acd", "ab*c.")); // output: true - System.out.println(isMatch("abaa", "a.*a*")); // output: true - } -} diff --git a/src/main/java/com/rampatra/strings/CompressString.java b/src/main/java/com/rampatra/strings/CompressString.java deleted file mode 100644 index ed3ce3d1..00000000 --- a/src/main/java/com/rampatra/strings/CompressString.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.rampatra.strings; - -/** - * @author rampatra - * @since 2019-04-08 - */ -public class CompressString { - - /** - * Compress a string, consisting of only alphabets, such that the compressed string contains the letter and - * a number next to it representing the number of times it is repeated. Also, compress only if the letter is - * repeated more than once and ignore it occurs just once. - * EXAMPLE: - * Input: aaabbcdd - * Output: a3b2cd2 - *

- * Time Complexity: O(n) - * Space Complexity: O(n) - * where, - * n is the number of characters in the input string - * - * @param str the input string consisting on only alphabets - * @return the compressed string - */ - private static String compress(String str) { - // some basic validation - if (str.length() == 0) { - throw new IllegalArgumentException("Empty String"); - } - - StringBuilder sb = new StringBuilder(); - int letterCount = 0; - - for (int i = 0; i < str.length(); i++) { - /* - When the current character is a different one, append the previous character and its count to the - result, and finally, reset the counter - */ - if (i != 0 && str.charAt(i) != str.charAt(i - 1)) { - sb.append(str.charAt(i - 1)); - if (letterCount > 1) sb.append(letterCount); - letterCount = 0; - } - letterCount++; - } - - // last character - sb.append(str.charAt(str.length() - 1)); - if (letterCount > 1) sb.append(letterCount); - - return sb.toString(); - } - - public static void main(String[] args) { - System.out.println(compress("a")); - System.out.println(compress("aabbcc")); - System.out.println(compress("aabcc")); - System.out.println(compress("aaaabbbccaad")); - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/strings/IntegerToString.java b/src/main/java/com/rampatra/strings/IntegerToString.java deleted file mode 100644 index 08d27131..00000000 --- a/src/main/java/com/rampatra/strings/IntegerToString.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.rampatra.strings; - -/** - * @author rampatra - * @since 2019-04-01 - */ -public class IntegerToString { - - private static final int[] sizeTable = {9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, - 999999999, Integer.MAX_VALUE}; - - private static String getStringFromInteger(int num) { - boolean isNegative = num < 0; - num = isNegative ? -num : num; - int size = getStringSize(num); - size = isNegative ? size + 1 : size; - char[] chars = new char[size]; - - int rem; - for (int i = size - 1; isNegative ? i > 0 : i >= 0; i--) { - rem = num % 10; - num = num / 10; - chars[i] = (char) (rem + '0'); - } - - if (isNegative) { - chars[0] = '-'; - } - - return new String(chars); - } - - private static int getStringSize(int num) { - if (num == Integer.MAX_VALUE) return 10; - - for (int i = 0; ; i++) { - if (num < sizeTable[i]) { - return i + 1; - } - } - } - - public static void main(String[] args) { - System.out.println(getStringFromInteger(0)); - System.out.println(getStringFromInteger(123)); - System.out.println(getStringFromInteger(+123)); - System.out.println(getStringFromInteger(-123)); - System.out.println(getStringFromInteger(Integer.MAX_VALUE)); - System.out.println(getStringFromInteger(Integer.MIN_VALUE)); // not working - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/strings/KeepOnlyKConsecutiveLetters.java b/src/main/java/com/rampatra/strings/KeepOnlyKConsecutiveLetters.java deleted file mode 100644 index aab4df26..00000000 --- a/src/main/java/com/rampatra/strings/KeepOnlyKConsecutiveLetters.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.rampatra.strings; - -/** - * @author rampatra - * @since 30/11/2018 - */ -public class KeepOnlyKConsecutiveLetters { - - /** - * A method which takes a string {@code str} and a number {@code k} and - * returns a string with at most {@code k} consecutive characters in the - * string. - *

- * For example, - * 1) aaaaaabbbbbccccc, 3 -> aaabbbccc - * 2) abc, 2 -> abc - * 3) aabbccc, 3 -> aabbccc - * - * @param str input string - * @param k - * @return a string with at most {@code k} consecutive characters - */ - private static String keepOnlyKConsecutiveLetters(String str, int k) { - StringBuilder sb = new StringBuilder(); - int count = 0; - - for (int i = 0; i < str.length(); i++) { - if (i != 0 && str.charAt(i) != str.charAt(i - 1)) { - count = 0; - } - if (count < k) { - sb.append(str.charAt(i)); - count++; - } - } - - return sb.toString(); - } - - public static void main(String[] args) { - System.out.println("aaaaabbbbbccccc, 5: " + keepOnlyKConsecutiveLetters("aaaaabbbbbccccc", 5)); - System.out.println("aaaaabbbbbccccc, 2: " + keepOnlyKConsecutiveLetters("aaaaabbbbbccccc", 2)); - System.out.println("aaaaabbbbbccccc, 1: " + keepOnlyKConsecutiveLetters("aaaaabbbbbccccc", 1)); - System.out.println("aabbcc, 2: " + keepOnlyKConsecutiveLetters("aabbcc", 2)); - System.out.println("aabbcc, 0: " + keepOnlyKConsecutiveLetters("aabbcc", 0)); - System.out.println("abc, 2: " + keepOnlyKConsecutiveLetters("abc", 2)); - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/strings/NearPalindrome.java b/src/main/java/com/rampatra/strings/NearPalindrome.java deleted file mode 100644 index 6e4efd7d..00000000 --- a/src/main/java/com/rampatra/strings/NearPalindrome.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.rampatra.strings; - -/** - * @author rampatra - * @since 05/12/2018 - */ -public class NearPalindrome { - - /** - * Checks if a string can be a palindrome by changing just one character in the string {@code str}. - * - * @param str the input string - * @return {@code true} if it can be converted to a palindrome with one character change or else {@code false} - */ - private static boolean isStringPalindromeByChangingOneChar(String str) { - int diffCount = 0; - for (int i = 0, j = str.length() - 1; i < str.length() / 2; i++, j--) { - if (str.charAt(i) != str.charAt(j)) { - if (diffCount > 0) { - return false; - } else { - diffCount++; - } - } - } - return true; - } - - public static void main(String[] args) { - System.out.println(isStringPalindromeByChangingOneChar("")); - System.out.println(isStringPalindromeByChangingOneChar("a")); - System.out.println(isStringPalindromeByChangingOneChar("ab")); - System.out.println(isStringPalindromeByChangingOneChar("aabbca")); - System.out.println(isStringPalindromeByChangingOneChar("abccaa")); - System.out.println(isStringPalindromeByChangingOneChar("abbcca")); - } -} diff --git a/src/main/java/com/rampatra/strings/RemoveDuplicatesAndArrangeLetters.java b/src/main/java/com/rampatra/strings/RemoveDuplicatesAndArrangeLetters.java deleted file mode 100644 index edb99699..00000000 --- a/src/main/java/com/rampatra/strings/RemoveDuplicatesAndArrangeLetters.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.rampatra.strings; - -import java.util.Set; -import java.util.TreeSet; -import java.util.stream.Collectors; - -/** - * @author rampatra - * @since 2019-04-02 - */ -public class RemoveDuplicatesAndArrangeLetters { - - private static String removeDuplicatesAndArrangeLettersLexicographically(String str) { - Set charSet = new TreeSet<>(); - char[] chars = str.toCharArray(); - - for (char ch : chars) { - charSet.add(ch); - } - - return charSet.toString(); - } - - private static String removeDuplicatesAndArrangeLettersLexicographically_Java8(String str) { - return str.chars() - .distinct() - .sorted() - .mapToObj(i -> (char) i) - .map(String::valueOf) - .collect(Collectors.joining()); - } - - public static void main(String[] args) { - System.out.println(removeDuplicatesAndArrangeLettersLexicographically("algo&dsInJava")); - System.out.println(removeDuplicatesAndArrangeLettersLexicographically_Java8("algo&dsInJava")); - } -} diff --git a/src/main/java/com/rampatra/strings/RemoveExtraSpaces.java b/src/main/java/com/rampatra/strings/RemoveExtraSpaces.java deleted file mode 100644 index 3c5b6954..00000000 --- a/src/main/java/com/rampatra/strings/RemoveExtraSpaces.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.rampatra.strings; - -import java.util.Arrays; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 10/25/15 - * @time: 9:44 PM - */ -public class RemoveExtraSpaces { - - /** - * Removes extra spaces in string {@param s} without creating a - * extra variable to hold the result, in O(n) time complexity. - * - * @param s - * @return - */ - public static String removeExtraSpaces(String s) { - - char[] c = s.toCharArray(); - int j = c.length; - - for (int i = 1; i < c.length; i++) { - // check for two or more consecutive spaces - if (c[i] == ' ' && c[i - 1] == ' ') { - // if extra spaces encountered for the 1st time - if (j == c.length) j = i; - - // skip all extra spaces - while (i < c.length && c[i] == ' ') { - i++; - } - - // if reached end of string then stop - if (i == c.length) break; - } - - // copy characters occurring after extra spaces to their appropriate positions - while (i < c.length && j < c.length) { - // stop when you encounter extra spaces again - if (c[i] == ' ' && c[i - 1] == ' ') break; - - c[j] = c[i]; - i++; - j++; - } - } - - return String.valueOf(Arrays.copyOf(c, j)); - } - - public static void main(String[] args) { - System.out.println(removeExtraSpaces("ram swaroop is a good boy.")); - System.out.println(removeExtraSpaces("ram swaroop is a good boy.")); - System.out.println(removeExtraSpaces(" ram swaroop is a good boy.")); - System.out.println(removeExtraSpaces("ram swaroop is a good boy .")); - System.out.println(removeExtraSpaces(" ram swaroop is a good boy .")); - System.out.println(removeExtraSpaces(" ")); - System.out.println(removeExtraSpaces("")); - System.out.println(removeExtraSpaces(" ")); - } -} diff --git a/src/main/java/com/rampatra/strings/StringRotation.java b/src/main/java/com/rampatra/strings/StringRotation.java deleted file mode 100644 index 0ab15138..00000000 --- a/src/main/java/com/rampatra/strings/StringRotation.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.rampatra.strings; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 10/21/15 - * @time: 10:06 AM - * @see: me.rampatra.strings.SubString for a similar problem. - */ -public class StringRotation { - - /** - * Determines if string {@param s2} is a rotation of string {@param s1}. - * - * @param s1 - * @param s2 - * @return - */ - public static boolean isStringRotation(String s1, String s2) { - char[] c1 = s1.toCharArray(); - char[] c2 = s2.toCharArray(); - - int l1 = c1.length, - l2 = c2.length, - i, j, k; - - for (i = 0; i < l1; i++) { - for (j = 0; j < l2 && i + j < l1; j++) { - if (c1[i + j] != c2[j]) break; - } - k = 0; - while (k < l1 && j < l2) { - if (c1[k++] != c2[j]) break; - j++; - } - if (j == l2) { - return true; - } - } - return false; - } - - public static void main(String[] args) { - System.out.println(isStringRotation("rampatra", "swaroopram")); - System.out.println(isStringRotation("rampatra", "swaroopramramram")); - System.out.println(isStringRotation("rampatra", "mswaroopra")); - System.out.println(isStringRotation("rampatra", "swarooppram")); - System.out.println(isStringRotation("rampatra", "")); - System.out.println(isStringRotation("mswaroopra", "rampatra")); - System.out.println(isStringRotation("amam", "mama")); - } -} diff --git a/src/main/java/com/rampatra/strings/StringToInteger.java b/src/main/java/com/rampatra/strings/StringToInteger.java deleted file mode 100644 index 53b386e7..00000000 --- a/src/main/java/com/rampatra/strings/StringToInteger.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.rampatra.strings; - -/** - * @author rampatra - * @since 2019-04-01 - */ -public class StringToInteger { - - /** - * This method converts a {@code String} to an {@code int}. It assumes the {@code string} contains ASCII - * characters only. - * - * @param str the input string, for example, 0, 123, +123, -123, etc. - * @return the equivalent integer. - */ - private static int getIntegerFromString(String str) { - int number = 0; - int digit; - char ch; - int weight = 0; - boolean isNegative = false; - - // remove all leading and trailing whitespaces - str = str.trim(); - if (str.length() == 0) { - throw new NumberFormatException("Empty string"); - } - - for (int i = str.length() - 1; i >= 0; i--) { - ch = str.charAt(i); - if (ch == '-' && i == 0) { - isNegative = true; - continue; - } else if (ch == '+' && i == 0) { - continue; - } - - digit = ch - '0'; - - if (digit < 0 || digit > 9) { - throw new NumberFormatException("Invalid characters"); - } - - number += digit * (Math.pow(10, weight++)); - } - return isNegative ? -number : number; - } - - public static void main(String[] args) { - // normal cases - System.out.println(getIntegerFromString("0")); - System.out.println(getIntegerFromString("123")); - System.out.println(getIntegerFromString("0123")); - System.out.println(getIntegerFromString("+123")); - System.out.println(getIntegerFromString("-123")); - - // error cases - System.out.println(getIntegerFromString("1-23")); - System.out.println(getIntegerFromString("")); - System.out.println(getIntegerFromString(" ")); - System.out.println(getIntegerFromString(" ")); - System.out.println(getIntegerFromString("123L")); - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/strings/SubStringCheck.java b/src/main/java/com/rampatra/strings/SubStringCheck.java deleted file mode 100644 index 63786967..00000000 --- a/src/main/java/com/rampatra/strings/SubStringCheck.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.rampatra.strings; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 10/20/15 - * @time: 1:15 PM - * @see: StringRotation for a similar problem. - */ -public class SubStringCheck { - - /** - * Naive approach to determine whether string {@param s2} is a - * substring of string {@param s1}. - * - * @param s1 - * @param s2 - * @return - */ - public static boolean isSubString(String s1, String s2) { - char[] c1 = s1.toCharArray(), - c2 = s2.toCharArray(); - int l1 = c1.length, - l2 = c2.length, - i, j; - - for (i = 0; i <= l1 - l2; i++) { - for (j = 0; j < l2 && i + j < l1; j++) { - if (c1[i + j] != c2[j]) break; - } - if (j == l2) { - return true; - } - } - return false; - } - - public static void main(String[] args) { - System.out.println(isSubString("rampatra", "rampatra")); - System.out.println(isSubString("rampatra", "")); - System.out.println(isSubString("rampatra", "ram")); - System.out.println(isSubString("rampatra", "rams")); - System.out.println(isSubString("rampatra", "ramss")); - System.out.println(isSubString("rampatra", "ar")); - } -} diff --git a/src/main/java/com/rampatra/strings/SubStrings.java b/src/main/java/com/rampatra/strings/SubStrings.java deleted file mode 100644 index 792830c9..00000000 --- a/src/main/java/com/rampatra/strings/SubStrings.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.rampatra.strings; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 10/22/15 - * @time: 11:16 AM - */ -public class SubStrings { - - /** - * Prints all sub-strings of string {@param s} iteratively. - * - * @param s - */ - public static void printAllSubStrings(String s) { - for (int i = 0; i < s.length(); i++) { - for (int j = i; j < s.length(); j++) { - System.out.println(s.substring(i, j + 1)); - } - } - } - - /** - * Prints all sub-strings of string {@param s} recursively. - * - * @param s - */ - public static void printAllSubStringsRecursive(String s) { - if (s.length() == 0) return; - - for (int i = 1; i <= s.length(); i++) { - System.out.println(s.substring(0, i)); - } - printAllSubStrings(s.substring(1)); - } - - public static void main(String[] args) { - System.out.println("----Iterative----"); - printAllSubStrings("ram"); - System.out.println("--------"); - printAllSubStrings(""); - System.out.println("----Recursive----"); - printAllSubStringsRecursive("ram"); - System.out.println("--------"); - printAllSubStringsRecursive(""); - } -} diff --git a/src/main/java/com/rampatra/strings/WithoutString.java b/src/main/java/com/rampatra/strings/WithoutString.java deleted file mode 100644 index 859b6a76..00000000 --- a/src/main/java/com/rampatra/strings/WithoutString.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.rampatra.strings; - -import com.sun.tools.javac.util.Assert; - -/** - * Given two strings, base and remove, return a version of the base string where all instances - * of the remove string have been removed (not case sensitive). You may assume that the remove - * string is length 1 or more. Remove only non-overlapping instances, so with "xxx" removing - * "xx" leaves "x". - * - * @author rampatra - * @since 2019-01-23 - */ -public class WithoutString { - - private static String withoutString(String base, String remove) { - String original = base; - base = base.toLowerCase(); - remove = remove.toLowerCase(); - int baseLen = base.length(); - int removeLen = remove.length(); - StringBuilder sb = new StringBuilder(); - - for (int i = 0; i < baseLen; ) { - int j = 0; - // when we see a match, advance the pointer - while (j < removeLen && i + j < baseLen && base.charAt(i + j) == remove.charAt(j)) { - j++; - } - if (j == removeLen) { // an entire match was found, move ahead and skip these chars - i += removeLen; - } else { - sb.append(original.charAt(i)); // entire match was not found so append the char to StringBuilder - i++; - } - } - return sb.toString(); - } - - public static void main(String[] args) { - Assert.check(withoutString("Hello there", "llo").equals("He there")); - Assert.check(withoutString("THIS is a FISH", "is").equals("TH a FH")); - Assert.check(withoutString("xxx", "x").equals("")); - } -} diff --git a/src/main/java/com/rampatra/threads/Basics.java b/src/main/java/com/rampatra/threads/Basics.java deleted file mode 100644 index 52d443da..00000000 --- a/src/main/java/com/rampatra/threads/Basics.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.rampatra.threads; - -/** - * Created by IntelliJ IDEA. - * User: rampatra - * Date: 4/15/15 - * Time: 11:27 PM - * To change this template go to Preferences | IDE Settings | File and Code Templates - */ -public class Basics { - public static void main(String[] args) { - Runnable r = new Runnable() { - @Override - public void run() { - for (int i = 0; i < 10; i++) { - System.out.println(Thread.currentThread().getName() + ": " + i); - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - - } - System.out.println("====== " + Thread.currentThread().getName() + " woke up ======"); - } - } - }; - Thread t1 = new Thread(r); - Thread t2 = new Thread(r); - Thread t3 = new Thread(r); - - t1.setName("T1"); - t2.setName("T2"); - t3.setName("T3"); - - t1.start(); - t2.start(); - t3.start(); - } -} diff --git a/src/main/java/com/rampatra/threads/NamePrint.java b/src/main/java/com/rampatra/threads/NamePrint.java deleted file mode 100644 index 05e19820..00000000 --- a/src/main/java/com/rampatra/threads/NamePrint.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.rampatra.threads; - -/** - * Problem Description: Print first name and last name (in order) using two different threads 1000 times. - * - * @author rampatra - * @since 10/6/15 - */ -public class NamePrint { - - Object lock = new Object(); - volatile boolean isFirstNamePrinted = false; - - class PrintFirstName implements Runnable { - @Override - public void run() { - synchronized (lock) { - for (int i = 0; i < 1000; i++) { - try { - // wait if first name is printed but not the last name - if (isFirstNamePrinted) { - lock.wait(); - } - } catch (InterruptedException e) { - e.printStackTrace(); - } - System.out.print("Ram "); - isFirstNamePrinted = true; - lock.notify(); - } - } - } - } - - class PrintLastName implements Runnable { - @Override - public void run() { - synchronized (lock) { - for (int i = 0; i < 1000; i++) { - try { - // wait if first name is not printed - if (!isFirstNamePrinted) { - lock.wait(); - } - } catch (InterruptedException e) { - e.printStackTrace(); - } - System.out.println("Swaroop"); - isFirstNamePrinted = false; - lock.notify(); - } - } - } - } - - public void printNameUsingMultipleThreads() { - Runnable printFirstName = new PrintFirstName(); - Runnable printLastName = new PrintLastName(); - - Thread firstThread = new Thread(printFirstName); - Thread secondThread = new Thread(printLastName); - - firstThread.start(); - secondThread.start(); - } - - public static void main(String[] args) { - NamePrint obj = new NamePrint(); - obj.printNameUsingMultipleThreads(); - } -} diff --git a/src/main/java/com/rampatra/threads/ProducerConsumerUsingLockApi.java b/src/main/java/com/rampatra/threads/ProducerConsumerUsingLockApi.java deleted file mode 100644 index 4c1443e0..00000000 --- a/src/main/java/com/rampatra/threads/ProducerConsumerUsingLockApi.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.rampatra.threads; - -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.Condition; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -/** - * Problem Description: A simple Producer/Consumer using the Lock and Condition Api pattern. For the language primitive, - * i.e, synchronize and wait/notify pattern, please see {@link ProducerConsumerUsingWaitNotify}. - *

- *

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

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

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

- * - A fair Lock generates a fair Condition. Fair here means the first thread in the waiting queue will be picked first - * by the scheduler. This is a costly operation so use it only when necessary. - * - * @author rampatra - * @since 2019-07-10 - */ -public class ProducerConsumerUsingLockApi { - - private static int currSize = 0; - private static int totalSize = 10; - private static int[] buffer = new int[totalSize]; - private static Lock lock = new ReentrantLock(); - private static Condition isEmpty = lock.newCondition(); - private static Condition isFull = lock.newCondition(); - - static class Producer { - static void produce() { - try { - - lock.lock(); - while (currSize >= totalSize) { - isFull.await(); - } - buffer[currSize++] = 1; - isEmpty.signal(); - - } catch (InterruptedException e) { - e.printStackTrace(); - } finally { - lock.unlock(); - } - } - } - - static class Consumer { - static void consume() { - try { - - lock.lock(); - while (currSize <= 0) { - isEmpty.await(); - } - System.out.println(buffer[--currSize]); - isFull.signal(); - - } catch (InterruptedException e) { - e.printStackTrace(); - } finally { - lock.unlock(); - } - } - } - - public static void main(String[] args) throws InterruptedException { - - ExecutorService executorService = Executors.newFixedThreadPool(2); - - Runnable producerTask = () -> { - for (int i = 0; i < 1000; i++) { - Producer.produce(); - } - }; - - Runnable consumerTask = () -> { - for (int i = 0; i < 1000; i++) { - Consumer.consume(); - } - }; - - executorService.submit(producerTask); - executorService.submit(consumerTask); - - executorService.awaitTermination(3000, TimeUnit.MILLISECONDS); - - // as produce() and consume() are called equal number of times, this should be zero in the end - System.out.println("Buffer Size: " + currSize); - - executorService.shutdown(); - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/threads/ProducerConsumerUsingWaitNotify.java b/src/main/java/com/rampatra/threads/ProducerConsumerUsingWaitNotify.java deleted file mode 100644 index da753f04..00000000 --- a/src/main/java/com/rampatra/threads/ProducerConsumerUsingWaitNotify.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.rampatra.threads; - -/** - * Problem Description: A simple Producer/Consumer using Synchronize and Wait/Notify pattern. For a better - * solution, please see {@link ProducerConsumerUsingLockApi}. - * - * @author rampatra - * @since 2019-06-30 - */ -public class ProducerConsumerUsingWaitNotify { - - private static int currSize = 0; - private static int totalSize = 10; - private static int[] buffer = new int[totalSize]; - private static final Object lock = new Object(); - - static class Producer { - void produce() throws InterruptedException { - synchronized (lock) { - if (isFull()) { - lock.wait(); - } - buffer[currSize++] = 1; - lock.notify(); - } - } - } - - static class Consumer { - void consume() throws InterruptedException { - synchronized (lock) { - if (isEmpty()) { - lock.wait(); - } - System.out.println(buffer[--currSize]); - lock.notify(); - } - } - } - - private static boolean isFull() { - return currSize >= totalSize - 1; // as index starts from zero - } - - private static boolean isEmpty() { - return currSize == 0; - } - - public static void main(String[] args) throws InterruptedException { - - Runnable producerTask = () -> { - for (int i = 0; i < 1000; i++) { - try { - new Producer().produce(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - }; - - Runnable consumerTask = () -> { - for (int i = 0; i < 1000; i++) { - try { - new Consumer().consume(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - }; - - Thread producer = new Thread(producerTask); - Thread consumer = new Thread(consumerTask); - - // start both the threads - producer.start(); - consumer.start(); - - // wait for both the threads to complete - producer.join(); - consumer.join(); - - // as produce() and consume() are called equal number of times, this should be zero in the end - System.out.println("Buffer Size: " + currSize); - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/threads/SimpleDeadlock.java b/src/main/java/com/rampatra/threads/SimpleDeadlock.java deleted file mode 100644 index b3b749a4..00000000 --- a/src/main/java/com/rampatra/threads/SimpleDeadlock.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.rampatra.threads; - - -import java.lang.management.ManagementFactory; -import java.lang.management.ThreadMXBean; - -/** - * Problem Description: Deadlock example. - * - * @author rampatra - * @since 2019-03-13 - */ -public class SimpleDeadlock implements Runnable { - - private final Object obj1; - private final Object obj2; - - private SimpleDeadlock(Object obj1, Object obj2) { - this.obj1 = obj1; - this.obj2 = obj2; - } - - public void run() { - try { - synchronized (obj1) { - // sleep for some time so that the next thread starts and acquires the other lock in the mean time - Thread.sleep(5000); - synchronized (obj2) { - System.out.println("No deadlock!"); - } - } - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - - public static void main(String[] args) { - - Object obj1 = new Object(); - Object obj2 = new Object(); - - Thread thread1 = new Thread(new SimpleDeadlock(obj1, obj2)); - Thread thread2 = new Thread(new SimpleDeadlock(obj2, obj1)); // note here that the object order is different - - thread1.start(); - thread2.start(); - - // a way to detect deadlocks, although an expensive one - ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean(); - while (true) { - long[] deadlock = threadMXBean.findDeadlockedThreads(); - if (deadlock != null && deadlock.length > 0) { - System.out.println("Deadlock detected, exiting now..."); - System.exit(1); - } - } - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/trees/BFSUsingQueue.java b/src/main/java/com/rampatra/trees/BFSUsingQueue.java deleted file mode 100644 index 04166d8d..00000000 --- a/src/main/java/com/rampatra/trees/BFSUsingQueue.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.rampatra.trees; - -import com.rampatra.base.BinaryNode; -import com.rampatra.base.BinaryTree; -import com.rampatra.base.LinkedQueue; -import com.rampatra.base.Queue; - -import java.util.NoSuchElementException; - -import static java.lang.System.out; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/26/15 - * @time: 7:34 PM - */ -public class BFSUsingQueue { - - /** - * Breadth first traversal (Level-order traversal using Queue). - * - * @param node a tree node with left and right references and a value of type {@code E} - * @param the type of value that the {@code node} holds - */ - public static > void breadthFirstTraversalUsingQueue(BinaryNode node) { - Queue> queue = new LinkedQueue<>(); - breadthFirstTraversalUsingQueue(node, queue); - } - - private static > void breadthFirstTraversalUsingQueue(BinaryNode node, - Queue> queue) { - - if (node != null) { - printValue(node); - queue.add(node.left); - queue.add(node.right); - } - - try { - breadthFirstTraversalUsingQueue(queue.remove(), queue); - } catch (NoSuchElementException e) { - return; - } - } - - private static > void printValue(BinaryNode node) { - if (node == null) return; - - out.print(node.value); - } - - /** - * Level order traversal using queue but iteratively. - * - * @param root the root node from where the traversal should start - * @param type of the {@code value} that {@code BinaryNode} holds - */ - public static > void breadthFirstTraversalUsingQueueIterative(BinaryNode root) { - if (root == null) return; - - Queue> q = new LinkedQueue<>(); - q.add(root); - - while (!q.isEmpty()) { - BinaryNode node = q.remove(); - out.print(node.value); - - if (node.left != null) q.add(node.left); - if (node.right != null) q.add(node.right); - } - } - - public static void main(String[] args) { - BinaryTree bt = new BinaryTree<>(); - bt.put(6); - bt.put(3); - bt.put(5); - bt.put(7); - bt.put(8); - bt.put(9); - breadthFirstTraversalUsingQueue(bt.root); - System.out.println(); - breadthFirstTraversalUsingQueueIterative(bt.root); - } -} diff --git a/src/main/java/com/rampatra/trees/CheckForBST.java b/src/main/java/com/rampatra/trees/CheckForBST.java deleted file mode 100644 index aea4bc19..00000000 --- a/src/main/java/com/rampatra/trees/CheckForBST.java +++ /dev/null @@ -1,131 +0,0 @@ -package com.rampatra.trees; - -import com.rampatra.base.BinaryNode; -import com.rampatra.base.BinarySearchTree; -import com.rampatra.base.BinaryTree; - -import java.util.List; - -import static java.lang.System.out; - -/** - * A binary search tree is a binary tree in which every node fits a specific ordering property: all left - * descendents <= n < all right descendents. This must be true for each node n. - *

- * Note: The definition of a binary search tree can vary slightly with respect to equality. Under some definitions, the - * tree cannot have duplicate values. In others, the duplicate values will be on the right or can be on either side. All - * are valid definitions, but you should clarify this with your interviewer - * - * @author rampatra - * @since 6/26/15 - */ -public class CheckForBST { - - /** - * Traverse the tree in in-order fashion and insert all nodes - * in a list and check for sort order of list. - *

- * Concept: In-order traversal of a BST is always sorted in ascending - * manner. - * - * @param node - * @param list - * @return - */ - public static > boolean isBST(BinaryNode node, List> list) { - if (node == null) return true; - - boolean left = isBST(node.left, list); - - // while adding node to list, compare it with previous node in list - if (list.size() > 0 && list.get(list.size() - 1).value.compareTo(node.value) > 0) { - return false; - } - list.add(node); - - boolean right = isBST(node.right, list); - - return left && right; - } - - /** - * Traverse the tree in in-order fashion and keep track of its in-order - * predecessor value. If at any point current node's value is found greater - * than its predecessor value then return {@code false}. - *

- * Concept: In-order traversal of a BST is always sorted in ascending - * manner. - * - * @param node - * @param prev - * @return - */ - public static > boolean isBST(BinaryNode node, BinaryNode prev) { - if (node == null) return true; - - boolean left = isBST(node.left, prev); - - // compare current node with previous node - if (prev.value != null && prev.value.compareTo(node.value) > 0) { - return false; - } - prev.value = node.value; - - boolean right = isBST(node.right, prev); - - return left && right; - } - - /** - * Simplest way to test whether a binary tree is a BST or not. - *

- * CONCEPT: A node's left sub-tree cannot have a value more than - * the node's value and similarly the node's right sub-tree cannot - * have a value less than the node's value. - * - * @param node - * @param minValue - * @param maxValue - * @param - * @return - */ - public static > boolean isBST(BinaryNode node, E minValue, E maxValue) { - if (node == null) return true; - - if (node.value.compareTo(minValue) < 0 || node.value.compareTo(maxValue) > 0) { - return false; - } - - return isBST(node.left, minValue, node.value) && isBST(node.right, node.value, maxValue); - } - - public static void main(String[] args) { - // in-order approach - BinarySearchTree binarySearchTree = new BinarySearchTree<>(); - binarySearchTree.put(6); - binarySearchTree.put(3); - binarySearchTree.put(5); - binarySearchTree.put(7); - binarySearchTree.put(8); - binarySearchTree.put(9); - out.println("1) Is BST: "); - out.println(isBST(binarySearchTree.root, new BinaryNode<>(null))); // should be true - - BinaryTree binaryTree = new BinaryTree<>(); - binaryTree.put(6); - binaryTree.put(4); - binaryTree.put(9); - binaryTree.put(2); - binaryTree.put(8); - binaryTree.put(7); - binaryTree.put(10); - out.println("2) Is BST: "); - out.println(isBST(binaryTree.root, new BinaryNode<>(null))); // should be false - - // min max approach - out.println("3) Is BST: "); - out.println(isBST(binarySearchTree.root, Integer.MIN_VALUE, Integer.MAX_VALUE)); // should be true - out.println("4) Is BST: "); - out.println(isBST(binaryTree.root, Integer.MIN_VALUE, Integer.MAX_VALUE)); // should be false - } -} diff --git a/src/main/java/com/rampatra/trees/ChildrenSum.java b/src/main/java/com/rampatra/trees/ChildrenSum.java deleted file mode 100644 index 232e1554..00000000 --- a/src/main/java/com/rampatra/trees/ChildrenSum.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.rampatra.trees; - -import com.rampatra.base.BinaryNode; -import com.rampatra.base.BinaryTree; - -import static java.lang.System.out; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/26/15 - * @time: 7:01 PM - */ -public class ChildrenSum { - - /** - * Children Sum Invariant: For every node, the value must be equal to - * sum of values in the left and right child. - * Consider data value as 0 for NULL child. - * - * @param node - * @param - * @return - */ - public static > boolean isChildrenSum(BinaryNode node) { - if (node == null || node.left == null && node.right == null) return true; - - E leftChildValue = (E) (node.left == null ? 0 : node.left.value); - E rightChildValue = (E) (node.right == null ? 0 : node.right.value); - - if (!node.value.toString().equals( - String.valueOf(Integer.parseInt(leftChildValue.toString()) + - Integer.parseInt(rightChildValue.toString())) - )) { - return false; - } - - return isChildrenSum(node.left) && isChildrenSum(node.right); - } - - - /** - * Converts a tree to hold the children sum invariant. - *

- * It only increments data values in any node (Does not - * change structure of tree and cannot decrement value of - * any node). - * - * @param node - * @param - */ - public static > void toChildrenSum(BinaryNode node) { - - if (node == null || node.left == null && node.right == null) return; - - toChildrenSum(node.left); - toChildrenSum(node.right); - - Integer nodeValue = (Integer) (node == null ? 0 : node.value); - Integer leftChildValue = (Integer) (node.left == null ? 0 : node.left.value); - Integer rightChildValue = (Integer) (node.right == null ? 0 : node.right.value); - - int diff = leftChildValue + rightChildValue - nodeValue; - - if (diff < 0) { // tricky: children sum is less - increment(node, -diff); - } else if (diff > 0) { // simple: children sum is more, so just add the diff to parent node - //node.value += diff; - } - } - - // TODO: Not done due to generics - private static > void increment(BinaryNode node, int diff) { - if (node.left != null) { - //node.left.value += Math.abs(diff); - increment(node.left, diff); - } else if (node.right != null) { - //node.right.value += Math.abs(diff); - increment(node.right, diff); - } - } - - public static void main(String[] args) { - BinaryTree bt = new BinaryTree<>(); - bt.put(6); - bt.put(3); - bt.put(5); - bt.put(7); - bt.put(8); - bt.put(9); - out.println("Is Children Sum : "); - out.println(isChildrenSum(bt.root)); - /*binaryTree.toChildrenSum(); - out.print("\nBreadth-first Traversal after to children sum: "); - binaryTree.breadthFirstTraversal();*/ - } -} diff --git a/src/main/java/com/rampatra/trees/ConnectNodesAtSameLevel.java b/src/main/java/com/rampatra/trees/ConnectNodesAtSameLevel.java deleted file mode 100644 index 684e3e01..00000000 --- a/src/main/java/com/rampatra/trees/ConnectNodesAtSameLevel.java +++ /dev/null @@ -1,127 +0,0 @@ -package com.rampatra.trees; - -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.List; -import java.util.Queue; - -/** - * Given a binary tree, return lists of nodes at each level. The number of lists in the output will be equal to - * the number of levels in the tree. - * - * @author rampatra - * @since 2019-04-02 - */ -public class ConnectNodesAtSameLevel { - - private static class TreeNode { - Integer val; - TreeNode left; - TreeNode right; - - TreeNode(Integer val) { - this.val = val; - } - - @Override - public String toString() { - return Integer.toString(val); - } - } - - private static List> connectNodes(TreeNode root) { - if (root == null) return null; - - Queue queue = new ArrayDeque<>(); - List> allNodes = new ArrayList<>(); - List connectedNodesAtLevel = new ArrayList<>(); - - queue.add(root); - queue.add(new TreeNode(null)); // we use a node with null value as a marker for each level - - while (!queue.isEmpty()) { - TreeNode node = queue.poll(); - - if (node.val != null) { - connectedNodesAtLevel.add(node); - } else { // when we encounter a null in the queue, we know that a level is completed - allNodes.add(connectedNodesAtLevel); - connectedNodesAtLevel = new ArrayList<>(); - if (queue.peek() != null) queue.add(new TreeNode(null)); - continue; - } - - if (node.left != null) queue.add(node.left); - if (node.right != null) queue.add(node.right); - } - - return allNodes; - } - - public static void main(String[] args) { - /* - The BST looks like: - - 4 - / \ - 2 8 - / \ / \ - 1 3 6 9 - / - 0 - - */ - TreeNode treeRoot = new TreeNode(4); - treeRoot.left = new TreeNode(2); - treeRoot.right = new TreeNode(8); - treeRoot.left.left = new TreeNode(1); - treeRoot.left.right = new TreeNode(3); - treeRoot.left.left.left = new TreeNode(0); - treeRoot.right.left = new TreeNode(6); - treeRoot.right.right = new TreeNode(9); - - connectNodes(treeRoot).forEach(System.out::println); - System.out.println("--------------"); - - /* - The BST looks like: - - 4 - / \ - 2 8 - \ / \ - 3 6 9 - - */ - treeRoot = new TreeNode(4); - treeRoot.left = new TreeNode(2); - treeRoot.right = new TreeNode(8); - treeRoot.left.right = new TreeNode(3); - treeRoot.right.left = new TreeNode(6); - treeRoot.right.right = new TreeNode(9); - - connectNodes(treeRoot).forEach(System.out::println); - System.out.println("--------------"); - - - /* - The BST looks like: - - 4 - / \ - 2 8 - / \ / \ - 1 3 6 9 - - */ - treeRoot = new TreeNode(4); - treeRoot.left = new TreeNode(2); - treeRoot.right = new TreeNode(8); - treeRoot.left.left = new TreeNode(1); - treeRoot.left.right = new TreeNode(3); - treeRoot.right.left = new TreeNode(6); - treeRoot.right.right = new TreeNode(9); - - connectNodes(treeRoot).forEach(System.out::println); - } -} diff --git a/src/main/java/com/rampatra/trees/ConstructTreeFromInOrderAndPreOrder.java b/src/main/java/com/rampatra/trees/ConstructTreeFromInOrderAndPreOrder.java deleted file mode 100644 index f9eddac0..00000000 --- a/src/main/java/com/rampatra/trees/ConstructTreeFromInOrderAndPreOrder.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.rampatra.trees; - -import com.rampatra.base.BinaryNode; - -import java.util.List; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/26/15 - * @time: 5:34 PM - */ -public class ConstructTreeFromInOrderAndPreOrder { - - public > void constructTreeWithInOrderAndPreOrder(List> inOrder, - List> preOrder) { - for (int i = 0; i < preOrder.size(); i++) { - - } - } - - public static void main(String[] args) { - - } -} diff --git a/src/main/java/com/rampatra/trees/DoubleTree.java b/src/main/java/com/rampatra/trees/DoubleTree.java deleted file mode 100644 index 791e5ff4..00000000 --- a/src/main/java/com/rampatra/trees/DoubleTree.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.rampatra.trees; - -import com.rampatra.base.BinaryNode; -import com.rampatra.base.BinaryTree; - -import static java.lang.System.out; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/26/15 - * @time: 6:02 PM - */ -public class DoubleTree { - - /** - * Converts a given tree to its Double tree. To create a Double tree - * of the given tree, create a new duplicate for each node, and insert - * the duplicate as the left child of the original node. - * - * @param node - */ - public static > void doubleTree(BinaryNode node) { - if (node == null) return; - - BinaryNode newNode = new BinaryNode<>(node.value, node.left, null); - - node.left = newNode; - - doubleTree(newNode.left); - doubleTree(node.right); - } - - public static void main(String[] args) { - BinaryTree bt = new BinaryTree<>(); - bt.put(6); - bt.put(3); - bt.put(5); - bt.put(7); - bt.put(8); - bt.put(9); - bt.breadthFirstTraversal(); - out.println(); - doubleTree(bt.root); - out.println("BFS after Double tree: "); - bt.breadthFirstTraversal(); - } -} diff --git a/src/main/java/com/rampatra/trees/HeightBalanced.java b/src/main/java/com/rampatra/trees/HeightBalanced.java deleted file mode 100644 index 20e24201..00000000 --- a/src/main/java/com/rampatra/trees/HeightBalanced.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.rampatra.trees; - -import com.ctci.treesandgraphs.TreeNode; -import com.rampatra.base.BinaryNode; -import com.rampatra.base.BinarySearchTree; - -import static java.lang.System.out; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/26/15 - * @time: 7:07 PM - */ -public class HeightBalanced> extends BinarySearchTree { - - /** - * An empty tree is height-balanced. A non-empty binary tree T is balanced if: - * 1) Left subtree of T is balanced - * 2) Right subtree of T is balanced - * 3) The difference between heights of left subtree and right subtree is not more than 1. - * - * This approach is simple but we are traversing each node multiple times while calculating the height. For a more - * optimized approach see {@link com.ctci.treesandgraphs.CheckBalanced#isBalancedOptimized(TreeNode)} where while - * calculating the height of tree we check whether it is balanced or not simultaneously. - * - * @return True if tree is height balanced otherwise false. - */ - public boolean isHeightBalanced() { - return isHeightBalanced(root); - } - - public boolean isHeightBalanced(BinaryNode node) { - if (node == null) return true; - - if (Math.abs(height(node.left) - height(node.right)) > 1) { - return false; - } - - return isHeightBalanced(node.left) && isHeightBalanced(node.right); - } - - public static void main(String[] args) { - HeightBalanced bst = new HeightBalanced<>(); - bst.put(6); - bst.put(3); - bst.put(5); - bst.put(7); - bst.put(8); - bst.put(9); - out.print("\nIs height balanced: " + bst.isHeightBalanced()); - } -} diff --git a/src/main/java/com/rampatra/trees/IdenticalTrees.java b/src/main/java/com/rampatra/trees/IdenticalTrees.java deleted file mode 100644 index 221aeb24..00000000 --- a/src/main/java/com/rampatra/trees/IdenticalTrees.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.rampatra.trees; - -import com.rampatra.base.BinaryNode; -import com.rampatra.base.BinarySearchTree; - -import static java.lang.System.out; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/26/15 - * @time: 5:36 PM - */ -public class IdenticalTrees { - - /** - * Checks whether two trees having their roots at node1 and node2 - * are identical or not. - * - * @param node1 - * @param node2 - * @param - * @return - */ - public static > boolean isIdentical(BinaryNode node1, BinaryNode node2) { - if (node1 == null && node2 == null) return true; - if (node1 == null && node2 != null || (node1 != null && node2 == null)) return false; - - if (node1.value == node2.value) { - return true && isIdentical(node1.left, node2.left) && isIdentical(node1.right, node2.right); - } else { - return false; - } - } - - public static void main(String[] args) { - BinarySearchTree bst = new BinarySearchTree<>(); - bst.put(6); - bst.put(3); - bst.put(5); - bst.put(7); - bst.put(8); - bst.put(9); - out.println(IdenticalTrees.isIdentical(bst.root.right, bst.root.right)); - out.println(IdenticalTrees.isIdentical(bst.root.right, bst.root)); - } -} diff --git a/src/main/java/com/rampatra/trees/InOrderUsingStack.java b/src/main/java/com/rampatra/trees/InOrderUsingStack.java deleted file mode 100644 index 15ef82d0..00000000 --- a/src/main/java/com/rampatra/trees/InOrderUsingStack.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.rampatra.trees; - -import com.rampatra.base.BinaryNode; -import com.rampatra.base.BinarySearchTree; -import com.rampatra.base.LinkedStack; -import com.rampatra.base.Stack; - -import static java.lang.System.out; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/26/15 - * @time: 7:31 PM - */ -public class InOrderUsingStack { - - /** - * In-order traversal of tree using one stack and without recursion. - * - * @param node - */ - public static > void inOrderUsingStack(BinaryNode node) { - if (node == null) return; - - Stack> stack = new LinkedStack<>(); - - BinaryNode curr = node; // set root node as current node - stack.push(curr); // push current node - - while (!stack.isEmpty()) { - - while (curr != null) { - curr = curr.left; - if (curr != null) stack.push(curr); // push all left nodes of the current node - } - - BinaryNode top = stack.pop(); - out.print(top.value); // print top of stack - curr = top.right; - if (curr != null) stack.push(curr); // push right child of top node - } - } - - public static void main(String[] args) { - BinarySearchTree bst = new BinarySearchTree<>(); - bst.put(6); - bst.put(3); - bst.put(5); - bst.put(7); - bst.put(8); - bst.put(9); - inOrderUsingStack(bst.root); - } -} diff --git a/src/main/java/com/rampatra/trees/InOrderWithoutStackAndRecursion.java b/src/main/java/com/rampatra/trees/InOrderWithoutStackAndRecursion.java deleted file mode 100644 index 5663986e..00000000 --- a/src/main/java/com/rampatra/trees/InOrderWithoutStackAndRecursion.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.rampatra.trees; - -import com.rampatra.base.BinaryNode; -import com.rampatra.base.BinarySearchTree; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/26/15 - * @time: 7:23 PM - */ -public class InOrderWithoutStackAndRecursion> extends BinarySearchTree { - - public void inOrder() { - inOrderWithoutStackAndRecursion(root); - } - - /** - * Using Morris Traversal, we can traverse the tree without using stack and - * recursion. The idea of Morris Traversal is based on Threaded Binary Tree. - * In this traversal, we first create links to Inorder successor and print the - * data using these links, and finally revert the changes to restore original tree. - *

- * A binary tree is THREADED by making all right child pointers that would normally - * be null point to the inorder successor of the node (if it exists), and all left - * child pointers that would normally be null point to the inorder predecessor of - * the node. - *

- * PSEUDOCODE: - * 1. Initialize current as root - * 2. While current is not NULL - * If current does not have left child - * a) Print current’s data - * b) Go to right child, i.e., current = current->right - * Else - * a) Make current as right child of the rightmost node in current's left subtree - * b) Go to left child, i.e., current = current->left - * - * @param node - */ - public void inOrderWithoutStackAndRecursion(BinaryNode node) { - if (node == null) return; - - BinaryNode curr = node; - - while (curr != null) { - // print the leftmost node - if (curr.left == null) { - printValue(curr); - curr = curr.right; - } else { // make current as right child of the rightmost node in current's left subtree - BinaryNode pre = curr.left; - - while (pre.right != curr && pre.right != null) { - pre = pre.right; - } - if (pre.right != curr) { - pre.right = curr; - curr = curr.left; - } else { - printValue(curr); - curr = curr.right; - pre.right = null; // revert to the original tree structure - } - } - } - } - - public static void main(String[] args) { - InOrderWithoutStackAndRecursion bst = new InOrderWithoutStackAndRecursion<>(); - bst.put(6); - bst.put(3); - bst.put(5); - bst.put(7); - bst.put(8); - bst.put(9); - bst.inOrder(); - } -} diff --git a/src/main/java/com/rampatra/trees/LeafNodes.java b/src/main/java/com/rampatra/trees/LeafNodes.java deleted file mode 100644 index bc3d271e..00000000 --- a/src/main/java/com/rampatra/trees/LeafNodes.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.rampatra.trees; - -import com.rampatra.base.BinaryNode; -import com.rampatra.base.BinaryTree; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/26/15 - * @time: 6:08 PM - */ -public class LeafNodes { - - /** - * Returns the number of leaf nodes in a binary tree. - * - * @return - */ - public static > int countLeafNodes(BinaryNode node) { - if (node == null) { - return 0; - } else if (node.left == null && node.right == null) { - return 1; - } else { - return countLeafNodes(node.left) + countLeafNodes(node.right); - } - } - - public static void main(String[] args) { - BinaryTree bt = new BinaryTree<>(); - bt.put(6); - bt.put(3); - bt.put(5); - bt.put(7); - bt.put(8); - bt.put(9); - System.out.println(countLeafNodes(bt.root)); - } -} diff --git a/src/main/java/com/rampatra/trees/LeastCommonAncestorInBST.java b/src/main/java/com/rampatra/trees/LeastCommonAncestorInBST.java deleted file mode 100644 index 1d195b90..00000000 --- a/src/main/java/com/rampatra/trees/LeastCommonAncestorInBST.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.rampatra.trees; - -import com.rampatra.base.BinaryNode; -import com.rampatra.base.BinarySearchTree; - -import java.util.NoSuchElementException; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/26/15 - * @time: 7:38 PM - */ -public class LeastCommonAncestorInBST { - - - public void leastCommonAncestor() { - /*int value1, value2; - Scanner in = new Scanner(System.in); - out.println("Enter value 1: "); - value1 = (E) Integer.valueOf(in.nextLine()); - out.println("Enter value 1: "); - value2 = (E) in.nextLine(); - out.println("LCA of " + value1 + " and " + value2 + " is: " + leastCommonAncestor(root, value1, value2).value);*/ - } - - /** - * Determines the LCA for a BST - *

- * DEFINITION OF LCA: - * Let T be a rooted tree. The lowest - * common ancestor between two nodes n1 and - * n2 is defined as the lowest node in T that has - * both n1 and n2 as descendants (where we allow - * a node to be a descendant of itself). - * - * @param node - * @param value1 - * @param value2 - * @param - * @return - */ - public static > BinaryNode leastCommonAncestor(BinaryNode node, E value1, E value2) { - if (node == null || value1 == null || value2 == null || value1.compareTo(value2) > 0) { - throw new NoSuchElementException(); - } - - if (value1.compareTo(node.value) <= 0 && value2.compareTo(node.value) >= 0) { - return node; - } else if (value1.compareTo(node.value) > 0 && value2.compareTo(node.value) > 0) { - return leastCommonAncestor(node.right, value1, value2); - } else { - return leastCommonAncestor(node.left, value1, value2); - } - } - - public static void main(String[] args) { - BinarySearchTree bst = new BinarySearchTree<>(); - bst.put(6); - bst.put(3); - bst.put(5); - bst.put(7); - bst.put(8); - bst.put(9); - System.out.println(leastCommonAncestor(bst.root, 5, 6).value); - } -} diff --git a/src/main/java/com/rampatra/trees/LeastCommonAncestorInBT.java b/src/main/java/com/rampatra/trees/LeastCommonAncestorInBT.java deleted file mode 100644 index 24bd6786..00000000 --- a/src/main/java/com/rampatra/trees/LeastCommonAncestorInBT.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.rampatra.trees; - -/** - * Given a binary tree {@code root}, find the LCA of two given nodes {@code node1} and {@code node2}. LCA is a node - * which is closest to both of the nodes. - *

- * See this youtube video for a visual understanding of the - * approach taken to solve this problem. - * - * @author rampatra - * @since 2019-04-06 - */ -public class LeastCommonAncestorInBT { - private static class TreeNode { - int val; - TreeNode left; - TreeNode right; - - TreeNode(int val) { - this.val = val; - } - - @Override - public String toString() { - return String.valueOf(val); - } - } - - private static TreeNode findLCA(TreeNode root, TreeNode node1, TreeNode node2) { - if (root == null) return null; - - /* - optimal: check this first before checking the child nodes recursively because even if the other node - is in one of the sub-trees the LCA would be root node - */ - if (root == node1 || root == node2) { - return root; - } - - TreeNode left = findLCA(root.left, node1, node2); - TreeNode right = findLCA(root.right, node1, node2); - - if (left != null && right != null) { // one node is in the left sub-tree and the other on the right sub-tree - return root; - } else if (left != null) { // we found one node in the left sub-tree - return left; - } else if (right != null) { // we found one node in the right sub-tree - return right; - } else { - return null; - } - } - - public static void main(String[] args) { - /* - The BST looks like: - - 4 - / \ - 2 8 - / \ / \ - 1 3 6 9 - / - 0 - - */ - TreeNode treeRoot = new TreeNode(4); - treeRoot.left = new TreeNode(2); - treeRoot.right = new TreeNode(8); - treeRoot.left.left = new TreeNode(1); - treeRoot.left.right = new TreeNode(3); - treeRoot.left.left.left = new TreeNode(0); - treeRoot.right.left = new TreeNode(6); - treeRoot.right.right = new TreeNode(9); - - System.out.println(findLCA(treeRoot, treeRoot, treeRoot).val); // findLCA(4, 4) - System.out.println(findLCA(treeRoot, treeRoot.left, treeRoot.right).val); // findLCA(2, 8) - System.out.println(findLCA(treeRoot, treeRoot.left, treeRoot.left.left).val); // findLCA(2, 1) - System.out.println(findLCA(treeRoot, treeRoot.left.left, treeRoot.left).val); // findLCA(1, 2) - System.out.println(findLCA(treeRoot, treeRoot.left.left.left, treeRoot.right.left).val); // findLCA(0, 6) - System.out.println(findLCA(treeRoot, treeRoot.right, treeRoot.right.right).val); // findLCA(8, 9) - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/trees/MirrorTree.java b/src/main/java/com/rampatra/trees/MirrorTree.java deleted file mode 100644 index 421e2241..00000000 --- a/src/main/java/com/rampatra/trees/MirrorTree.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.rampatra.trees; - -import com.rampatra.base.BinaryNode; -import com.rampatra.base.BinaryTree; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/26/15 - * @time: 7:03 PM - */ -public class MirrorTree { - - /** - * Converts a Tree to its Mirror Tree. - *

- * MIRROR OF A BINARY TREE T is another Binary Tree M(T) with - * left and right children of all non-leaf nodes interchanged. - *

- * TIP: In-order traversal of mirror tree is exactly the - * reverse of the in-order traversal of the original tree. - */ - public static > void mirror(BinaryNode node) { - if (node == null) return; - - // mirror sub-trees - mirror(node.left); - mirror(node.right); - - // swap nodes - BinaryNode tempNode; - tempNode = node.left; - node.left = node.right; - node.right = tempNode; - } - - public static void main(String[] args) { - BinaryTree bt = new BinaryTree<>(); - bt.put(6); - bt.put(3); - bt.put(5); - bt.put(7); - bt.put(8); - bt.put(9); - System.out.println("Original Tree"); - bt.breadthFirstTraversal(); - System.out.println("\nMirror Tree"); - mirror(bt.root); - bt.breadthFirstTraversal(); - } -} diff --git a/src/main/java/com/rampatra/trees/RandomNodeInBT.java b/src/main/java/com/rampatra/trees/RandomNodeInBT.java deleted file mode 100644 index a2719bc7..00000000 --- a/src/main/java/com/rampatra/trees/RandomNodeInBT.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.rampatra.trees; - -import java.util.Random; - -/** - * You are implementing a binary tree class from scratch, which has a method getRandomNode() which returns a - * random node from the tree. All nodes should be equally likely to be chosen. Design and implement an algorithm - * for getRandomNode(). - * - * @author rampatra - * @since 2019-04-03 - */ -public class RandomNodeInBT { - - private static class TreeNode { - int val; - TreeNode left; - TreeNode right; - int size; // num of nodes in left subtree + 1 + num of nodes in right subtree - - TreeNode(int val, int size) { - this.val = val; - this.size = size; - } - - TreeNode getRandomNode() { - int randomNum = new Random().nextInt(this.size); // generates a random num from 0 to size - 1 (both inclusive) - - /* - the below makes all nodes equally likely because the probability is distributed - evenly (approximately) depending on the number of children - */ - if (this.left != null && randomNum < this.left.size) { - return left.getRandomNode(); - } else if (this.right != null && randomNum > this.right.size) { - return right.getRandomNode(); - } else { - return this; - } - } - } - - public static void main(String[] args) { - /* - The BST looks like: - - 4 - / \ - 2 8 - / \ / \ - 1 3 6 9 - - */ - TreeNode treeRoot = new TreeNode(4, 7); - treeRoot.left = new TreeNode(2, 3); - treeRoot.right = new TreeNode(8, 3); - treeRoot.left.left = new TreeNode(1, 1); - treeRoot.left.right = new TreeNode(3, 1); - treeRoot.right.left = new TreeNode(6, 1); - treeRoot.right.right = new TreeNode(9, 1); - - System.out.println(treeRoot.getRandomNode().val); - System.out.println(treeRoot.getRandomNode().val); - System.out.println(treeRoot.getRandomNode().val); - System.out.println(treeRoot.getRandomNode().val); - System.out.println(treeRoot.getRandomNode().val); - System.out.println(treeRoot.getRandomNode().val); - System.out.println(treeRoot.getRandomNode().val); - System.out.println(treeRoot.getRandomNode().val); - - System.out.println("-------"); - - System.out.println(new Random().nextInt(8)); - System.out.println(new Random().nextInt(8)); - System.out.println(new Random().nextInt(8)); - System.out.println(new Random().nextInt(8)); - System.out.println(new Random().nextInt(8)); - System.out.println(new Random().nextInt(8)); - System.out.println(new Random().nextInt(8)); - System.out.println(new Random().nextInt(8)); - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/trees/RootToLeafPaths.java b/src/main/java/com/rampatra/trees/RootToLeafPaths.java deleted file mode 100644 index a42ca4b6..00000000 --- a/src/main/java/com/rampatra/trees/RootToLeafPaths.java +++ /dev/null @@ -1,122 +0,0 @@ -package com.rampatra.trees; - -import com.rampatra.base.BinaryNode; -import com.rampatra.base.BinaryTree; - -import java.util.ArrayList; -import java.util.List; - -import static java.lang.System.out; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/26/15 - * @time: 5:52 PM - */ -public class RootToLeafPaths> extends BinaryTree { - - /** - * Prints the node to leaf paths, one per line. - */ - public void rootToLeafPaths() { - List pathList = new ArrayList<>(); - rootToLeafPaths(root, pathList); - - /*E[] pathList = (E[]) new Object[100]; - rootToLeafPaths(root, pathList, 0);*/ - } - - /** - * Prints the node to leaf paths, one per line. - * (Using array) - */ - public void rootToLeafPaths(BinaryNode node, E[] pathList, int pathLength) { - if (node == null) return; - - pathList[pathLength] = node.value; - pathLength++; - - // if its a leaf node then print the list - if (node.left == null && node.right == null) { - int i; - for (i = 0; i < pathLength - 1; i++) { - out.print(pathList[i] + " -> "); - } - // outside the loop so that "->" doesn't appear after the last node - out.println(pathList[i]); - } else { - // do the same for subtrees - rootToLeafPaths(node.left, pathList, pathLength); - rootToLeafPaths(node.right, pathList, pathLength); - } - } - - /** - * Prints the node to leaf paths, one per line. - * (Using ArrayList) - */ - public void rootToLeafPaths(BinaryNode node, List pathList) { - if (node == null) return; - - pathList.add(node.value); - - // if its a leaf node then print the list - if (node.left == null && node.right == null) { - int i; - for (i = 0; i < pathList.size() - 1; i++) { - out.print(pathList.get(i) + " -> "); - } - // outside the loop so that "->" doesn't appear after the last node - out.println(pathList.get(i)); - } else { - // do the same for subtrees - rootToLeafPaths(node.left, new ArrayList<>(pathList)); - rootToLeafPaths(node.right, new ArrayList<>(pathList)); - } - } - - - /** - * Given a binary tree and a number, return true if the tree has a root-to-leaf - * path such that adding up all the values along the path equals the given number. - * Return false if no such path can be found. - * - * @param node - * @param pathList - * @param pathSum - * @return - */ - public boolean rootToLeafPathsSum(BinaryNode node, List pathList, int pathSum) { - int sum = 0; - - if (node != null) pathList.add(node.value); - - // if its either a leaf node or null then path is complete, add all elements present in list - if (node == null || (node.left == null && node.right == null)) { - for (int i = 0; i < pathList.size(); i++) { - sum += Integer.parseInt(pathList.get(i).toString()); - } - return sum == pathSum; - } else { - // do the same for subtrees - return rootToLeafPathsSum(node.left, new ArrayList<>(pathList), pathSum) || - rootToLeafPathsSum(node.right, new ArrayList<>(pathList), pathSum); - } - } - - public static void main(String[] args) { - RootToLeafPaths bt = new RootToLeafPaths<>(); - bt.put(6); - bt.put(3); - bt.put(5); - bt.put(7); - bt.put(8); - bt.put(9); - out.println("Root to leafs: "); - bt.rootToLeafPaths(); - out.println("Root to Leaf Sum: "); - out.println(bt.rootToLeafPathsSum(bt.root, new ArrayList(), 13)); - } -} diff --git a/src/main/java/com/rampatra/trees/SecondSmallestInBST.java b/src/main/java/com/rampatra/trees/SecondSmallestInBST.java deleted file mode 100644 index 4e287365..00000000 --- a/src/main/java/com/rampatra/trees/SecondSmallestInBST.java +++ /dev/null @@ -1,108 +0,0 @@ -package com.rampatra.trees; - -/** - * Given a Binary Search Tree, find out the second smallest element in the tree. - * - * @author rampatra - * @since 2019-04-02 - */ -public class SecondSmallestInBST { - - private static class TreeNode { - int val; - TreeNode left; - TreeNode right; - - TreeNode(int val) { - this.val = val; - } - } - - private static TreeNode getSecondSmallestNode(TreeNode root) { - if (root == null) return null; - - TreeNode curr = root; - - if (curr.left == null) { - if (curr.right == null) { - return null; - } else { - return curr; - } - } - - while (curr.left.left != null) { - curr = curr.left; - } - - if (curr.left.right != null) { - return curr.left.right; - } else { - return curr; - } - } - - public static void main(String[] args) { - /* - The BST looks like: - - 4 - / \ - 2 8 - / \ / \ - 1 3 6 9 - / - 0 - - */ - TreeNode treeRoot = new TreeNode(4); - treeRoot.left = new TreeNode(2); - treeRoot.right = new TreeNode(8); - treeRoot.left.left = new TreeNode(1); - treeRoot.left.right = new TreeNode(3); - treeRoot.left.left.left = new TreeNode(0); - treeRoot.right.left = new TreeNode(6); - treeRoot.right.right = new TreeNode(9); - - System.out.println(getSecondSmallestNode(treeRoot).val); - - /* - The BST looks like: - - 4 - / \ - 2 8 - / \ / \ - 1 3 6 9 - - */ - treeRoot = new TreeNode(4); - treeRoot.left = new TreeNode(2); - treeRoot.right = new TreeNode(8); - treeRoot.left.left = new TreeNode(1); - treeRoot.left.right = new TreeNode(3); - treeRoot.right.left = new TreeNode(6); - treeRoot.right.right = new TreeNode(9); - - System.out.println(getSecondSmallestNode(treeRoot).val); - - /* - The BST looks like: - - 4 - / \ - 2 8 - \ / \ - 3 6 9 - - */ - treeRoot = new TreeNode(4); - treeRoot.left = new TreeNode(2); - treeRoot.right = new TreeNode(8); - treeRoot.left.right = new TreeNode(3); - treeRoot.right.left = new TreeNode(6); - treeRoot.right.right = new TreeNode(9); - - System.out.println(getSecondSmallestNode(treeRoot).val); - } -} \ No newline at end of file diff --git a/src/main/java/com/rampatra/trees/SpiralTraversal.java b/src/main/java/com/rampatra/trees/SpiralTraversal.java deleted file mode 100644 index fa313e1c..00000000 --- a/src/main/java/com/rampatra/trees/SpiralTraversal.java +++ /dev/null @@ -1,115 +0,0 @@ -package com.rampatra.trees; - -import com.rampatra.base.BinaryNode; -import com.rampatra.base.BinaryTree; -import com.rampatra.base.LinkedStack; -import com.rampatra.base.Stack; - -import java.util.EmptyStackException; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/26/15 - * @time: 5:14 PM - */ -public class SpiralTraversal> extends BinaryTree { - - /** - * In spiral order traversal, nodes at different levels - * are printed in alternating order. - */ - public void spiralTraversal() { - spiralTraversal(root, 0); // uses recursion - } - - public void spiralTraversal(BinaryNode node, int level) { - if (node == null) return; - - // print the starting node - if (level == 0) printValue(node); - - // print the neighbour nodes - if (level % 2 == 0) { - printValue(node.left); - printValue(node.right); - } else { - printValue(node.right); - printValue(node.left); - } - - // go to next level - level++; - if (level % 2 == 0) { - spiralTraversal(node.left, level); - spiralTraversal(node.right, level); - } else { - spiralTraversal(node.right, level); - spiralTraversal(node.left, level); - } - } - - public void spiralTraversalUsingStacks(BinaryNode node) { - Stack> stack1 = new LinkedStack<>(); // for nodes to be printed ltr - Stack> stack2 = new LinkedStack<>(); // for nodes to be printed rtl - - printValue(node); - - stack1.push(node.right); - stack1.push(node.left); - - // pop stack1 and push their child nodes in stack2 - while (!stack1.isEmpty()) { - - BinaryNode leftChild = stack1.pop(); - BinaryNode rightChild = stack1.pop(); - - printValue(leftChild); - printValue(rightChild); - - try { - if (leftChild != null) stack2.push(leftChild.left); - if (leftChild != null) stack2.push(leftChild.right); - if (rightChild != null) stack2.push(rightChild.left); - if (rightChild != null) stack2.push(rightChild.right); - } catch (EmptyStackException e) { - // ignore error when stack empty - } - } - - // pop stack2 and push their child nodes in stack1 - while (!stack2.isEmpty()) { - - BinaryNode rightChild = stack2.pop(); - BinaryNode leftChild = stack2.pop(); - - printValue(rightChild); - printValue(leftChild); - - try { - if (rightChild != null) stack1.push(rightChild.right); - if (rightChild != null) stack1.push(rightChild.left); - if (leftChild != null) stack1.push(leftChild.right); - if (leftChild != null) stack1.push(leftChild.left); - } catch (EmptyStackException e) { - // ignore error when stack empty - } - } - } - - public static void main(String[] args) { - SpiralTraversal bt = new SpiralTraversal<>(); - bt.put(6); - bt.put(3); - bt.put(5); - bt.put(7); - bt.put(8); - bt.put(9); - bt.breadthFirstTraversal(); - System.out.println(""); - bt.spiralTraversal(); - System.out.println(""); - bt.spiralTraversalUsingStacks(bt.root); - } -} diff --git a/src/main/java/com/rampatra/trees/TreeToList.java b/src/main/java/com/rampatra/trees/TreeToList.java deleted file mode 100644 index 26256b30..00000000 --- a/src/main/java/com/rampatra/trees/TreeToList.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.rampatra.trees; - -import com.rampatra.base.BinaryNode; -import com.rampatra.base.BinarySearchTree; - -/** - * Created by IntelliJ IDEA. - * - * @author rampatra - * @since 6/26/15 - * @time: 4:38 PM - */ -public class TreeToList> extends BinarySearchTree { - - /** - * A recursive function that takes an ordered binary tree - * and rearranges the internal pointers to make a circular - * doubly linked list out of the tree nodes. The list should - * be arranged so that the nodes are in increasing order. - */ - public void treeToList() { - // print the list - printList(treeToList(root)); - } - - public static > BinaryNode treeToList(BinaryNode node) { - if (node == null) return null; - - BinaryNode aList = treeToList(node.left); - BinaryNode bList = treeToList(node.right); - - node.left = node; - node.right = node; - - // attach left child then root followed by right child (so that final list is in ascending order) - aList = addToList(aList, node); - aList = addToList(aList, bList); - - return aList; - } - - private static > BinaryNode addToList(BinaryNode aList, BinaryNode bList) { - - if (aList == null) return bList; - if (bList == null) return aList; - - // find the last node in each list - BinaryNode aListLast = aList.left; - BinaryNode bListLast = bList.left; - - // join end of one list to beginning of another - aListLast.right = bList; - bList.left = aListLast; - - // make circular - aListLast.left = bListLast; - bListLast.right = aList; - - return aList; - } - - public static void main(String[] args) { - BinarySearchTree bst = new BinarySearchTree<>(); - bst.put(6); - bst.put(3); - bst.put(5); - bst.put(7); - bst.put(8); - bst.put(9); - bst.inOrder(); - // TODO incorrect results - bst.printList(treeToList(bst.root)); - } -} diff --git a/src/main/java/com/rampatra/trees/TwoSwappedNodesInBST.java b/src/main/java/com/rampatra/trees/TwoSwappedNodesInBST.java deleted file mode 100644 index 4ec473da..00000000 --- a/src/main/java/com/rampatra/trees/TwoSwappedNodesInBST.java +++ /dev/null @@ -1,143 +0,0 @@ -package com.rampatra.trees; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * Two nodes are swapped in a BST, write a function to find these two nodes. - *

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

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

- * See this youtube video for a visual understanding. - * - * @author rampatra - * @since 2019-04-06 - */ -public class TwoSwappedNodesInBST { - - private static class TreeNode { - int val; - TreeNode left; - TreeNode right; - - TreeNode(int val) { - this.val = val; - } - - @Override - public String toString() { - return String.valueOf(val); - } - } - - private static List findSwappedNodes(TreeNode root) { - List inOrderTraversal = new ArrayList<>(); - TreeNode firstSwappedNode = null; - TreeNode secondSwappedNode = null; - TreeNode plausibleSwappedNode = null; - - traverseInOrder(root, inOrderTraversal); - - for (int i = 0; i < inOrderTraversal.size() - 1; i++) { - // find nodes not in ascending order - if (inOrderTraversal.get(i).val > inOrderTraversal.get(i + 1).val) { - if (firstSwappedNode == null) { - firstSwappedNode = inOrderTraversal.get(i); // take the left node from the first violation - plausibleSwappedNode = inOrderTraversal.get(i + 1); - } else { - secondSwappedNode = inOrderTraversal.get(i + 1); // take the right node from the second violation - } - } - } - - return Arrays.asList(firstSwappedNode, secondSwappedNode == null ? plausibleSwappedNode : secondSwappedNode); - } - - private static void traverseInOrder(TreeNode node, List inOrderTraversal) { - if (node == null) return; - - traverseInOrder(node.left, inOrderTraversal); - inOrderTraversal.add(node); - traverseInOrder(node.right, inOrderTraversal); - } - - public static void main(String[] args) { - /* - - Test case 1: Node 8 and node 2 are swapped - - The current BST looks like: - - 4 - / \ - 8 2 - / \ / \ - 1 3 6 9 - / - 0 - - Instead, the correct BST should look like: - - 4 - / \ - 2 8 - / \ / \ - 1 3 6 9 - / - 0 - - */ - TreeNode treeRoot = new TreeNode(4); - treeRoot.left = new TreeNode(8); - treeRoot.right = new TreeNode(2); - treeRoot.left.left = new TreeNode(1); - treeRoot.left.right = new TreeNode(3); - treeRoot.left.left.left = new TreeNode(0); - treeRoot.right.left = new TreeNode(6); - treeRoot.right.right = new TreeNode(9); - - System.out.println(findSwappedNodes(treeRoot)); - - /* - - Test case 2: Node 3 and node 2 are swapped (note: these are parent child nodes) - - The current BST looks like: - - 4 - / \ - 3 8 - / \ / \ - 1 2 6 9 - / - 0 - - Instead, the correct BST should look like: - - 4 - / \ - 2 8 - / \ / \ - 1 3 6 9 - / - 0 - - */ - treeRoot = new TreeNode(4); - treeRoot.left = new TreeNode(3); - treeRoot.right = new TreeNode(8); - treeRoot.left.left = new TreeNode(1); - treeRoot.left.right = new TreeNode(2); - treeRoot.left.left.left = new TreeNode(0); - treeRoot.right.left = new TreeNode(6); - treeRoot.right.right = new TreeNode(9); - - System.out.println(findSwappedNodes(treeRoot)); - } -} \ No newline at end of file diff --git a/src/main/java/com/stack/GetMinimumFromStackInConstantTime.adoc b/src/main/java/com/stack/GetMinimumFromStackInConstantTime.adoc new file mode 100644 index 00000000..82de1d3a --- /dev/null +++ b/src/main/java/com/stack/GetMinimumFromStackInConstantTime.adoc @@ -0,0 +1 @@ +image::../../../images/GetMinimumFromStackInConstantTime.png[] \ No newline at end of file diff --git a/src/main/java/com/stack/GetMinimumFromStackInConstantTime.java b/src/main/java/com/stack/GetMinimumFromStackInConstantTime.java new file mode 100644 index 00000000..bddc4a84 --- /dev/null +++ b/src/main/java/com/stack/GetMinimumFromStackInConstantTime.java @@ -0,0 +1,61 @@ +package com.stack; + +//Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. +//push(x) -- Push element x onto stack. +//pop() -- Removes the element on top of the stack. +//top() -- Get the top element. +//getMin() -- Retrieve the minimum element in the stack. + +/** + * Your GetMinimumFromStackInConstantTime object will be instantiated and called as such: + * GetMinimumFromStackInConstantTime obj = new GetMinimumFromStackInConstantTime(); + * obj.push(x); + * obj.pop(); + * int param_3 = obj.top(); + * int param_4 = obj.getMin(); + */ +class GetMinimumFromStackInConstantTime { + class Node { + int data; + int min; + Node next; + + public Node(int data, int min) { + this.data = data; + this.min = min; + this.next = null; + } + } + + Node head; + + /** + * initialize your data structure here. + */ + public GetMinimumFromStackInConstantTime() { + + } + + public void push(int x) { + if (head == null) { + head = new Node(x, x); + } else { /**important*/ + Node newNode = new Node(x, Math.min(x, head.min)); + newNode.next = head; + head = newNode; + } + } + + public void pop() { + head = head.next; + } + + public int top() { + return head.data; + } + + public int getMin() { + return head.min; + } +} + diff --git a/src/main/java/com/stack/ParenthesisChecker.java b/src/main/java/com/stack/ParenthesisChecker.java new file mode 100644 index 00000000..d8c7c2a7 --- /dev/null +++ b/src/main/java/com/stack/ParenthesisChecker.java @@ -0,0 +1,47 @@ +package com.stack; + +import java.util.HashMap; +import java.util.Stack; + +/** + * Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. + *

+ * The brackets must close in the correct order, "()" and "()[]{}" are all valid but "(]" and "([)]" are not. + *

+ * Analysis + *

+ * A typical problem which can be solved by using a stack data structure. + */ +public class ParenthesisChecker { + + public static boolean isValid(String s) { + HashMap map = new HashMap<>(); + map.put('(', ')'); + map.put('[', ']'); + map.put('{', '}'); + + Stack stack = new Stack<>(); + + for (int i = 0; i < s.length(); i++) { + char curr = s.charAt(i); + + if (map.keySet().contains(curr)) { /**if the character is in keySet means its opening brace + we push it onto the Stack*/ + stack.push(curr); + } else if (map.values().contains(curr)) { /** if character is in values means its closing brace + so we pop it out and check with curr */ + if (!stack.empty() && map.get(stack.peek()) == curr) { + stack.pop(); + } else { + return false; + } + } + } + return stack.empty(); + } + + public static void main (String args[]){ + String input = "[()]{}{[()()]()}"; + System.out.println("isValid : "+isValid(input)); + } +} diff --git a/src/main/java/com/string/DefangingAnIpAddress.java b/src/main/java/com/string/DefangingAnIpAddress.java new file mode 100644 index 00000000..9c3392d5 --- /dev/null +++ b/src/main/java/com/string/DefangingAnIpAddress.java @@ -0,0 +1,37 @@ +package com.string; + +/** + * Given a valid (IPv4) IP address, return a defanged version of that IP address. + * + * A defanged IP address replaces every period "." with "[.]". + * + * Example 1: + * + * Input: address = "1.1.1.1" + * Output: "1[.]1[.]1[.]1" + * Example 2: + * + * Input: address = "255.100.50.0" + * Output: "255[.]100[.]50[.]0" + */ +public class DefangingAnIpAddress { + + public static void main (String args[]){ + String s = defangIPaddr("198.100.100.100"); + System.out.println(s); + } + + public static String defangIPaddr(String address) { + StringBuilder sb = new StringBuilder(); + for (char c : address.toCharArray()) { + if (c == '.') { + sb.append("[.]"); + } + else { + sb.append(c); + } + } + + return sb.toString(); + } +} diff --git a/src/main/java/com/string/EditDistanceBetween2Strings_DynamicProgramming.JPG b/src/main/java/com/string/EditDistanceBetween2Strings_DynamicProgramming.JPG new file mode 100644 index 00000000..57a6e9b0 Binary files /dev/null and b/src/main/java/com/string/EditDistanceBetween2Strings_DynamicProgramming.JPG differ diff --git a/src/main/java/com/string/EditDistanceBetween2Strings_DynamicProgramming.java b/src/main/java/com/string/EditDistanceBetween2Strings_DynamicProgramming.java new file mode 100644 index 00000000..b13cd652 --- /dev/null +++ b/src/main/java/com/string/EditDistanceBetween2Strings_DynamicProgramming.java @@ -0,0 +1,44 @@ +package com.string; + + +/** + * https://www.youtube.com/watch?v=b6AGUjqIPsA + * + */ +public class EditDistanceBetween2Strings_DynamicProgramming { + + public static void main (String args[]){ + String from = "YELLOW"; + String to = "HELLO"; + System.out.println("MinEditDistance:" +editDist(from,to,from.length(),to.length())); + } + + static int editDist(String from, String to, int m, int n) + { + // If first string is empty, the only option is to + // insert all characters of second string into first + if (m == 0) + return n; + + // If second string is empty, the only option is to + // remove all characters of first string + if (n == 0) + return m; + + // If last characters of two strings are same, nothing + // much to do. Ignore last characters and get count for + // remaining strings. + if (from.charAt(m - 1) == to.charAt(n - 1)) + return editDist(from, to, m - 1, n - 1); /** diagonal - blind copy*/ + + // If last characters are not same, consider all three + // operations on last character of first string, recursively + // compute minimum cost for all three operations and take + // minimum of three values. + + return 1 + Integer.min(Integer.min(editDist(from, to, m, n - 1), // Insert --just left + editDist(from, to, m - 1, n)),// Remove --just above + editDist(from, to, m - 1, n - 1)); // Replace --just diagonal + + } +} diff --git a/src/main/java/com/string/FindFirstNonRepeatingCharacter.java b/src/main/java/com/string/FindFirstNonRepeatingCharacter.java new file mode 100644 index 00000000..390a462b --- /dev/null +++ b/src/main/java/com/string/FindFirstNonRepeatingCharacter.java @@ -0,0 +1,41 @@ +package com.string; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Given a string S consisting of lowercase Latin Letters. Find the first non repeating character in S. + */ +public class FindFirstNonRepeatingCharacter { + + public static void main(String args[]) { + String input = "ABCDHJACDHJ"; + int c = findFirstNonRepeatingChar(input); + if (c == -1) { + System.out.println("findFirstNonRepeatingChar : " + "Not Found"); + } else { + System.out.println("findFirstNonRepeatingChar : " + (char) c); + } + } + + private static int findFirstNonRepeatingChar(String input) { + /**insertion order will preserved as we are using linkedHashMap */ + Map map = new LinkedHashMap<>(); + + /** store frequency of each character in map*/ + for (char c : input.toCharArray()) { + if (map.containsKey(c)) { + map.put(c, map.get(c) + 1); + } else { + map.put(c, 1); + } + } + + for (char c : map.keySet()) { + if (map.get(c) == 1) { + return c; + } + } + return -1; + } +} diff --git a/src/main/java/com/string/FindLongestWordInDictionary.java b/src/main/java/com/string/FindLongestWordInDictionary.java new file mode 100644 index 00000000..d73505f2 --- /dev/null +++ b/src/main/java/com/string/FindLongestWordInDictionary.java @@ -0,0 +1,86 @@ +package com.string; + +// Java program to find largest +// word in Dictionary by deleting +// some characters of given String +/** + * Giving a dictionary and a string ‘str’, + * find the longest string in dictionary which can be formed by deleting some characters of the given ‘str’. + * + * Input : dict = {"ale", "apple", "monkey", "plea"} + * str = "abpcplea" + * Output : apple + * + * Input : dict = {"pintu", "geeksfor", "geeksgeeks", + * " forgeek"} + * str = "geeksforgeeks" + * Output : geeksgeeks + */ + +import java.util.*; + +class FindLongestWordInDictionary +{ + + // Returns true if str1[] is a + // subsequence of str2[]. m is + // length of str1 and n is length of str2 + static boolean isSubSequence(String str1, + String str2) + { + int m = str1.length(), n = str2.length(); + + int j = 0; // For index of str1 (or subsequence) + + // Traverse str2 and str1, and compare current + // character of str2 with first unmatched char + // of str1, if matched then move ahead in str1 + for (int i = 0; i < n && j < m; i++) + { + if (str1.charAt(j) == str2.charAt(i)) + { + j++; + } + } + + // If all characters of str1 + // were found in str2 . All characters of dictionary word are present in given String + return (j == m); + } + + // Returns the longest String +// in dictionary which is a +// subsequence of str. + static String findLongestString(Set dict, + String str) + { + String result = ""; + int length = 0; + + // Traverse through all words of dictionary + for (String word : dict) + { + + // If current word is subsequence of str + // and is largest such word so far. + if (length < word.length() && + isSubSequence(word, str)) + { + result = word; + length = word.length(); + } + } + + // Return longest String + return result; + } + + // Driver code + public static void main(String[] args) + { + String[] arr = {"ale", "apple", "monkey", "plea"}; + Set dict = new HashSet(Arrays.asList(arr)); + String str = "abpcplea"; + System.out.println(findLongestString(dict, str)); + } +} diff --git a/src/main/java/com/string/LongestPalindromeInString.java b/src/main/java/com/string/LongestPalindromeInString.java new file mode 100644 index 00000000..10242edf --- /dev/null +++ b/src/main/java/com/string/LongestPalindromeInString.java @@ -0,0 +1,69 @@ +package com.string; + +/** + * Given a string s, find the longest palindromic subsequence’s length in s + * + * Input: + * + * "cbbd" + * Output: + * 2 + * One possible longest palindromic subsequence is "bb". + * + * Time Complexity: O(N) + * Space Complexity: O(N) + * + */ +public class LongestPalindromeInString { + + int manachersAlgorithm(String s, int N) { + String str = getModifiedString(s, N); + int len = (2 * N) + 1; + int[] P = new int[len]; + int c = 0; //stores the center of the longest palindromic substring until now + int r = 0; //stores the right boundary of the longest palindromic substring until now + int maxLen = 0; + for(int i = 0; i < len; i++) { + //get mirror index of i + int mirror = (2 * c) - i; + + //see if the mirror of i is expanding beyond the left boundary of current longest palindrome at center c + //if it is, then take r - i as P[i] + //else take P[mirror] as P[i] + if(i < r) { + P[i] = Math.min(r - i, P[mirror]); + } + + //expand at i + int a = i + (1 + P[i]); + int b = i - (1 + P[i]); + while(a < len && b >= 0 && str.charAt(a) == str.charAt(b)) { + P[i]++; + a++; + b--; + } + + //check if the expanded palindrome at i is expanding beyond the right boundary of current longest palindrome at center c + //if it is, the new center is i + if(i + P[i] > r) { + c = i; + r = i + P[i]; + + if(P[i] > maxLen) { //update maxlen + maxLen = P[i]; + } + } + } + return maxLen; + } + + String getModifiedString(String s, int N){ + StringBuilder sb = new StringBuilder(); + for(int i = 0; i < N; i++){ + sb.append("#"); + sb.append(s.charAt(i)); + } + sb.append("#"); + return sb.toString(); + } +} diff --git a/src/main/java/com/string/LongestPalindromicSubstring_ManacherAlgo.html b/src/main/java/com/string/LongestPalindromicSubstring_ManacherAlgo.html new file mode 100644 index 00000000..a95e16f7 --- /dev/null +++ b/src/main/java/com/string/LongestPalindromicSubstring_ManacherAlgo.html @@ -0,0 +1,16 @@ +Manacher’s Algorithm Explained— Longest Palindromic Substring

Manacher’s Algorithm Explained— Longest Palindromic Substring

Mithra Talluri
Jul 6, 2019 · 5 min read

Manacher’s Algorithm helps us find the longest palindromic substring in the given string. It optimizes over the brute force solution by using some insights into how palindromes work. How? Let’s see!

Let’s focus on odd length palindromes for simplicity. We go about the string from left to right.

Notations:

Let c be the center of the longest length palindrome we have encountered till now. And let l and r be the left and right boundaries of this palindrome, i.e., the left-most character index and the right-most character index respectively. Now, let’s take an example to understand c, l, and r.

Eg: “abacabacabb”

When going from left to right, when i is at index 1, the longest palindromic substring is “aba” (length = 3).

c, l, and r for palindromic string “aba”

The answer for the given string is 9 when the palindrome is centered at index 5; c, l, and r are as follows:

Final c, l, and r positions for the whole string

Now that we know what c, l, and r denote, let’s take a small break from the algorithm and understand a few interesting facts about palindromes.

Mirror index: For any palindrome centered at a center c, the mirror of index j is j’ such that

For palindrome “abacaba”, the mirror of j is j’ and the mirror of j’ is j.

for some j, its mirror j’ for palindrome “abacaba”

Now, come back to the algorithm. When we move i from left to right, we try to “expand” the palindrome at each i. When I say the word expand, it means that I’ll check whether there exists a palindrome centered at i and if there exists one, I’ll store the “expansion length” to the left or to the right in a new array called P[] array or (some prefer) LPS[].

If the palindrome at i expands beyond the current right boundary r, then c is updated to i and new l, r are found and updated.

Example time. Let’s take the previously discussed palindrome “abacaba” which is centered at i = 3.

P[i] = 3 as expansion length for palindrome centered at i is 3

Therefore, the P[] array stores the expansion length of the palindrome centered at each index. But we don’t need to manually go to each index and expand to check the expansion length every time. This is exactly where Manacher’s algorithm optimizes better than brute force, by using some insights on how palindromes work. Let’s see how the optimization is done.

Important recap: c indicates the center of the current longest odd length palindrome. And l, r denote the palindrome’s left and right boundaries.

Let’s see the P[] array for the string “abacaba”.

When i = 4, the index is inside the scope of the current longest palindrome, i.e., i < r. So, instead of naively expanding at i, we want to know the minimum expansion length that is certainly possible at i, so that we can expand on that minimum P[i] and see, instead of doing from start. So, we check for mirror i’.

As long as the palindrome at index i’ does NOT expand beyond the left boundary (l) of the current longest palindrome, we can say that the minimum certainly possible expansion length at i is P[i’].

Remember that we are only talking about the minimum possible expansion length, the actual expansion length could be more and, we’ll find that out by expanding later on. In this case, P[4] = P[2] = 0. We try to expand but still, P[4] remains 0.

Now, if the palindrome at index i’ expands beyond the left boundary (l) of the current longest palindrome, we can say that the minimum certainly possible expansion length at i is r-i.

Eg: “acacacb”

Here, palindrome centered at i’ expands beyond the left boundary

So, P[4] = 5–4 = 1

You could ask but why can’t the palindrome centered at i expand after r in this case? If it did, then it would have already been covered with the current center c only. But, it didn’t. So, P[i] = r-i.

(That is, if palindrome at i were to expand beyond r, then the character at index 6 should have been ‘a’. But if that were to happen, the current palindrome centered at c would NOT have been “cacac” but “acacaca”)

So, we can sum the two quoted points above as follows:

Updating P[i] to the minimum certainly possible expansion length

That’s it. Now the only thing left is to expand at i after P[i], so we check characters from index (P[i] + 1) and keep expanding at i.

If this palindrome expands beyond r, update c to i and r to (i + P[i]).

Voila! The P[] array is now filled and the maximum value in this array gives us the longest palindromic substring in the given string!

We have taken an odd length string for the above explanation. So, for this algorithm to work out, we simply append N + 1 special characters (say ‘#’) in between every two characters, just to make sure that our modified string is always of odd length.

Eg1: aba -> #a#b#a#
Eg2: abba-> #a#b#b#a#

Here’s the implementation in Java:

Time Complexity: O(N)
Space Complexity: O(N)

Feel free to voice your doubts and concerns in the comments below. Thank you for reading! 😃

Mithra Talluri

Written by

Software Engineer at Sureify

HackerNoon.com

how hackers start their afternoons.

More From Medium

More from HackerNoon.com

More from HackerNoon.com

WTF is The Blockchain?

More from HackerNoon.com

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
+ + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/string/LongestPalindromicSubstring_ManachersAlgo.java b/src/main/java/com/string/LongestPalindromicSubstring_ManachersAlgo.java new file mode 100644 index 00000000..20747fc8 --- /dev/null +++ b/src/main/java/com/string/LongestPalindromicSubstring_ManachersAlgo.java @@ -0,0 +1,4 @@ +package com.string; + +public class LongestPalindromicSubstring_ManachersAlgo { +} diff --git a/src/main/java/com/string/LongestPalindromicSubstring_WithoutManacherAlgo.java b/src/main/java/com/string/LongestPalindromicSubstring_WithoutManacherAlgo.java new file mode 100644 index 00000000..dcbf646b --- /dev/null +++ b/src/main/java/com/string/LongestPalindromicSubstring_WithoutManacherAlgo.java @@ -0,0 +1,54 @@ +package com.string; + +/** + * We can scan to both sides for each character. + * Time O(n^2), Space O(1) + * If you need better use Manacher's Algorithm with time complexity O(n) + */ + +public class LongestPalindromicSubstring_WithoutManacherAlgo { + + public String longestPalindrome(String s) { + + if (s.length() <= 1) { + return s; + } + /**initialize the longest to first character */ + String longest = s.substring(0, 1); + + for (int i = 0; i < s.length(); i++) { + + // get longest palindrome with center of i + String tmp = helper(s, i, i); + if (tmp.length() > longest.length()) { + longest = tmp; + } + + // get longest palindrome with center of i, i+1 + tmp = helper(s, i, i + 1); + if (tmp.length() > longest.length()) { + longest = tmp; + } + + } + + return longest; + } + + // Given a center, either one letter or two letter, + // Find longest palindrome + public String helper(String s, int begin, int end) { + while (begin >= 0 && end <= s.length() - 1 && s.charAt(begin) == s.charAt(end)) { /** begin and end within boundary && Start and end characters are matching */ + /**Expand the boundaries */ + begin--; + end++; + } + return s.substring(begin + 1, end); + } + + public static void main(String[] args) { + LongestPalindromicSubstring_WithoutManacherAlgo palindrome = new LongestPalindromicSubstring_WithoutManacherAlgo(); + String result = palindrome.longestPalindrome("daxah"); + System.out.println("longestPalindrome - " + result); + } +} diff --git a/src/main/java/com/string/PermutationOfString.java b/src/main/java/com/string/PermutationOfString.java new file mode 100644 index 00000000..1bfdb845 --- /dev/null +++ b/src/main/java/com/string/PermutationOfString.java @@ -0,0 +1,63 @@ +package com.string; + +/** + * A string of length n has n! permutation. + * Below are the permutations of string ABC. + * ABC ACB BAC BCA CBA CAB + * + * Algorithm Paradigm: Backtracking + * Time Complexity: O(n*n!) + * Note that there are n! permutations and it requires O(n) time to print a a permutation. + */ +// Java program to print all permutations of a +// given string. + public class PermutationOfString + { + public static void main(String[] args) + { + String str = "ABC"; + int n = str.length(); + PermutationOfString permutation = new PermutationOfString(); + permutation.permute(str, 0, n-1); + } + + /** + * permutation function + * @param str string to calculate permutation for + * @param l starting index + * @param r end index + */ + private void permute(String str, int l, int r) + { + if (l == r) + System.out.println(str); + else + { + for (int i = l; i <= r; i++) + { + str = swap(str,l,i); + permute(str, l+1, r); + str = swap(str,l,i); + } + } + } + + /** + * Swap Characters at position + * @param a string value + * @param i position 1 + * @param j position 2 + * @return swapped string + */ + public String swap(String a, int i, int j) + { + char temp; + char[] charArray = a.toCharArray(); + temp = charArray[i] ; + charArray[i] = charArray[j]; + charArray[j] = temp; + return String.valueOf(charArray); + } + + } + diff --git a/src/main/java/com/string/PermutationsOfString.JPG b/src/main/java/com/string/PermutationsOfString.JPG new file mode 100644 index 00000000..185ee00d Binary files /dev/null and b/src/main/java/com/string/PermutationsOfString.JPG differ diff --git a/src/main/java/com/string/RemoveVowelsFromString.java b/src/main/java/com/string/RemoveVowelsFromString.java new file mode 100644 index 00000000..cf8dc687 --- /dev/null +++ b/src/main/java/com/string/RemoveVowelsFromString.java @@ -0,0 +1,26 @@ +package com.string; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +public class RemoveVowelsFromString { + + public static void main(String args[]) { + String input = "hello"; + StringBuilder output = removeVowels(input); + System.out.println(output); + } + + private static StringBuilder removeVowels(String input) { + Set vowelSet = new HashSet<>(Arrays.asList('a', 'e', 'i', 'o', 'u')); + StringBuilder output = new StringBuilder(); + for (Character c : input.toCharArray()) { + if (!vowelSet.contains(c)) { + output.append(c); + } + } + return output; + + } +} diff --git a/src/main/java/com/string/ReverseWordInGivenString.java b/src/main/java/com/string/ReverseWordInGivenString.java new file mode 100644 index 00000000..8532e659 --- /dev/null +++ b/src/main/java/com/string/ReverseWordInGivenString.java @@ -0,0 +1,27 @@ +package com.string; + +import java.util.Stack; + +public class ReverseWordInGivenString { + + public static void main (String args[]){ + String input = "HELLO"; + System.out.println("reverseWord : "+ reverseWord(input)); + } + + private static StringBuilder reverseWord(String input) { + Stack stack = new Stack<>(); + StringBuilder output = new StringBuilder(); + + for(char c : input.toCharArray()){ + stack.push(c); + } + + while(!stack.isEmpty()){ + output.append(stack.pop()); + } + return output; + + } + +} diff --git a/src/main/java/com/string/ReverseWordsInString_WithoutReversingIndividualWords.java b/src/main/java/com/string/ReverseWordsInString_WithoutReversingIndividualWords.java new file mode 100644 index 00000000..18270432 --- /dev/null +++ b/src/main/java/com/string/ReverseWordsInString_WithoutReversingIndividualWords.java @@ -0,0 +1,48 @@ +package com.string; + +import java.util.Stack; + +/** + * Given a String of length S, + * reverse the whole string without reversing the individual words in it. Words are separated by dots. + */ +public class ReverseWordsInString_WithoutReversingIndividualWords { + + public static void main (String args[]){ + String input = "I.love.potato"; + System.out.println("reverseWord : "+ reverseWord(input)); + + System.out.println("reverseWordWithoutStack : " + reverseWordWithoutStack(input)); + } + + private static StringBuilder reverseWord(String input) { + Stack stack = new Stack<>(); + StringBuilder output = new StringBuilder(); + String[] arr = input.split("[.]"); + + for(String s : arr){ + stack.push(s); + } + + while(!stack.isEmpty()){ + output.append(stack.pop()).append("."); + } + return output; + + } + + /** + * Solution without Stack. This is reduce space taken by stack in above solution. + * @param input + * @return + */ + private static StringBuilder reverseWordWithoutStack(String input) { + String s[] = input.split("[.]"); + StringBuilder ans = new StringBuilder(); + for (int i = s.length - 1; i >= 0; i--) { + ans.append(s[i]).append("."); + } + return ans; + } + +} diff --git a/src/main/java/com/string/SingleRowKeyboard.java b/src/main/java/com/string/SingleRowKeyboard.java new file mode 100644 index 00000000..92abb77b --- /dev/null +++ b/src/main/java/com/string/SingleRowKeyboard.java @@ -0,0 +1,44 @@ +package com.string; + +import java.util.HashMap; +import java.util.Map; + +/** + * Problem Statement + * There is a special keyboard with all keys in a single row. + *

+ * You have given a string keyboard of length 26 indicating the layout of the keyboard (indexed from 0 to 25), + * initially your finger is at index 0. To type a character, you have to move your finger to the index of the desired character. + * The time taken to move your finger from index i to index j is |i – j|. + *

+ * You want to type a string word. Write a program to calculate how much time it takes to type it with one finger. + *

+ * Input :- Keyboard = "abcdefghijklmnopqrstuvwxyz", Word = "cba" + * Output :- 4 + * Input :- Keyboard = "pqrstuvwxyzabcdefghijklmno", Word = "hello" + * Output :- 31 + */ + +public class SingleRowKeyboard { + public static void main(String[] args) { + int result = calculateTime("pqrstuvwxyzabcdefghijklmno", "rqp"); + System.out.println(result); + } + + private static int calculateTime(String keyboard, String word) { + Map map = new HashMap<>(); + int pos = 0; + for (char c : keyboard.toCharArray()) { + map.put(c, pos++); + } + + int total = 0; + int current = 0; + for (char c : word.toCharArray()) { + total += Math.abs(current - map.get(c)); + current = map.get(c); + } + return total; + } + +} diff --git a/src/main/java/com/test/TestDefault.java b/src/main/java/com/test/TestDefault.java new file mode 100644 index 00000000..dd1aed66 --- /dev/null +++ b/src/main/java/com/test/TestDefault.java @@ -0,0 +1,12 @@ +package com.test; + +public class TestDefault { + int i; + + + public static void main (String args[]){ + TestDefault td = new TestDefault(); + System.out.println(td.i); + + } +} diff --git a/src/main/java/com/theory/LowLevelDesign.java b/src/main/java/com/theory/LowLevelDesign.java new file mode 100644 index 00000000..09541fd7 --- /dev/null +++ b/src/main/java/com/theory/LowLevelDesign.java @@ -0,0 +1,79 @@ +package com.theory; +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.MessageListener; +import javax.jms.TextMessage; + +/** + * This design uses Strategy Pattern + * + * Strategy pattern and the open closed principle + * According to the strategy pattern, the behaviour of a class should be encapsulated + * using interfaces and should not be inherited. + * This is compatible with the open closed principle, + */ + +public class LowLevelDesign { + + MessageProcessor processor; + + class MessageConsumer implements MessageListener{ + + @JMSListener + public void onMessage(Message message){ + if (message instanceof TextMessage){ + processor = new MessageProcessor(); + MessageParser mp = new swiftParser(); + processor.setParser(mp); + processor.process(message); + } + if (message instanceof BytesMessage){ + + } + + + } + + } + + class MessageProcessor { + + MessageParser parser; + + public void setParser(MessageParser p){ + this.parser = p; + } + + public void process(Message message){ + parser.parse(message); + } + + } + + interface MessageParser{ + void parse(Message message); + } + + class SwiftParser implements MessageParser{ + + @Override + public void parse(Message message) { + + } + } + class JsonParser implements MessageParser{ + + @Override + public void parse(Message message) { + + } + } + class XMLParser implements MessageParser{ + + @Override + public void parse(Message message) { + + } + } + +} diff --git a/src/main/java/com/theory/Remember.adoc b/src/main/java/com/theory/Remember.adoc new file mode 100644 index 00000000..22ca56ed --- /dev/null +++ b/src/main/java/com/theory/Remember.adoc @@ -0,0 +1,3 @@ +1. Sorting takes at least O(nlogn) time. +2. We can use a HashSet to add and remove elements. The add, remove and contains methods have constant time complexity O(1). +3. \ No newline at end of file diff --git a/src/main/java/com/theory/StrategyPattern.png b/src/main/java/com/theory/StrategyPattern.png new file mode 100644 index 00000000..ce62922d Binary files /dev/null and b/src/main/java/com/theory/StrategyPattern.png differ diff --git a/src/main/java/com/theory/UsefulLinks b/src/main/java/com/theory/UsefulLinks new file mode 100644 index 00000000..6eeb7555 --- /dev/null +++ b/src/main/java/com/theory/UsefulLinks @@ -0,0 +1,19 @@ +https://cheatsheet.dennyzhang.com/cheatsheet-leetcode-A4 +https://github.com/kdn251/interviews#data-structures +https://www.interviewcake.com/data-structures-reference +https://gist.github.com/TSiege/cbb0507082bb18ff7e4b +https://www.programcreek.com/2012/11/top-10-algorithms-for-coding-interview/ - short and easy to understand programs + +Tree Traversal +https://medium.com/@ajinkyajawale/inorder-preorder-postorder-traversal-of-binary-tree-58326119d8da +All Interview Questions on Tree +https://medium.com/@codingfreak/binary-tree-interview-questions-and-practice-problems-439df7e5ea1f + +GitHub +https://github.com/kdn251/interviews +https://github.com/mission-peace/interview/wiki/String - Tushar Roy +https://github.com/varunu28/InterviewBit-Java-Solutions +https://github.com/dennyzhang/code.dennyzhang.com/tree/master/problems +https://github.com/yc-gh/GeeksForGeeks + + diff --git a/src/main/java/com/theory/Useful_Java_API.md b/src/main/java/com/theory/Useful_Java_API.md new file mode 100644 index 00000000..f12dab7b --- /dev/null +++ b/src/main/java/com/theory/Useful_Java_API.md @@ -0,0 +1,15 @@ +# 1. String/Array +1. toCharArray() //get char array of a String +2. charAt(int x) //get a char at the specific index +3. length() //string length +4. length //array size +5. substring(int beginIndex) +6. substring(int beginIndex, int endIndex) +7. Integer.valueOf()//string to integer +8. String.valueOf()/integer to string +9. Arrays.sort() //sort an array +10. Arrays.toString(char[] a) //convert to string +11. Arrays.copyOf(T[] original, int newLength) +12. System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length) +13. maxHeap = new PriorityQueue<>(Comparator.reverseOrder()); //in descending order +14. minHeap = new PriorityQueue<>(); // natural ascending order \ No newline at end of file diff --git a/src/main/java/com/theory/design.adoc b/src/main/java/com/theory/design.adoc new file mode 100644 index 00000000..30dbcf49 --- /dev/null +++ b/src/main/java/com/theory/design.adoc @@ -0,0 +1,7 @@ +image::../../../images/uml.png[] +image::../../../images/class.png[] +image::../../../images/classdia.png[] +image::../../../images/solidPrinciple.png[] +image::softwareArchitecture.png[] +image::StrategyPattern.png[] + diff --git a/src/main/java/com/theory/design.html b/src/main/java/com/theory/design.html new file mode 100644 index 00000000..cf8d7a64 --- /dev/null +++ b/src/main/java/com/theory/design.html @@ -0,0 +1,480 @@ + + + + + + + +Untitled + + + + +

+
+
+
+uml +
+
+
+
+class +
+
+
+
+classdia +
+
+
+
+solidPrinciple +
+
+
+
+softwareArchitecture +
+
+
+
+StrategyPattern +
+
+
+ + + \ No newline at end of file diff --git a/src/main/java/com/theory/softwareArchitecture.png b/src/main/java/com/theory/softwareArchitecture.png new file mode 100644 index 00000000..d70c77d8 Binary files /dev/null and b/src/main/java/com/theory/softwareArchitecture.png differ diff --git a/src/main/java/com/theory/spring/Spring.adoc b/src/main/java/com/theory/spring/Spring.adoc new file mode 100644 index 00000000..e38ae52a --- /dev/null +++ b/src/main/java/com/theory/spring/Spring.adoc @@ -0,0 +1,22 @@ += Spring + +1. Spring Annotations + +image::../../../../images/spring_annotations.png[] +image::../../../../images/spring_annotations_1.png[] + +https://www.jrebel.com/blog/spring-annotations-cheat-sheet[] + +2. Spring Beans + +image::../../../../images/spring_beans.png[] + +3. Spring Boot – Actuator + +Monitoring our app, gathering metrics, understanding traffic or the state of our database becomes trivial with this dependency. + +Actuator is mainly used to expose operational information about the running application – health, metrics, info, dump, env, etc. It uses HTTP endpoints or JMX beans to enable us to interact with it. + +1.1. Actuator Maven Dependency + +image::../../../../images/spring_actuator.png[] \ No newline at end of file diff --git a/src/main/java/com/theory/spring/Spring_1.html b/src/main/java/com/theory/spring/Spring_1.html new file mode 100644 index 00000000..59036a63 --- /dev/null +++ b/src/main/java/com/theory/spring/Spring_1.html @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + +Spring Annotations Cheat Sheet | Rebel + + + + + +
spring framework annotations cheat sheet
+October 26, 2016 +

Spring Annotations Cheat Sheet

Java Frameworks
Developer Productivity

In our post today, we're talking about Spring Framework Annotations. We've gathered up all the commonly-used and useful annotations developers will use and packed them into a one-page Spring annotations cheat sheet. It covers everything from the basic annotations you need to get your project started, to service discovery annotations.

Important Spring Annotations

Spring uses dependency injection to configure and to bring your application together. It means that you just declare the components of your system and how they interact. Then Spring wires it all together at runtime. Here are the most important annotations you should know of.

  • @Configuration - annotation is used to mark a class as a source of the bean definitions. Beans are the components of the system that you want to wire together. A method marked with the @Bean annotation is a bean producer. Spring will handle the life cycle of the beans for you, and it will use these methods to create the beans.
  • @ComponentScan - use to make sure that Spring knows about your configuration classes and can initialize the beans correctly. It makes Spring scan the packages configured with it for the @Configuration classes.
  • @Import -  If you need even more precise control of the configuration classes, you can always use @import  to load additional configuration. This one works even when you specify the beans in an XML file like it's 1999.
  • @Component - Another way to declare a bean is to mark a class with a @Component annotation. Doing this turns the class into a Spring bean at the auto-scan time.
  • @Service - Mark a specialization of a @Component. It tells Spring that it's safe to manage them with more freedom than regular components. Remember, services have no encapsulated state.
  • @Autowired - To wire the application parts together, use the @Autowired on the fields, constructors, or methods in a component. Spring's dependency injection mechanism wires appropriate beans into the class members marked with @Autowired.

More Complex Spring Annotations

Now it's time to go a bit deeper. The bean initialization is eager by default. Spring will try to initialize all the beans and wire them all together. You can mark a @Bean or @Component with @Lazy to have them be initialized on demand. It can save some startup time!

If you have multiple beans that can be wired into the field marked with @Autowired, use @Qualifier to filter which beans should be used there.

Another useful annotation is @Value. This one indicates a default value expression for the field or parameter to initialize the property with. Typically something like the following expression, referencing a configuration property will be used there: "#{systemProperties.myProp}".

And to make the system more robust, you can enable the verification to make Spring fail when a bean to autowire is not found. Use @Required to fail the wiring if the dependency cannot be injected.

  • @Lazy - Initialize bean on demand
  • @Value - indicate default value expression for field or parameter
  • @Required - Fail wiring if dependency can't be injected

Armed with these annotations you can make the application come together with a very little effort. Naturally, there are more Spring annotations that you might want to use, but these here are the core of the framework that enables the flexibility Spring is known for!

Important Spring Boot Annotations

Let's look at some of the most frequently used annotations in the context of web apps. Most of our readers are either backend engineers or are doing full stack developer jobs. So it makes sense to popularize the Spring Framework annotations that make web development easier.

@SpringBootApplicaiton

First one of the most basic, super helpful annotations, our all time favorite @SpringBootApplication. There's nothing magical about it. It's syntactic sugar for combining other annotations that we'll look at in just a moment. @SpringBootApplication is @Configuration, @EnableAutoConfiguration and @ComponentScan annotations combined, configured with their default attributes.

@Configuration and @ComponentScan

The @Configuration and @ComponentScan annotations that we described above make Spring create and configure the beans and components of your application. It's a great way to decouple the actual business logic code from wiring the app together.

@EnableAutoConfiguration

Now the @EnableAutoConfiguration annotation is even better. It makes Spring guess the configuration based on the JAR files available on the classpath. It can figure out what libraries you use and preconfigure their components without you lifting a finger. It is how all the spring-boot-starter libraries work. Meaning it's a major lifesaver both when you're just starting to work with a library as well as when you know and trust the default config to be reasonable.

 

Important Spring Boot Web Annotations

The following annotations make Spring configure your app to be a web application, capable of serving the HTTP response.

@Controller

@Controller marks the class as a web controller, capable of handling the HTTP requests. Spring will look at the methods of the class marked with the @Controller annotation and establish the routing table to know which methods serve which endpoints.

@ResponseBody

The @ResponseBody is a utility annotation that makes Spring bind a method's return value to the HTTP response body. When building a JSON endpoint, this is an amazing way to magically convert your objects into JSON for easier consumption.

@RestController

Then there's the @RestController annotation -- a convenience syntax for @Controller and @ResponseBody together. This means that all the action methods in the marked class will return the JSON response.

@RequestMapping(method = RequestMethod.GET, value = "/path")

The @RequestMapping(method = RequestMethod.GET, value = "/path") annotation specifies a method in the controller that should be responsible for serving the HTTP request to the given path. Spring will work the implementation details of how it's done. You simply specify the path value on the annotation and Spring will route the requests into the correct action methods.

@RequestParam(value="name", defaultValue="World")

Naturally, the methods handling the requests might take parameters. To help you with binding the HTTP parameters into the action method arguments, you can use the @RequestParam(value="name", defaultValue="World") annotation. Spring will parse the request parameters and put the appropriate ones into your method arguments.

@PathVariable("placeholderName")

Another common way to provide information to the backend is to encode it in the URL. Then you can use the @PathVariable("placeholderName") annotation to bring the values from the URL to the method arguments.

Most Useful Spring Cloud Annotations

Now you have a fully functioning web app that is both neat on the code level as well as separated into beans and service classes. The app is declaratively configuring background jobs and gets constructed and configured at runtime without extra uproar.

If you're in the mood to build a larger system of such web apps, you'll need to work more on the organizational problems. These include issues like how to configure these multiple apps, how to make them communicate with each other, and how to make sure that network failures will not crash the whole system.

The Spring Cloud project tries to precisely answer these questions and help you take your apps to the cloud.

@EnableConfigServer

@EnableConfigServer turns your application into a server other apps can get their configuration from. You need a configuration server to have a central repository of all the appropriate configurations. The good thing is that creating one is just an annotation away.

Now when you have the central configuration server available, you can use the spring.application.cloud.config.uri property in the client Spring apps to point them to the configuration server. When these apps start, they will reach out to the configuration server and obtain the necessary properties. You don't have to package your configuration together with the app code. This separation of concerns works wonders to simplify your deployments.


Spring Discovery Service Annotations

The next bit we want to cover is even cooler. Imagine a situation when you have many small services that are context bounded, excel at one thing and put together, form a complex system that brings your real business value. How do you wire the services together? You cannot go with hardcoding the URLs in code or even the configuration -- it just won't scale. What you need is a discovery service.

You probably know where I'm going. You can get yourself a fully functioning Eureka service discovery server just by using a single annotation.

@EnableEurekaServer

Just by adding the @EnableEurekaServer annotation to your brand new Spring Boot app, you make it an Eureka discovery service. Now other apps can locate services through it. To take advantage of this wonderful topology, you need to instruct the apps that they should become clients for this Eureka server.

@EnableDiscoveryClient

Luckily for you, there is a @EnableDiscoveryClient annotation. This makes your app register in the service discovery server and then consult with it to discover the other services you need. When all the apps use the discovery client, you don't need to hardcode any IP addresses or URLs. You can always say: please Eureka, give me a location of the service by a given name.

@EnableCircuitBreaker

Now with all this fancy distributed system going around, you cannot expect things never to break down. Network can and will fail on you. You need a way to mitigate the damage, and still serve something meaningful back to your clients. So, how can developers ensure resiliency in applications? Resilience patterns.

In this instance, you need a resilience pattern called the circuit breaker pattern. When things go south, you'll have a way to specify the fallback methods for retrieving data from another service or to respond with reasonable defaults. To make your app aware of the circuit breaker patterns, add the @EnableCircuitBreaker annotation. This will configure Hystrix circuit breaker protocols for your application.

And then mark the important methods with the @HystrixCommand(fallbackMethod = "fallbackMethodName") annotations. This says that in the case of an emergency when the method throws exceptions or times out, your app should make use of the fallback method. When things are going well, and everything works, this approach will help keep your code neat and maintainable.

Final Thoughts

In this post, we've looked at many annotations that a Java developer should know if they want to use the Spring Framework. We've covered the most frequently used and perhaps the most important annotations -- those that enable dependency injection for your components, the ways to bind your code to respond to HTTP requests, and how to enable the correct patterns for cloud-based applications and microservices architectures.

Download the Spring Annotations Cheat Sheet

Ready to download our one-page Spring Annotations cheat sheet pdf? Click the button below to get started!

Spring Annotations Cheat Sheet

Get the Cheat Sheet

Additional Resources

If you're looking for additional Java cheat sheets, be sure to check out our Java cheat sheet collection. It's packed full of cheat sheets and shortcuts for popular Java technologies.

Want to see how many developers are using Spring framework in 2020? Check out our latest Java Productivity Report! It shows the most-used frameworks, IDEs, and application servers -- all via our 2020 Java developer survey.

Get the Report

X
+ + \ No newline at end of file diff --git a/src/main/java/com/tree/BFSorLevelOrderTraversalOfBinaryTree.java b/src/main/java/com/tree/BFSorLevelOrderTraversalOfBinaryTree.java new file mode 100644 index 00000000..1ae0642c --- /dev/null +++ b/src/main/java/com/tree/BFSorLevelOrderTraversalOfBinaryTree.java @@ -0,0 +1,57 @@ +package com.tree; + +import com.tree.model.TreeNode; + +import java.util.LinkedList; +import java.util.Queue; + +/** + * printLevelorder(tree) + * 1) Create an empty queue q + * 2) temp_node = root /*start from root + * 3)Loop while temp_node is not NULL + *a)print temp_node->data. + *b)Enqueue temp_node’s children(first left then right children)to q + *c)Dequeue a node from q and assign it’s value to temp_node + */ +public class BFSorLevelOrderTraversalOfBinaryTree { + + public static void main(String[] args) { + /* + Binary Tree + + 1 + / \ + 2 3 + / \ + 4 5 + */ + TreeNode tree = new TreeNode(1); + tree.left = new TreeNode(2); + tree.right = new TreeNode(3); + tree.left.left = new TreeNode(4); + tree.left.right = new TreeNode(5); + + bfsOrlevelOrderTraversal(tree); + + } + + private static void bfsOrlevelOrderTraversal(TreeNode tree) { + + if (tree == null) { + return; + } + Queue queue = new LinkedList(); + queue.offer(tree); + while (!queue.isEmpty()) { + TreeNode node = queue.poll(); + System.out.println(node.val); + if (node.left != null) { + queue.offer(node.left); + } + if (node.right != null) { + queue.offer(node.right); + } + } + } +} diff --git a/src/main/java/com/tree/BinaryTreeZigZagLevelOrderTraversal.html b/src/main/java/com/tree/BinaryTreeZigZagLevelOrderTraversal.html new file mode 100644 index 00000000..204fa9cc --- /dev/null +++ b/src/main/java/com/tree/BinaryTreeZigZagLevelOrderTraversal.html @@ -0,0 +1,2163 @@ + + + + + + + + + + +Zig Zag Traversal of Binary Tree. | JavaByPatel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+
+
+ +
+
+
+ + +
+ +
+
+
+
+
+
+ +
+ + +
+ + +
+ +
+
+

+Zig Zag Traversal of Binary Tree. +

+ +
+
+
+
+
+
+
+ + + + + + +
+
+
+
+

+Level order traversal in spiral form OR
Printing a Binary Tree in Zig Zag Level-Order OR
Print a binary tree in Zig Zag way.

+
+Given a binary tree, write a program to print nodes of the tree in spiral order. You can also say it as Spiral order traversal of a tree. +Let us first understand what we want to achieve? what is the input and what will be the expected output?
+
+
+  +
+See below image for better understanding the problem statement.
+
+
+
+
+Note:
+If you observe Zig Zag Traversing is very similar to Level order traversal with few modification.
+So first let's understand how to travel a Binary Tree in Level Order. +Level order traversal of Tree shown in Case 1 is  20  4  10  8  5.
+Level order traversal of Tree shown in Case 2 is  20  4  10  8  5  2  1.
+
+For more details on Level order traversal, Please refer : Level order traversal
+
+

+Algorithm
+

+
+1.  Take 2 Stack, one for current level and one for next level.
+2.  For filling the next Level stack, we have to see whether it need to be filled Left to Right or Right
+     to left as we are reading the Level Order spirally.
+3.  When we are reading current level stack, all the children's of current level stack will go to next 
+     level stack.
+4.  When current level stack has no value and is Empty at that time point current level stack
+     reference to hold next level stack values, that is current level stack will now point to next level
+     stack and next level stack should be reinitialize for its next level.
+     Also, this is the time when we need to alter our reading style for childrens that is it need to be
+     read in left - right fashion.
+
+Lets take a example and see, +
+
+
+
+

+Java Program for reading a Binary Tree in Spiral way.

+
+
class Node{
+ private int data;
+ private Node left;
+ private Node right;
+
+ public Node(int data) {
+  this.data=data;
+ }
+
+ public int getData() {
+  return data;
+ }
+ public void setData(int data) {
+  this.data = data;
+ }
+ public Node getLeft() {
+  return left;
+ }
+ public void setLeft(Node left) {
+  this.left = left;
+ }
+ public Node getRight() {
+  return right;
+ }
+ public void setRight(Node right) {
+  this.right = right;
+ }
+} 
+ZigZagTreeTraversal.java +
+
package tree;
+
+import java.util.LinkedList;
+import java.util.Queue;
+import java.util.Stack;
+
+public class ZigZagTreeTraversal {
+ private Node rootNode;
+
+ public static void main(String[] args) {
+  new ZigZagTreeTraversal();
+ }
+
+ public ZigZagTreeTraversal(){
+
+  addNode(rootNode, 1); 
+  addNode(rootNode, 2); 
+  addNode(rootNode, 3); 
+  addNode(rootNode, 4); 
+  addNode(rootNode, 5); 
+  addNode(rootNode, 6); 
+  addNode(rootNode, 7);
+  addNode(rootNode, 8);
+  addNode(rootNode, 9);
+  addNode(rootNode, 10);
+  addNode(rootNode, 11);
+
+  zigZagTraverse(rootNode);  
+ }
+
+ private void zigZagTraverse(Node rootNode) {
+  if(rootNode==null){
+   return;
+  }
+  Stack<Node> currentLevelStack = new Stack<Node>();
+  Stack<Node> nextLevelStack = new Stack<Node>();
+  
+  boolean isLeftRightReading = true;
+  currentLevelStack.add(rootNode);
+  
+  while(!currentLevelStack.isEmpty()){
+   Node n = currentLevelStack.pop();
+   System.out.print(n.getData() + " ");
+
+   if(isLeftRightReading){
+  
+    if(n.getLeft()!=null)
+     nextLevelStack.push(n.getLeft());
+
+    if(n.getRight()!=null)
+     nextLevelStack.push(n.getRight());
+
+   }else{
+    if(n.getRight()!=null)
+     nextLevelStack.push(n.getRight());
+
+    if(n.getLeft()!=null)
+     nextLevelStack.push(n.getLeft());
+
+   }
+
+   if(currentLevelStack.isEmpty()){
+    isLeftRightReading = !isLeftRightReading;
+    currentLevelStack=nextLevelStack;
+    nextLevelStack = new Stack<Node>();
+   }
+
+  }
+ }
+ 
+ 
+ private void addNode(Node rootNode, int data){
+
+  //First check is there any Nodes present.
+  if(rootNode==null){
+   // No Nodes are Present, create one and assign it to startNode
+   Node temp1=new Node(data);
+   this.rootNode=temp1;
+  }else{
+   //Nodes present, So check the proper position where to add New Node.
+
+   //Checking whether Left child and Right child are present for root Node. 
+   if(rootNode.getLeft()!=null && rootNode.getRight()!=null){
+    //Left and Right Child exist, Also, we need to add new Node in Sequential Fashion of Left and Right, 
+    //We have to scan all Levels one by one to check a proper place for new Node.
+    //Also, we for each and every node we need to check whether Left and Right Exist, 
+    //So we need to store them for later Processing that is why we introduced Queue.
+
+    Queue<Node> queue = new LinkedList<Node>();
+    queue.add(rootNode);
+
+    while(!queue.isEmpty()){
+     Node obj = (Node)queue.poll();
+     if(obj.getLeft()!=null && obj.getRight()!=null){
+      queue.add(obj.getLeft());
+      queue.add(obj.getRight());
+     }else if(obj.getLeft()==null){
+      Node temp1=new Node(data);
+      obj.setLeft(temp1);
+      break;
+     }else{
+      Node temp1=new Node(data);
+      obj.setRight(temp1);
+      break;
+     }
+    }
+
+   }else{
+    // We reach this condition when either Left or Right is Null, but not sure which side is Null.
+    if(rootNode.getLeft()==null){
+     Node temp1=new Node(data);
+     rootNode.setLeft(temp1);
+    }else{
+     Node temp1=new Node(data);
+     rootNode.setRight(temp1);
+    }
+   }
+  }
+ }
+ 
+}
+
+

+Reading a Binary Tree in Zig Zag way from Bottom to up.

+
+What do I mean by reading a binary tree in reverse Zig Zag way is,
+
+
+
+
+So how to read in reversed zig zag fashion?
+We just saw how to read in Zig Zag fashion from Top to bottom,
+instead of printing the result every time, if we collect it in some variable say zigZagTreeReadOutput,
+then what we get for above tree is,
+String zigZagTreeReadOutput = "20,10,4,8,5,2,1"
+
+Now, for finding the reversed ZigZag traversal of same tree,
we can simply reverse the result of Top down Zig Zag traversal record.

+So we will get, 1,2,5,8,4,10,20

+
+

+You may also like to see +

+
+

+Advanced Multithreading Interview Question-Answer

+

+Traverse a Binary Tree in Level Order Traversal

+

+Serialize and Deserialize a Binary Tree

+

+Find diameter of Binary Tree

+

+How Much Water Can a Bar Graph with different heights can Hold

+

+Interview Question-Answer on Java

+
+Enjoy !!!! 
+
+
+If you find any issue in post or face any error while implementing, Please comment.
+
+
+ +
+
+
+ + + + +
+
+
+ +
+ +
+ +
+
+
+
+
+
+

Post a Comment

+
+ +

+

+ + + + + +
+
+
+ + + +
+ +
+ + +
+
+ +Newer Post + + +Older Post + +Home +
+
+
+
+
+ + +
+ +
+
+ + + + +
+ + + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/tree/BinaryTreeZigZagLevelOrderTraversal.java b/src/main/java/com/tree/BinaryTreeZigZagLevelOrderTraversal.java new file mode 100644 index 00000000..29b5aa3c --- /dev/null +++ b/src/main/java/com/tree/BinaryTreeZigZagLevelOrderTraversal.java @@ -0,0 +1,117 @@ +package com.tree; + +import com.tree.model.TreeNode; + +import java.util.*; + +/** + * Description: + * Given a binary tree, return the zigzag level order traversal of its TreeNodes' values. (ie, from left to right, then + * right to left for the next level and alternate between). + * + * For example: + * Given binary tree [3,9,20,null,null,15,7], + * 3 + * / \ + * 9 20 + * / \ + * 15 7 + * return its zigzag level order traversal as: + * [ + * [3], + * [20,9], + * [15,7] + * ] + * + * Algorithm + * 1. Take 2 Stack, one for current level and one for next level. + * + * + * 2. For filling the next Level stack, we have to see whether it need to be filled Left to Right or Right + * to left as we are reading the Level Order spirally. + * 3. When we are reading current level stack, all the children's of current level stack will go to next + * level stack. + * 4. When current level stack has no value and is Empty at that time point current level stack + * reference to hold next level stack values, that is current level stack will now point to next level + * stack and next level stack should be reinitialize for its next level. + * Also, this is the time when we need to alter our reading style for childrens that is it need to be + * read in left - right fashion. + * + */ + +public class BinaryTreeZigZagLevelOrderTraversal { + + /** + * Time Complexity: + * Space Complexity: + * Runtime: 1 ms. + * + * @param rootTreeNode + * @return + */ + public static void zigZagTraverse(TreeNode rootTreeNode) { + + // Base case + if(rootTreeNode==null){ + return; + } + + Stack currentLevelStack = new Stack(); + Stack nextLevelStack = new Stack(); + + boolean isLeftRightReading = true; + currentLevelStack.add(rootTreeNode); + + while(!currentLevelStack.isEmpty()){ + TreeNode n = currentLevelStack.pop(); + System.out.print(n.val+ " "); + + if(isLeftRightReading){ + + if(n.left!=null) + nextLevelStack.push(n.left); + + if(n.right!=null) + nextLevelStack.push(n.right); + + }else{ + if(n.right!=null) + nextLevelStack.push(n.right); + + if(n.left!=null) + nextLevelStack.push(n.left); + + } + + if(currentLevelStack.isEmpty()){ + isLeftRightReading = !isLeftRightReading; + currentLevelStack=nextLevelStack; + nextLevelStack = new Stack(); + } + + } + } + + + public static void main(String[] args) { + /* + Binary Tree + + 1 + / \ + 2 3 + / \ + 4 5 + */ + TreeNode tree = new TreeNode(1); + tree.left = new TreeNode(2); + tree.right = new TreeNode(3); + tree.left.left = new TreeNode(4); + tree.left.right = new TreeNode(5); + + zigZagTraverse(tree); + + } +} + + diff --git a/src/main/java/com/tree/CheckBinaryTreeIsBST.java b/src/main/java/com/tree/CheckBinaryTreeIsBST.java new file mode 100644 index 00000000..81afa10b --- /dev/null +++ b/src/main/java/com/tree/CheckBinaryTreeIsBST.java @@ -0,0 +1,53 @@ +package com.tree; + +import com.tree.model.TreeNode; + +public class CheckBinaryTreeIsBST { + + public static void main(String args[]) { + + /* + Binary Tree + + 1 + / \ + 2 3 + / \ + 4 5 + */ + TreeNode tree = new TreeNode(10); + tree.left = new TreeNode(8); + tree.right = new TreeNode(30); + tree.left.left = new TreeNode(6); + tree.left.right = new TreeNode(9); + tree.right.left = new TreeNode(15); + tree.right.right = new TreeNode(35); + tree.left.left.left = new TreeNode(4); + + + int min = Integer.MIN_VALUE; + int max = Integer.MAX_VALUE; + + System.out.println("Is Binary Search Tree:" + isBST(tree,min,max)); + } + + /**Returns true if the given tree is a BST and its + values are >= min and <= max. */ + private static boolean isBST(TreeNode node, int min, int max) { + + /* an empty tree is BST */ + if (node == null) + return true; + + /**important*/ + /** false if this node violates the min/max constraints */ + if(node.val < min || node.val >max){ + return false; + } + + /** otherwise check the subtrees recursively + tightening the min/max constraints */ + // Allow only distinct values + return isBST(node.left,min,node.val-1) && isBST(node.right, node.val+1, max); + } +} diff --git a/src/main/java/com/tree/DFSInorderTraversalOfTree.java b/src/main/java/com/tree/DFSInorderTraversalOfTree.java new file mode 100644 index 00000000..6c0dcbeb --- /dev/null +++ b/src/main/java/com/tree/DFSInorderTraversalOfTree.java @@ -0,0 +1,81 @@ +package com.tree; + + +import com.tree.model.TreeNode; + +import java.util.Stack; + +/** + * LEFT *ROOT* RIGHT + * + * It's worth remembering that the inOrder traversal is a depth-first algorithm and + * prints the tree node in sorted order if given binary tree is a binary search tree. + * + * Visit left node + * Print value of the root + * Visit right node + * + */ +public class DFSInorderTraversalOfTree { + + public static void main (String args[]){ + TreeNode root= create(); + inOrderTraversal(root); + inorderStack(root); + } + + /** + * Recurssive Approach + * @param root + */ + private static void inOrderTraversal(TreeNode root) { + if (root == null){ + return; + } + inOrderTraversal(root.left); + System.out.print(root.val + " "); + inOrderTraversal(root.right); + } + + /**Iterative Approach*/ + public static void inorderStack(TreeNode root) + { + Stack s =new Stack(); + while(true){ + + // Go to the left extreme insert all the elements to stack + while(root != null){ + s.push(root); + root = root.left; + } + // check if Stack is empty, if yes, exit from everywhere + if (s.isEmpty()) { + return; + } + // pop the element from the stack , print it and add the nodes at + // the right to the Stack + root =s.pop(); + System.out.print(root.val + " "); + root = root.right; + } + } + + + /** + * Java method to create binary tree with test data + * + * @return a sample binary tree for testing + */ + public static TreeNode create() { + TreeNode root = new TreeNode(40); + root.left = new TreeNode(20); + root.left.left = new TreeNode(10); + root.left.left.left = new TreeNode(5); + root.left.right = new TreeNode(30); + root.right = new TreeNode(50); + root.right.right = new TreeNode(60); + root.left.right.left = new TreeNode(67); + root.left.right.right = new TreeNode(78); + return root; + } +} diff --git a/src/main/java/com/tree/DFSPreOrderTraversalOfBinaryTree.java b/src/main/java/com/tree/DFSPreOrderTraversalOfBinaryTree.java new file mode 100644 index 00000000..ae273e9f --- /dev/null +++ b/src/main/java/com/tree/DFSPreOrderTraversalOfBinaryTree.java @@ -0,0 +1,71 @@ +package com.tree; + +import com.tree.model.TreeNode; + +import java.util.Stack; + +/** + * *ROOT* LEFT RIGHT + */ +public class DFSPreOrderTraversalOfBinaryTree { + + /** + * Recurssive Approach + * + * @param root + */ + private static void preOrderTraversal(TreeNode root) { + if (root == null) { + return; + } + System.out.print(root.val + " "); + preOrderTraversal(root.left); + preOrderTraversal(root.right); + } + + /** + * Iterative Approach + */ + public static void preOrderStack(TreeNode root) { + Stack s = new Stack(); + while (true) { + // First print the root node and then add left node + while (root != null) { + System.out.print(root.val + " "); + s.push(root); + root = root.left; + } + // check if Stack is emtpy, if yes, exit from everywhere + if (s.isEmpty()) { + return; + } + // pop the element from the stack and go right to the tree + root = s.pop(); + root = root.right; + } + } + + + /** + * Java method to create binary tree with test data + * + * @return a sample binary tree for testing + */ + public static TreeNode create() { + TreeNode root = new TreeNode(40); + root.left = new TreeNode(20); + root.left.left = new TreeNode(10); + root.left.left.left = new TreeNode(5); + root.left.right = new TreeNode(30); + root.right = new TreeNode(50); + root.right.right = new TreeNode(60); + root.left.right.left = new TreeNode(67); + root.left.right.right = new TreeNode(78); + return root; + } + + public static void main(String args[]) { + TreeNode root = create(); + preOrderStack(root); + } +} diff --git a/src/main/java/com/tree/IncreasingOrderSearchTree.java b/src/main/java/com/tree/IncreasingOrderSearchTree.java new file mode 100644 index 00000000..9baf8bb9 --- /dev/null +++ b/src/main/java/com/tree/IncreasingOrderSearchTree.java @@ -0,0 +1,95 @@ +package com.tree; + +import com.tree.model.TreeNode; + +import java.awt.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Given a binary search tree, rearrange the tree in in-order so that the leftmost node in the tree + * is now the root of the tree, and every node has no left child and only 1 right child. + * Example 1: + * Input: [5,3,6,2,4,null,8,1,null,null,null,7,9] + * + * 5 + * / \ + * 3 6 + * / \ \ + * 2 4 8 + * / / \ + * 1 7 9 + * + * Output: [1,null,2,null,3,null,4,null,5,null,6,null,7,null,8,null,9] + * + * 1 + * \ + * 2 + * \ + * 3 + * \ + * 4 + * \ + * 5 + * \ + * 6 + * \ + * 7 + * \ + * 8 + * \ + * 9 + * + * he definition of a binary search tree is that for every node, + * all the values of the left branch are less than the value at the root, + * and all the values of the right branch are greater than the value at the root. + * + * Because of this, an in-order traversal of the nodes will yield all the values in increasing order. + * + * Algorithm + * + * Once we have traversed all the nodes in increasing order, + * we can construct new nodes using those values to form the answer. + * + * Complexity Analysis + * + * Time Complexity: O(N), where N is the number of nodes in the given tree. + * + * Space Complexity: O(N), the size of the answer. + * + */ +public class IncreasingOrderSearchTree { + public static void main (String args[]){ + TreeNode node = new TreeNode(0); + increasingOrderSearchTree(node); + } + + + public static TreeNode increasingOrderSearchTree(TreeNode node){ + Listvalues = new ArrayList<>(); + + /**important */ + inOrderTraversal(node, values);//values contains all the elements in increasing order. + TreeNode ans = new TreeNode(0); + TreeNode current = ans; + + /**important */ + for(int val : values){ + current.right = new TreeNode(val); + current = current.right; + } + + return current.right; + + } + + public static void inOrderTraversal(TreeNode node, List values){ + if(node == null){ + return; + } + inOrderTraversal(node.left,values); + values.add(node.val); + inOrderTraversal(node.right,values); + } +} diff --git a/src/main/java/com/tree/LargestBSTInBinaryTree.java b/src/main/java/com/tree/LargestBSTInBinaryTree.java new file mode 100644 index 00000000..c721c1b3 --- /dev/null +++ b/src/main/java/com/tree/LargestBSTInBinaryTree.java @@ -0,0 +1,109 @@ +package com.tree; + + +import com.tree.model.TreeNode; + +/** + * Date 07/20/2014 + * @author tusroy + * + * Video link - https://youtu.be/4fiDs7CCxkc + * + * Given a binary tree, find size of largest binary search subtree in this + * binary tree. + * + * Traverse tree in post order fashion. Left and right nodes return 4 piece + * of information to root which isBST, size of max BST, min and max in those + * subtree. + * If both left and right subtree are BST and this node data is greater than max + * of left and less than min of right then it returns to above level left size + + * right size + 1 and new min will be min of left side and new max will be max of + * right side. + * + * Time Complexity is O(n) + * O(n) where n is the number of nodes in the given Binary Tree. + * * + * References: + * http://www.geeksforgeeks.org/find-the-largest-subtree-in-a-tree-that-is-also-a-bst/ + * https://leetcode.com/problems/largest-bst-subtree/ + */ +public class LargestBSTInBinaryTree { + + public int largestBST(TreeNode root){ + MinMax m = largest(root); + return m.size; + } + + private MinMax largest(TreeNode root){ + //if root is null return min as Integer.MAX and max as Integer.MIN + if(root == null){ + return new MinMax(); + } + + //postorder traversal of tree. First visit left and right then + //use information of left and right to calculate largest BST. + MinMax leftMinMax = largest(root.left); + MinMax rightMinMax =largest(root.right); + + MinMax m = new MinMax(); + + //if either of left or right subtree says its not BST or the data + //of this node is not greater/equal than max of left and less than min of right + //then subtree with this node as root will not be BST. + //Return false and max size of left and right subtree to parent + if(leftMinMax.isBST == false || rightMinMax.isBST == false || (leftMinMax.max > root.val || rightMinMax.min <= root.val)){ + m.isBST = false; + m.size = Math.max(leftMinMax.size, rightMinMax.size); + return m; + } + + //if we reach this point means subtree with this node as root is BST. + //Set isBST as true. Then set size as size of left + size of right + 1. + //Set min and max to be returned to parent. + m.isBST = true; + m.size = leftMinMax.size + rightMinMax.size + 1; + + //if root.left is null then set root.val as min else + //take min of left side as min + m.min = root.left != null ? leftMinMax.min : root.val; + + //if root.right is null then set root.val as max else + //take max of right side as max. + m.max = root.right != null ? rightMinMax.max : root.val; + + return m; + } + + public static void main(String args[]){ + LargestBSTInBinaryTree lbi = new LargestBSTInBinaryTree(); + TreeNode tree = new TreeNode(10); + tree.left = new TreeNode(8); + tree.right = new TreeNode(30); + tree.left.left = new TreeNode(6); + tree.left.right = new TreeNode(9); + tree.right.left = new TreeNode(15); + tree.right.right = new TreeNode(35); + tree.left.left.left = new TreeNode(4); + int largestBSTSize = lbi.largestBST(tree); + System.out.println("Size of largest BST is " + largestBSTSize); + assert largestBSTSize == 8; + } +} + +/** + * Object of this class holds information which child passes back + * to parent node. + */ +class MinMax{ + int min; + int max; + boolean isBST; + int size ; + + MinMax(){ + min = Integer.MAX_VALUE; + max = Integer.MIN_VALUE; + isBST = true; + size = 0; + } +} \ No newline at end of file diff --git a/src/main/java/com/tree/LargestNumberInBSTWhichIsLessThanOrEqualToN.java b/src/main/java/com/tree/LargestNumberInBSTWhichIsLessThanOrEqualToN.java new file mode 100644 index 00000000..f636dd6e --- /dev/null +++ b/src/main/java/com/tree/LargestNumberInBSTWhichIsLessThanOrEqualToN.java @@ -0,0 +1,50 @@ +package com.tree; + +import com.tree.model.TreeNode; + +public class LargestNumberInBSTWhichIsLessThanOrEqualToN { + + public static void main(String args[]) { + + /* + Binary Tree + + 1 + / \ + 2 3 + / \ + 4 5 + */ + TreeNode tree = new TreeNode(10); + tree.left = new TreeNode(8); + tree.right = new TreeNode(30); + tree.left.left = new TreeNode(6); + tree.left.right = new TreeNode(9); + tree.right.left = new TreeNode(15); + tree.right.right = new TreeNode(35); + tree.left.left.left = new TreeNode(4); + + System.out.println("MaxValueLessThanN : " + findMaxValueLessThanN(tree,7)); + } + + //Iterative Solution + public static int findMaxValueLessThanN(TreeNode root, int n) { + int val = -1; + while(root != null) { + if(root.val > n) { + //When you go towards left of root node, it means current value is greater than N, + //No need to take backup as current node is > N and you need value less than N. + //Note: when you move towards right that is the only case your current node is lower than N and + //you are searching for higher node and we are already taking backup at that time. + root = root.left; + } else { + //When you go towards right of root node, it means you will be moving towards higher value compared to current one, + //Take the backup of current one as that may be second highest. + val = root.val; + root = root.right; + } + } + return val; + } + +} diff --git a/src/main/java/com/tree/LeftViewOfBinaryTree.java b/src/main/java/com/tree/LeftViewOfBinaryTree.java new file mode 100644 index 00000000..8cb4b92b --- /dev/null +++ b/src/main/java/com/tree/LeftViewOfBinaryTree.java @@ -0,0 +1,56 @@ +package com.tree; + +import com.tree.model.TreeNode; + +/** +* Time Complexity is O(n) + Space Complexity is O(1) +* */ + +public class LeftViewOfBinaryTree { + + /** + * important + */ + static int maxLevelSoFar = -1; + + public static void main(String args[]) { + + /* + Binary Tree + + 1 + / \ + 2 3 + / \ + 4 5 + */ + TreeNode tree = new TreeNode(1); + tree.left = new TreeNode(2); + tree.right = new TreeNode(3); + tree.left.left = new TreeNode(4); + tree.left.right = new TreeNode(5); + tree.right.left = new TreeNode(7); + tree.right.right = new TreeNode(8); + tree.left.left.left = new TreeNode(10); + + printLeftView(tree, 0); + } + + private static void printLeftView(TreeNode tree, int currentLevel) { + + /**important*/ /**Base Condition */ + if (tree == null) + return; + + if (currentLevel > maxLevelSoFar) { + System.out.println(tree.val + " "); + maxLevelSoFar = currentLevel; + } + + /**Recursive condition */ + printLeftView(tree.left, currentLevel + 1); //if condition will be true for currentLevel + printLeftView(tree.right, currentLevel + 1); //if condition will be false for same currentLevel + + } +} diff --git a/src/main/java/com/tree/MergeTwoBinaryTrees.java b/src/main/java/com/tree/MergeTwoBinaryTrees.java new file mode 100644 index 00000000..b6b0af30 --- /dev/null +++ b/src/main/java/com/tree/MergeTwoBinaryTrees.java @@ -0,0 +1,49 @@ +package com.tree; + +import com.tree.model.TreeNode; + +/** + * Complexity Analysis + * + * Time complexity : O(n)O(n). We traverse over a total of nn nodes. Here, nn refers to the smaller of the number of nodes in the two trees. + * + * Space complexity : O(n)O(n). The depth of stack can grow upto nn in case of a skewed tree. + */ + +public class MergeTwoBinaryTrees { + + public static void main (String args[]) { + TreeNode tree1 = new TreeNode(100); + tree1.left = new TreeNode(50); + tree1.right = new TreeNode(150); + tree1.left.left = new TreeNode(25); + tree1.left.right = new TreeNode(55); + tree1.right.left = new TreeNode(125); + tree1.right.right = new TreeNode(165); + + TreeNode tree2 = new TreeNode(1000); + tree2.left = new TreeNode(500); + tree2.right = new TreeNode(1500); + tree2.left.left = new TreeNode(250); + tree2.left.right = new TreeNode(550); + tree2.right.left = new TreeNode(1250); + tree2.right.right = new TreeNode(1650); + + mergeTrees(tree1, tree2); + } + + public static TreeNode mergeTrees(TreeNode t1, TreeNode t2) { + /**Base conditions*/ + if (t1 == null) + return t2; + if (t2 == null) + return t1; + + /**construct treeNode here*/ + t1.val += t2.val; + t1.left = mergeTrees(t1.left, t2.left); + t1.right = mergeTrees(t1.right, t2.right); + + return t1; + } +} diff --git a/src/main/java/com/tree/MirrorBinaryTree.JPG b/src/main/java/com/tree/MirrorBinaryTree.JPG new file mode 100644 index 00000000..2434c6f3 Binary files /dev/null and b/src/main/java/com/tree/MirrorBinaryTree.JPG differ diff --git a/src/main/java/com/tree/MirrorBinaryTree.java b/src/main/java/com/tree/MirrorBinaryTree.java new file mode 100644 index 00000000..18968116 --- /dev/null +++ b/src/main/java/com/tree/MirrorBinaryTree.java @@ -0,0 +1,34 @@ +package com.tree; + +import com.tree.model.TreeNode; + +public class MirrorBinaryTree { + + public static void main (String args[]){ + + TreeNode root = new TreeNode(10); + root.left = new TreeNode(20); + root.right = new TreeNode(30); + root.left.left = new TreeNode(40); + root.left.right = new TreeNode(50); + + mirrorBinaryTree(root); + + } + + private static void mirrorBinaryTree(TreeNode root) { + + if(root!= null){ + + mirrorBinaryTree(root.left); + mirrorBinaryTree(root.right); + + /** swap the left and right pointers */ + TreeNode temp = root.left; + root.left = root.right; + root.right = temp; + } + return; + } + +} diff --git a/src/main/java/com/tree/Nary_TreePreorderTraversal.java b/src/main/java/com/tree/Nary_TreePreorderTraversal.java new file mode 100644 index 00000000..3058504c --- /dev/null +++ b/src/main/java/com/tree/Nary_TreePreorderTraversal.java @@ -0,0 +1,63 @@ +package com.tree; + + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + + +// Definition for a Node. +class Node { + public int val; + public List children; + + public Node() { + } + + public Node(int _val, List _children) { + val = _val; + children = _children; + } +}; + + +public class Nary_TreePreorderTraversal { + + public static void main(String args[]) { + List list = new ArrayList<>(); + Node tree = new Node(); + preOrderTraversal(tree, list); + for(Node n : list){ + System.out.println(n.val); + } + + } + + public static void preOrderTraversal(Node tree, List list){ + + if (tree==null){ + return; + } + + Stack stack = new Stack<>(); + stack.push(tree); + + while(!stack .isEmpty()){ + + Node node = stack.pop(); + list.add(node); + + for(Node child :node.children){ + stack.push(child); + } + + } + + } + +} + + + + + diff --git a/src/main/java/com/tree/NodesAtGivenDistanceFromTargetNodeInBinaryTree.adoc b/src/main/java/com/tree/NodesAtGivenDistanceFromTargetNodeInBinaryTree.adoc new file mode 100644 index 00000000..51947b1e --- /dev/null +++ b/src/main/java/com/tree/NodesAtGivenDistanceFromTargetNodeInBinaryTree.adoc @@ -0,0 +1,18 @@ +image::../../../images/KDistanceFromGivenNode.png[] +*We will do level by level search in tree which is a graph* + +image::../../../images/KDistanceFromGivenNode1.png[] +image::../../../images/KDistanceFromGivenNode2.png[] +image::../../../images/KDistanceFromGivenNode3.png[] + +*Time and Space Complexity* + +*M = # of Edges* +*N = # of Nodes* + +**in a binary tree no of edges are nodes-1 +** + +image::../../../images/KDistanceFromGivenNode4.png[] +image::../../../images/KDistanceFromGivenNode5.png[] +image::../../../images/KDistanceFromGivenNode6.png[] \ No newline at end of file diff --git a/src/main/java/com/tree/NodesAtGivenDistanceFromTargetNodeInBinaryTree.html b/src/main/java/com/tree/NodesAtGivenDistanceFromTargetNodeInBinaryTree.html new file mode 100644 index 00000000..560d3993 --- /dev/null +++ b/src/main/java/com/tree/NodesAtGivenDistanceFromTargetNodeInBinaryTree.html @@ -0,0 +1,455 @@ + + + + + + + +Untitled + + + + + +
+
+
+KDistanceFromGivenNode +
+
+
+ + + \ No newline at end of file diff --git a/src/main/java/com/tree/NodesAtGivenDistanceFromTargetNodeInBinaryTree.java b/src/main/java/com/tree/NodesAtGivenDistanceFromTargetNodeInBinaryTree.java new file mode 100644 index 00000000..86c91dca --- /dev/null +++ b/src/main/java/com/tree/NodesAtGivenDistanceFromTargetNodeInBinaryTree.java @@ -0,0 +1,86 @@ +package com.tree; + +import com.tree.model.TreeNode; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class NodesAtGivenDistanceFromTargetNodeInBinaryTree { + + // Function to check if given TreeNode is a leaf TreeNode or not + public static boolean isLeaf(TreeNode TreeNode) { + return (TreeNode.left == null && TreeNode.right == null); + } + + // Recursive function to find all TreeNodes at given distance from leaf TreeNodes + public static void leafTreeNodeDistance(TreeNode TreeNode, List path, + Set set, int dist) { + // base case: empty tree + if (TreeNode == null) { + return; + } + + // if a leaf TreeNode is found, insert the TreeNode at distance 'dist' from + // leaf TreeNode into the set + if (isLeaf(TreeNode) && path.size() >= dist) { + set.add(path.get(path.size() - dist)); + return; + } + + // include current TreeNode into current path + path.add(TreeNode); + + // recur for left and right subtree + leafTreeNodeDistance(TreeNode.left, path, set, dist); + leafTreeNodeDistance(TreeNode.right, path, set, dist); + + // remove current TreeNode from the current path + path.remove(TreeNode); + } + + // find all distinct TreeNodes at given distance from leaf TreeNodes + public static void leafTreeNodeDistance(TreeNode TreeNode, int dist) { + // list to store root to leaf path + List path = new ArrayList<>(); + + // create an empty set to store distinct TreeNodes at given + // distance from leaf TreeNodes + Set set = new HashSet<>(); + + // find all TreeNodes + leafTreeNodeDistance(TreeNode, path, set, dist); + + // print output + for (TreeNode e : set) { + System.out.print(e.val + " "); + } + } + + // main function + public static void main(String[] args) { + /* Construct below tree + 15 + / \ + / \ + 10 20 + / \ / \ + 8 12 16 25 + / + 18 + */ + + TreeNode root = new TreeNode(15); + root.left = new TreeNode(10); + root.right = new TreeNode(20); + root.left.left = new TreeNode(8); + root.left.right = new TreeNode(12); + root.right.left = new TreeNode(16); + root.right.right = new TreeNode(25); + root.right.left.left = new TreeNode(18); + + int dist = 1; + leafTreeNodeDistance(root, dist); + } +} \ No newline at end of file diff --git a/src/main/java/com/tree/PrintNodesAtDistanceKFromRootNode.adoc b/src/main/java/com/tree/PrintNodesAtDistanceKFromRootNode.adoc new file mode 100644 index 00000000..b787da9b --- /dev/null +++ b/src/main/java/com/tree/PrintNodesAtDistanceKFromRootNode.adoc @@ -0,0 +1 @@ +image::../../../images/ProntNodesAtKdistanceFromRoot.png[] \ No newline at end of file diff --git a/src/main/java/com/tree/PrintNodesAtDistanceKFromRootNode.java b/src/main/java/com/tree/PrintNodesAtDistanceKFromRootNode.java new file mode 100644 index 00000000..31347081 --- /dev/null +++ b/src/main/java/com/tree/PrintNodesAtDistanceKFromRootNode.java @@ -0,0 +1,38 @@ +package com.tree; + +import com.tree.model.TreeNode; + +public class PrintNodesAtDistanceKFromRootNode { + + public static void main (String args[]){ + + TreeNode root = new TreeNode(10); + root.left = new TreeNode(20); + root.right = new TreeNode(30); + root.left.left = new TreeNode(40); + root.left.right = new TreeNode(50); + + int distance = 1; + printNodesAtKDistanceFromRoot(root,distance); + + } + + private static void printNodesAtKDistanceFromRoot(TreeNode root, int distance) { + /** Null check */ + if (root == null){ + return; + } + + /**Base condition */ + if (distance == 0){ + System.out.println(root.val); + } + + /** Recursive condition */ + else{ + printNodesAtKDistanceFromRoot(root.left,distance-1); + printNodesAtKDistanceFromRoot(root.right, distance-1); + } + } + +} diff --git a/src/main/java/com/tree/RangeSumOfBST.java b/src/main/java/com/tree/RangeSumOfBST.java new file mode 100644 index 00000000..9a1da2c3 --- /dev/null +++ b/src/main/java/com/tree/RangeSumOfBST.java @@ -0,0 +1,52 @@ +package com.tree; + +import com.tree.model.TreeNode; + +/** + * Complexity Analysis + *

+ * Time Complexity: O(N)O(N), where NN is the number of nodes in the tree. + *

+ * Space Complexity: O(H)O(H), where HH is the height of the tree. + * + * Approach 1: Depth First Search + * Intuition and Algorithm + * + * We traverse the tree using a depth first search. + * If node.val falls outside the range [L, R], (for example node.val < L), + * then we know that only the right branch could have nodes with value inside [L, R]. + * + */ +public class RangeSumOfBST { + static int ans = 0; + + public static void main(String args[]) { + TreeNode tree = new TreeNode(50); + tree.left = new TreeNode(40); + tree.right = new TreeNode(60); + tree.left.left = new TreeNode(30); + tree.left.right = new TreeNode(45); + tree.right.left = new TreeNode(56); + tree.right.right = new TreeNode(65); + tree.left.left.left = new TreeNode(20); + calculateRangeSum(tree, 20, 40); + System.out.println("SUM : " + ans); + } + + private static void calculateRangeSum(TreeNode tree, int min, int max) { + + if (tree != null) { + + if (tree.val >= min && tree.val <= max) { + ans += tree.val; + } + + if (tree.val > min) { + calculateRangeSum(tree.left, min, max); + } + if (tree.val < max) { + calculateRangeSum(tree.right, min, max); + } + } + } +} diff --git a/src/main/java/com/tree/SearchInBinarySearchTree.java b/src/main/java/com/tree/SearchInBinarySearchTree.java new file mode 100644 index 00000000..5cc60a86 --- /dev/null +++ b/src/main/java/com/tree/SearchInBinarySearchTree.java @@ -0,0 +1,23 @@ +package com.tree; + +import com.tree.model.TreeNode; + +public class SearchInBinarySearchTree { + + public static TreeNode searchInBST(TreeNode node, int val){ + if (node == null){ + return null; + } + + if (node.val == val){ + return node; + } + + if (val < node.val){ + return searchInBST(node.left, val); + }else{ + return searchInBST(node.right, val); + } + + } +} diff --git a/src/main/java/com/tree/SumOfLeftLeavesOfBinaryTree.java b/src/main/java/com/tree/SumOfLeftLeavesOfBinaryTree.java new file mode 100644 index 00000000..89343cd7 --- /dev/null +++ b/src/main/java/com/tree/SumOfLeftLeavesOfBinaryTree.java @@ -0,0 +1,4 @@ +package com.tree; + +public class SumOfLeftLeavesOfBinaryTree { +} diff --git a/src/main/java/com/tree/TopViewBinaryTree.adoc b/src/main/java/com/tree/TopViewBinaryTree.adoc new file mode 100644 index 00000000..8e73654b --- /dev/null +++ b/src/main/java/com/tree/TopViewBinaryTree.adoc @@ -0,0 +1 @@ +image::../../../images/TopViewOfBinaryTree.png[] \ No newline at end of file diff --git a/src/main/java/com/tree/TopViewOfBinaryTree.java b/src/main/java/com/tree/TopViewOfBinaryTree.java new file mode 100644 index 00000000..4b6ff1e4 --- /dev/null +++ b/src/main/java/com/tree/TopViewOfBinaryTree.java @@ -0,0 +1,8 @@ +package com.tree; + +public class TopViewOfBinaryTree { + + + + +} diff --git a/src/main/java/com/tree/TwoNodesOfTwoBSTEqualToGivenSum.java b/src/main/java/com/tree/TwoNodesOfTwoBSTEqualToGivenSum.java new file mode 100644 index 00000000..38e81e38 --- /dev/null +++ b/src/main/java/com/tree/TwoNodesOfTwoBSTEqualToGivenSum.java @@ -0,0 +1,84 @@ +package com.tree; + +import com.tree.model.TreeNode; + +/** + * + * Efficient Approach: + * + * Traverse BST 1 from smallest value to node to largest by taking index i. This can be achieved with the help of inorder traversal and storing value in arr + * Traverse BST 2 from largest value node to smallest by taking index j. This can be achieved with the help of inorder traversal. + * Perform these two traversals one by one and store into two array. + * Sum up the corresponding node’s value from both the BSTs at a particular instance of traversals. + * If sum > x, then print pair and decrement j by 1. + * If x > sum, then increment i by 1. + * Perform these operations until either of the two traversals gets completed. + * + */ + +public class TwoNodesOfTwoBSTEqualToGivenSum { + + public static void main (String args[]){ + TreeNode tree1 = new TreeNode(100); + tree1.left = new TreeNode(50); + tree1.right = new TreeNode(150); + tree1.left.left = new TreeNode(25); + tree1.left.right = new TreeNode(55); + tree1.right.left = new TreeNode(125); + tree1.right.right = new TreeNode(165); + + TreeNode tree2 = new TreeNode(1000); + tree2.left = new TreeNode(500); + tree2.right = new TreeNode(1500); + tree2.left.left = new TreeNode(250); + tree2.left.right = new TreeNode(550); + tree2.right.left = new TreeNode(1250); + tree2.right.right = new TreeNode(1650); + + int sum = 300; + findPairsInTwoBSTSumIsEqualToGivenSum(tree1,tree2,sum); + + } + + private static void findPairsInTwoBSTSumIsEqualToGivenSum(TreeNode tree1, TreeNode tree2, int sum) { + int arr1[] = new int[10]; + inorderTraversal(tree1, arr1, 0); + + int arr2[] = new int[10]; + inorderTraversal(tree2, arr2, 0); + + int arr1Index = 0; + int arr2Index = arr2.length-1; + int count = 0; + + while (arr1Index < arr1.length-1 && arr2Index > 0) + { + if(arr1[arr1Index] + arr2[arr2Index] == sum){ + count= count+1; + } + + if(arr1[arr1Index]+arr2[arr2Index] < sum){ + arr1Index = arr1Index +1 ; + }else{ + arr2Index = arr2Index -1; + } + + } + + System.out.println("Count - " + count); + + } + + public static void inorderTraversal(TreeNode tree, int[]arr, int i){ + + if(tree == null){ + return; + } + + inorderTraversal(tree.left,arr,i); + arr[i++] = tree.val; + inorderTraversal(tree.right,arr,i); + + } + +} diff --git a/src/main/java/com/tree/VerticalOrderTraversalOfBinaryTree.html b/src/main/java/com/tree/VerticalOrderTraversalOfBinaryTree.html new file mode 100644 index 00000000..01282632 --- /dev/null +++ b/src/main/java/com/tree/VerticalOrderTraversalOfBinaryTree.html @@ -0,0 +1,2295 @@ + + + + + + + + + + +Print a Binary Tree in Vertical Order. Find Vertical Sum of given Binary Tree. | JavaByPatel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ + +
+
+
+ +
+
+
+ + +
+ +
+
+
+
+
+
+ +
+ + +
+ + +
+ +
+
+

+Print a Binary Tree in Vertical Order. Find Vertical Sum of given Binary Tree. +

+ +
+
+
+
+
+
+
+ + + + + + +
+
+
+
+

+Print Binary Tree in Vertical Order OR
Print the Binary Tree in Vertical Order Path OR
Vertical order traversal of a Binary Tree.
Find Vertical Sum of given Binary Tree

+
+Given a binary tree, print it vertically.
+
+Let us first understand what we want to achieve? what is the input and what will be the expected output?
+
+
+
+Note:
+Vertical order traversal of Tree shown above will be 
+Print data present at Line 1 ( 4 )
+Print data present at Line 2 ( 2 ) + +Print data present at Line 3 ( 1, 5, 6 )
+Print data present at Line 4 ( 3 )
+Print data present at Line 5 ( 7 )
+
+

+Solution
+

+
+Vertical order Traversal of a tree is little bit different than Pre order, Post order, In order and Level order traversal.

We need to identify, which node will be part of Line 1, Line 2, Line 3 and so on, How to do that? +If you observe, then there is a close relation between each line from root.
+
+
+
+
If somehow we find out, which nodes fall in column -2, column -1, column 0, column 1 and column 2, then our task is done.

From the above image, we can see that, Root node is at scale 0.
With the reference from Root node which is at distance(column) 0, we will calculate the horizontal distance of each node at left(Negative) side and right(Positive) side.
+ +

+Lets understand it with example:

+
1. Node 1 is at distance 0 as this is the start point in scale.
2. Node 2 is at distance -1. (horizontal distance between root node 1 and node 2),
    as we are moving 1 column on left side of scale.

3.
Node 4 is at distance -2 (horizontal distance between root node 1 and node 4),
    as we are moving 2 column on left side of scale.

+4. Node 5 is at distance 0 (horizontal distance between root node 1 and node 5),
    as we are again on 0th column on scale.
    Remember we are only interested on nodes falling on same column.

5. Node 3 is at distance +1 (horizontal distance between root node 1 and node 3),
    as we are moving 1 column on right side of scale.

6. Node 6 is at distance 0 (horizontal distance between root node 1 and node 6),
    as we are again on 0th column on scale.
7. Node 7 is at distance +2 (horizontal distance between root node 1 and node 7),
    as we are moving 2 column on right side of scale.

From the above understanding, can we say,
If two nodes have the same Horizontal Distance from root, then they are on same vertical line.


+ +This is what exactly we will do,
we will keep one variable horizontal distance(hd) which will keep track of horizontal distance of each node from root node,


+

+Algorithm
+

+
+1. Read the tree in Pre-order traversal

2.
First node encounter will be root node, which is at hd 0 as this is starting point in scale. (hd is 0)

3. From this point,
    When we will move on Left, that is we are moving one column on left side, we will do (hd-1),
    When we will move on Right, that is we are moving one column on right side, we will do (hd+1).

4.
We will take one map, which will keep dumping all the nodes found at same horizontal distance

+    from root. (for map, key is hd and value will be nodes found).
 

    For each node encountered, check whether distance is already present in map,
         If it is present then we already encountered nodes at same distance prior to this node,
         So append current node data to existing nodes.

         If it is not present then this is the first time we are encountering this distance,
         so simply store the data against hd.

5. Better to use TreeMap in this case, as it will store the result in ascending order,
    which we are interested in.

+
+6. Print map.
+
+
+
+

+Java Program for printing Binary tree in vertical order

+
+
class Node{
+ private int data;
+ private Node left;
+ private Node right;
+
+ public Node(int data) {
+  this.data=data;
+ }
+
+ public int getData() {
+  return data;
+ }
+ public void setData(int data) {
+  this.data = data;
+ }
+ public Node getLeft() {
+  return left;
+ }
+ public void setLeft(Node left) {
+  this.left = left;
+ }
+ public Node getRight() {
+  return right;
+ }
+ public void setRight(Node right) {
+  this.right = right;
+ }
+}
+
+PrintBinaryTreeInVerticalOrder.java +
+
package tree;
+
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Queue;
+import java.util.TreeMap;
+
+public class PrintBinaryTreeInVerticalOrder {
+ private Node rootNode;
+
+ public static void main(String[] args) {
+  new PrintBinaryTreeInVerticalOrder();
+ }
+
+ public PrintBinaryTreeInVerticalOrder(){
+  addNode(rootNode, 1); 
+  addNode(rootNode, 2); 
+  addNode(rootNode, 3); 
+  addNode(rootNode, 4); 
+  addNode(rootNode, 5); 
+  addNode(rootNode, 6); 
+  addNode(rootNode, 7); 
+
+  TreeMap<Integer, String> map = new TreeMap<Integer, String>();
+  printTreeInVerticalOrder(rootNode, map, 0);
+  
+  for (Map.Entry<Integer, String> entry : map.entrySet()) {
+   System.out.println(entry.getValue());
+  }
+ }
+
+ private void printTreeInVerticalOrder(Node rootNode, TreeMap<Integer, String> map, int hd) {
+  if(rootNode==null){
+   return;
+  }
+  
+  if(map.get(hd)!=null){
+   map.put(hd, map.get(hd)+","+rootNode.getData());
+  }else{
+   map.put(hd, String.valueOf(rootNode.getData()));
+  }
+  
+  printTreeInVerticalOrder(rootNode.getLeft(), map, hd-1);
+  printTreeInVerticalOrder(rootNode.getRight(), map, hd+1);
+ }
+
+ 
+ private void addNode(Node rootNode, int data){
+
+  //First check is there any Nodes present.
+  if(rootNode==null){
+   // No Nodes are Present, create one and assign it to startNode
+   Node temp1=new Node(data);
+   this.rootNode=temp1;
+  }else{
+   //Nodes present, So check the proper position where to add New Node.
+
+   //Checking whether Left child and Right child are present for root Node. 
+   if(rootNode.getLeft()!=null && rootNode.getRight()!=null){
+    //Left and Right Child exist, Also, we need to add ne Node in Sequential Fashion of Left and Right, 
+    //We have to scan all Levels one by one to check a proper place for new Node.
+    //Also, we for each and every node we need to check whether Left and Right Exist, 
+    //So we need to store them for later Processing that is why we introduced Queue.
+
+    Queue<Node> queue = new LinkedList<Node>();
+    queue.add(rootNode);
+
+    while(!queue.isEmpty()){
+     Node obj = (Node)queue.poll();
+     if(obj.getLeft()!=null && obj.getRight()!=null){
+      queue.add(obj.getLeft());
+      queue.add(obj.getRight());
+     }else if(obj.getLeft()==null){
+      Node temp1=new Node(data);
+      obj.setLeft(temp1);
+      break;
+     }else{
+      Node temp1=new Node(data);
+      obj.setRight(temp1);
+      break;
+     }
+    }
+
+   }else{
+    // We reach this condition when either Left or Right is Null, but not sure which side is Null.
+    if(rootNode.getLeft()==null){
+     Node temp1=new Node(data);
+     rootNode.setLeft(temp1);
+    }else{
+     Node temp1=new Node(data);
+     rootNode.setRight(temp1);
+    }
+   }
+  }
+ }
+}
+
+
+In above solution, Vertical order traversal of a tree is working fine, but nodes at same level are not printed in sequence they are present because we are doing Pre-order traversal of a tree (Depth first traversal) in which Left sub-tree nodes are read first and then it picks right sub-tree.

For mainlining sequence, we have to do Breadth first traversal that is Level order traversal, which make sure nodes are Lower levels are read first than Nodes at higher level
that is all Nodes at Level 0 are read first and then Node at Level 1 and then Node at Level 2 and so on.

For this we have to take a queue, which will preserve nodes at same level for later processing.

+
So changes that need to be done in above solution is shown below,

+
private static void printTreeInVerticalOrderMaintainSequence(VerticalOrderNode rootNode, TreeMap<Integer, String> map) {
+ if(rootNode==null){
+  return;
+ }
+
+ Queue<VerticalOrderNode> q = new LinkedList<VerticalOrderNode>();
+ q.add(rootNode);
+
+ while(!q.isEmpty()){
+  VerticalOrderNode temp = q.poll();
+
+  if(map.get(temp.getLevel())!=null){
+   map.put(temp.getLevel(), map.get(temp.getLevel())+","+temp.getData());
+  }else{
+   map.put(temp.getLevel(), String.valueOf(temp.getData()));
+  }
+
+  if(temp.getLeftNode()!=null){
+   temp.getLeftNode().setLevel(temp.getLevel()-1);
+   q.add(temp.getLeftNode());
+  }
+
+  if(temp.getRightNode()!=null){
+   temp.getRightNode().setLevel(temp.getLevel()+1);
+   q.add(temp.getRightNode());
+  } 
+ }
+}
+
+class VerticalOrderNode{
+
+ private int data;
+ private VerticalOrderNode leftNode;
+ private VerticalOrderNode rightNode;
+ private int level;
+
+}
+
+
+

+Find Vertical Sum of given Binary Tree

+
+Given a Binary Tree, find vertical sum of the nodes that are in same vertical line.
Print all sums through different vertical lines.

+Let us first understand what we want to achieve? what is the input and what will be the expected output?
+
+
+
+
+
+

+Solution
+

+
+Solution for finding Vertical sum of binary tree is very similar to Print Binary tree vertically as we saw above.
+
+Solution for finding Vertical sum only differ in adding the nodes at same vertical line instead of printing them all, which we did in printing Binary tree vertically above.
+
+Lets see what we did for printing the nodes vertically,
+
  
+  if(map.get(hd)!=null){
+     map.put(hd, map.get(hd)+","+rootNode.getData());  
+
+     // Above line concat the data present at same vertical line.
+
+  }else{
+     map.put(hd, String.valueOf(rootNode.getData()));
+  }
+  
+
+
+If we change the logic which concat the data present at same vertical line to add data at same vertical line, then our task is done. +
+
+
  
+  if(map.get(hd)!=null){
+     map.put(hd, String.valueOf( Integer.parseInt(map.get(hd)) + rootNode.getData()) );
+
+     // This line sums the data present at same vertical line.
+
+  }else{
+     map.put(hd, String.valueOf(rootNode.getData()));
+  }
+  
+
+
+For finding Vertical sum of binary tree, just change the above line in solution to Print Binary tree vertically and we are done. + +
+
+

+You may also like to see +

+
+

+Traverse a Binary Tree in Inorder, Preorder, Postorder, Levelorder traversal

+ +

+Serialize and Deserialize a Binary Tree

+ +

+Print Nodes visible from Top View of Binary Tree

+ +

+Connvert sorted array to balanced BST

+ +

+Traverse a Binary Tree in Zig Zag(Spiral) traversal.

+
+
+
+Enjoy !!!! 
+
+
+If you find any issue in post or face any error while implementing, Please comment.
+
+
+ +
+
+
+ + + + +
+
+
+ +
+ +
+ +

+2 +comments +

+
+
+
+ + +
+ +
+
+ +
+
+Bhavuk +mod +
+ +
+
+
+

This code works only for first layer of the root. For the remaining nodes, the node which is nearer to the root gets printed after the node away from the root.

For eg - Consider a tree where the values are inserted as - {1, (2,3), (4,5,6,7)}.
Now, add 8 as right child of 5.

Required result, 3 should be printed before 8.
As per the algorithm, 8 gets printed before 3.

Please correct me if I'm wrong.

+Reply +
+
+
+
+
+
+ +
+
+
+ + +
+ +
+
+ +
+
+JavaByPatel +mod +
+ +
+
+
+

Hi Bhavuk,

You are absolutely right. Thanks for pointing it. Really appreciable.

For maintaining sequence, we have to read the tree in Level Order which will make sure that Nodes at Lower levels are read first than higher levels, that is all Nodes at Level 0 are read first and then Node at Level 1 and then Node at Level 2 and so on.

Updated the solution, I hope this is what you are looking for. Please let me know if there is any question.

Thanks for your time.

+Reply +
+
+
+
+
+
+ +
+
+
+
+
+
+

Post a Comment

+
+ +

+

+ + + + + +
+
+
+ + + +
+ +
+ + +
+
+ +Newer Post + + +Older Post + +Home +
+
+
+
+
+ + +
+ +
+
+ + + + +
+ + + + + +
+ + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/tree/VerticalOrderTraversalOfBinaryTree.java b/src/main/java/com/tree/VerticalOrderTraversalOfBinaryTree.java new file mode 100644 index 00000000..a7458fb1 --- /dev/null +++ b/src/main/java/com/tree/VerticalOrderTraversalOfBinaryTree.java @@ -0,0 +1,87 @@ +package com.tree; + +import com.tree.model.TreeNode; + +import java.util.TreeMap; + +/** + * + * Horizontal Distance for Root = 0 + * Left child = HD (parent) -1 + * Right child = HD (parent) +1 + * + * If two nodes have the same Horizontal Distance from root, then they are on same vertical line. + * + * Algorithm + * 1. Read the tree in Pre-order traversal + * + * 2. First node encounter will be root node, which is at hd 0 as this is starting point in scale. (hd is 0) + * + * 3. From this point, + * When we will move on Left, that is we are moving one column on left side, we will do (hd-1), + * When we will move on Right, that is we are moving one column on right side, we will do (hd+1). + * + * 4. We will take one map, which will keep dumping all the nodes found at same horizontal distance + * from root. (for map, key is hd and value will be nodes found). + * + * For each node encountered, check whether distance is already present in map, + * If it is present then we already encountered nodes at same distance prior to this node, + * So append current node data to existing nodes. + * + * If it is not present then this is the first time we are encountering this distance, + * so simply store the data against hd. + * + * 5. Better to use TreeMap in this case, as it will store the result in ascending order, + * which we are interested in. + * + * 6. Print map. + * + */ +public class VerticalOrderTraversalOfBinaryTree { + public static void main(String args[]) { + + /* + Binary Tree + + 1 + / \ + 2 3 + / \ + 4 5 + */ + TreeNode tree = new TreeNode(1); + tree.left = new TreeNode(2); + tree.right = new TreeNode(3); + tree.left.left = new TreeNode(4); + tree.left.right = new TreeNode(5); + tree.right.left = new TreeNode(7); + tree.right.right = new TreeNode(8); + tree.left.left.left = new TreeNode(10); + + /**Better to use TreeMap in this case, as it will store the result in ascending order of keys i.e + * horizontal distance*/ + TreeMap map= new TreeMap(); + printInVerticalOrder(tree, map, 0); + + for(Integer key : map.keySet()){ + System.out.print(map.get(key) + " "); + } + } + + private static void printInVerticalOrder(TreeNode root, TreeMap map, int horizontalDistance) { + + if(root == null){ + return; + } + + if(map.get(horizontalDistance)!=null){ + map.put(horizontalDistance, map.get(horizontalDistance)+","+root.val); + }else{ + map.put(horizontalDistance, String.valueOf(root.val)); + } + + printInVerticalOrder(root.left, map,horizontalDistance-1); + printInVerticalOrder(root.right, map,horizontalDistance+1); + + } +} diff --git a/src/main/java/com/tree/model/TreeNode.java b/src/main/java/com/tree/model/TreeNode.java new file mode 100644 index 00000000..f1a0b50b --- /dev/null +++ b/src/main/java/com/tree/model/TreeNode.java @@ -0,0 +1,11 @@ +package com.tree.model; + +public class TreeNode { + public int val; + public TreeNode left; + public TreeNode right; + + public TreeNode(int data) { + this.val = data; + } +}