├── .gitignore ├── DataStructures ├── TreeNode.java ├── InorderTraversal.java ├── PreorderTraversal.java ├── PostorderTraversal.java ├── Queueby2Stacks.java ├── DoublyLinkedList1.java ├── Bag.java ├── Stackby2queues.java ├── DetectCycleInDirectedGraph.java ├── LinkedList.java ├── DoublyLinkedList.java ├── SegementTree.java └── Graph.java ├── Algorithms ├── SearchingSorting │ ├── BinarySearch.java │ ├── BucketSort.java │ ├── KMP.java │ ├── CountingSort.java │ ├── HeapSort.java │ ├── ReversePairs.java │ ├── InsertionSort.java │ ├── MergeSort.java │ └── QuickSort.java ├── Graph │ ├── dijkstra_cpp.cpp │ ├── DetectCycleInDirectedGraph.java │ ├── MST_Prim.java │ ├── Dijkstra.java │ ├── DetectCycleInUndirectedGraphByBFS.java │ └── MST_Kruskal.java └── DivideAndConquer │ └── KaratsubaMultiplication.java └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | /target/ 3 | /.classpath 4 | /*.project 5 | /.settings 6 | /*.springBeans 7 | .vscode 8 | -------------------------------------------------------------------------------- /DataStructures/TreeNode.java: -------------------------------------------------------------------------------- 1 | package DataStructures; 2 | 3 | 4 | public class TreeNode { 5 | int val; 6 | TreeNode left; 7 | TreeNode right; 8 | TreeNode (int i) { 9 | val = i; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Algorithms/SearchingSorting/BinarySearch.java: -------------------------------------------------------------------------------- 1 | package SearchingSorting; 2 | 3 | // Binary Search 4 | // @happygirlzt 5 | // Created on 19 Aug, 2018 6 | 7 | // The worstTime(n) is O(logn) 8 | public class BinarySearch { 9 | public static int binarysearch(int[] a, int key) { 10 | int low = 0; 11 | int high = a.length - 1; 12 | 13 | while (low <= high) { 14 | int mid = (low + high) >> 1; // same effect as (low + high) / 2 15 | 16 | int midVal = a[mid]; 17 | 18 | if (midVal < key) { 19 | low = mid + 1; 20 | } else if (midVal > key) { 21 | high = mid - 1; 22 | } else { 23 | return mid; 24 | } 25 | } 26 | 27 | return -(low + 1); // not found; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /DataStructures/InorderTraversal.java: -------------------------------------------------------------------------------- 1 | package DataStructures; 2 | 3 | /** 4 | * Using Stack to implement the inorder traversal of binary tree 5 | * Created on 2018-08-26 6 | * @author happygirlzt 7 | * 8 | */ 9 | 10 | import java.util.Stack; 11 | 12 | public class InorderTraversal { 13 | public void iterative(TreeNode root) { 14 | Stack st = new Stack<>(); 15 | 16 | TreeNode cur = root; 17 | 18 | while (cur != null || !st.empty()) { 19 | // Reach the leftmost node 20 | while (cur != null) { 21 | st.push(cur); 22 | cur = cur.left; 23 | } 24 | 25 | cur = st.pop(); 26 | 27 | cur = cur.right; 28 | } 29 | } 30 | 31 | public void inOrder(TreeNode root) { 32 | if (root == null) return; 33 | 34 | if (root.left != null) inOrder(root.left); 35 | System.out.println(root.val + " "); 36 | if (root.right != null) inOrder(root.right); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /DataStructures/PreorderTraversal.java: -------------------------------------------------------------------------------- 1 | package DataStructures; 2 | 3 | /** 4 | * Preorder traversal iteratively and recursively. 5 | * 6 | * @author happygirlzt 7 | * 8 | */ 9 | import java.util.Stack; 10 | 11 | public class PreorderTraversal { 12 | public void iterative(TreeNode root) { 13 | if (root == null) return; 14 | 15 | Stack st = new Stack<>(); 16 | TreeNode cur = root; 17 | st.push(cur); 18 | 19 | while (!st.isEmpty()) { 20 | cur = st.pop(); 21 | System.out.println(cur.val + " "); 22 | 23 | if (cur.right != null) { 24 | st.push(cur.right); 25 | } 26 | 27 | if (cur.left != null) { 28 | st.push(cur.left); 29 | } 30 | } 31 | } 32 | 33 | public void preOrder(TreeNode root) { 34 | if (root == null) return; 35 | 36 | System.out.println(root.val + " "); 37 | if (root.left != null) preOrder(root.left); 38 | if (root.right != null) preOrder(root.right); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Algorithms/SearchingSorting/BucketSort.java: -------------------------------------------------------------------------------- 1 | import java.util.List; 2 | import java.util.Collections; 3 | 4 | public class BucketSort { 5 | static void bucketSort(int[] a, int n) { 6 | List[] buckets = new List[12]; 7 | 8 | for (int i = 0; i < n; i++) { 9 | int bi = a[i]; 10 | 11 | buckets[bi].add(a[i]); 12 | } 13 | 14 | for (int i = 0; i < n; i++) { 15 | Collections.sort(buckets[i]); 16 | } 17 | 18 | int index = 0; 19 | for (int i = 0; i < n; i++) { 20 | for (int j = 0; j < buckets[i].size(); j++) { 21 | a[index++] = buckets[i].get(j); 22 | } 23 | } 24 | } 25 | 26 | static void printArray(int[] a) { 27 | for (int i = 0; i < a.length; i++) { 28 | System.out.print(a[i] + " "); 29 | } 30 | 31 | System.out.println(); 32 | } 33 | 34 | public static void main(String[] args) { 35 | int[] a = {1, 9, 2, 4, 7, 3}; 36 | int n = a.length; 37 | bucketSort(a, n); 38 | 39 | printArray(a); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /DataStructures/PostorderTraversal.java: -------------------------------------------------------------------------------- 1 | package DataStructures; 2 | 3 | 4 | /** 5 | * Postorder traversal iteratively and recursively 6 | * @author happygirlzt 7 | * 8 | */ 9 | import java.util.Stack; 10 | 11 | public class PostorderTraversal { 12 | public void iteratively(TreeNode root) { 13 | if (root == null) 14 | return; 15 | // Create two stacks 16 | Stack s1 = new Stack<>(); 17 | Stack s2 = new Stack<>(); 18 | 19 | TreeNode cur = root; 20 | s1.push(cur); 21 | 22 | // Run while s1 is not empty() 23 | while (!s1.isEmpty()) { 24 | cur = s1.pop(); 25 | s2.push(cur); 26 | 27 | if (cur.left != null) { 28 | s1.push(cur.left); 29 | } 30 | 31 | if (cur.right != null) { 32 | s1.push(cur.right); 33 | } 34 | } 35 | 36 | // All nodes are in s2 37 | while (!s2.isEmpty()) { 38 | TreeNode tmp = s2.pop(); 39 | System.out.println(tmp.val + " "); 40 | } 41 | } 42 | 43 | public void postOrder(TreeNode root) { 44 | if (root == null) return; 45 | 46 | if (root.left != null) postOrder(root.left); 47 | if (root.right != null) postOrder(root.right); 48 | System.out.println(root.val + " "); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /DataStructures/Queueby2Stacks.java: -------------------------------------------------------------------------------- 1 | package DataStructures; 2 | 3 | /* 4 | Java program to implement a queue by 2 stacks 5 | 6 | empty() 7 | peek() 8 | pop() 9 | push(e item) 10 | */ 11 | 12 | 13 | import java.util.*; 14 | 15 | public class Queueby2Stacks { 16 | // Initiate two stacks 17 | public static Stack s1 = new Stack<>(); 18 | public static Stack s2 = new Stack<>(); 19 | 20 | public static int curr_size; 21 | 22 | public Queueby2Stacks() { 23 | curr_size = 0; 24 | } 25 | 26 | public static void push(int x) { 27 | s1.push(x); 28 | curr_size++; 29 | } 30 | 31 | public static int pop() { 32 | if(s1.empty() && s2.empty()) { 33 | System.out.println("Q is empty."); 34 | System.exit(0); 35 | } 36 | // Move elements from s1 to s2 only if 37 | // s2 is empty. 38 | if(s2.empty()) { 39 | while(!s1.empty()) { 40 | s2.push(s1.pop()); 41 | } 42 | } 43 | 44 | int y = s2.pop(); 45 | curr_size--; 46 | return y; 47 | } 48 | 49 | public static int size() { 50 | return curr_size; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Algorithms/SearchingSorting/KMP.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Created on 18 May 2019 by happygirlzt 3 | * 4 | * Modified from CLRS 5 | * 6 | */ 7 | 8 | // Reference: https://web.stanford.edu/class/cs97si/10-string-algorithms.pdf 9 | 10 | public class KMP { 11 | public int kmp(String t, String p) { 12 | int n = t.length(); 13 | int m = p.length(); 14 | if (m == 0) return 0; 15 | 16 | int[] pi = new int[m]; 17 | computePrefix(p, pi); 18 | 19 | int k = -1; 20 | for (int i = 0; i < n; i++) { 21 | while (k >= 0 && p.charAt(k + 1) != t.charAt(i)) { 22 | k = pi[k]; 23 | } 24 | 25 | if (p.charAt(k + 1) == t.charAt(i)) { 26 | k++; 27 | } 28 | 29 | if (k == m - 1) { 30 | return i - m + 1; 31 | } 32 | } 33 | 34 | return -1; 35 | } 36 | 37 | private void computePrefix(String p, int[] pi) { 38 | pi[0] = -1; 39 | int k = -1; 40 | int m = p.length(); 41 | for (int i = 1; i < m; i++) { 42 | while (k >= 0 && p.charAt(k + 1) != p.charAt(i)) { 43 | k = pi[k]; 44 | } 45 | 46 | if (p.charAt(k + 1) == p.charAt(i)) { 47 | k++; 48 | } 49 | 50 | pi[i] = k; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Algorithms/Graph/dijkstra_cpp.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Created on 25 Jun 2019 by happygirlzt 3 | * 4 | */ 5 | 6 | #include 7 | using namespace std; 8 | 9 | int dist[100005]; 10 | bool visited[100005]; 11 | 12 | vector< pair > v[100005]; 13 | 14 | void dijkstra() { 15 | multiset< pair > q; 16 | q.insert({0, 1}); 17 | 18 | while (!q.empty()) { 19 | pair< int, int > cur = *q.begin(); 20 | q.erase(q.begin()); 21 | 22 | int next = cur.second; 23 | if (visited[next]) continue; 24 | visited[next] = true; 25 | 26 | for (int i = 0; i < v[next].size(); i++) { 27 | int x = v[next][i].first; 28 | int y = v[next][i].second; 29 | 30 | if (dist[next] + y < dist[x]) { 31 | dist[x] = dist[next] + y; 32 | q.insert({dist[x], x}); 33 | } 34 | } 35 | } 36 | } 37 | 38 | int main() { 39 | int m, n, x, y, w; 40 | cin >> n >> m; 41 | 42 | for (int i = 0; i <= n + 4; i++) { 43 | dist[i] = 1e9; 44 | visited[i] = false; 45 | } 46 | 47 | dist[0] = 0; 48 | dist[1] = 0; 49 | 50 | for (int i = 0; i < m; i++) { 51 | cin >> x >> y >> w; 52 | v[x].push_back(make_pair(y, w)); 53 | } 54 | 55 | dijkstra(); 56 | for (int i = 2; i <= n; i++) { 57 | cout << dist[i] << " "; 58 | } 59 | 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /Algorithms/SearchingSorting/CountingSort.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Created on 4 Jun 2019 by happygirlzt 3 | * 4 | * Hackerearth Link: https://www.hackerearth.com/zh/practice/algorithms/sorting/counting-sort/tutorial/ 5 | * 6 | */ 7 | 8 | import java.util.*; 9 | 10 | class CountingSort { 11 | public static void countSort(int[] a, int[] count) { 12 | int[] sorted = new int[a.length]; 13 | for (int i = 0; i < a.length; i++) { 14 | count[a[i]]++; 15 | } 16 | 17 | int index = 0; 18 | 19 | for (int i = 0; i < count.length; i++) { 20 | int tmp = count[i]; 21 | 22 | while (tmp > 0) { 23 | sorted[index++] = i; 24 | tmp--; 25 | } 26 | } 27 | 28 | System.arraycopy(sorted, 0, a, 0, a.length); 29 | } 30 | 31 | public static void main(String args[] ) throws Exception { 32 | Scanner s = new Scanner(System.in); 33 | int n = s.nextInt(); 34 | int[] a = new int[n]; 35 | int max = Integer.MIN_VALUE; 36 | for (int i = 0; i < n; i++) { 37 | a[i] = s.nextInt(); 38 | max = Math.max(max, a[i]); 39 | } 40 | 41 | int[] count = new int[max + 1]; 42 | countSort(a, count); 43 | 44 | for (int i = 0; i < n; i++) { 45 | System.out.println(a[i] + " " + count[a[i]]); 46 | int tmp = count[a[i]]; 47 | while (--tmp > 0) { 48 | i++; 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Algorithms/SearchingSorting/HeapSort.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Creaeted on 18 Sep 2018 by happygirlzt 3 | * 4 | * Updated on 11 Jun 2019 5 | * 6 | * A heap sort uses a binary heap. It first adds all the elements to a heap 7 | * and then removes the largest elements successively to obtain a sorted list. 8 | */ 9 | 10 | import java.util.*; 11 | 12 | public class HeapSort { 13 | public static void heapSort(int[] a) { 14 | int n = a.length; 15 | for (int i = n / 2 - 1; i >= 0; i--) { 16 | heapify(a, n, i); 17 | } 18 | 19 | for (int i = n - 1; i >= 0; i--) { 20 | swap(a, i, 0); 21 | heapify(a, i, 0); 22 | } 23 | } 24 | 25 | private static void swap(int[] a, int i, int j) { 26 | int tmp = a[i]; 27 | a[i] = a[j]; 28 | a[j] = tmp; 29 | } 30 | 31 | private static void heapify(int[] a, int n, int i) { 32 | int largest = i; 33 | int left = i * 2 + 1; 34 | int right = i * 2 + 2; 35 | 36 | if (left < n && a[left] > a[largest]) { 37 | largest = left; 38 | } 39 | 40 | if (right < n && a[right] > a[largest]) { 41 | largest = right; 42 | } 43 | 44 | if (largest != i) { 45 | swap(a, largest, i); 46 | heapify(a, n, largest); 47 | } 48 | } 49 | 50 | public static void main(String[] args) { 51 | int[] a = {12, 11, 13, 5, 0, 2}; 52 | int n = a.length; 53 | 54 | heapSort(a); 55 | System.out.println(Arrays.toString(a)); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Algorithms/Graph/DetectCycleInDirectedGraph.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Created on 27 Jun 2019 by happygirlzt 3 | * 4 | * Detect Cycle in Directed Graph by DFS 5 | * 6 | */ 7 | import java.util.*; 8 | 9 | public class DetectCycleInDirectedGraph { 10 | public static boolean hasCycle(int n, int[][] edges) { 11 | List[] g = new List[n]; 12 | int[] colors = new int[n]; 13 | buildGraph(g, edges); 14 | 15 | for (int i = 0; i < n; i++) { 16 | if (colors[i] == 0 && dfs(g, i, colors)) return true; 17 | } 18 | 19 | return false; 20 | } 21 | 22 | private static boolean dfs(List[] g, int cur, int[] colors) { 23 | if (g[cur] == null || g[cur].size() == 0) return false; 24 | 25 | colors[cur] = 1; 26 | for (int next : g[cur]) { 27 | if (colors[next] == 1) return true; 28 | if (colors[next] == 0 && dfs(g, next, colors)) return true; 29 | } 30 | 31 | colors[cur] = 2; 32 | return false; 33 | } 34 | 35 | private static void buildGraph(List[] g, int[][] edges) { 36 | for (int[] e : edges) { 37 | int from = e[0]; 38 | int to = e[1]; 39 | if (g[from] == null) { 40 | g[from] = new LinkedList<>(); 41 | } 42 | 43 | g[from].add(to); 44 | } 45 | } 46 | 47 | public static void main(String[] args) { 48 | int n = 4; 49 | int[][] edges = {{0, 1}, {0, 2}, {1, 3}, {2, 3}}; 50 | int source = 0, destination = 3; 51 | 52 | System.out.println(hasCycle(n, edges)); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Algorithms/SearchingSorting/ReversePairs.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Created on 16 May 2019 by happygirlzt 3 | * 4 | * Find the count of the reversed pairs in a given array 5 | * 6 | */ 7 | 8 | import java.util.*; 9 | 10 | class ReversePairs { 11 | public static long count = 0; 12 | 13 | public static void main(String args[] ) throws Exception { 14 | Scanner s = new Scanner(System.in); 15 | int n = s.nextInt(); 16 | int[] a = new int[n]; 17 | for (int i = 0; i < n; i++) { 18 | a[i] = s.nextInt(); 19 | } 20 | 21 | mergeSort(a, 0, n - 1); 22 | System.out.println(count); 23 | } 24 | 25 | private static void mergeSort(int[] a, int lo, int hi) { 26 | if (lo >= hi) return; 27 | 28 | int mid = lo + (hi - lo) / 2; 29 | 30 | mergeSort(a, lo, mid); 31 | mergeSort(a, mid + 1, hi); 32 | merge(a, lo, mid, hi); 33 | } 34 | 35 | private static void merge(int[] a, int lo, int mid, int hi) { 36 | int p = lo, q = mid + 1; 37 | 38 | int[] nums = new int[hi - lo + 1]; 39 | int index = 0; 40 | 41 | while (p <= mid && q <= hi) { 42 | if (a[p] > a[q]) { 43 | count += mid - p + 1; 44 | nums[index++] = a[q++]; 45 | } else { 46 | nums[index++] = a[p++]; 47 | } 48 | } 49 | 50 | while (p <= mid) { 51 | nums[index++] = a[p++]; 52 | } 53 | 54 | while (q <= hi) { 55 | nums[index++] = a[q++]; 56 | } 57 | 58 | System.arraycopy(nums, 0, a, lo, hi - lo + 1); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /DataStructures/DoublyLinkedList1.java: -------------------------------------------------------------------------------- 1 | class DoublyLinkedList { 2 | class Node { 3 | Node prev; 4 | Node next; 5 | int val; 6 | public Node(int v) { 7 | val = v; 8 | } 9 | } 10 | 11 | Node head; 12 | Node tail; 13 | 14 | public DoublyLinkedLits() { 15 | head = null; 16 | tail = null; 17 | } 18 | // Operation 0: Insert at the first 19 | public void insertHead(int data) { 20 | Node newNode = new Node(data); 21 | 22 | newNode.next = head; 23 | newNode.prev = null; 24 | 25 | if (head != null) { 26 | head.prev = newNode; 27 | } 28 | 29 | head = newNode; 30 | } 31 | 32 | // Opertaion 1: Insert after a given node 33 | public void insertAfter(Node preNode, int data) { 34 | Node newNode = new Node(data); 35 | 36 | if (preNode == null) return; 37 | newNode.next = preNode.next; 38 | newNode.prev = preNode; 39 | preNode.next = newNode; 40 | 41 | if (newNode.next != null) { 42 | newNode.next.prev = newNode; 43 | } 44 | } 45 | 46 | // Operation 2: Insert at the end 47 | public void insertTail(int data) { 48 | Node newNode = new Node(data); 49 | 50 | Node last = head; 51 | 52 | newNode.next = null; 53 | // the linked list is empty 54 | if (head == null) { 55 | newNode.prev = null; 56 | head = newNode; 57 | return; 58 | } 59 | 60 | while (last.next != null) { 61 | last = last.next; 62 | } 63 | 64 | last.next = newNode; 65 | newNode.prev = last; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /DataStructures/Bag.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Created on 16 Oct 2018 by happygirlzt 3 | * 4 | * Implement of bag ADT 5 | */ 6 | 7 | import java.util.Iterator; 8 | import java.util.NoSuchElementException; 9 | 10 | public class Bag implements Iterable { 11 | private ListNode first; 12 | private int n; 13 | 14 | private static class ListNode { 15 | private Item item; 16 | private ListNode next; 17 | } 18 | 19 | /** 20 | * Initialize 21 | */ 22 | public Bag() { 23 | first = null; 24 | n = 0; 25 | } 26 | 27 | public boolean isEmpty() { 28 | return first == null; 29 | } 30 | 31 | public int size() { 32 | return n; 33 | } 34 | 35 | /** 36 | * Add a new item before the first 37 | */ 38 | public void add(Item item) { 39 | ListNode dummy = first; 40 | first = new ListNode(); 41 | first.item = item; 42 | first.next = dummy; 43 | n++; 44 | } 45 | 46 | public class ListIterator implements Iterator { 47 | private ListNode cur; 48 | 49 | public ListIterator(ListNode first) { 50 | cur = first; 51 | } 52 | 53 | public boolean hasNext() { 54 | return cur != null; 55 | } 56 | 57 | public void remove() { 58 | throw new UnsupportedOperationException(); 59 | } 60 | 61 | public Item next() { 62 | if (!hasNext()) { 63 | throw new NoSuchElementException(); 64 | } 65 | Item item = cur.item; 66 | cur = cur.next; 67 | return item; 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Algorithms/SearchingSorting/InsertionSort.java: -------------------------------------------------------------------------------- 1 | package SearchingSorting; 2 | 3 | /** 4 | * Time complexity is O(n^2) 5 | */ 6 | public class InsertionSort{ 7 | 8 | public static void insertionSort(int arr[]) { 9 | int n = arr.length; 10 | for (int i = 1; i < n; i ++) { 11 | int key = arr[i]; 12 | int j = i - 1; 13 | 14 | /* Move elements of arr[0..i-1], 15 | that are greater than key, to one 16 | position ahead of their current 17 | position */ 18 | while (j >= 0 && arr[j] > key) { 19 | arr[j+1] = arr[j]; 20 | j = j - 1; 21 | } 22 | 23 | arr[j+1] = key; 24 | } 25 | } 26 | 27 | /* Print array of size n */ 28 | public static void printArray(int arr[]) { 29 | int n = arr.length; 30 | for (int i = 0; i < n; i++) { 31 | System.out.print(arr[i] + " "); 32 | } 33 | System.out.println(); 34 | } 35 | 36 | // UPD on 18 Sep 2018 37 | 38 | public static void insertionSort1(int[] list) { 39 | for (int i = 1; i < list.length; i++) { 40 | /** Insert list[i] into a sorted sublist list[0...i-1] so that 41 | list[0...i] is sorted */ 42 | int cur = list[i]; 43 | int k; 44 | for (k = i - 1; k >= 0 && list[k] > cur; k--) { 45 | list[k + 1] = list[k]; 46 | } 47 | 48 | // Insert the current element into list[k + 1] 49 | list[k + 1] = cur; 50 | } 51 | } 52 | 53 | 54 | public static void main(String[] args) { 55 | int arr[] = {12, 11, 14, 23, 2}; 56 | 57 | insertionSort(arr); 58 | 59 | printArray(arr); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /DataStructures/Stackby2queues.java: -------------------------------------------------------------------------------- 1 | package DataStructures; 2 | 3 | // Java program to implement a stack using two queues 4 | 5 | import java.util.LinkedList; 6 | import java.util.Queue; 7 | 8 | public class Stackby2queues { 9 | public static Queue q1 = new LinkedList<>(); 10 | public static Queue q2 = new LinkedList<>(); 11 | 12 | public static int curr_size; 13 | 14 | public Stackby2queues(){ 15 | curr_size = 0; 16 | } 17 | 18 | public static void pop() { 19 | if (q1.isEmpty()) { 20 | return; 21 | } 22 | 23 | // leave one element in q1 and 24 | // push others in q2 25 | while(q1.size() != 1) { 26 | q2.add(q1.peek()); 27 | q1.remove(); 28 | } 29 | 30 | // remove the only left element 31 | // from q1 32 | q1.remove(); 33 | curr_size--; 34 | 35 | // swap the names of two queues 36 | Queue q = q1; 37 | q1 = q2; 38 | q2 = q; 39 | } 40 | 41 | public static void push(int x) { 42 | q1.add(x); 43 | curr_size++; 44 | } 45 | 46 | public static int top() { 47 | if (q1.isEmpty()) 48 | return -1; 49 | 50 | while(q1.size() != 1) { 51 | q2.add(q1.peek()); 52 | q1.remove(); 53 | } 54 | 55 | // last pushed element 56 | int temp = q1.peek(); 57 | 58 | // to empty the auxiliary queue after 59 | // last operation 60 | q1.remove(); 61 | 62 | // push last element to q2 63 | q2.add(temp); 64 | 65 | // swap the two queues names 66 | Queue q = q1; 67 | q1 = q2; 68 | q2 = q; 69 | return temp; 70 | } 71 | 72 | public int size() { 73 | return curr_size; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /DataStructures/DetectCycleInDirectedGraph.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Created on 23 Sep 2018 by happygirlzt 3 | * 4 | * Detect cycle in a directed graph 5 | */ 6 | 7 | import java.util.ArrayList; 8 | import java.util.LinkedList; 9 | import java.util.List; 10 | 11 | public class DetectCycleInDirectedGraph { 12 | class Graph { 13 | int vertices; 14 | LinkedList[] adjList; 15 | 16 | // Created empty graph with v vertices 17 | Graph(int vertices) { 18 | this.vertices = vertices; 19 | adjList = new LinkedList[vertices]; 20 | for (int i = 0; i < vertices; i++) { 21 | adjList[i] = new LinkedList<>(); 22 | } 23 | } 24 | } 25 | 26 | // add an edge v-w 27 | public void addEgde(int v, int w) { 28 | adjList[v].addFirst(w); 29 | } 30 | 31 | public boolean isCycle() { 32 | boolean visited[] = new boolean[vertices]; 33 | boolean recursiveArr[] = new boolean[vertices]; 34 | 35 | // do DFS from each node 36 | for (int i = 0; i < vertices; i++) { 37 | if (isCycleUnil(i, visited, recursiveArr)) 38 | return true; 39 | } 40 | 41 | return false; 42 | } 43 | 44 | public boolean isCycleUtil(int vertex, boolean[] visited, boolean[] recursiveArr) { 45 | visited[vertex] = true; 46 | recursiveArr[vertex] = true; 47 | 48 | // recursive call to all the adjacent vertices 49 | for (int i = 0; i < adjList[vertex].size(); i++) { 50 | // if not already visited 51 | int adjVertex = adjList[vertex].get(i); 52 | if (!visited[adjVertex] && isCycleUtil(adjVertex, visited, recursiveArr)) { 53 | return true; 54 | } else if (recursiveArr[adjVertex]) { 55 | return true; 56 | } 57 | } 58 | 59 | recursiveArr[vertex] = false; 60 | return false; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Algorithms/Graph/MST_Prim.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Created on 15 May 2019 by happygirlzt 3 | * 4 | * Minimum spanning tree, Prim's Algorithm 5 | * 6 | * Credit to https://www.hackerearth.com/zh/practice/algorithms/graphs/minimum-spanning-tree/tutorial/ 7 | */ 8 | 9 | import java.util.*; 10 | 11 | class MST_Prim { 12 | static class Pair { 13 | int weight; 14 | int y; 15 | public Pair(int w, int b) { 16 | weight = w; 17 | y = b; 18 | } 19 | } 20 | 21 | public static void main(String[] args) { 22 | Scanner s = new Scanner(System.in); 23 | int nodes = s.nextInt(); 24 | int edges = s.nextInt(); 25 | Map> g = new HashMap<>(); 26 | for (int i = 0; i < edges; i++) { 27 | int a = s.nextInt(); 28 | int b = s.nextInt(); 29 | int w = s.nextInt(); 30 | g.putIfAbsent(a, new ArrayList<>()); 31 | g.putIfAbsent(b, new ArrayList<>()); 32 | g.get(a).add(new Pair(w, b)); 33 | g.get(b).add(new Pair(w, a)); 34 | } 35 | 36 | int minimumCost = prim(1, g); 37 | System.out.println(minimumCost); 38 | } 39 | 40 | private static int prim(int x, Map> g) { 41 | boolean[] visited = new boolean[10005]; 42 | PriorityQueue heap = new PriorityQueue<>((a, b) -> a.weight - b.weight); 43 | heap.offer(new Pair(0, x)); 44 | 45 | int minimumCost = 0; 46 | while (!heap.isEmpty()) { 47 | Pair p = heap.poll(); 48 | x = p.y; 49 | if (visited[x]) continue; 50 | visited[x] = true; 51 | minimumCost += p.weight; 52 | 53 | for (int i = 0; i < g.get(x).size(); i++) { 54 | if (!visited[g.get(x).get(i).y]) { 55 | heap.offer(g.get(x).get(i)); 56 | } 57 | } 58 | } 59 | 60 | return minimumCost; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Algorithms/SearchingSorting/MergeSort.java: -------------------------------------------------------------------------------- 1 | package SearchingSorting; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * Stable 7 | * Time Complexity: O(NlogN) in all cases 8 | * Space Complexity: O(N) 9 | */ 10 | public class MergeSort { 11 | public static void sort(int[] nums) { 12 | mergeSort(nums, 0, nums.length - 1); 13 | } 14 | 15 | private static void mergeSort(int[] nums, int lo, int hi) { 16 | if (lo >= hi) return; 17 | int mid = lo + (hi - lo) / 2; 18 | mergeSort(nums, lo, mid); 19 | mergeSort(nums, mid + 1, hi); 20 | merge(nums, lo, mid, mid + 1, hi); 21 | } 22 | 23 | // lo0 - hi0, lo1 - hi2 24 | private static void merge(int[] nums, int lo0, int hi0, int lo1, int hi1) { 25 | int size1 = hi0 - lo0 + 1; 26 | int size2 = hi1 - lo1 + 1; 27 | int[] a1 = new int[size1]; 28 | System.arraycopy(nums, lo0, a1, 0, size1); 29 | int[] a2 = new int[size2]; 30 | System.arraycopy(nums, lo1, a2, 0, size2); 31 | 32 | /* 33 | System.out.println(Arrays.toString(a1)); 34 | System.out.println(Arrays.toString(a2)); 35 | System.out.println(Arrays.toString(nums)); 36 | */ 37 | 38 | // ATTENTION: this is lo0, not 0 39 | int index = lo0; 40 | int i = 0, j = 0; 41 | while (i < size1 && j < size2) { 42 | if (a1[i] <= a2[j]) { 43 | nums[index++] = a1[i++]; 44 | } else { 45 | nums[index++] = a2[j++]; 46 | } 47 | } 48 | 49 | while (i < size1) { 50 | nums[index++] = a1[i++]; 51 | } 52 | 53 | while (j < size2) { 54 | nums[index++] = a2[j++]; 55 | } 56 | } 57 | 58 | public static void main(String[] args) { 59 | int[] a = { 3, 5, 8, 2, 1, 0, -3 }; 60 | System.out.println(Arrays.toString(a)); 61 | 62 | sort(a); 63 | System.out.println(Arrays.toString(a)); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Algorithms/DivideAndConquer/KaratsubaMultiplication.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Integer Multiplication 3 | * 4 | * Created on 21 Jan 2019 by happygirlzt 5 | * 6 | */ 7 | 8 | import java.math.BigInteger; 9 | import java.util.Random; 10 | 11 | public class KaratsubaMultiplication { 12 | private final static BigInteger ZERO = new BigInteger("0"); 13 | 14 | public static BigInteger karatsuba(BigInteger x, BigInteger y) { 15 | int N = Math.max(x.bitLength(), y.bitLength()); 16 | if (N <= 2000) return x.multiply(y); 17 | 18 | N = (N / 2) + (N % 2); 19 | 20 | BigInteger b = x.shiftRight(N); 21 | BigInteger a = x.subtract(b.shiftLeft(N)); 22 | BigInteger d = y.shiftRight(N); 23 | BigInteger c = y.subtract(d.shiftLeft(N)); 24 | 25 | BigInteger ac = karatsuba(a, c); 26 | BigInteger bd = karatsuba(b, d); 27 | BigInteger abcd = karatsuba(a.add(b), c.add(d)); 28 | 29 | return ac.add(abcd.subtract(ac).subtract(bd).shiftLeft(N).add(bd.shiftLeft(2 * N))); 30 | } 31 | 32 | public static void main(String[] args) { 33 | long start, stop, elapsed; 34 | Random random = new Random(); 35 | int N = 8888; 36 | BigInteger a = new BigInteger(N, random); 37 | System.out.println("====================================================================="); 38 | System.out.println("a is " + a.toString()); 39 | BigInteger b = new BigInteger(N, random); 40 | System.out.println("b is " + b.toString()); 41 | 42 | start = System.currentTimeMillis(); 43 | System.out.println("Starting..."); 44 | BigInteger c = karatsuba(a, b); 45 | stop = System.currentTimeMillis(); 46 | System.out.println("Stopped"); 47 | System.out.println("Time used by Karatsuba " + (stop - start)); 48 | 49 | start = System.currentTimeMillis(); 50 | BigInteger d = a.multiply(b); 51 | stop = System.currentTimeMillis(); 52 | System.out.println("Time used " + (stop - start)); 53 | 54 | System.out.println(c.equals(d)); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Algorithms/Graph/Dijkstra.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Created 16 May 2019 by happygirlzt 3 | * 4 | * Single Source Shortest Path, Dijkstra's Algorithm 5 | * 6 | */ 7 | 8 | class Dijkstra { 9 | static class Pair { 10 | int weight; 11 | int y; 12 | public Pair(int w, int y) { 13 | weight = w; 14 | this.y = y; 15 | } 16 | } 17 | 18 | public static void main(String[] args) { 19 | Scanner s = new Scanner(System.in); 20 | int n = s.nextInt(); 21 | int m = s.nextInt(); 22 | 23 | Map> g = new HashMap<>(); 24 | for (int i = 0; i < m; i++) { 25 | int a = s.nextInt(); 26 | int b = s.nextInt(); 27 | int w = s.nextInt(); 28 | 29 | g.putIfAbsent(a, new ArrayList<>()); 30 | g.putIfAbsent(b, new ArrayList<>()); 31 | g.get(a).add(new Pair(w, b)); 32 | g.get(b).add(new Pair(w, a)); 33 | } 34 | 35 | int[] res = new int[n - 1]; 36 | dijsktra(g, res); 37 | System.out.println(Arrays.toString(res)); 38 | } 39 | 40 | private static void dijkstra(Map> g, int[] res) { 41 | boolean[] visited = new boolean[100005]; 42 | int[] dist = new int[100005]; 43 | Arrays.fill(dist, Integer.MAX_VALUE); 44 | dist[1] = 0; 45 | PriorityQueue heap = new PriorityQueue<>((a, b) -> a.weight - b.weight); 46 | heap.offer(new Pair(0, 1)); 47 | 48 | int index = 0; 49 | while (!heap.isEmpty()) { 50 | Pair p = heap.poll(); 51 | int x = p.y; 52 | int weight = p.weight; 53 | if (visited[x]) continue; 54 | visited[x] = true; 55 | 56 | res[index++] = weight; 57 | for (int i = 0; i < g.get(x).size(); i++) { 58 | int y = g.get(x).get(i).y; 59 | int w = g.get(x).get(i).weight; 60 | 61 | if (dist[x] + w < dist[y]) { 62 | dist[y] = dist[x] + w; 63 | heap.offer(new Pair(dist[y], y)); 64 | } 65 | } 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Algorithms/Graph/DetectCycleInUndirectedGraphByBFS.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Created on 6 Apr 2019 by happygirlzt 3 | */ 4 | 5 | import java.util.ArrayList; 6 | import java.util.Arrays; 7 | import java.util.Queue; 8 | import java.util.LinkedList; 9 | import java.util.Map; 10 | import java.util.HashMap; 11 | import java.util.Set; 12 | import java.util.HashSet; 13 | 14 | class DetectCycleInUndirectedGraphByBFS { 15 | public static void main(String[] arg) { 16 | int V = 5; 17 | Map> g = new HashMap<>(); 18 | int[][] edges = {{0, 1}, {1, 2}, {0, 3}, {0, 2}, {3, 4}}; 19 | buildGraph(g, edges); 20 | 21 | if (hasCycle(g, V)) { 22 | System.out.println("This graph has cycle"); 23 | } else { 24 | System.out.println("This graph does not have cycle"); 25 | } 26 | } 27 | 28 | private static void buildGraph(Map> g, int[][] edges) { 29 | for (int[] edge : edges) { 30 | g.putIfAbsent(edge[0], new HashSet<>()); 31 | g.putIfAbsent(edge[1], new HashSet<>()); 32 | g.get(edge[0]).add(edge[1]); 33 | g.get(edge[1]).add(edge[0]); 34 | } 35 | } 36 | 37 | public static boolean hasCycle(Map> g, int V) { 38 | boolean[] visited = new boolean[V]; 39 | for (int i = 0; i < V; i++) { 40 | if (!visited[i] && bfs(g, i, V, visited)) return true; 41 | } 42 | 43 | return false; 44 | } 45 | 46 | private static boolean bfs(Map> g, int s, int V, boolean[] visited) { 47 | int[] parent = new int[V]; 48 | Arrays.fill(parent, -1); 49 | 50 | Queue q = new LinkedList<>(); 51 | 52 | visited[s] = true; 53 | q.add(s); 54 | 55 | while (!q.isEmpty()) { 56 | int u = q.poll(); 57 | 58 | if (g.get(u).size() == 0) continue; 59 | for (int v : g.get(u)) { 60 | if (!visited[v]) { 61 | visited[v] = true; 62 | q.offer(v); 63 | parent[v] = u; 64 | } else if (parent[u] != v) return true; 65 | } 66 | } 67 | 68 | return false; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Algorithms/SearchingSorting/QuickSort.java: -------------------------------------------------------------------------------- 1 | /** 2 | * QuickSort - Best Ω(n log(n)) Worst O(n^2) 3 | * 4 | * Created on 2018-08-28 by happygirlzt 5 | * 6 | * UPD on 18 Sep 2018 7 | * UPD on 20 Feb 2019 8 | * 9 | * public void quickSort(int[] list) { 10 | * if (list.length > 1) { 11 | * select a pivot; 12 | * partition list into list1 and list2 such that 13 | * all elements in list1 <= pivot and 14 | * all elements in list2 > pivot 15 | * quickSort(list1); 16 | * quickSort(list2); 17 | * } 18 | * } 19 | * Time complexity: O(n) partition time 20 | * O(n^2) worst time, the pivot divides the array each time into one big 21 | * subarray with the other array empty 22 | * O(nlogn) best time, the pivot divides the array each into two parts of 23 | * about the same size. T(n) = T(n/2) + T(n/2) + n 24 | * Not stable 25 | */ 26 | 27 | // Hackerearch Link: https://www.hackerearth.com/zh/practice/algorithms/sorting/quick-sort/tutorial/ 28 | 29 | import java.util.*; 30 | 31 | class QuickSort { 32 | private static void quickSort(int[] a, int lo, int hi) { 33 | if (lo >= hi) return; 34 | int pivot = partition(a, lo, hi); 35 | 36 | quickSort(a, lo, pivot - 1); 37 | quickSort(a, pivot + 1, hi); 38 | } 39 | 40 | private static int partition(int[] a, int lo, int hi) { 41 | Random random = new Random(); 42 | int pivotIndex = random.nextInt(hi - lo + 1) + lo; 43 | int pivotValue = a[pivotIndex]; 44 | int savedPosition = hi; 45 | swap(a, hi, pivotIndex); 46 | hi--; 47 | 48 | while (lo <= hi) { 49 | if (a[lo] > pivotValue) { 50 | swap(a, lo, hi); 51 | hi--; 52 | } else { 53 | lo++; 54 | } 55 | } 56 | 57 | swap(a, lo, savedPosition); 58 | return lo; 59 | } 60 | 61 | private static void swap(int[] a, int lo, int hi) { 62 | int tmp = a[lo]; 63 | a[lo] = a[hi]; 64 | a[hi] = tmp; 65 | } 66 | 67 | public static void main(String args[] ) throws Exception { 68 | Scanner s = new Scanner(System.in); 69 | int n = s.nextInt(); 70 | int[] a = new int[n]; 71 | for (int i = 0; i < n; i++) { 72 | a[i] = s.nextInt(); 73 | } 74 | 75 | quickSort(a, 0, n - 1); 76 | for (int i = 0; i < n; i++) { 77 | System.out.print(a[i] + " "); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Algorithms/Graph/MST_Kruskal.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Created on 15 May 2019 by happygirlzt 3 | * 4 | * Minimum Spanning Tree, Kruskal’s Algorithm 5 | * 6 | * Credit to https://www.hackerearth.com/zh/practice/algorithms/graphs/minimum-spanning-tree/tutorial/ 7 | * 8 | */ 9 | 10 | class MST_Kruskal { 11 | class Edge { 12 | int weight; 13 | int x; 14 | int y; 15 | public Pair(int w, int a, int b) { 16 | weight = w; 17 | x = a; 18 | y = b; 19 | } 20 | } 21 | 22 | class DSU { 23 | int[] root; 24 | int[] size; 25 | 26 | public DSU(int n) { 27 | root = new int[n]; 28 | size = new int[n]; 29 | 30 | for (int i = 0; i < n; i++) { 31 | root[i] = i; 32 | } 33 | 34 | Arrays.fill(size, 1); 35 | } 36 | 37 | public int find(int x) { 38 | if (root[x] != x) { 39 | root[x] = find(root[x]); 40 | } 41 | 42 | return root[x]; 43 | } 44 | 45 | public void union(int x, int y) { 46 | int rootX = find(x); 47 | int rootY = find(y); 48 | if (rootX == rootY) { 49 | return; 50 | } 51 | 52 | if (size[rootX] < size[rootY]) { 53 | root[rootX] = rootY; 54 | size[rootY]++; 55 | } else { 56 | root[rootY] = rootX; 57 | size[rootX]++; 58 | } 59 | } 60 | } 61 | 62 | private static int kruskal(Edge[] edges) { 63 | DSU dsu = new DSU(10005); 64 | 65 | int minimumCost = 0; 66 | for (Edge e : edges) { 67 | int x = e.x; 68 | int y = e.y; 69 | int weight = e.weight; 70 | 71 | if (dsu.find(x) != dsu.find(y)) { 72 | minimumCost += weight; 73 | dsu.union(x, y); 74 | } 75 | } 76 | 77 | return minimimCost; 78 | } 79 | 80 | public static void main(String[] args) { 81 | Scanner s = new Scanner(System.in); 82 | int n = s.nextInt(); 83 | int m = s.nextInt(); 84 | 85 | Edge[] edges = new Edge[m]; 86 | for (int i = 0; i < m; i++) { 87 | int a = s.nextInt(); 88 | int b = s.nextInt(); 89 | int w = s.nextInt(); 90 | 91 | edges[i] = new Edge(w, a, b); 92 | } 93 | 94 | int minimumCost = kruskal(edges); 95 | System.out.println(minimumCost); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /DataStructures/LinkedList.java: -------------------------------------------------------------------------------- 1 | class LinkedList { 2 | 3 | class ListNode { 4 | public int val; 5 | public ListNode next; 6 | public ListNode(int v) { 7 | val = v; 8 | } 9 | } 10 | 11 | private ListNode dummy; 12 | private int size; 13 | 14 | public MyLinkedList() { 15 | dummy = new ListNode(0); 16 | size = 0; 17 | } 18 | 19 | /** Get the value of the index-th node in the linked list. If the index is invalid, return -1. */ 20 | public int get(int index) { 21 | if (index > size - 1) return -1; 22 | ListNode p = dummy; 23 | while (index-- > 0) { 24 | p = p.next; 25 | } 26 | 27 | return p.next.val; 28 | } 29 | 30 | /** Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list. */ 31 | public void addAtHead(int val) { 32 | size++; 33 | ListNode added = new ListNode(val); 34 | added.next = dummy.next; 35 | dummy.next = added; 36 | // showNode(); 37 | } 38 | 39 | /** Append a node of value val to the last element of the linked list. */ 40 | public void addAtTail(int val) { 41 | size++; 42 | ListNode p = dummy; 43 | while (p.next != null) { 44 | p = p.next; 45 | } 46 | p.next = new ListNode(val); 47 | } 48 | 49 | /** Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted. */ 50 | public void addAtIndex(int index, int val) { 51 | if (index == size) { 52 | addAtTail(val); 53 | } else if (index > size) { 54 | return; 55 | } else { 56 | size++; 57 | ListNode p = dummy; 58 | while (index-- > 0) { 59 | p = p.next; 60 | } 61 | 62 | ListNode added = new ListNode(val); 63 | added.next = p.next; 64 | p.next = added; 65 | } 66 | } 67 | 68 | /** Delete the index-th node in the linked list, if the index is valid. */ 69 | public void deleteAtIndex(int index) { 70 | if (index > size - 1) return; 71 | ListNode p = dummy; 72 | while (index-- > 0) { 73 | p = p.next; 74 | } 75 | 76 | ListNode post = p.next.next; 77 | p.next = post; 78 | size--; 79 | } 80 | 81 | public void showNode() { 82 | ListNode p = dummy; 83 | while (p != null) { 84 | System.out.print(p.val + " "); 85 | p = p.next; 86 | } 87 | System.out.println(); 88 | } 89 | -------------------------------------------------------------------------------- /DataStructures/DoublyLinkedList.java: -------------------------------------------------------------------------------- 1 | class DoublyLinkedList { 2 | Node head; 3 | Node tail; 4 | int len; 5 | 6 | class Node { 7 | int val; 8 | Node prev; 9 | Node next; 10 | 11 | Node(int v) { 12 | val = v; 13 | } 14 | } 15 | 16 | public MyLinkedList() { 17 | len = 0; 18 | head = null; 19 | tail = null; 20 | } 21 | 22 | // Adding a node at the front of the list 23 | public void addAtHead(int val) { 24 | Node buff = head; 25 | head = new Node(val); 26 | if (tail == null) { 27 | tail = head; 28 | } else { 29 | head.next = buff; 30 | buff.prev = head; 31 | } 32 | len++; 33 | } 34 | 35 | // Add a node of val after 36 | public void addAtIndex(int index, int val) { 37 | Node cur = head; 38 | if (index == len) { 39 | addAtTail(val); 40 | return; 41 | } else if (index == 0) { 42 | addAtHead(val); 43 | return; 44 | } else if (index < len / 2) { 45 | for (int i = 1; i < index; i++) { 46 | cur = cur.next; 47 | } 48 | } else if (index < len) { 49 | cur = tail; 50 | for (int i = len - 1; i >= index; i--) { 51 | cur = cur.prev; 52 | } 53 | } else { 54 | return; 55 | } 56 | 57 | Node ins = new Node(val); 58 | ins.next = cur.next; 59 | ins.prev = cur; 60 | cur.next.prev = ins; 61 | cur.next = ins; 62 | len++; 63 | } 64 | 65 | public void addAtTail(int val) { 66 | if (tail != null) { 67 | tail.next = new Node(val); 68 | tail.next.prev = tail; 69 | tail = tail.next; 70 | } else { 71 | tail = new Node(val); 72 | head = tail; 73 | } 74 | len++; 75 | } 76 | 77 | public int get(int index) { 78 | if (index < 0 || index >= len) { 79 | return -1; 80 | } 81 | 82 | Node cur = head; 83 | if (index < len / 2) { 84 | for (int i = 1; i <= index; i++) { 85 | cur = cur.next; 86 | } 87 | } else { 88 | cur = tail; 89 | for (int i = len - 2; i >= index; i--) { 90 | cur = cur.prev; 91 | } 92 | } 93 | 94 | return cur.val; 95 | } 96 | 97 | public void deleteAtIndex(int index) { 98 | if (index < 0 || index >= len) { 99 | return; 100 | } 101 | 102 | if (len == 1) { 103 | tail = null; 104 | head = null; 105 | len--; 106 | return; 107 | } 108 | 109 | if (index == 0) { 110 | head = head.next; 111 | len--; 112 | return; 113 | } 114 | 115 | if (index == len - 1) { 116 | tail = tail.prev; 117 | len--; 118 | return; 119 | } 120 | 121 | Node cur = head; 122 | if (index < len / 2) { 123 | for (int i = 1; i <= index; i++) { 124 | cur = cur.next; 125 | } 126 | } else { 127 | cur = tail; 128 | for (int i = len - 2; i >= index; i--) { 129 | cur = cur.prev; 130 | } 131 | } 132 | 133 | cur.prev.next = cur.next; 134 | cur.next.prev = cur.prev; 135 | len--; 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | <2018-06-07 Thu> 2 | 3 | # Asymptotic Notations 4 | ## Big-Theta 5 | The theta notation bounds a functions from above and below, so it defines exact asymptotic behavior. 6 | 7 | Big-Theta serve as both a lower bound and upper bound. 8 | 9 | ## Big-O notation 10 | To determine an /upper bound/ for the behavior od a function, that is, to determine how /bad/ the performance of the function can get. 11 | 12 | ## Big-Omega 13 | To provide a crude /lower bound/ for a function. 14 | To show how good a function can be. 15 | 16 | # Data Structures 17 | ## Lists, stacks and queues 18 | ## Trees and graphs 19 | ## Sets, heaps 20 | ## Hashes and maps 21 | 22 | # Algorithms 23 | ## Sorting 24 | ### Bubble Sort 25 | ### Selection Sort 26 | ### Insertion Sort 27 | ### Merge Sort 28 | ### Quick Sort 29 | ### Counting Sort 30 | ### Radix Sort 31 | ### Heap Sort 32 | ### Bucket Sort 33 | 34 | ## Graph algorithms 35 | ### Common Problems 36 | 1. Directed or undirected 37 | 2. Weighted or not 38 | 3. Sparse or dense with edges 39 | 4. Representation: adjacency matrix, adjacency list, an edge list or other sturcture 40 | 41 | ### Minimum Spanning Tree 42 | #### Kruskal's Algorithm 43 | #### Prim's Algorithm 44 | ### Shortest Path Problem 45 | 46 | ### Connectivity 47 | 48 | ### Detect Cycle 49 | #### Directed Graphs 50 | 1. Depth First Search 51 | O(V + E) 52 | 53 | Use three colors to every vertex 54 | - white: vertex is not processed. Initially, all vertices are white 55 | - gray: vertex is being processed(dfs for this vertex has started, but not finished which means that all descendants (in dfs tree) of this vertex are not processed yet( or this vertex is in function call stack)) 56 | - black: vertex and all its descendants are processed. 57 | 58 | While doing dfs, if we encounter an edge from current vertex to a gray vertex, then this edge is back edge and hence there is a cycle. 59 | 60 | 2. Breadth First Search 61 | Step 1: Compute in-degree for each of the vertex present in the graphs 62 | Step 2: Pick all the vertices with in-degree as 0 and add them into a queue 63 | Step 3: Remove a vertex from a queue and: 64 | 1. Increment count of visited nodes by 1 65 | 2. Decrease in-degree by 1 for all its neighboring nodes 66 | 3. If in-degree of a neighboring nodes is reduced to zero, then all it to the queue 67 | Step 4: Repeat Step 3 until the queue is empty 68 | Step 5: If count of visited nodes is not equal to the number of nodes in the graphm, the graph has cycle; otherwise not; 69 | 70 | 71 | #### Undirected Graphs 72 | 1. Union-find 73 | 2. Depth-first search 74 | O(V+E) 75 | 3. Breadth-first search 76 | 77 | ### Eulerian Path 78 | O(E) 79 | 80 | Visits every edge exactly once. 81 | 82 | An Eulerian path to exist: 83 | - At most one vertex has (outdegree - indegree) = 1 84 | - At most one vertex has (indegree - outdegree) = 1 85 | - All other vertices have equal in and out degrees 86 | 87 | Find a valid starting node: 88 | The node with exactly one extra outgoing edge(outdegree - indegree = 1), it will be the only valid start node. 89 | Similarly, the node which (indegree - outdegree = 1) should be the end node. 90 | 91 | ### Topological Sort 92 | The only type of graph which has a valid topological sort: Directed Acyclic Graphs(DAG) 93 | 94 | ## Dynamic programming 95 | ## Complexity analysis 96 | 97 | # Math 98 | ## Basic probability 99 | ## Div/modulo 100 | ## Bit manipulation 101 | 102 | # Operating Systems 103 | ## Threads, locks, processes 104 | - Concurrency: multiple computations running simultaneously 105 | ### Process 106 | A process is an instance of a running program that is isolated from other processes on the same machine. It has its own private section of the machine's memory. 107 | 108 | ### Thread 109 | A thread is a locus of control inside a running program. 110 | 111 | ### Race condition 112 | The correctness of the program(the satisfaction of postconditions and invariants) depends on the relative timing of events in concurrent computations A and B. 113 | ## Memory management 114 | ## Filesystems and networking 115 | 116 | # System Design 117 | ## Distributed Systems 118 | ## Approximations 119 | 120 | # References 121 | 1. [GeeksForGeeks Asymptotic Notations](https://www.geeksforgeeks.org/analysis-of-algorithms-set-3asymptotic-notations/) 122 | 2. [Detect Cycle in a directed graph using colors](https://www.geeksforgeeks.org/detect-cycle-direct-graph-using-colors/) 123 | 3. [MIT 6.005 — Software Construction](http://web.mit.edu/6.005/www/fa15/classes/19-concurrency/) 124 | 4. [Hackerearth Algorithms Tutorial](https://www.hackerearth.com/zh/practice/algorithms/searching/linear-search/tutorial/) 125 | -------------------------------------------------------------------------------- /DataStructures/SegementTree.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by happygirlzt on 9 Jul 2020 3 | * 4 | * Range sum query https://leetcode.com/problems/range-sum-query-mutable/ 5 | */ 6 | public class SegmentTree { 7 | // Memory Limit Exceeded Error!!! 8 | class NumArray { 9 | int[] tree; 10 | int n; 11 | int[] a; 12 | // Build the segment tree 13 | private void buildTree(int[] nums, int node, int start, int end) { 14 | // System.out.println(Arrays.toString(tree)); 15 | if (start == end) { 16 | tree[node] = nums[start]; 17 | } else { 18 | int mid = start + (end - start) / 2; 19 | buildTree(nums, 2 * node, start, mid); 20 | buildTree(nums, 2 * node + 1, mid + 1, end); 21 | tree[node] = tree[node * 2] + tree[node * 2 + 1]; 22 | } 23 | } 24 | 25 | public NumArray(int[] nums) { 26 | n = nums.length; 27 | if (n == 0) return; 28 | a = new int[n + 1]; 29 | tree = new int[(int) Math.pow(2, n)]; 30 | System.arraycopy(nums, 0, a, 1, n); 31 | buildTree(a, 1, 1, n); 32 | } 33 | 34 | private void updateTree(int node, int start, int end, int i, int val) { 35 | if (start == end) { 36 | tree[node] = val; 37 | a[i] = val; 38 | } else { 39 | int mid = start + (end - start) / 2; 40 | if (start <= i && i <= mid) { // left part 41 | updateTree(node * 2, start, mid, i, val); 42 | } else { 43 | updateTree(node * 2 + 1, mid + 1, end, i, val); 44 | } 45 | 46 | tree[node] = tree[node * 2] + tree[node * 2 + 1]; 47 | } 48 | } 49 | 50 | public void update(int i, int val) { 51 | updateTree(1, 1, n, i + 1, val); 52 | } 53 | 54 | public int sumRange(int i, int j) { 55 | return query(1, 1, n, i + 1, j + 1); 56 | } 57 | 58 | private int query(int node, int start, int end, int i, int j) { 59 | // outside 60 | if (j < start || i > end) return 0; 61 | if (i <= start && end <= j) return tree[node]; 62 | int mid = start + (end - start) / 2; 63 | return query(node * 2, start, mid, i, j) + query(node * 2 + 1, mid + 1, end, i, j); 64 | } 65 | } 66 | 67 | // Use TreeNode 68 | class NumArray { 69 | class TreeNode { 70 | TreeNode left, right; 71 | int start, end; 72 | int sum; 73 | public TreeNode(int s, int e) { 74 | left = null; 75 | right = null; 76 | start = s; 77 | end = e; 78 | } 79 | } 80 | 81 | TreeNode root = null; 82 | private TreeNode buildTree(int[] nums, int start, int end) { 83 | if (start > end) return null; 84 | TreeNode res = new TreeNode(start, end); 85 | if (start == end) { 86 | res.sum = nums[start]; 87 | } else { 88 | int mid = start + (end - start) / 2; 89 | res.left = buildTree(nums, start, mid); 90 | res.right = buildTree(nums, mid + 1, end); 91 | res.sum = res.left.sum + res.right.sum; 92 | } 93 | 94 | return res; 95 | } 96 | 97 | public NumArray(int[] nums) { 98 | root = buildTree(nums, 0, nums.length - 1); 99 | } 100 | 101 | private void update(TreeNode root, int i, int val) { 102 | if (root.start == root.end) { 103 | root.sum = val; 104 | } else { 105 | int mid = root.start + (root.end - root.start) / 2; 106 | if (i <= mid) { 107 | update(root.left, i, val); 108 | } else { 109 | update(root.right, i, val); 110 | } 111 | 112 | root.sum = root.left.sum + root.right.sum; 113 | } 114 | } 115 | public void update(int i, int val) { 116 | update(root, i, val); 117 | } 118 | 119 | 120 | private int query(TreeNode root, int i, int j) { 121 | if (j == root.end && i == root.start) { 122 | return root.sum; 123 | } else { 124 | int mid = root.start + (root.end - root.start) / 2; 125 | if (j <= mid) { 126 | return query(root.left, i, j); 127 | } else if (i >= mid + 1) { 128 | return query(root.right, i, j); 129 | } else { 130 | return query(root.right, mid + 1, j) + query(root.left, i, mid); 131 | } 132 | } 133 | } 134 | public int sumRange(int i, int j) { 135 | return query(root, i, j); 136 | } 137 | } 138 | } -------------------------------------------------------------------------------- /DataStructures/Graph.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Created on 23 Sep 2018 by happygirlzt 3 | * 4 | * Graph API 5 | */ 6 | 7 | public class Graph { 8 | 9 | private final int V; // V is number of vertices 10 | private List[] adj; // Adjacency List 11 | 12 | // Created empty graph with v vertices 13 | Graph(int V) { 14 | this.V = V; 15 | adj = (List) new ArrayList[V]; 16 | for (int v = 0; v < V; v++) { 17 | adj[v] = new ArrayList(); 18 | } 19 | } 20 | 21 | // add an edge v-w 22 | public void addEdge(int v, int w) { 23 | adj[v].add(w); 24 | adj[w].add(v); 25 | } 26 | 27 | // vertices adjacent to v 28 | public Iterable adj(int v) { 29 | return adj[v]; 30 | } 31 | 32 | /** Degree of vertex v in graph G, degree = #edges */ 33 | public static int degree(Graph G, int v) { 34 | int degree = 0; 35 | for (int w : G.adj(v)) { 36 | degree += 1; 37 | } 38 | 39 | return degree; 40 | } 41 | } 42 | 43 | class DepthFirstPaths { 44 | // theta(V+E) time 45 | // theta(V) space 46 | private boolean[] marked; // marked[v] is true iff v connected to s 47 | private int[] edgeTo; // edgeTo[v] is previous vertex on path from s to v 48 | private int s; 49 | 50 | DepthFirstPaths(Graph G, int s) { 51 | ... 52 | dfs(G, s); 53 | } 54 | 55 | private void dfs(Graph G, int v) { 56 | marked[v] = true; 57 | for (int w : G.adj(v)) { 58 | if (!marked[w]) { 59 | edgeTo[w] = v; 60 | dfs(G, w); 61 | } 62 | } 63 | } 64 | } 65 | 66 | // Topological Sort Implementation 67 | class DepthFirstOrder { 68 | private boolean[] marked; 69 | private Stack reversePostorder; 70 | 71 | // Perform DFS all unmarked vertices 72 | public DepthFirstOrder(Digraph G) { 73 | reversePostorder = new Stack(); 74 | marked = new boolean[G.V()]; 75 | 76 | for (int v = 0; v < G.V(); v++) { 77 | if (!marked[v]) { 78 | dfs(G, v); 79 | } 80 | } 81 | } 82 | 83 | private void dfs(Digraph G, int v) { 84 | marked[v] = true; 85 | for (int w : G.adj(v)) { 86 | if (!marked[w]) { 87 | dfs(G, w); 88 | } 89 | } 90 | 91 | reversePostorder.push(v); 92 | } 93 | 94 | public Iterable reversePostorder() { 95 | return reversePostorder; 96 | } 97 | } 98 | 99 | // BreadthFirstPaths 100 | class BreadthFirstPaths { 101 | private boolean[] marked; // marked[v] is true iff v connected to s 102 | private int[] edgeTo; // edgeTo[v] is previous vertex on path from s to v 103 | 104 | private void bfs(Graph G, int s) { 105 | Queue fringe = new Queue<>(); 106 | 107 | // set up starting vertex 108 | fringe.enqueue(s); 109 | marked[s] = true; 110 | while (!fringe.isEmpty()) { 111 | int v = fringe.dequeue(); 112 | for (int w : G.adj(v)) { 113 | if (!marked[w]) { 114 | fringe.enqueue(w); 115 | marked[w] = true; 116 | edgeTo[w] = v; 117 | } 118 | } 119 | } 120 | } 121 | } 122 | 123 | 124 | // topological sort 125 | class TopologicalSort { 126 | // a recursive function used by topological sort 127 | void dfs(int v, boolean[] visied, Stack stack) { 128 | // mark the current node as visited 129 | visited[v] = true; 130 | Integer i; 131 | 132 | // Recur for all the vertices adjacent to this 133 | // vertex 134 | Iterator it = adj[v].iterator(); 135 | while (it.hasNext()) { 136 | i = it.next(); 137 | if (!visited[i]) { 138 | dfs(i, visited, stack); 139 | } 140 | } 141 | 142 | // push current vertex to stack which store res 143 | stack.push(new Integer(v)); 144 | } 145 | 146 | void topologicalSort() { 147 | Stack stack = new Stack<>(); 148 | 149 | // mark all the vertices as not visited 150 | boolean[] visited = new boolean[V]; 151 | for (int i = 0; i < V; i++) { 152 | visited[i] = false; 153 | } 154 | 155 | // call the dfs function to store 156 | // topological sort starting from 157 | // all vertices one by one 158 | for (int i = 0; i < V; i++) { 159 | if (visited[i] == false) { 160 | dfs(i, visited, stack); 161 | } 162 | } 163 | 164 | // print contents of stack 165 | while (!stack.isEmpty()) { 166 | System.out.print(stack.pop()); 167 | } 168 | } 169 | } 170 | 171 | // DetectCycle 172 | class CycleDetector { 173 | boolean detectCycle(ArrayList[] graph, int V) { 174 | 175 | boolean[] visited = new boolean[V]; 176 | boolean[] done = new boolean[V]; 177 | 178 | for (int i = 0; i < V; i++) { 179 | if (!dfs(graph, i, visited, done)) { 180 | return false; 181 | } 182 | } 183 | 184 | return true; 185 | } 186 | 187 | private boolean dfs(ArrayList[] graph, int v, boolean[] visited, boolean[] done) { 188 | // v 是索引 189 | visited[v] = true; 190 | 191 | for (int i = 0; i < graph[i].size(); i++) { 192 | if (!visited[i]) { 193 | return dfs(graph, i, visited, done); 194 | } else if (!done[i]) { 195 | return false; 196 | } 197 | } 198 | 199 | done[v] = true; 200 | return true; 201 | } 202 | } 203 | --------------------------------------------------------------------------------