├── .gitignore ├── README.md ├── src ├── algorithms │ ├── dynamicProgramming │ │ └── Fibonacci.java │ ├── graph │ │ ├── DijkstrasShortestPath.java │ │ └── KruskalsMST.java │ ├── search │ │ └── BinarySearch.java │ ├── series │ │ ├── Fibonacci.java │ │ └── SieveOfEratosthenes.java │ ├── shuffle │ │ └── KnuthShuffling.java │ ├── sort │ │ ├── BubbleSort.java │ │ ├── CountingSort.java │ │ ├── HeapSort.java │ │ ├── InsertionSort.java │ │ ├── MergeSort.java │ │ ├── QuickSelect.java │ │ ├── QuickSort.java │ │ └── SelectionSort.java │ └── unionFind │ │ └── QuickUnion.java ├── dataStructures │ ├── basic │ │ ├── LinkedStack.java │ │ ├── Queue.java │ │ ├── QueueWithStacks.java │ │ ├── ResizingArray.java │ │ └── Stack.java │ ├── binarySearchTree │ │ ├── BinarySearchTree.java │ │ ├── DeletableBST.java │ │ ├── OrderedOperationsBST.java │ │ ├── ShortestPathInBST.java │ │ └── TraversableBST.java │ ├── heap │ │ ├── MinHeap.java │ │ └── TopTransactions.java │ ├── linkedList │ │ ├── CycleInLinkedList.java │ │ ├── DoublyLinkedList.java │ │ ├── LinkedList.java │ │ └── ReverseASinglyLinkedList.java │ └── trie │ │ ├── Trie.java │ │ └── TrieRecursion.java ├── problems │ ├── bitManipulation │ │ └── LonelyInteger.java │ └── string │ │ └── Anagram.java └── utils │ ├── Template.java │ └── Util.java └── test ├── algorithms ├── dynamicProgramming │ └── FibonacciTest.java ├── graph │ ├── DijkstrasShortestPathTest.java │ ├── Kruskal_Algorithm_Graph.png │ └── KruskalsMSTTest.java ├── search │ └── BinarySearchTest.java ├── series │ ├── FibonacciTest.java │ └── SieveOfEratosthenesTest.java ├── shuffle │ └── KnuthShufflingTest.java ├── sort │ ├── BubbleSortTest.java │ ├── CountingSortTest.java │ ├── HeapSortTest.java │ ├── InsertionSortTest.java │ ├── MergeSortTest.java │ ├── QuickSelectSortTest.java │ ├── QuickSelectTest.java │ └── QuickSortTest.java └── unionFind │ └── QuickUnionTest.java ├── dataStructures ├── basic │ ├── LinkedStackTest.java │ ├── QueueTest.java │ ├── QueueWithStacksTest.java │ ├── ResizingArrayTest.java │ └── StackTest.java ├── binarySearchTree │ ├── BinarySearchTreeTest.java │ ├── DeletableBSTTest.java │ ├── OrderedOperationsBSTTest.java │ ├── ShortestPathInBSTTest.java │ └── TraversableBSTTest.java ├── heap │ ├── MinHeapTest.java │ └── TopTransactionsTest.java ├── linkedList │ ├── CycleInLinkedListTest.java │ ├── DoublyLinkedListTest.java │ ├── LinkedListTest.java │ └── ReverseASinglyLinkedListTest.java └── trie │ ├── TrieRecursionTest.java │ └── TrieTest.java └── problems ├── bitManipulation └── LonelyIntegerTest.java └── string └── AnagramTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | # Don't track content of these folders 2 | 3 | Elegant-Algorithms.iml 4 | 5 | out/ 6 | .idea/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Elegant-Algorithms 2 | **_Elegant implementations of Elegant algorithms._** 3 | 4 | **Quote by Francis Sullivan:** 5 | *"For me, great algorithms are the poetry of computation. Just like verse, they can be terse, allusive, dense, and even mysterious. But once unlocked they cast a brilliant new light on some aspect of computing."* 6 | 7 | If you have a more elegant implementation for an algorithm, please do contribute. Contributions are welcome for algorithms that are not yet present in this repository. -------------------------------------------------------------------------------- /src/algorithms/dynamicProgramming/Fibonacci.java: -------------------------------------------------------------------------------- 1 | package algorithms.dynamicProgramming; 2 | 3 | /** 4 | * Time Complexity = O(n) 5 | * Space Complexity = O(n) 6 | */ 7 | 8 | public class Fibonacci { 9 | public int[] fibo(int n) { 10 | int[] a = new int[n]; 11 | a[1] = 1; 12 | for (int i = 2; i < n; i++) { 13 | a[i] = a[i - 1] + a[i - 2]; 14 | } 15 | return a; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/algorithms/graph/DijkstrasShortestPath.java: -------------------------------------------------------------------------------- 1 | package algorithms.graph; 2 | 3 | import java.util.*; 4 | import java.util.Map.Entry; 5 | 6 | /** 7 | * Dijkstra's shortest path algorithm is greedy algorithm 8 | * Time complexity - O(E log V) 9 | */ 10 | 11 | public class DijkstrasShortestPath { 12 | public static class Graph { 13 | Map idToVertex; 14 | 15 | public Graph(int n) { 16 | idToVertex = new HashMap<>(n); 17 | for (int i = 1; i <= n; i++) { 18 | idToVertex.put(i, new Vertex(i)); 19 | } 20 | } 21 | 22 | public Vertex getVertex(int id) { 23 | return idToVertex.get(id); 24 | } 25 | 26 | public void addEdge(int vertexOneId, int vertexTwoId, int distance) { 27 | Vertex one = getVertex(vertexOneId); 28 | Vertex two = getVertex(vertexTwoId); 29 | one.addEdge(two, distance); 30 | two.addEdge(one, distance); 31 | } 32 | 33 | public Set getVertices() { 34 | return new HashSet<>(idToVertex.values()); 35 | } 36 | } 37 | 38 | public static class Vertex { 39 | int id; 40 | Vertex parent; 41 | int distanceFromSource; 42 | Map adjacent = new HashMap<>(); 43 | 44 | Vertex(int id) { 45 | this.id = id; 46 | distanceFromSource = Integer.MAX_VALUE; 47 | } 48 | 49 | public void addEdge(Vertex v, int distance) { 50 | if (adjacent.containsKey(v)) { 51 | if (adjacent.get(v) > distance) adjacent.put(v, distance); 52 | } else { 53 | adjacent.put(v, distance); 54 | } 55 | } 56 | } 57 | 58 | public void shortestPath(Graph graph, int sourceId) { 59 | Vertex source = graph.getVertex(sourceId); 60 | source.distanceFromSource = 0; 61 | 62 | PriorityQueue queue = new PriorityQueue<>(Comparator.comparingInt(v -> v.distanceFromSource)); 63 | queue.add(source); 64 | 65 | while (!queue.isEmpty()) { 66 | Vertex current = queue.poll(); 67 | 68 | for (Entry entry : current.adjacent.entrySet()) { 69 | Vertex adjacent = entry.getKey(); 70 | int newDistance = current.distanceFromSource + entry.getValue(); 71 | 72 | if (newDistance < adjacent.distanceFromSource) { 73 | adjacent.distanceFromSource = newDistance; 74 | adjacent.parent = current; 75 | if (queue.contains(adjacent)) queue.remove(adjacent); 76 | queue.add(adjacent); 77 | } 78 | } 79 | } 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /src/algorithms/graph/KruskalsMST.java: -------------------------------------------------------------------------------- 1 | package algorithms.graph; 2 | 3 | import com.sun.istack.internal.NotNull; 4 | import algorithms.unionFind.QuickUnion; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Collections; 8 | import java.util.List; 9 | 10 | /** 11 | * Time complexity - O(E log E) where E is the number of Edges 12 | */ 13 | 14 | public class KruskalsMST { 15 | 16 | public static class Edge implements Comparable{ 17 | int vertexOne; 18 | int vertexTwo; 19 | int cost; 20 | 21 | Edge(int vertexOne, int vertexTwo, int cost) { 22 | this.vertexOne = vertexOne; 23 | this.vertexTwo = vertexTwo; 24 | this.cost = cost; 25 | } 26 | 27 | @Override 28 | public int compareTo(@NotNull Object o) { 29 | return this.cost - ((Edge) o).cost; 30 | } 31 | } 32 | 33 | public List mst(List graph) { 34 | List mst = new ArrayList<>(); 35 | Collections.sort(graph); 36 | QuickUnion quickUnion = new QuickUnion(graph.size()*2); 37 | for(Edge e : graph) { 38 | if(!quickUnion.isConnected(e.vertexOne, e.vertexTwo)) { 39 | quickUnion.union(e.vertexOne, e.vertexTwo); 40 | mst.add(e); 41 | } 42 | } 43 | return mst; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/algorithms/search/BinarySearch.java: -------------------------------------------------------------------------------- 1 | package algorithms.search; 2 | 3 | /** 4 | * In order for BinarySearch to work the array must be sorted 5 | * Time complexity - O(log n) 6 | * Space complexity - O(1) 7 | */ 8 | 9 | public class BinarySearch { 10 | public int search(int[] a, int k) { 11 | if (a == null || a.length == 0) return -1; 12 | 13 | int start = 0, end = a.length - 1; 14 | while (start <= end) { 15 | int mid = start + (end - start) / 2; 16 | if (k < a[mid]) end = mid - 1; 17 | else if (k > a[mid]) start = mid + 1; 18 | else return mid; 19 | } 20 | 21 | return -1; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/algorithms/series/Fibonacci.java: -------------------------------------------------------------------------------- 1 | package algorithms.series; 2 | 3 | /** 4 | * Time Complexity = O(n) 5 | * Space Complexity = O(n) 6 | */ 7 | 8 | public class Fibonacci { 9 | public int[] fibo(int n) { 10 | int[] output = new int[n]; 11 | int a = 0, b = 1; 12 | output[0] = a; 13 | output[1] = b; 14 | 15 | for (int i = 2; i < n; i++) { 16 | int c = a + b; 17 | output[i] = c; 18 | a = b; 19 | b = c; 20 | } 21 | return output; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/algorithms/series/SieveOfEratosthenes.java: -------------------------------------------------------------------------------- 1 | package algorithms.series; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * Time complexity - O(n log log n) 8 | * Space complexity - O(n) 9 | */ 10 | 11 | public class SieveOfEratosthenes { 12 | public List primes(int n) { 13 | int[] sieve = sieve(n); 14 | List primes = new ArrayList<>(); 15 | for (int i = 2; i < sieve.length; i++) 16 | if (sieve[i] == 0) 17 | primes.add(i); 18 | return primes; 19 | } 20 | 21 | private int[] sieve(int n) { 22 | int[] sieve = new int[n + 1]; 23 | for (int i = 2; i < sieve.length; i++) 24 | if (sieve[i] == 0) 25 | for (int j = i + i; j < sieve.length; j += i) 26 | sieve[j] = 1; 27 | return sieve; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/algorithms/shuffle/KnuthShuffling.java: -------------------------------------------------------------------------------- 1 | package algorithms.shuffle; 2 | 3 | import java.util.Random; 4 | 5 | import static utils.Util.swap; 6 | 7 | /** 8 | * Uniformly random permutation in linear time 9 | * Time complexity - O(n) 10 | */ 11 | 12 | public class KnuthShuffling { 13 | public void shuffle(int[] a) { 14 | for (int i = 0; i < a.length; i++) { 15 | Random random = new Random(); 16 | int r = random.nextInt(i+1); 17 | swap(a, r, i); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/algorithms/sort/BubbleSort.java: -------------------------------------------------------------------------------- 1 | package algorithms.sort; 2 | 3 | import static utils.Util.swap; 4 | 5 | /** 6 | * Time complexity - O(n^2) 7 | * Space Complexity - In-place sorting O(1) 8 | */ 9 | 10 | public class BubbleSort { 11 | 12 | public void sort(int[] a) { 13 | for(int i = 0; i < a.length; i++) 14 | for(int j = 0; j < a.length-1; j++) 15 | if(a[j] > a[j+1]) swap(a, j, j+1); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/algorithms/sort/CountingSort.java: -------------------------------------------------------------------------------- 1 | package algorithms.sort; 2 | 3 | /** 4 | * Time complexity - O(n+k) n is the number of elements in the array and k is the range of elements. 5 | * Counting algorithms.sort is efficient if the range of input data is not significantly greater 6 | */ 7 | 8 | public class CountingSort { 9 | public void sort(int[] a, int max) { 10 | int[] count = new int[max+1]; 11 | for (int i = 0; i < a.length; i++) { 12 | count[a[i]]++; 13 | } 14 | int k = 0; 15 | for (int i = 0; i < count.length; i++) { 16 | for (int j = 0; j < count[i]; j++) { 17 | a[k++] = i; 18 | } 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/algorithms/sort/HeapSort.java: -------------------------------------------------------------------------------- 1 | package algorithms.sort; 2 | 3 | import dataStructures.heap.MinHeap; 4 | 5 | /** 6 | * In-place sorting with O(n log n) time complexity, 7 | * in-place if we use the min heap to store the data directly 8 | * Heap Sort is not stable 9 | */ 10 | 11 | public class HeapSort { 12 | 13 | public void sort(int[] a) { 14 | MinHeap heap = new MinHeap(a.length); 15 | for (int element : a) { 16 | heap.add(element); 17 | } 18 | for (int i = 0; i < a.length; i++) 19 | a[i] = heap.pop(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/algorithms/sort/InsertionSort.java: -------------------------------------------------------------------------------- 1 | package algorithms.sort; 2 | 3 | import static utils.Util.swap; 4 | 5 | /** 6 | * Time Complexity - O(n^2) 7 | * Space Complexity - In-place sorting O(1) 8 | * Stable Sort 9 | * 10 | * Advantage over QuickSelect algorithms.sort - Insertion algorithms.sort does less operations on a already sorted or mostly in order list of elements 11 | */ 12 | 13 | public class InsertionSort { 14 | 15 | public void sort(int[] a) { 16 | for(int i = 1; i < a.length; i++) { 17 | for(int j = i; j > 0; j--) { 18 | if(a[j] < a[j-1]) swap(a, j, j-1); 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/algorithms/sort/MergeSort.java: -------------------------------------------------------------------------------- 1 | package algorithms.sort; 2 | 3 | /** 4 | * Time complexity - O(n log n) 5 | * Space complexity - Not in place - O(n) - auxiliary array 6 | * Stable Sort 7 | */ 8 | 9 | public class MergeSort { 10 | public void sort(int[] a) { 11 | sort(a, 0, a.length - 1, new int[a.length]); 12 | } 13 | 14 | private void sort(int[] a, int start, int end, int[] aux) { 15 | if (start == end) 16 | return; 17 | int mid = start + (end - start) / 2; 18 | sort(a, start, mid, aux); 19 | sort(a, mid + 1, end, aux); 20 | merge(a, start, mid, end, aux); 21 | } 22 | 23 | private void merge(int[] a, int start, int mid, int end, int[] aux) { 24 | for (int k = start; k <= end; k++) 25 | aux[k] = a[k]; 26 | int i = start, j = mid + 1; 27 | for (int k = start; k <= end; k++) { 28 | if (i > mid) a[k] = aux[j++]; 29 | else if (j > end) a[k] = aux[i++]; 30 | else if (aux[i] < aux[j]) a[k] = aux[i++]; 31 | else a[k] = aux[j++]; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/algorithms/sort/QuickSelect.java: -------------------------------------------------------------------------------- 1 | package algorithms.sort; 2 | 3 | /** 4 | * Based on quick algorithms.sort 5 | * Given an unsorted array find the kth largest element with out sorting 6 | * 7 | * Average Time complexity - O(n), worst case - O(n^2) but random shuffle provides 8 | * a probabilistic guarantee (chance of getting struck by a lightning). 9 | */ 10 | 11 | public class QuickSelect { 12 | public int select(int[] a, int k) { 13 | if (k >= a.length) return -1; 14 | 15 | QuickSort quick = new QuickSort(); 16 | int start = 0, end = a.length - 1; 17 | while (true) { 18 | int p = quick.pivot(a, start, end); 19 | if (k < p) end = p - 1; 20 | else if (k > p) start = p + 1; 21 | else return a[k]; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/algorithms/sort/QuickSort.java: -------------------------------------------------------------------------------- 1 | package algorithms.sort; 2 | 3 | import static utils.Util.swap; 4 | 5 | /** 6 | * Time complexity - worst case - O(n^2) but if we shuffle the array the chances of having the worst case has some what 7 | * the same probability of us getting struck by lightning right now. 8 | * Average time complexity - O(n log n) 9 | * 10 | * Space complexity - In-place sorting O(1) 11 | */ 12 | 13 | public class QuickSort { 14 | public void sort(int[] a) { 15 | sort(a, 0, a.length - 1); 16 | } 17 | 18 | private void sort(int[] a, int start, int end) { 19 | if (start >= end) return; 20 | 21 | int p = pivot(a, start, end); 22 | sort(a, start, p - 1); 23 | sort(a, p + 1, end); 24 | } 25 | 26 | public int pivot(int[] a, int start, int end) { 27 | int i = start, j = end + 1, p = start; 28 | while (true) { 29 | while (a[++i] < a[p]) 30 | if (i > end) break; 31 | while (a[--j] > a[p]) 32 | if (j < start) break; 33 | if (i >= j) break; 34 | swap(a, i, j); 35 | } 36 | swap(a, j, p); 37 | return j; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/algorithms/sort/SelectionSort.java: -------------------------------------------------------------------------------- 1 | package algorithms.sort; 2 | 3 | import static utils.Util.swap; 4 | 5 | /** 6 | * Time Complexity - O(n^2) 7 | * Space Complexity - In-place sorting O(1) 8 | */ 9 | 10 | public class SelectionSort { 11 | 12 | public void sort(int[] a) { 13 | if(a == null) return; 14 | 15 | for(int i = 0 ; i < a.length; i++) { 16 | int minIndex = i; 17 | for(int j = i; j < a.length; j++) { 18 | if(a[j] < a[minIndex]) minIndex = j; 19 | } 20 | swap(a, i, minIndex); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/algorithms/unionFind/QuickUnion.java: -------------------------------------------------------------------------------- 1 | package algorithms.unionFind; 2 | 3 | /** 4 | * Weighted QuickUnion with path compression 5 | * There is a proof that the depth of any node in this tree is at most log base 2 of N - (if n is a billion then log base 2 is 30) 6 | * Time complexity - union is log base 2 of N, isConnected is log base 2 of N 7 | */ 8 | 9 | public class QuickUnion { 10 | 11 | int[] store; 12 | int[] size; 13 | 14 | public QuickUnion(int n) { 15 | store = new int[n]; 16 | size = new int[n]; 17 | for (int i = 0; i < n; i++) { 18 | store[i] = i; 19 | size[i] = 1; 20 | } 21 | } 22 | 23 | public void union(int a, int b) { 24 | a = find(a); 25 | b = find(b); 26 | if (a == b) return; 27 | if (size[a] > size[b]) { 28 | store[b] = a; 29 | size[a] += size[b]; 30 | } else { 31 | store[a] = b; 32 | size[b] += size[a]; 33 | } 34 | } 35 | 36 | public boolean isConnected(int a, int b) { 37 | return find(a) == find(b); 38 | } 39 | 40 | private int find(int a) { 41 | while (a != store[a]) { 42 | store[a] = store[store[a]]; //path compression 43 | a = store[a]; 44 | } 45 | return a; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/dataStructures/basic/LinkedStack.java: -------------------------------------------------------------------------------- 1 | package dataStructures.basic; 2 | 3 | /** 4 | * Time complexity - push: O(1), pop: O(1) 5 | */ 6 | 7 | public class LinkedStack { 8 | 9 | Node first; 10 | 11 | private class Node { 12 | 13 | Node(int data) { 14 | this.data = data; 15 | } 16 | 17 | int data; 18 | Node next; 19 | } 20 | 21 | public void push(int element) { 22 | Node temp = new Node(element); 23 | temp.next = first; 24 | first = temp; 25 | } 26 | 27 | public int pop() { 28 | if (isEmpty()) throw new StackOverflowError(); 29 | int result = first.data; 30 | first = first.next; 31 | return result; 32 | } 33 | 34 | public boolean isEmpty() { 35 | return first == null; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/dataStructures/basic/Queue.java: -------------------------------------------------------------------------------- 1 | package dataStructures.basic; 2 | 3 | import java.util.NoSuchElementException; 4 | 5 | /** 6 | * Time complexity - push: O(1), pop: O(1) 7 | */ 8 | 9 | public class Queue { 10 | 11 | private class Node { 12 | 13 | Node(int data) { 14 | this.data = data; 15 | } 16 | 17 | int data; 18 | Node next; 19 | } 20 | 21 | Node first; 22 | Node last; 23 | 24 | public void enqueue(int element) { 25 | Node old = last; 26 | last = new Node(element); 27 | if (isEmpty()) first = last; 28 | else old.next = last; 29 | } 30 | 31 | public int dequeue() { 32 | if (isEmpty()) throw new NoSuchElementException(); 33 | int result = first.data; 34 | first = first.next; 35 | return result; 36 | } 37 | 38 | public boolean isEmpty() { 39 | return first == null; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/dataStructures/basic/QueueWithStacks.java: -------------------------------------------------------------------------------- 1 | package dataStructures.basic; 2 | 3 | public class QueueWithStacks { 4 | private Stack input; 5 | private Stack output; 6 | 7 | public void enqueue(int element) { 8 | input.push(element); 9 | } 10 | 11 | public int dequeue() { 12 | if(output.isEmpty()) { 13 | while(!input.isEmpty()) { 14 | output.push(input.pop()); 15 | } 16 | } 17 | return output.pop(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/dataStructures/basic/ResizingArray.java: -------------------------------------------------------------------------------- 1 | package dataStructures.basic; 2 | 3 | /** 4 | * Time complexity - add: O(1), get: O(1), remove: O(n) 5 | * Prevents 6 | */ 7 | 8 | public class ResizingArray { 9 | 10 | public static final int INITIAL_SIZE = 5; 11 | int[] store; 12 | int index = 0; 13 | 14 | ResizingArray() { 15 | store = new int[INITIAL_SIZE]; 16 | } 17 | 18 | ResizingArray(int initialSize) { 19 | store = new int[initialSize]; 20 | } 21 | 22 | public void add(int element) { 23 | if (index == store.length) resize(); 24 | 25 | store[index++] = element; 26 | } 27 | 28 | public int get(int index) { 29 | if (index < store.length) { 30 | return store[index]; 31 | } else { 32 | throw new ArrayIndexOutOfBoundsException(); 33 | } 34 | } 35 | 36 | public int remove(int index) { 37 | if (index > this.index) { 38 | throw new ArrayIndexOutOfBoundsException(); 39 | } 40 | 41 | int result = store[index]; 42 | for (int i = index + 1; i < store.length; i++) { 43 | store[i - 1] = store[i]; 44 | } 45 | this.index--; 46 | reduce(); 47 | return result; 48 | } 49 | 50 | public int getSize() { 51 | return index; 52 | } 53 | 54 | private void reduce() { 55 | if (index < store.length / 3) { 56 | store = copy(store.length / 2); 57 | } 58 | } 59 | 60 | 61 | int getStoreSize() { 62 | return store.length; 63 | } 64 | 65 | private void resize() { 66 | store = copy(store.length * 2); 67 | } 68 | 69 | private int[] copy(int resize) { 70 | int[] temp = new int[resize]; 71 | for (int i = 0; i < index; i++) { 72 | temp[i] = store[i]; 73 | } 74 | return temp; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/dataStructures/basic/Stack.java: -------------------------------------------------------------------------------- 1 | package dataStructures.basic; 2 | 3 | /** 4 | * Time complexity - push: O(n), pop: O(n) 5 | */ 6 | 7 | public class Stack { 8 | int index = -1; 9 | int[] array; 10 | 11 | Stack(int n) { 12 | array = new int[n]; 13 | } 14 | 15 | public void push(int element) { 16 | array[++index] = element; 17 | } 18 | 19 | public int pop() { 20 | return array[index--]; 21 | } 22 | 23 | public boolean isEmpty() { 24 | return index == -1; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/dataStructures/binarySearchTree/BinarySearchTree.java: -------------------------------------------------------------------------------- 1 | package dataStructures.binarySearchTree; 2 | 3 | /** 4 | * Time complexity - worst case - search/insert/rank - O(h) where h is the height of the tree 5 | * it take at least O(log n) compares to find a node 6 | */ 7 | 8 | public class BinarySearchTree { 9 | 10 | protected Node root; 11 | 12 | public class Node { 13 | protected int key; 14 | protected int val; 15 | protected Node left; 16 | protected Node right; 17 | protected int count; 18 | 19 | Node(int key, int val) { 20 | this.key = key; 21 | this.val = val; 22 | this.count = 1; 23 | } 24 | 25 | public int getVal() { 26 | return val; 27 | } 28 | } 29 | 30 | public void put(int key, int val) { 31 | root = put(root, key, val); 32 | } 33 | 34 | public Node get(int key) { 35 | return get(root, key); 36 | } 37 | 38 | public int size() { 39 | return size(root); 40 | } 41 | 42 | public int rank(int key) { 43 | return rank(root, key); 44 | } 45 | 46 | public boolean contains(int key) { 47 | return get(key) != null; 48 | } 49 | 50 | private int rank(Node x, int key) { 51 | if (x == null) return 0; 52 | 53 | if (key < x.key) return rank(x.left, key); 54 | else if (key > x.key) return 1 + size(x.left) + rank(x.right, key); 55 | else return size(x.left); 56 | } 57 | 58 | protected int size(Node x) { 59 | if (x == null) return 0; 60 | return x.count; 61 | } 62 | 63 | private Node put(Node x, int key, int val) { 64 | if (x == null) return new Node(key, val); 65 | 66 | if (key < x.key) 67 | x.left = put(x.left, key, val); 68 | else if (key > x.key) 69 | x.right = put(x.right, key, val); 70 | else 71 | x.val = val; 72 | x.count = 1 + size(x.left) + size(x.right); 73 | return x; 74 | } 75 | 76 | private Node get(Node x, int key) { 77 | if (x == null) return null; 78 | 79 | if (key < x.key) 80 | return get(x.left, key); 81 | else if (key > x.key) 82 | return get(x.right, key); 83 | else 84 | return x; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/dataStructures/binarySearchTree/DeletableBST.java: -------------------------------------------------------------------------------- 1 | package dataStructures.binarySearchTree; 2 | 3 | public class DeletableBST extends BinarySearchTree { 4 | 5 | public void deleteMin() { 6 | root = deleteMin(root); 7 | } 8 | 9 | private Node deleteMin(Node x) { 10 | if (x.left == null) return x.right; 11 | x.left = deleteMin(x.left); 12 | x.count = 1 + size(x.left) + size(x.right); 13 | return x; 14 | } 15 | 16 | public void deleteMax() { 17 | root = deleteMax(root); 18 | } 19 | 20 | private Node deleteMax(Node x) { 21 | if (x.right == null) return x.left; 22 | x.right = deleteMax(x.right); 23 | x.count = 1 + size(x.left) + size(x.right); 24 | return x; 25 | } 26 | 27 | public void delete(int key) { 28 | root = delete(root, key); 29 | } 30 | 31 | private Node delete(Node x, int key) { 32 | if (x == null) return null; 33 | if (key < x.key) return delete(x.left, key); 34 | else if (key > x.key) return delete(x.right, key); 35 | else { 36 | if (x.right == null) return x.left; 37 | if (x.left == null) return x.right; 38 | 39 | Node temp = x; 40 | x = min(temp.right); 41 | deleteMin(temp.right); 42 | x.left = temp.left; 43 | x.right = temp.right; 44 | } 45 | x.count = 1 + size(x.left) + size(x.right); 46 | return x; 47 | } 48 | 49 | private Node min(Node x) { 50 | if (x == null) return null; 51 | while (x.left != null) { 52 | x = x.left; 53 | } 54 | return x; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/dataStructures/binarySearchTree/OrderedOperationsBST.java: -------------------------------------------------------------------------------- 1 | package dataStructures.binarySearchTree; 2 | 3 | public class OrderedOperationsBST extends BinarySearchTree { 4 | 5 | public Node floor(int key) { 6 | return floor(root, key); 7 | } 8 | 9 | private Node floor(Node x, int key) { 10 | if (x == null) return null; 11 | 12 | if (key < x.key) return floor(x.left, key); 13 | else if (key == x.key) return x; 14 | else { 15 | Node temp = floor(x.right, key); 16 | if (temp != null) return temp; 17 | else return x; 18 | } 19 | } 20 | 21 | public Node ceil(int key) { 22 | return ceil(root, key); 23 | } 24 | 25 | private Node ceil(Node x, int key) { 26 | if (x == null) return null; 27 | 28 | if (key > x.key) return ceil(x.right, key); 29 | else if (key == x.key) return x; 30 | else { 31 | Node temp = ceil(x.left, key); 32 | if (temp != null) return temp; 33 | else return x; 34 | } 35 | } 36 | 37 | public Node min() { 38 | if (root == null) return null; 39 | 40 | Node x = root; 41 | while (x.left != null) { 42 | x = x.left; 43 | } 44 | 45 | return x; 46 | } 47 | 48 | public Node max() { 49 | if (root == null) return null; 50 | 51 | Node x = root; 52 | while (x.right != null) { 53 | x = x.right; 54 | } 55 | 56 | return x; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/dataStructures/binarySearchTree/ShortestPathInBST.java: -------------------------------------------------------------------------------- 1 | package dataStructures.binarySearchTree; 2 | 3 | public class ShortestPathInBST { 4 | public String shortestPath(BinarySearchTree bst, int source, int destination) { 5 | if (!bst.contains(source) || !bst.contains(destination)) return ""; 6 | 7 | if (source > destination) { 8 | int temp = source; 9 | source = destination; 10 | destination = temp; 11 | } 12 | 13 | StringBuilder br = new StringBuilder(); 14 | 15 | shortestPath(bst.root, source, destination, br); 16 | 17 | return br.toString(); 18 | } 19 | 20 | private void shortestPath(BinarySearchTree.Node node, int source, int destination, StringBuilder br) { 21 | if (source < node.key && destination < node.key) 22 | shortestPath(node.left, source, destination, br); 23 | else if (source > node.key && destination > node.key) 24 | shortestPath(node.right, source, destination, br); 25 | else { 26 | probe(node.left, source, br); 27 | br.append(node.key + " "); 28 | probe(node.right, destination, br); 29 | } 30 | } 31 | 32 | private void probe(BinarySearchTree.Node node, int key, StringBuilder br) { 33 | if (node == null) return; 34 | 35 | br.append(node.key + " "); 36 | if (key < node.key) probe(node.left, key, br); 37 | else if (key > node.key) probe(node.right, key, br); 38 | else return; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/dataStructures/binarySearchTree/TraversableBST.java: -------------------------------------------------------------------------------- 1 | package dataStructures.binarySearchTree; 2 | 3 | import dataStructures.basic.Queue; 4 | 5 | public class TraversableBST extends BinarySearchTree { 6 | public Queue inOrderKeys() { 7 | Queue queue = new Queue(); 8 | inOrder(root, queue); 9 | return queue; 10 | } 11 | 12 | public Queue preOrderKeys() { 13 | Queue queue = new Queue(); 14 | preOrder(root, queue); 15 | return queue; 16 | } 17 | 18 | public Queue postOrderKeys() { 19 | Queue queue = new Queue(); 20 | postOrder(root, queue); 21 | return queue; 22 | } 23 | 24 | private void inOrder(BinarySearchTree.Node x, Queue queue) { 25 | if(x == null) return; 26 | inOrder(x.left, queue); 27 | queue.enqueue(x.key); 28 | inOrder(x.right, queue); 29 | } 30 | 31 | private void preOrder(Node x, Queue queue) { 32 | if(x == null) return; 33 | queue.enqueue(x.key); 34 | preOrder(x.left, queue); 35 | preOrder(x.right, queue); 36 | } 37 | 38 | private void postOrder(Node x, Queue queue) { 39 | if(x == null) return; 40 | postOrder(x.left, queue); 41 | postOrder(x.right, queue); 42 | queue.enqueue(x.key); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/dataStructures/heap/MinHeap.java: -------------------------------------------------------------------------------- 1 | package dataStructures.heap; 2 | 3 | import java.util.Arrays; 4 | 5 | import static utils.Util.swap; 6 | 7 | /** 8 | * Binary Heap 9 | * Time complexity - getMin : O(1), pop : O(log n), add : O(log n) 10 | */ 11 | 12 | public class MinHeap { 13 | int index = 0; 14 | int[] store; 15 | 16 | public MinHeap(int n) { 17 | store = new int[n + 1]; 18 | } 19 | 20 | public MinHeap(MinHeap copy) { 21 | index = copy.size(); 22 | store = copy.getAll(); 23 | } 24 | 25 | public void add(int item) { 26 | store[++index] = item; 27 | swim(index); 28 | } 29 | 30 | public int pop() { 31 | swap(store, 1, index--); 32 | sink(1); 33 | return store[index + 1]; 34 | } 35 | 36 | public int getMin() { 37 | return store[1]; 38 | } 39 | 40 | public boolean isEmpty() { 41 | return index == 0; 42 | } 43 | 44 | public int peek() { 45 | if (isEmpty()) throw new Empty(); 46 | return store[1]; 47 | } 48 | 49 | public int size() { 50 | return index; 51 | } 52 | 53 | public int[] getAll() { 54 | return Arrays.copyOfRange(store, 0, index + 1); 55 | } 56 | 57 | private void sink(int current) { 58 | while (current * 2 <= index) { 59 | int child = current * 2; 60 | if (child < index && store[child] > store[child + 1]) child++; 61 | if (store[current] < store[child]) break; 62 | swap(store, current, child); 63 | current = child; 64 | } 65 | } 66 | 67 | private void swim(int current) { 68 | while (current / 2 != 0 && store[current] < store[current / 2]) { 69 | swap(store, current, current / 2); 70 | current = current / 2; 71 | } 72 | } 73 | 74 | public static class Empty extends RuntimeException { 75 | } 76 | } -------------------------------------------------------------------------------- /src/dataStructures/heap/TopTransactions.java: -------------------------------------------------------------------------------- 1 | package dataStructures.heap; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * For a continuous set of transactions as input always return top m transactions. 8 | * Time complexity: add - O(log n), find - O(m long n) where m is the number of top transactions to be returned. 9 | */ 10 | 11 | public class TopTransactions { 12 | 13 | MinHeap heap; 14 | int size; 15 | 16 | public TopTransactions(int size) { 17 | heap = new MinHeap(size); 18 | this.size = size; 19 | } 20 | 21 | public List find() { 22 | MinHeap heap = new MinHeap(this.heap); 23 | List result = new ArrayList<>(); 24 | while (!heap.isEmpty()) { 25 | result.add(heap.pop()); 26 | } 27 | return result; 28 | } 29 | 30 | public void add(int amount) { 31 | if(heap.isEmpty() || heap.size() < size) { 32 | heap.add(amount); 33 | } else { 34 | if(amount > heap.peek()) { 35 | heap.pop(); 36 | heap.add(amount); 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/dataStructures/linkedList/CycleInLinkedList.java: -------------------------------------------------------------------------------- 1 | package dataStructures.linkedList; 2 | 3 | /** 4 | * Time complexity - O(n) 5 | */ 6 | 7 | public class CycleInLinkedList extends LinkedList { 8 | public boolean findCycle() { 9 | LinkedList.Node slow = this.getFirst(); 10 | LinkedList.Node fast = this.getFirst().getNext(); 11 | 12 | while(fast != null && fast.getNext() != null && slow != null) { 13 | if(slow.getData() == fast.getData()) return true; 14 | else { 15 | slow = slow.getNext(); 16 | fast = fast.getNext().getNext(); 17 | } 18 | } 19 | 20 | return false; 21 | } 22 | 23 | public void link(Node a, Node b) { 24 | a.next = b; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/dataStructures/linkedList/DoublyLinkedList.java: -------------------------------------------------------------------------------- 1 | package dataStructures.linkedList; 2 | 3 | /** 4 | * Time complexity 5 | * linkFirst, linkLast - O(1) 6 | * linkBetween - O(1) 7 | * find - O(n) 8 | */ 9 | 10 | public class DoublyLinkedList { 11 | 12 | private Node first; 13 | private Node last; 14 | 15 | public class Node { 16 | private int data; 17 | protected Node next; 18 | protected Node prev; 19 | 20 | Node(int data) { 21 | this.data = data; 22 | } 23 | 24 | public int getData() { 25 | return data; 26 | } 27 | 28 | public Node getNext() { 29 | return next; 30 | } 31 | 32 | public Node getPrev() { 33 | return prev; 34 | } 35 | } 36 | 37 | public void linkFirst(int data) { 38 | Node old = first; 39 | first = new Node(data); 40 | if (last == null) { 41 | last = first; 42 | } else { 43 | first.next = old; 44 | old.prev = first; 45 | } 46 | } 47 | 48 | public void linkLast(int data) { 49 | Node secLast = last; 50 | last = new Node(data); 51 | secLast.next = last; 52 | last.prev = secLast; 53 | } 54 | 55 | public void linkBetween(int data, Node node) { 56 | Node temp = new Node(data); 57 | temp.prev = node; 58 | temp.next = node.next; 59 | node.next = temp; 60 | } 61 | 62 | public Node find(int data) { 63 | Node current = first; 64 | while (current != null) { 65 | if (data == current.getData()) return current; 66 | current = current.next; 67 | } 68 | return null; 69 | } 70 | 71 | public Node getFirst() { 72 | return first; 73 | } 74 | 75 | public Node getLast() { 76 | return last; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/dataStructures/linkedList/LinkedList.java: -------------------------------------------------------------------------------- 1 | package dataStructures.linkedList; 2 | 3 | /** 4 | * Time complexity 5 | * linkFirst, linkLast - O(1) 6 | * linkBetween - O(1) 7 | * find - O(n) 8 | */ 9 | 10 | public class LinkedList { 11 | 12 | private Node first; 13 | private Node last; 14 | 15 | public class Node { 16 | private int data; 17 | protected Node next; 18 | 19 | Node(int data) { 20 | this.data = data; 21 | } 22 | 23 | public int getData() { 24 | return data; 25 | } 26 | 27 | public Node getNext() { 28 | return next; 29 | } 30 | } 31 | 32 | public void linkFirst(int data) { 33 | Node old = first; 34 | first = new Node(data); 35 | if (last == null) { 36 | last = first; 37 | } else { 38 | first.next = old; 39 | } 40 | } 41 | 42 | public void linkLast(int data) { 43 | Node secLast = last; 44 | last = new Node(data); 45 | if (secLast != null) { 46 | secLast.next = last; 47 | } else { 48 | first = last; 49 | } 50 | } 51 | 52 | public void linkBetween(int data, Node node) { 53 | if (node == null) { 54 | return; 55 | } 56 | Node temp = new Node(data); 57 | temp.next = node.next; 58 | node.next = temp; 59 | } 60 | 61 | public Node find(int data) { 62 | Node current = first; 63 | while (current != null) { 64 | if (data == current.getData()) return current; 65 | current = current.next; 66 | } 67 | return null; 68 | } 69 | 70 | public Node getFirst() { 71 | return first; 72 | } 73 | 74 | public Node getLast() { 75 | return last; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/dataStructures/linkedList/ReverseASinglyLinkedList.java: -------------------------------------------------------------------------------- 1 | package dataStructures.linkedList; 2 | 3 | /** 4 | * Time complexity - O(n) 5 | */ 6 | 7 | public class ReverseASinglyLinkedList { 8 | public LinkedList.Node reverse(LinkedList.Node node) { 9 | if (node == null) return null; 10 | 11 | LinkedList.Node prev = null; 12 | LinkedList.Node current = node; 13 | LinkedList.Node next = current.next; 14 | 15 | while (current != null) { 16 | current.next = prev; 17 | prev = current; 18 | current = next; 19 | if (current != null) { 20 | next = current.next; 21 | } 22 | } 23 | return prev; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/dataStructures/trie/Trie.java: -------------------------------------------------------------------------------- 1 | package dataStructures.trie; 2 | 3 | import java.util.HashMap; 4 | 5 | /** 6 | * Time Complexity 7 | * l -> average length of strings 8 | * n -> number of strings 9 | * Insert - O(l*n) 10 | * Search - O(l) 11 | * 12 | * A data structure that trades store for speed. 13 | * Real time example: search auto complete or suggestions 14 | */ 15 | 16 | public class Trie { 17 | 18 | protected Node root; 19 | 20 | Trie() { 21 | root = new Node(); 22 | } 23 | 24 | protected class Node { 25 | boolean end; 26 | int count; 27 | HashMap children; 28 | 29 | Node() { 30 | children = new HashMap<>(); 31 | } 32 | } 33 | 34 | public void insert(String word) { 35 | Node current = root; 36 | for(int i = 0; i < word.length(); i++) { 37 | char c = word.charAt(i); 38 | if(!current.children.containsKey(c)) { 39 | current.children.put(c, new Node()); 40 | } 41 | current = current.children.get(c); 42 | current.count++; 43 | } 44 | current.end = true; 45 | } 46 | 47 | public boolean isPresent(String word) { 48 | Node current = root; 49 | for(int i = 0; i < word.length(); i++) { 50 | char c = word.charAt(i); 51 | if(!current.children.containsKey(c)) { 52 | return false; 53 | } 54 | current = current.children.get(c); 55 | } 56 | return current.end; 57 | } 58 | 59 | public int findCount(String word) { 60 | Node current = root; 61 | for(int i = 0; i < word.length(); i++) { 62 | char c = word.charAt(i); 63 | if(!current.children.containsKey(c)) { 64 | return 0; 65 | } 66 | current = current.children.get(c); 67 | } 68 | return current.count; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/dataStructures/trie/TrieRecursion.java: -------------------------------------------------------------------------------- 1 | package dataStructures.trie; 2 | 3 | public class TrieRecursion extends Trie { 4 | 5 | @Override 6 | public void insert(String word) { 7 | insert(word, root, 0); 8 | } 9 | 10 | private void insert(String word, Node node, int index) { 11 | if (word.length() == index) { 12 | node.end = true; 13 | return; 14 | } 15 | 16 | char currentChar = word.charAt(index); 17 | Node child = node.children.get(currentChar); 18 | if (child == null) { 19 | child = new Node(); 20 | node.children.put(currentChar, child); 21 | } 22 | 23 | child.count++; 24 | insert(word, child, ++index); 25 | } 26 | 27 | @Override 28 | public boolean isPresent(String word) { 29 | return isPresent(word, root, 0); 30 | } 31 | 32 | private boolean isPresent(String word, Node node, int index) { 33 | if (word.length() == index) { 34 | return node.end; 35 | } 36 | 37 | char currentChar = word.charAt(index); 38 | if (node.children.containsKey(currentChar)) { 39 | return isPresent(word, node.children.get(currentChar), ++index); 40 | } else { 41 | return false; 42 | } 43 | } 44 | 45 | @Override 46 | public int findCount(String word) { 47 | return findCount(word, root, 0); 48 | } 49 | 50 | public void delete(String word) { 51 | delete(word, root, 0); 52 | } 53 | 54 | private boolean delete(String word, Node node, int index) { 55 | if (word.length() == index) { 56 | if (!node.end) { 57 | return false; 58 | } 59 | node.end = false; 60 | return node.children.size() == 0; 61 | } 62 | char currentChar = word.charAt(index); 63 | Node child = node.children.get(currentChar); 64 | if (child == null) { 65 | return false; 66 | } 67 | boolean shouldDeleteCurrentNode = delete(word, child, ++index); 68 | if (shouldDeleteCurrentNode) { 69 | node.children.remove(currentChar); 70 | return node.children.size() == 0; 71 | } 72 | return false; 73 | } 74 | 75 | private int findCount(String word, Node node, int index) { 76 | if (word.length() == index) { 77 | return node.count; 78 | } 79 | 80 | char currentChar = word.charAt(index); 81 | if (node.children.containsKey(currentChar)) { 82 | return findCount(word, node.children.get(currentChar), ++index); 83 | } else { 84 | return 0; 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/problems/bitManipulation/LonelyInteger.java: -------------------------------------------------------------------------------- 1 | package problems.bitManipulation; 2 | 3 | /** 4 | * Given a list of integers find the only integer that does not repeat. 5 | * We can do this using HashMap but requires time - O(n) and space O(n). 6 | * But instead if we use bit manipulation, we can reduce the space complexity to O(1) 7 | * 8 | * By taking xor of all the elements, we cancel out repeating elements and what remains is the loner. 9 | */ 10 | 11 | public class LonelyInteger { 12 | public int find(int[] integers) { 13 | int result = 0; 14 | for(int value: integers) { 15 | result ^= value; 16 | } 17 | return result; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/problems/string/Anagram.java: -------------------------------------------------------------------------------- 1 | package problems.string; 2 | 3 | /** 4 | * Anagram: same letter, same count, different order 5 | * Given two strings(lower case a -> z) how many chars do we need to remove to make them anagrams 6 | * Example: glue, legs --> Answer: 2 (u from glue and s from legs) 7 | */ 8 | 9 | public class Anagram { 10 | 11 | public static final int NUMBER_OF_CHARACTERS = 26; 12 | 13 | public int numberOfChanges(String firstString, String secondString) { 14 | int[] charCountFirst = getCharCount(firstString); 15 | int[] charCountSecond = getCharCount(secondString); 16 | return getDelta(charCountFirst, charCountSecond); 17 | } 18 | 19 | private int[] getCharCount(String str) { 20 | int[] charCount = new int[NUMBER_OF_CHARACTERS]; 21 | int offset = (int) 'a'; 22 | for (char c : str.toCharArray()) { 23 | charCount[c - offset]++; 24 | } 25 | return charCount; 26 | } 27 | 28 | private int getDelta(int[] charCount1, int[] charCount2) { 29 | int diff = 0; 30 | for (int i = 0; i < NUMBER_OF_CHARACTERS; i++) { 31 | diff += Math.abs(charCount1[i] - charCount2[i]); 32 | } 33 | return diff; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/utils/Template.java: -------------------------------------------------------------------------------- 1 | package utils; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStreamReader; 6 | import java.io.PrintWriter; 7 | import java.util.StringTokenizer; 8 | 9 | /** 10 | * Light competitive programming template to handle heavy reads and writes with large buffer space 11 | */ 12 | 13 | public class Template { 14 | 15 | public static BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 16 | public static StringTokenizer tr = null; 17 | public static PrintWriter out = new PrintWriter(System.out); 18 | 19 | 20 | public static void main(String[] args) { 21 | solve(); 22 | out.close(); 23 | } 24 | 25 | private static void solve() { 26 | 27 | 28 | } 29 | 30 | public static String n() { 31 | while (tr == null || !tr.hasMoreTokens()) { 32 | try { 33 | tr = new StringTokenizer(br.readLine()); 34 | } catch (IOException e) { 35 | e.printStackTrace(); 36 | } 37 | } 38 | return tr.nextToken(); 39 | } 40 | 41 | public static int ni() { 42 | return Integer.parseInt(n()); 43 | } 44 | 45 | public static long nl() { 46 | return Long.parseLong(n()); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/utils/Util.java: -------------------------------------------------------------------------------- 1 | package utils; 2 | 3 | public class Util { 4 | public static void swap(int[] a, int i, int j) { 5 | int temp = a[i]; 6 | a[i] = a[j]; 7 | a[j] = temp; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/algorithms/dynamicProgramming/FibonacciTest.java: -------------------------------------------------------------------------------- 1 | package algorithms.dynamicProgramming; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | public class FibonacciTest { 8 | 9 | @Test 10 | public void shouldGenerateFibonacciSeries() { 11 | int[] expected = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181}; 12 | Fibonacci fibonacci = new Fibonacci(); 13 | int[] series = fibonacci.fibo(20); 14 | assertArrayEquals(expected, series); 15 | } 16 | } -------------------------------------------------------------------------------- /test/algorithms/graph/DijkstrasShortestPathTest.java: -------------------------------------------------------------------------------- 1 | package algorithms.graph; 2 | 3 | import org.junit.Test; 4 | 5 | import algorithms.graph.DijkstrasShortestPath.Graph; 6 | import algorithms.graph.DijkstrasShortestPath.Vertex; 7 | 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | import java.util.Set; 11 | 12 | import static org.junit.Assert.assertEquals; 13 | 14 | public class DijkstrasShortestPathTest { 15 | 16 | Map idToName = getIdToName(); 17 | Graph graph = constructGraph(); 18 | 19 | @Test 20 | public void shouldFindTheShortestPathToAllVertexFromTheGivenSource() { 21 | DijkstrasShortestPath dijkstra = new DijkstrasShortestPath(); 22 | dijkstra.shortestPath(graph, 1); 23 | 24 | Map expectedDistance = getExpectedShortestPathDistance(); 25 | Map expectedPaths = getExpectedShortestPath(); 26 | 27 | Set vertices = graph.getVertices(); 28 | 29 | for (Vertex v : vertices) { 30 | assertEquals(expectedDistance.get(v.id).intValue(), v.distanceFromSource); 31 | assertEquals(expectedPaths.get(v.id), getPrintablePath(v)); 32 | } 33 | } 34 | 35 | private Graph constructGraph() { 36 | Graph graph = new Graph(7); 37 | graph.addEdge(1, 2, 7); 38 | graph.addEdge(2, 3, 8); 39 | graph.addEdge(3, 5, 5); 40 | graph.addEdge(1, 4, 5); 41 | graph.addEdge(5, 6, 8); 42 | graph.addEdge(4, 6, 6); 43 | graph.addEdge(5, 7, 9); 44 | graph.addEdge(6, 7, 11); 45 | graph.addEdge(4, 2, 9); 46 | graph.addEdge(4, 5, 15); 47 | graph.addEdge(2, 5, 7); 48 | return graph; 49 | } 50 | 51 | private String getPrintablePath(Vertex v) { 52 | StringBuilder br = new StringBuilder(); 53 | while (v != null) { 54 | br.append(idToName.get(v.id) + "-<"); 55 | v = v.parent; 56 | } 57 | return br.reverse().subSequence(2, br.length()).toString(); 58 | } 59 | 60 | private Map getExpectedShortestPathDistance() { 61 | return new HashMap() {{ 62 | put(1, 0); 63 | put(2, 7); 64 | put(3, 15); 65 | put(4, 5); 66 | put(5, 14); 67 | put(6, 11); 68 | put(7, 22); 69 | }}; 70 | } 71 | 72 | private Map getExpectedShortestPath() { 73 | return new HashMap() {{ 74 | put(1, "A"); 75 | put(2, "A<-B"); 76 | put(3, "A<-B<-C"); 77 | put(4, "A<-D"); 78 | put(5, "A<-B<-E"); 79 | put(6, "A<-D<-F"); 80 | put(7, "A<-D<-F<-G"); 81 | }}; 82 | } 83 | 84 | private Map getIdToName() { 85 | return new HashMap() {{ 86 | put(1, "A"); 87 | put(2, "B"); 88 | put(3, "C"); 89 | put(4, "D"); 90 | put(5, "E"); 91 | put(6, "F"); 92 | put(7, "G"); 93 | }}; 94 | } 95 | } -------------------------------------------------------------------------------- /test/algorithms/graph/Kruskal_Algorithm_Graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DhayanandBaskar/elegant-algorithms/f948168b0e2b0f28020356cfddde21cbe0e6ae25/test/algorithms/graph/Kruskal_Algorithm_Graph.png -------------------------------------------------------------------------------- /test/algorithms/graph/KruskalsMSTTest.java: -------------------------------------------------------------------------------- 1 | package algorithms.graph; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.*; 6 | 7 | import algorithms.graph.KruskalsMST.Edge; 8 | 9 | import static org.junit.Assert.*; 10 | 11 | public class KruskalsMSTTest { 12 | @Test 13 | public void shouldReturnMSTForAGivenGraph() { 14 | List graph = constructGraph(); 15 | KruskalsMST kruskal = new KruskalsMST(); 16 | List mst = kruskal.mst(graph); 17 | HashSet mstString = printableMST(mst); 18 | System.out.println(mstString); 19 | String[] expected = {"C<--5-->E", "D<--6-->F", "A<--7-->B", "E<--9-->G", "A<--5-->D", "B<--7-->E"}; 20 | for (String e : expected) { 21 | assertTrue(mstString.contains(e)); 22 | } 23 | } 24 | 25 | private HashSet printableMST(List mst) { 26 | Map idToName = getEdgeIdToName(); 27 | HashSet mstString = new HashSet<>(); 28 | for (Edge e : mst) { 29 | mstString.add(idToName.get(e.vertexOne) + "<--" + e.cost + "-->" + idToName.get(e.vertexTwo)); 30 | } 31 | return mstString; 32 | } 33 | 34 | private Map getEdgeIdToName() { 35 | Map idToName = new HashMap<>(); 36 | idToName.put(1, "A"); 37 | idToName.put(2, "B"); 38 | idToName.put(3, "C"); 39 | idToName.put(4, "D"); 40 | idToName.put(5, "E"); 41 | idToName.put(6, "F"); 42 | idToName.put(7, "G"); 43 | return idToName; 44 | } 45 | 46 | private List constructGraph() { 47 | List graph = new ArrayList<>(); 48 | graph.add(new Edge(1, 2, 7)); 49 | graph.add(new Edge(2, 3, 8)); 50 | graph.add(new Edge(3, 5, 5)); 51 | graph.add(new Edge(1, 4, 5)); 52 | graph.add(new Edge(5, 6, 8)); 53 | graph.add(new Edge(4, 6, 6)); 54 | graph.add(new Edge(5, 7, 9)); 55 | graph.add(new Edge(6, 7, 11)); 56 | graph.add(new Edge(4, 2, 9)); 57 | graph.add(new Edge(4, 5, 15)); 58 | graph.add(new Edge(2, 5, 7)); 59 | return graph; 60 | } 61 | } -------------------------------------------------------------------------------- /test/algorithms/search/BinarySearchTest.java: -------------------------------------------------------------------------------- 1 | package algorithms.search; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.assertEquals; 6 | 7 | public class BinarySearchTest { 8 | 9 | @Test 10 | public void shouldSearchAndReturnTheIndexForAGivenElement() { 11 | int[] a = {1, 4, 6, 8, 11, 23, 29, 31, 39, 42, 44, 65, 73, 81}; 12 | int index = (new BinarySearch()).search(a, 65); 13 | assertEquals(11, index); 14 | } 15 | 16 | @Test 17 | public void shouldReturnNegativeOneIfElementNotFound() { 18 | int[] a = {1, 4, 6, 8, 11, 23, 29, 31, 39, 42, 44, 65, 73, 81}; 19 | int index = (new BinarySearch()).search(a, 101); 20 | assertEquals(-1, index); 21 | } 22 | 23 | @Test 24 | public void shouldReturnNegativeOneIfSearchInvokedOnANullArray() { 25 | int index = (new BinarySearch()).search(null, 101); 26 | assertEquals(-1, index); 27 | } 28 | 29 | @Test 30 | public void shouldReturnNegativeOneIfSearchInvokedOnAnEmptyArray() { 31 | int[] a = {}; 32 | int index = (new BinarySearch()).search(a, 101); 33 | assertEquals(-1, index); 34 | } 35 | } -------------------------------------------------------------------------------- /test/algorithms/series/FibonacciTest.java: -------------------------------------------------------------------------------- 1 | package algorithms.series; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | public class FibonacciTest { 8 | 9 | @Test 10 | public void shouldGenerateFibonacciSeries() { 11 | int[] expected = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181}; 12 | Fibonacci fibonacci = new Fibonacci(); 13 | int[] series = fibonacci.fibo(20); 14 | assertArrayEquals(expected, series); 15 | } 16 | } -------------------------------------------------------------------------------- /test/algorithms/series/SieveOfEratosthenesTest.java: -------------------------------------------------------------------------------- 1 | package algorithms.series; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.List; 6 | 7 | import static org.junit.Assert.assertArrayEquals; 8 | import static org.junit.Assert.assertEquals; 9 | 10 | public class SieveOfEratosthenesTest { 11 | 12 | @Test 13 | public void shouldPrintPrimeNumbersTillGivenInput() { 14 | SieveOfEratosthenes sieve = new SieveOfEratosthenes(); 15 | Integer[] expected = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97}; 16 | List primes = sieve.primes(100); 17 | Integer[] result = new Integer[primes.size()]; 18 | result = primes.toArray(result); 19 | assertArrayEquals(expected, result); 20 | } 21 | 22 | @Test 23 | public void shouldReturnEmptyListWhenInvokedByZero() { 24 | SieveOfEratosthenes sieve = new SieveOfEratosthenes(); 25 | List primes = sieve.primes(0); 26 | assertEquals(0, primes.size()); 27 | } 28 | } -------------------------------------------------------------------------------- /test/algorithms/shuffle/KnuthShufflingTest.java: -------------------------------------------------------------------------------- 1 | package algorithms.shuffle; 2 | 3 | import org.junit.Test; 4 | 5 | import java.util.Arrays; 6 | 7 | /** 8 | * Can not assert as the shuffle produces new outputs each time we execute this test 9 | */ 10 | 11 | public class KnuthShufflingTest { 12 | @Test 13 | public void shouldShuffleAGivenArray() { 14 | int[] a = {44, 81, 23, 11, 39, 4, 1, 6, 73, 42, 29, 65, 8, 31}; 15 | System.out.println("Before: " + Arrays.toString(a)); 16 | KnuthShuffling s = new KnuthShuffling(); 17 | s.shuffle(a); 18 | System.out.println("After: " + Arrays.toString(a)); 19 | } 20 | } -------------------------------------------------------------------------------- /test/algorithms/sort/BubbleSortTest.java: -------------------------------------------------------------------------------- 1 | package algorithms.sort; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.assertArrayEquals; 6 | 7 | public class BubbleSortTest { 8 | 9 | @Test 10 | public void shouldSortTheGivenArray() { 11 | BubbleSort bubbleSort = new BubbleSort(); 12 | int[] a = {44, 81, 23, 11, 39, 4, 1, 6, 73, 42, 29, 65, 8, 31}; 13 | int[] expected = {1, 4, 6, 8, 11, 23, 29, 31, 39, 42, 44, 65, 73, 81}; 14 | bubbleSort.sort(a); 15 | assertArrayEquals(expected, a); 16 | } 17 | } -------------------------------------------------------------------------------- /test/algorithms/sort/CountingSortTest.java: -------------------------------------------------------------------------------- 1 | package algorithms.sort; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.assertArrayEquals; 6 | 7 | public class CountingSortTest { 8 | 9 | @Test 10 | public void shouldSortTheGivenArray() { 11 | CountingSort countingSort = new CountingSort(); 12 | int[] a = {9, 6, 11, 1, 3, 5, 4, 6, 8, 1, 4, 3, 1, 4, 5, 6, 9, 8, 11, 9, 3, 4, 5}; 13 | int[] expected = {1, 1, 1, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 8, 8, 9, 9, 9, 11, 11}; 14 | countingSort.sort(a, 11); 15 | assertArrayEquals(expected, a); 16 | } 17 | } -------------------------------------------------------------------------------- /test/algorithms/sort/HeapSortTest.java: -------------------------------------------------------------------------------- 1 | package algorithms.sort; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | public class HeapSortTest { 8 | 9 | @Test 10 | public void shouldSortTheGivenArray() { 11 | HeapSort sort = new HeapSort(); 12 | int[] a = {44, 81, 23, 11, 39, 4, 1, 6, 73, 42, 29, 65, 8, 31}; 13 | int[] expected = {1, 4, 6, 8, 11, 23, 29, 31, 39, 42, 44, 65, 73, 81}; 14 | sort.sort(a); 15 | assertArrayEquals(expected, a); 16 | } 17 | } -------------------------------------------------------------------------------- /test/algorithms/sort/InsertionSortTest.java: -------------------------------------------------------------------------------- 1 | package algorithms.sort; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | public class InsertionSortTest { 8 | 9 | @Test 10 | public void shouldSortTheGivenArray() { 11 | InsertionSort insertionSort = new InsertionSort(); 12 | int[] a = {44, 81, 23, 11, 39, 4, 1, 6, 73, 42, 29, 65, 8, 31}; 13 | int[] expected = {1, 4, 6, 8, 11, 23, 29, 31, 39, 42, 44, 65, 73, 81}; 14 | insertionSort.sort(a); 15 | assertArrayEquals(expected, a); 16 | } 17 | } -------------------------------------------------------------------------------- /test/algorithms/sort/MergeSortTest.java: -------------------------------------------------------------------------------- 1 | package algorithms.sort; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | public class MergeSortTest { 8 | 9 | @Test 10 | public void shouldSortTheGivenArray() { 11 | MergeSort mergeSort = new MergeSort(); 12 | int[] a = {44, 81, 23, 11, 39, 4, 1, 6, 73, 42, 29, 65, 8, 31}; 13 | int[] expected = {1, 4, 6, 8, 11, 23, 29, 31, 39, 42, 44, 65, 73, 81}; 14 | mergeSort.sort(a); 15 | assertArrayEquals(expected, a); 16 | } 17 | } -------------------------------------------------------------------------------- /test/algorithms/sort/QuickSelectSortTest.java: -------------------------------------------------------------------------------- 1 | package algorithms.sort; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.assertArrayEquals; 6 | 7 | public class QuickSelectSortTest { 8 | 9 | @Test 10 | public void shouldSortTheGivenArray() { 11 | SelectionSort selectionSort = new SelectionSort(); 12 | int[] a = {44, 81, 23, 11, 39, 4, 1, 6, 73, 42, 29, 65, 8, 31}; 13 | int[] expected = {1, 4, 6, 8, 11, 23, 29, 31, 39, 42, 44, 65, 73, 81}; 14 | selectionSort.sort(a); 15 | assertArrayEquals(expected, a); 16 | } 17 | } -------------------------------------------------------------------------------- /test/algorithms/sort/QuickSelectTest.java: -------------------------------------------------------------------------------- 1 | package algorithms.sort; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | public class QuickSelectTest { 8 | 9 | @Test 10 | public void shouldSelectKthElementFromTheGivenArray() { 11 | int[] a = {44, 81, 23, 11, 39, 4, 1, 6, 73, 42, 29, 65, 8, 31}; 12 | int kthLargest = (new QuickSelect()).select(a, 10); 13 | assertEquals(44, kthLargest); 14 | } 15 | } -------------------------------------------------------------------------------- /test/algorithms/sort/QuickSortTest.java: -------------------------------------------------------------------------------- 1 | package algorithms.sort; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | public class QuickSortTest { 8 | 9 | @Test 10 | public void shouldSortTheGivenArray() { 11 | QuickSort quickSort = new QuickSort(); 12 | int[] a = {44, 81, 23, 11, 39, 4, 1, 6, 73, 42, 29, 65, 8, 31}; 13 | int[] expected = {1, 4, 6, 8, 11, 23, 29, 31, 39, 42, 44, 65, 73, 81}; 14 | quickSort.sort(a); 15 | assertArrayEquals(expected, a); 16 | } 17 | } -------------------------------------------------------------------------------- /test/algorithms/unionFind/QuickUnionTest.java: -------------------------------------------------------------------------------- 1 | package algorithms.unionFind; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | public class QuickUnionTest { 8 | 9 | @Test 10 | public void shouldReturnTrueIfTwoElementsAreConnected() { 11 | QuickUnion quickUnion = new QuickUnion(20); 12 | quickUnion.union(5 ,4); 13 | quickUnion.union(8 ,7); 14 | quickUnion.union(11 ,9); 15 | quickUnion.union(4 ,9); 16 | quickUnion.union(6 ,9); 17 | 18 | assertTrue(quickUnion.isConnected(6, 5)); 19 | } 20 | 21 | @Test 22 | public void shouldReturnFalseIfTwoElementsAreNotConnected() { 23 | QuickUnion quickUnion = new QuickUnion(20); 24 | quickUnion.union(5 ,4); 25 | quickUnion.union(8 ,7); 26 | quickUnion.union(11 ,9); 27 | quickUnion.union(4 ,9); 28 | quickUnion.union(6 ,9); 29 | 30 | assertFalse(quickUnion.isConnected(8, 5)); 31 | } 32 | } -------------------------------------------------------------------------------- /test/dataStructures/basic/LinkedStackTest.java: -------------------------------------------------------------------------------- 1 | package dataStructures.basic; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | public class LinkedStackTest { 8 | 9 | @Test 10 | public void shouldBeAbleToPushAndPopElementsToStack() { 11 | LinkedStack stack = new LinkedStack(); 12 | stack.push(44); 13 | stack.push(55); 14 | stack.push(66); 15 | stack.push(77); 16 | stack.push(88); 17 | 18 | assertEquals(88, stack.pop()); 19 | assertEquals(77, stack.pop()); 20 | assertEquals(66, stack.pop()); 21 | assertEquals(55, stack.pop()); 22 | assertEquals(44, stack.pop()); 23 | assertTrue(stack.isEmpty()); 24 | } 25 | } -------------------------------------------------------------------------------- /test/dataStructures/basic/QueueTest.java: -------------------------------------------------------------------------------- 1 | package dataStructures.basic; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | public class QueueTest { 8 | 9 | @Test 10 | public void shouldBeAbleToEnqueAndDequeElements() { 11 | Queue queue = new Queue(); 12 | queue.enqueue(5); 13 | queue.enqueue(6); 14 | queue.enqueue(7); 15 | queue.enqueue(8); 16 | queue.enqueue(9); 17 | 18 | assertEquals(5, queue.dequeue()); 19 | assertEquals(6, queue.dequeue()); 20 | assertEquals(7, queue.dequeue()); 21 | assertEquals(8, queue.dequeue()); 22 | assertEquals(9, queue.dequeue()); 23 | } 24 | } -------------------------------------------------------------------------------- /test/dataStructures/basic/QueueWithStacksTest.java: -------------------------------------------------------------------------------- 1 | package dataStructures.basic; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | public class QueueWithStacksTest { 8 | 9 | @Test 10 | public void shouldBeAbleToEnqueAndDequeElements() { 11 | Queue queue = new Queue(); 12 | queue.enqueue(6); 13 | queue.enqueue(7); 14 | queue.enqueue(8); 15 | queue.enqueue(9); 16 | 17 | assertEquals(6, queue.dequeue()); 18 | assertEquals(7, queue.dequeue()); 19 | assertEquals(8, queue.dequeue()); 20 | assertEquals(9, queue.dequeue()); 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /test/dataStructures/basic/ResizingArrayTest.java: -------------------------------------------------------------------------------- 1 | package dataStructures.basic; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | public class ResizingArrayTest { 8 | 9 | @Test 10 | public void shouldResizeWhenCapacityExceeds() { 11 | ResizingArray array = new ResizingArray(3); 12 | array.add(10); 13 | array.add(20); 14 | array.add(30); 15 | array.add(40); 16 | array.add(50); 17 | array.add(60); 18 | array.add(70); 19 | array.add(80); 20 | 21 | assertEquals(8, array.getSize()); 22 | } 23 | 24 | @Test 25 | public void shouldResizeWhenCapacityReduces() { 26 | ResizingArray array = new ResizingArray(3); 27 | array.add(1); 28 | array.add(2); 29 | array.add(3); 30 | array.add(4); 31 | array.add(5); 32 | array.add(6); 33 | array.add(7); 34 | array.add(8); 35 | 36 | array.remove(3); 37 | array.remove(3); 38 | array.remove(3); 39 | array.remove(3); 40 | array.remove(3); 41 | array.remove(3); 42 | assertEquals(6, array.getStoreSize()); 43 | } 44 | 45 | @Test 46 | public void shouldReturnElementForAGivenIndex() { 47 | ResizingArray array = new ResizingArray(5); 48 | array.add(10); 49 | array.add(50); 50 | array.add(500); 51 | assertEquals(50, array.get(1)); 52 | } 53 | 54 | @Test 55 | public void shouldRemoveAndReturnElementFromAGivenIndex() { 56 | ResizingArray array = new ResizingArray(5); 57 | array.add(110); 58 | array.add(20); 59 | array.add(3); 60 | assertEquals(20, array.remove(1)); 61 | } 62 | 63 | } -------------------------------------------------------------------------------- /test/dataStructures/basic/StackTest.java: -------------------------------------------------------------------------------- 1 | package dataStructures.basic; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | public class StackTest { 8 | @Test 9 | public void shouldBeAbleToPushAndPopElementsToStack() { 10 | Stack stack = new Stack(10); 11 | stack.push(33); 12 | stack.push(44); 13 | stack.push(55); 14 | stack.push(66); 15 | stack.push(77); 16 | stack.push(88); 17 | 18 | assertEquals(88, stack.pop()); 19 | assertEquals(77, stack.pop()); 20 | assertEquals(66, stack.pop()); 21 | assertEquals(55, stack.pop()); 22 | assertEquals(44, stack.pop()); 23 | assertEquals(33, stack.pop()); 24 | assertTrue(stack.isEmpty()); 25 | } 26 | } -------------------------------------------------------------------------------- /test/dataStructures/binarySearchTree/BinarySearchTreeTest.java: -------------------------------------------------------------------------------- 1 | package dataStructures.binarySearchTree; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | public class BinarySearchTreeTest { 8 | 9 | @Test 10 | public void shouldBeAbleToPutAndGetValuesIntoBST() { 11 | BinarySearchTree bst = constructBST(); 12 | 13 | assertEquals(44, bst.get(3).getVal()); 14 | assertEquals(100, bst.get(1).getVal()); 15 | assertEquals(15, bst.get(11).getVal()); 16 | assertEquals(22, bst.get(6).getVal()); 17 | assertEquals(25, bst.get(5).getVal()); 18 | } 19 | 20 | @Test 21 | public void shouldReturnSizeOfBST() { 22 | BinarySearchTree bst = constructBST(); 23 | assertEquals(5, bst.size()); 24 | } 25 | 26 | @Test 27 | public void shouldFindRankForAGivenKey() { 28 | BinarySearchTree bst = constructBST(); 29 | assertEquals(3, bst.rank(6)); 30 | assertEquals(2, bst.rank(5)); 31 | 32 | } 33 | 34 | private BinarySearchTree constructBST() { 35 | BinarySearchTree bst = new BinarySearchTree(); 36 | bst.put(5, 25); 37 | bst.put(6, 22); 38 | bst.put(11, 15); 39 | bst.put(1, 100); 40 | bst.put(3, 44); 41 | return bst; 42 | } 43 | } -------------------------------------------------------------------------------- /test/dataStructures/binarySearchTree/DeletableBSTTest.java: -------------------------------------------------------------------------------- 1 | package dataStructures.binarySearchTree; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | public class DeletableBSTTest { 8 | 9 | @Test 10 | public void shouldDeleteMin() { 11 | DeletableBST bst = constructBST(); 12 | 13 | assertEquals(100, bst.get(1).getVal()); 14 | bst.deleteMin(); 15 | assertTrue(bst.get(1) == null); 16 | } 17 | 18 | @Test 19 | public void shouldDeleteMax() { 20 | DeletableBST bst = constructBST(); 21 | 22 | assertEquals(15, bst.get(11).getVal()); 23 | bst.deleteMax(); 24 | assertTrue(bst.get(11) == null); 25 | } 26 | 27 | @Test 28 | public void shouldDeleteGivenKey() { 29 | DeletableBST bst = constructBST(); 30 | 31 | assertEquals(22, bst.get(6).getVal()); 32 | bst.delete(6); 33 | assertTrue(bst.get(6) == null); 34 | } 35 | 36 | private DeletableBST constructBST() { 37 | DeletableBST bst = new DeletableBST(); 38 | bst.put(5, 25); 39 | bst.put(6, 22); 40 | bst.put(11, 15); 41 | bst.put(1, 100); 42 | bst.put(3, 44); 43 | return bst; 44 | } 45 | } -------------------------------------------------------------------------------- /test/dataStructures/binarySearchTree/OrderedOperationsBSTTest.java: -------------------------------------------------------------------------------- 1 | package dataStructures.binarySearchTree; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | public class OrderedOperationsBSTTest { 8 | @Test 9 | public void shouldFindFloorInBST() { 10 | OrderedOperationsBST bst = constructBST(); 11 | assertEquals(3, bst.floor(4).key); 12 | } 13 | 14 | @Test 15 | public void shouldFindCeilInBST() { 16 | OrderedOperationsBST bst = constructBST(); 17 | assertEquals(5, bst.ceil(4).key); 18 | } 19 | 20 | @Test 21 | public void shouldFindAndReturnMinInBST() { 22 | OrderedOperationsBST bst = constructBST(); 23 | assertEquals(15, bst.min().getVal()); 24 | } 25 | 26 | @Test 27 | public void shouldFindAndReturnMaxInBST() { 28 | OrderedOperationsBST bst = constructBST(); 29 | assertEquals(100, bst.max().getVal()); 30 | } 31 | 32 | private OrderedOperationsBST constructBST() { 33 | OrderedOperationsBST bst = new OrderedOperationsBST(); 34 | 35 | bst.put(5, 25); 36 | bst.put(6, 22); 37 | bst.put(1, 15); 38 | bst.put(100, 100); 39 | bst.put(3, 44); 40 | 41 | return bst; 42 | } 43 | } -------------------------------------------------------------------------------- /test/dataStructures/binarySearchTree/ShortestPathInBSTTest.java: -------------------------------------------------------------------------------- 1 | package dataStructures.binarySearchTree; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | public class ShortestPathInBSTTest { 8 | 9 | @Test 10 | public void shouldFindShortestPathInBST() { 11 | BinarySearchTree bst = constructBST(); 12 | ShortestPathInBST pathFinder = new ShortestPathInBST(); 13 | assertEquals("26 24 31 56 71", pathFinder.shortestPath(bst, 24, 71).trim()); 14 | } 15 | 16 | private BinarySearchTree constructBST() { 17 | BinarySearchTree bst = new BinarySearchTree(); 18 | 19 | bst.put(15, 15); 20 | bst.put(7, 7); 21 | bst.put(11, 11); 22 | bst.put(20, 20); 23 | bst.put(31, 31); 24 | bst.put(56, 56); 25 | bst.put(42, 42); 26 | bst.put(71, 71); 27 | bst.put(26, 26); 28 | bst.put(6, 6); 29 | bst.put(3, 3); 30 | bst.put(4, 4); 31 | bst.put(24, 24); 32 | 33 | return bst; 34 | } 35 | } -------------------------------------------------------------------------------- /test/dataStructures/binarySearchTree/TraversableBSTTest.java: -------------------------------------------------------------------------------- 1 | package dataStructures.binarySearchTree; 2 | 3 | import dataStructures.basic.Queue; 4 | import org.junit.Test; 5 | 6 | import static org.junit.Assert.*; 7 | 8 | public class TraversableBSTTest { 9 | 10 | @Test 11 | public void shouldReturnBSTKeysViaQueueInOrder() { 12 | TraversableBST bst = constructBST(); 13 | Queue queue = bst.inOrderKeys(); 14 | assertEquals(1, queue.dequeue()); 15 | assertEquals(3, queue.dequeue()); 16 | assertEquals(5, queue.dequeue()); 17 | assertEquals(6, queue.dequeue()); 18 | assertEquals(11, queue.dequeue()); 19 | } 20 | 21 | @Test 22 | public void shouldReturnBSTKeysViaQueuePreOrder() { 23 | TraversableBST bst = constructBST(); 24 | Queue queue = bst.preOrderKeys(); 25 | assertEquals(5, queue.dequeue()); 26 | assertEquals(1, queue.dequeue()); 27 | assertEquals(3, queue.dequeue()); 28 | assertEquals(6, queue.dequeue()); 29 | assertEquals(11, queue.dequeue()); 30 | } 31 | 32 | @Test 33 | public void shouldReturnBSTKeysViaQueuePostOrder() { 34 | TraversableBST bst = constructBST(); 35 | Queue queue = bst.postOrderKeys(); 36 | assertEquals(3, queue.dequeue()); 37 | assertEquals(1, queue.dequeue()); 38 | assertEquals(11, queue.dequeue()); 39 | assertEquals(6, queue.dequeue()); 40 | assertEquals(5, queue.dequeue()); 41 | } 42 | 43 | 44 | private TraversableBST constructBST() { 45 | TraversableBST bst = new TraversableBST(); 46 | bst.put(5, 26); 47 | bst.put(6, 22); 48 | bst.put(11, 15); 49 | bst.put(1, 100); 50 | bst.put(3, 44); 51 | return bst; 52 | } 53 | 54 | } -------------------------------------------------------------------------------- /test/dataStructures/heap/MinHeapTest.java: -------------------------------------------------------------------------------- 1 | package dataStructures.heap; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | public class MinHeapTest { 8 | 9 | @Test 10 | public void shouldPopMinElementOnAGivenSequenceOfElements() { 11 | MinHeap heap = new MinHeap(20); 12 | heap.add(55); 13 | heap.add(5); 14 | heap.add(11); 15 | heap.add(14); 16 | heap.add(33); 17 | heap.add(2); 18 | heap.add(7); 19 | heap.add(109); 20 | heap.add(5); 21 | 22 | int min = heap.getMin(); 23 | assertEquals(2, min); 24 | } 25 | 26 | @Test 27 | public void shouldPopTheElementsInAssentingOrder() { 28 | MinHeap heap = new MinHeap(20); 29 | heap.add(66); 30 | heap.add(5); 31 | heap.add(11); 32 | heap.add(14); 33 | heap.add(33); 34 | heap.add(2); 35 | heap.add(7); 36 | heap.add(6); 37 | heap.add(5); 38 | heap.add(105); 39 | heap.add(555); 40 | 41 | int[] a = new int[11]; 42 | for (int i = 0; i < a.length; i++) { 43 | a[i] = heap.pop(); 44 | } 45 | int[] expected = {2, 5, 5, 6, 7, 11, 14, 33, 66, 105, 555}; 46 | assertArrayEquals(expected, a); 47 | } 48 | 49 | @Test 50 | public void shouldReturnMinElementWithoutRemovingFromHeapOnPeek() { 51 | MinHeap heap = new MinHeap(20); 52 | heap.add(66); 53 | heap.add(5); 54 | heap.add(11); 55 | heap.add(14); 56 | 57 | assertEquals(5, heap.peek()); 58 | assertEquals(5, heap.peek()); 59 | } 60 | 61 | @Test 62 | public void shouldReturnSizeOfHeap() { 63 | MinHeap heap = new MinHeap(20); 64 | heap.add(66); 65 | heap.add(5); 66 | heap.add(11); 67 | heap.add(105); 68 | heap.add(555); 69 | 70 | assertEquals(5, heap.size()); 71 | } 72 | 73 | @Test 74 | public void shouldReturnTrueIfHeapIsEmpty() { 75 | MinHeap heap = new MinHeap(20); 76 | heap.add(66); 77 | heap.pop(); 78 | assertTrue(heap.isEmpty()); 79 | } 80 | 81 | @Test 82 | public void shouldCreateCopyOfAHeapUsingConstructor() { 83 | MinHeap heap = new MinHeap(20); 84 | heap.add(66); 85 | heap.add(5); 86 | heap.add(11); 87 | heap.add(14); 88 | heap.add(105); 89 | heap.add(555); 90 | 91 | MinHeap newHeap = new MinHeap(heap); 92 | assertEquals(5, newHeap.pop()); 93 | assertEquals(11, newHeap.pop()); 94 | assertEquals(14, newHeap.pop()); 95 | assertEquals(66, newHeap.pop()); 96 | assertEquals(105, newHeap.pop()); 97 | assertEquals(555, newHeap.pop()); 98 | } 99 | } -------------------------------------------------------------------------------- /test/dataStructures/heap/TopTransactionsTest.java: -------------------------------------------------------------------------------- 1 | package dataStructures.heap; 2 | 3 | import org.junit.Before; 4 | import org.junit.Test; 5 | 6 | import static org.junit.Assert.*; 7 | 8 | public class TopTransactionsTest { 9 | 10 | TopTransactions topTransactions; 11 | 12 | @Before 13 | public void setup() { 14 | topTransactions = new TopTransactions(5); 15 | } 16 | 17 | @Test 18 | public void WhenNoElementsAdded_ShouldReturnEmptyList() { 19 | assertEquals(0, topTransactions.find().size()); 20 | } 21 | 22 | @Test 23 | public void WhenTenTransactionsAreAdded_ShouldReturnTopFive() { 24 | topTransactions.add(11); 25 | topTransactions.add(7); 26 | topTransactions.add(12); 27 | topTransactions.add(6); 28 | topTransactions.add(13); 29 | topTransactions.add(5); 30 | topTransactions.add(14); 31 | topTransactions.add(8); 32 | topTransactions.add(15); 33 | topTransactions.add(9); 34 | topTransactions.add(100); 35 | 36 | assertEquals("[12, 13, 14, 15, 100]", topTransactions.find().toString()); 37 | 38 | topTransactions.add(81); 39 | topTransactions.add(47); 40 | topTransactions.add(99); 41 | topTransactions.add(1001); 42 | 43 | assertEquals("[47, 81, 99, 100, 1001]", topTransactions.find().toString()); 44 | } 45 | } -------------------------------------------------------------------------------- /test/dataStructures/linkedList/CycleInLinkedListTest.java: -------------------------------------------------------------------------------- 1 | package dataStructures.linkedList; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | public class CycleInLinkedListTest { 8 | 9 | @Test 10 | public void shouldReturnTrueIfCycleIsPresent() { 11 | CycleInLinkedList list = constructLinkedList(); 12 | 13 | LinkedList.Node a = list.find(5); 14 | LinkedList.Node b = list.find(9); 15 | 16 | list.link(a, b); 17 | 18 | assertTrue(list.findCycle()); 19 | } 20 | 21 | @Test 22 | public void shouldReturnFalseIfCycleIsNotPresent() { 23 | CycleInLinkedList list = constructLinkedList(); 24 | assertFalse(list.findCycle()); 25 | } 26 | 27 | private CycleInLinkedList constructLinkedList() { 28 | CycleInLinkedList list = new CycleInLinkedList(); 29 | 30 | list.linkFirst(5); 31 | list.linkFirst(6); 32 | list.linkFirst(7); 33 | list.linkFirst(8); 34 | list.linkFirst(9); 35 | list.linkFirst(10); 36 | list.linkFirst(11); 37 | 38 | return list; 39 | } 40 | } -------------------------------------------------------------------------------- /test/dataStructures/linkedList/DoublyLinkedListTest.java: -------------------------------------------------------------------------------- 1 | package dataStructures.linkedList; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.assertEquals; 6 | 7 | public class DoublyLinkedListTest { 8 | 9 | @Test 10 | public void shouldBeAbleToAddElementsAndIterateThroughList() { 11 | DoublyLinkedList doublyLinkedList = constructLinkedList(); 12 | 13 | DoublyLinkedList.Node n = doublyLinkedList.getFirst(); 14 | StringBuilder br = new StringBuilder(); 15 | int count = 1; 16 | while (n != null) { 17 | if (n.getData() % 2 == 1 && count++ < 10) { 18 | doublyLinkedList.linkBetween(n.getData() + 1, n); 19 | } 20 | br.append(n.getData() + " "); 21 | n = n.getNext(); 22 | } 23 | System.out.println(br.toString().trim()); 24 | assertEquals("5 6 7 8 9 10 11 12", br.toString().trim()); 25 | } 26 | 27 | @Test 28 | public void shouldBeAbleToTraverseTheLinkedListInReverseOrder() { 29 | DoublyLinkedList list = constructLinkedList(); 30 | 31 | DoublyLinkedList.Node node = list.getLast(); 32 | StringBuilder br = new StringBuilder(); 33 | while (node != null) { 34 | br.append(node.getData() + " "); 35 | node = node.getPrev(); 36 | } 37 | 38 | System.out.println(br.toString().trim()); 39 | assertEquals("11 9 7 5", br.toString().trim()); 40 | } 41 | 42 | private DoublyLinkedList constructLinkedList() { 43 | DoublyLinkedList list = new DoublyLinkedList(); 44 | list.linkFirst(7); 45 | list.linkFirst(5); 46 | list.linkLast(9); 47 | list.linkLast(11); 48 | return list; 49 | } 50 | } -------------------------------------------------------------------------------- /test/dataStructures/linkedList/LinkedListTest.java: -------------------------------------------------------------------------------- 1 | package dataStructures.linkedList; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | public class LinkedListTest { 8 | 9 | @Test 10 | public void shouldBeAbleToAddElementsAndIterateThroughList() { 11 | LinkedList list = constructLinkedList(); 12 | 13 | LinkedList.Node node = list.getFirst(); 14 | StringBuilder br = new StringBuilder(); 15 | int count = 1; 16 | while (node != null) { 17 | if (node.getData() % 2 == 1 && count++ < 10) 18 | list.linkBetween(node.getData() + 1, node); 19 | br.append(node.getData() + " "); 20 | node = node.getNext(); 21 | } 22 | System.out.println(br.toString().trim()); 23 | assertEquals("5 6 7 8 9 10 11 12", br.toString().trim()); 24 | } 25 | 26 | private LinkedList constructLinkedList() { 27 | LinkedList list = new LinkedList(); 28 | list.linkFirst(7); 29 | list.linkFirst(5); 30 | list.linkLast(9); 31 | list.linkLast(11); 32 | return list; 33 | } 34 | } -------------------------------------------------------------------------------- /test/dataStructures/linkedList/ReverseASinglyLinkedListTest.java: -------------------------------------------------------------------------------- 1 | package dataStructures.linkedList; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | public class ReverseASinglyLinkedListTest { 8 | 9 | @Test 10 | public void shouldReverseASinglyLinkedList() { 11 | ReverseASinglyLinkedList reverser = new ReverseASinglyLinkedList(); 12 | LinkedList.Node node = reverser.reverse(constructLinkedList().getFirst()); 13 | StringBuilder br = new StringBuilder(); 14 | while (node != null) { 15 | br.append(node.getData() + " "); 16 | node = node.getNext(); 17 | } 18 | 19 | System.out.println(br.toString().trim()); 20 | assertEquals("11 10 9 8", br.toString().trim()); 21 | } 22 | 23 | private LinkedList constructLinkedList() { 24 | LinkedList list = new LinkedList(); 25 | list.linkLast(8); 26 | list.linkLast(9); 27 | list.linkLast(10); 28 | list.linkLast(11); 29 | return list; 30 | } 31 | } -------------------------------------------------------------------------------- /test/dataStructures/trie/TrieRecursionTest.java: -------------------------------------------------------------------------------- 1 | package dataStructures.trie; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | public class TrieRecursionTest { 8 | 9 | @Test 10 | public void shouldBeAbleToAddMultipleWordsAndTestIfTheyArePresent() { 11 | Trie trie = new TrieRecursion(); 12 | 13 | trie.insert("application"); 14 | trie.insert("apple"); 15 | trie.insert("app"); 16 | trie.insert("ice"); 17 | trie.insert("day"); 18 | trie.insert("dream"); 19 | trie.insert("dreamer"); 20 | 21 | assertTrue(trie.isPresent("application")); 22 | assertTrue(trie.isPresent("apple")); 23 | assertTrue(trie.isPresent("dreamer")); 24 | assertTrue(trie.isPresent("ice")); 25 | assertTrue(trie.isPresent("app")); 26 | } 27 | 28 | @Test 29 | public void shouldReturnCountOfWordsThatStartWithTheGivenWord() { 30 | Trie trie = new TrieRecursion(); 31 | trie.insert("application"); 32 | trie.insert("apple"); 33 | trie.insert("app"); 34 | trie.insert("ice"); 35 | 36 | assertEquals(3, trie.findCount("app")); 37 | } 38 | 39 | @Test 40 | public void shouldDeleteWordFromTrie() { 41 | TrieRecursion trie = new TrieRecursion(); 42 | 43 | trie.insert("app"); 44 | trie.insert("application"); 45 | trie.insert("apple"); 46 | trie.insert("ice"); 47 | 48 | assertTrue(trie.isPresent("apple")); 49 | trie.delete("apple"); 50 | assertFalse(trie.isPresent("apple")); 51 | } 52 | } -------------------------------------------------------------------------------- /test/dataStructures/trie/TrieTest.java: -------------------------------------------------------------------------------- 1 | package dataStructures.trie; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | public class TrieTest { 8 | 9 | @Test 10 | public void shouldBeAbleToAddMultipleWordsAndTestIfTheyArePresent() { 11 | Trie trie = new Trie(); 12 | trie.insert("apple"); 13 | trie.insert("application"); 14 | trie.insert("app"); 15 | trie.insert("ice"); 16 | trie.insert("day"); 17 | trie.insert("dream"); 18 | trie.insert("dreamer"); 19 | 20 | assertTrue(trie.isPresent("application")); 21 | assertTrue(trie.isPresent("apple")); 22 | assertTrue(trie.isPresent("dreamer")); 23 | assertTrue(trie.isPresent("ice")); 24 | assertTrue(trie.isPresent("app")); 25 | } 26 | 27 | @Test 28 | public void shouldReturnCountOfWordsThatStartWithTheGivenWord() { 29 | Trie trie = new Trie(); 30 | trie.insert("apple"); 31 | trie.insert("application"); 32 | trie.insert("app"); 33 | trie.insert("ice"); 34 | 35 | assertEquals(3, trie.findCount("app")); 36 | } 37 | } -------------------------------------------------------------------------------- /test/problems/bitManipulation/LonelyIntegerTest.java: -------------------------------------------------------------------------------- 1 | package problems.bitManipulation; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | public class LonelyIntegerTest { 8 | 9 | @Test 10 | public void shouldFindLonelyIntegerGivenAListOfIntegers() { 11 | int[] integers = {5, 7, 1, 8, 3, 6, 7, 3, 5, 1, 6}; 12 | LonelyInteger lonelyInteger = new LonelyInteger(); 13 | 14 | int loner = lonelyInteger.find(integers); 15 | 16 | assertEquals(8, loner); 17 | } 18 | } -------------------------------------------------------------------------------- /test/problems/string/AnagramTest.java: -------------------------------------------------------------------------------- 1 | package problems.string; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | public class AnagramTest { 8 | 9 | @Test 10 | public void GivenTwoStrings_ShouldReturnTheNumberOfChangesToConvertToAnagram() { 11 | Anagram anagram = new Anagram(); 12 | assertEquals(6, anagram.numberOfChanges("hello", "billion")); 13 | } 14 | } --------------------------------------------------------------------------------