├── Java ├── AllPossibleStrings.java ├── Anagrams.java ├── Balance.java ├── BinaryTree.java ├── CoinChange.java ├── CountPossibleDecodings.java ├── DigitPermutations.java ├── Fibonacci.java ├── FibonacciSteps.java ├── FizzBuzz.java ├── GameOfLife.java ├── Graph.java ├── HomogeneousRows.java ├── IntegerDivision.java ├── KadaneBitFlip.java ├── Karatsuba.java ├── KnuthShuffle.java ├── LongestCommonSubsequence.java ├── LongestCommonSubstring.java ├── LongestIncreasingSequence.java ├── LongestIncreasingSubsequence.java ├── LongestPalindromicSubsequence.java ├── LongestPalindromicSubstring.java ├── MaximumSubarray.java ├── MergeSort.java ├── MinimumStack.java ├── MissingRanges.java ├── NearestNeighbor.java ├── NeedleHaystack.java ├── NumericAddition.java ├── OddManOut.java ├── OrderStatistics.java ├── QueueStack.java ├── QuickSort.java ├── RansomNote.java ├── ReverseArray.java ├── ReverseWords.java ├── RotateMatrix.java ├── SetOperations.java ├── SortedArrayUnion.java ├── Sqrt.java ├── Steps.java ├── StringCompression.java ├── StringPermutations.java ├── StringToInteger.java ├── SubsetsN.java ├── SummedAreaTable.java ├── TargetSum.java ├── Thing.java ├── UniqueStringSubsets.java └── WordBreak.java ├── Python └── sqrt.py └── README.md /Java/AllPossibleStrings.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | /** 3 | * Given a number, return all possible strings that the number could represent 4 | * if 0 -> {A, B, C}, 2 -> {D, E, F}, and so on 5 | */ 6 | public class AllPossibleStrings { 7 | Character[][] arr = new Character[10][3]; 8 | String num; 9 | 10 | AllPossibleStrings(String num){ 11 | this.num = num; 12 | arr[0][0] = 'a'; arr[0][1] = 'b'; arr[0][2] = 'c'; 13 | arr[1][0] = 'd'; arr[1][1] = 'e'; arr[1][2] = 'f'; 14 | arr[2][0] = 'g'; arr[2][1] = 'h'; arr[2][2] = 'i'; 15 | arr[3][0] = 'j'; arr[3][1] = 'k'; arr[3][2] = 'l'; 16 | arr[4][0] = 'm'; arr[4][1] = 'n'; arr[4][2] = 'o'; 17 | arr[5][0] = 'p'; arr[5][1] = 'q'; arr[5][2] = 'r'; 18 | arr[6][0] = 's'; arr[6][1] = 't'; arr[6][2] = 'u'; 19 | arr[7][0] = 'v'; arr[7][1] = 'w'; arr[7][2] = 'x'; 20 | arr[8][0] = 'y'; arr[8][1] = 'z'; arr[8][2] = '~'; 21 | arr[9][0] = '!'; arr[9][1] = '@'; arr[9][2] = '#'; 22 | } 23 | 24 | void getStrings(int curr, StringBuffer charList){ 25 | int digit = Character.getNumericValue(num.charAt(curr)); 26 | // for each possible character that digit brings 27 | for (int i=0; i<3; i++){ 28 | StringBuffer temp = new StringBuffer(charList); 29 | temp.append(arr[digit][i]); // add character 30 | 31 | // if base case, print 32 | if (curr == num.length() - 1){ 33 | System.out.println(temp.toString()); 34 | } 35 | // recurse down 36 | else getStrings(curr + 1, temp); 37 | } 38 | } 39 | 40 | int getStringNum(int curr){ 41 | if (curr == num.length() - 1) return 3; 42 | int ans = 0; 43 | for(int i=0; i<3; i++){ 44 | ans += getStringNum(curr + 1); 45 | } 46 | return ans; 47 | } 48 | 49 | void run(){ 50 | getStrings(0, new StringBuffer()); 51 | System.out.println(getStringNum(0)); 52 | } 53 | 54 | public static void main(String[] args) { 55 | Scanner sc = new Scanner(System.in); 56 | (new AllPossibleStrings(sc.next())).run(); 57 | sc.close(); 58 | 59 | } 60 | } -------------------------------------------------------------------------------- /Java/Anagrams.java: -------------------------------------------------------------------------------- 1 | import java.util.Arrays; 2 | import java.util.HashMap; 3 | import java.util.Scanner; 4 | import java.util.ArrayList; 5 | 6 | 7 | public class Anagrams { 8 | String first; 9 | String second; 10 | Anagrams(String first, String second){ 11 | this.first = first; 12 | this.second = second; 13 | } 14 | 15 | /** 16 | * Given a list of strings, distribute them into anagram buckets 17 | * @param list list of strings to be sorted into buckets 18 | */ 19 | public void sortAnagrams(ArrayList list) { 20 | HashMap> bucketList = 21 | new HashMap>(); 22 | 23 | /* store each string into their anagram list */ 24 | for (String string: list) { 25 | char[] charArr = string.toCharArray(); 26 | Arrays.sort(charArr); // N(logN) 27 | String sortedString = new String(charArr); 28 | 29 | if (!bucketList.containsKey(sortedString)) { 30 | bucketList.put(sortedString, new ArrayList()); 31 | } 32 | bucketList.get(sortedString).add(string); 33 | } 34 | } 35 | 36 | /** 37 | * Compares 2 strings if they are anagrams of each other without using sort 38 | * O(N) 39 | * @param stringA first string 40 | * @param stringB second string 41 | * @returns true if both strings are anagrams of each other, 42 | * false otherwise 43 | */ 44 | boolean isAnagram(String stringA, String stringB) { 45 | if (stringA.length() != stringB.length()) return false; 46 | HashMap charMap = new HashMap(); 47 | 48 | /* iterate through each character */ 49 | for (int i=0; i entry: charMap.entrySet()) { 74 | if (entry.getValue() != 0) { 75 | return false; 76 | } 77 | } 78 | 79 | return true; 80 | } 81 | 82 | void run() { 83 | System.out.println(isAnagram(first, second)); 84 | } 85 | public static void main(String[] args) { 86 | Scanner sc = new Scanner(System.in); 87 | (new Anagrams(sc.next(), sc.next())).run(); 88 | sc.close(); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /Java/Balance.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | /** 3 | URL: http://www.careercup.com/question?id=12150672 4 | Problem Description: 5 | You have a room-full of balances and weights. Each balance weighs ten pounds and 6 | is considered perfectly balanced when the sum of weights on its left and right 7 | sides are exactly the same. You have placed some weights on some of the 8 | balances, and you have placed some of the balances on other balances. Given a 9 | description of how the balances are arranged and how much additional weight is 10 | on each balance, determine how to add weight to the balances so that they are 11 | all perfectly balanced. 12 | 13 | There may be more than one way to balance everything, but always choose the way 14 | that places additional weight on the lowest balances. 15 | 16 | The input file will begin with a single integer, N, specifying how many balances 17 | there are. Balance 0 is specified by lines 1 and 2, balance 1 is specified by 18 | lines 3 and 4, etc... Each pair of lines is formatted as follows: 19 | 20 | WL 21 | WR 22 | 23 | WL and WR indicate the weight added to the left and right sides, respectively. 24 | is a space-delimited list of the other balance that are on that side 25 | of this balance. may contain zero or more elements. 26 | 27 | Consider the following input: 28 | 4 29 | 0 1 30 | 0 2 31 | 0 32 | 0 3 33 | 3 34 | 0 35 | 0 36 | 0 37 | 38 | Balance 0 has balance 1 on its left side and balance 2 on its right side 39 | Balance 1 has balance 3 on its right side 40 | Balance 2 has three pounds on its left side 41 | Balance 3 has nothing on it 42 | 43 | Since balance 3 has nothing on it it is already perfectly balanced, and weighs a 44 | total of 10 pounds. Balance 2 has no other balance on it, so all we need to do 45 | is balance it by putting three pounds on its right side. Now it weighs a total 46 | of 16 pounds. Balance 1 has balance three on its right side, which weighs 10 47 | pounds, so we just put 10 pounds on its left side. Balance 1 weighs a total of 48 | 30 pounds. Balance 0 has balance 1 on its left side (30 pounds), and balance 2 49 | on its right side (16 pounds), we can balance it by adding 14 pounds to the 50 | right side. 51 | 52 | The output should be N lines long, with the nth line listing the weight added to 53 | the nth balance, formatted as follows: 54 | : 55 | 56 | So the output for this problem would be: 57 | 0: 0 14 58 | 1: 10 0 59 | 2: 0 3 60 | 3: 0 0 61 | */ 62 | public class Balance { 63 | Node[] balancesMap; // map of balances, array index -> id of balance 64 | String[] output; // output String where index corresponds to balance 65 | 66 | /** 67 | * recursively get the total balanced weight of a node (inclusive of itself) 68 | * O(N) since all nodes are visited once 69 | * @param aNode the node of interest 70 | * @return the total balanced weight 71 | */ 72 | public int getBalancedWeight(Node aNode) { 73 | if (!aNode._isBalance) { 74 | return aNode._weight; // if node is just a weight, return weight 75 | } 76 | 77 | /* total balanced weight of left children */ 78 | int totalLeftWeight = 0; 79 | for (Node leftChild: aNode._left) { 80 | totalLeftWeight += getBalancedWeight(leftChild); 81 | } 82 | 83 | /* total balanced weight of left children */ 84 | int totalRightWeight = 0; 85 | for (Node rightChild: aNode._right) { 86 | totalRightWeight += getBalancedWeight(rightChild); 87 | } 88 | 89 | /* formulate output string for current balance */ 90 | int diff = difference(totalLeftWeight, totalRightWeight); 91 | /* if left children are heavier than right */ 92 | if (totalLeftWeight > totalRightWeight) { 93 | output[aNode._index] = aNode._index + ": 0 " + diff; 94 | } 95 | /* if right children are heavier than left */ 96 | else if (totalLeftWeight < totalRightWeight) { 97 | output[aNode._index] = aNode._index + ": " + diff + " 0"; 98 | } 99 | /* else if equal */ 100 | else { 101 | output[aNode._index] = aNode._index + ": 0 0"; 102 | } 103 | 104 | return (aNode._weight + totalLeftWeight + totalRightWeight + diff); 105 | } 106 | 107 | /** 108 | * Helper method: returns the absolute difference between two numbers 109 | * @param a first number 110 | * @param b second number 111 | * @return absolute difference between a and b 112 | */ 113 | public int difference(int a, int b) { 114 | return Math.abs(a - b); 115 | } 116 | 117 | /** 118 | * Driver function 119 | * O(N) 120 | */ 121 | void run() { 122 | Scanner sc = new Scanner(System.in); 123 | int N = sc.nextInt(); 124 | balancesMap = new Node[N]; 125 | output = new String[N]; 126 | sc.nextLine(); 127 | 128 | /* read from inputs and populate data structure balancesMap 129 | * Time Complexity: O(N) 130 | */ 131 | for (int i=0; i<2*N; i+=2) { 132 | int index = i/2; // index of current balance 133 | Node balance; // current balance 134 | /* if balance is already init, reference from map */ 135 | if (balancesMap[index]!=null) { 136 | balance = balancesMap[index]; 137 | } 138 | /* else init and reference */ 139 | else { 140 | balance = new Node(true, index); 141 | balancesMap[index] = balance; // store in balancesMap 142 | } 143 | String firstInput = sc.nextLine(); 144 | String secondInput = sc.nextLine(); 145 | 146 | /* tokenize inputs by space */ 147 | String[] leftChildInfo = firstInput.split(" "); 148 | String[] rightChildInfo = secondInput.split(" "); 149 | 150 | /* for all the children on the left */ 151 | for (int j=0; j disjoint sets 212 | * find the balances without any parents (root nodes) 213 | * Time Complexity: O(N) 214 | */ 215 | Vector rootBalances = new Vector(); 216 | for (Node i: balancesMap) { 217 | // if balance has no parents, then it is the root node 218 | if (i._parent == null) { 219 | rootBalances.add(i); 220 | } 221 | } 222 | 223 | /* runs recursive function 224 | * Time Complexity: O(N) 225 | */ 226 | for (Node i: rootBalances) { 227 | getBalancedWeight(i); 228 | } 229 | 230 | /* prints output in order 231 | * Time Complexity: O(N) 232 | */ 233 | for (String i: output) { 234 | System.out.println(i); 235 | } 236 | 237 | /* Total Time complexity: O(N) + O(N) + O(N) + O(N) = O(N)*/ 238 | }// END: run() 239 | 240 | public static void main(String[] args){ 241 | Balance sol = new Balance(); 242 | sol.run(); 243 | } 244 | 245 | /** 246 | * Node class: Nodes are either balances or weights 247 | */ 248 | public class Node{ 249 | Vector _left; // left child list (list of weights and balances on the left) 250 | Vector _right; // right child list (list of weights and balances on the right) 251 | Node _parent; // parent node 252 | int _index; // index of balance, -1 for weights 253 | int _weight; // intrinsic weight of node 254 | boolean _isBalance; // true if node is a balance, else node is a weight 255 | 256 | public Node(boolean isBalance, int index_or_weight){ 257 | _isBalance = isBalance; 258 | if (isBalance){ 259 | _left = new Vector(); 260 | _right = new Vector(); 261 | _parent = null; 262 | _index = index_or_weight; 263 | _weight = 10; 264 | } 265 | else{ 266 | _index = -1; 267 | _weight = index_or_weight; 268 | } 269 | } 270 | } 271 | } -------------------------------------------------------------------------------- /Java/BinaryTree.java: -------------------------------------------------------------------------------- 1 | import java.util.LinkedList; 2 | /** 3 | * Algorithms on binary trees: 4 | * +--------------------+------------------------------------------------------+ 5 | * | Method Name | Description | 6 | * +--------------------+------------------------------------------------------+ 7 | * | find | given a node value, finds the node in tree using dfs | 8 | * | printPreOrder | Pre-order traversal | 9 | * | printInOrder | In-order traversal | 10 | * | printPostOrder | post-order traversal | 11 | * | isBST | checks if tree is a BST | 12 | * | getHeight | gets the height of the BST | 13 | * | isTreeBalanced | checks if the tree is height balanced | 14 | * | getLCA | determines the Lowest Common Ancestor of two nodes | 15 | * | printLevelWise | prints the tree level wise | 16 | * | printLevelAverage | prints the average value for each level in tree | 17 | * | getInOrderSuccessor| determines the in-order successor for a node | 18 | * +-------------------+------------------------------------------------------+ 19 | */ 20 | public class BinaryTree { 21 | Node root; 22 | 23 | public BinaryTree(Node root){ 24 | this.root = root; 25 | } 26 | 27 | /** 28 | * Retrieves the first node found in the tree for the given value using DFS 29 | * @param value the node value 30 | * @return a node possessing the value, null if not present in tree 31 | */ 32 | public Node find(Node subtree, int value) { 33 | /* base case: not found */ 34 | if (subtree == null) { 35 | return null; 36 | } 37 | int curr = subtree.value; 38 | if (curr == value) { 39 | return subtree; 40 | } 41 | /* check if found in left subtree */ 42 | Node leftAns = find(subtree.left, value); 43 | if (leftAns != null) { 44 | return leftAns; 45 | } 46 | /* check if found in right subtree */ 47 | Node rightAns = find(subtree.right, value); 48 | if (rightAns != null) { 49 | return rightAns; 50 | } 51 | return null; // if value not present in subtree 52 | } 53 | public Node find(int value) { 54 | return find(root, value); 55 | } 56 | 57 | /** 58 | * Prints tree in Pre-order traversal 59 | */ 60 | public void printPreOrder(Node node) { 61 | System.out.print(node + " "); 62 | if (node.left != null) { 63 | printPreOrder(node.left); 64 | } 65 | if (node.right != null) { 66 | printPreOrder(node.right); 67 | } 68 | } 69 | public void printPreOrder() { 70 | printPreOrder(root); 71 | } 72 | 73 | /** 74 | * Prints tree in In-order traversal 75 | */ 76 | public void printInOrder(Node node) { 77 | if (node.left != null) { 78 | printInOrder(node.left); 79 | } 80 | System.out.print(node + " "); 81 | if (node.right != null) { 82 | printInOrder(node.right); 83 | } 84 | } 85 | public void printInOrder() { 86 | printInOrder(root); 87 | } 88 | 89 | /** 90 | * Prints tree in Post-order traversal 91 | */ 92 | public void printPostOrder(Node node){ 93 | if (node.left != null) { 94 | printPostOrder(node.left); 95 | } 96 | if (node.right != null) { 97 | printPostOrder(node.right); 98 | } 99 | System.out.print(node + " "); 100 | } 101 | public void printPostOrder() { 102 | printPostOrder(root); 103 | } 104 | 105 | /** 106 | * Determines if tree is a BST 107 | * @param subtree root node of subtree 108 | * @param min min value for range 109 | * @param max max value of range 110 | * @return true if subtree is a BST, false otherwise 111 | */ 112 | public boolean isBST(Node subtree, int min, int max) { 113 | if (subtree == null) { 114 | return true; // empty tree is a BST 115 | } 116 | int value = subtree.value; 117 | /* if value is within range */ 118 | if (value>min && value<=max){ 119 | return (isBST(subtree.left, min, value) && 120 | isBST(subtree.right, value, max)); 121 | } 122 | else { 123 | return false; 124 | } 125 | } 126 | public boolean isBST() { 127 | return isBST(root, Integer.MIN_VALUE, Integer.MAX_VALUE); 128 | } 129 | 130 | /** 131 | * Determines the height of the subtree 132 | * @param subtree root node of subtree 133 | * @return height of subtree 134 | */ 135 | public int getHeight(Node subtree) { 136 | if (subtree == null) { 137 | return 0; 138 | } 139 | return Math.max(getHeight(subtree.left), getHeight(subtree.right)) + 1; 140 | } 141 | 142 | /** 143 | * Checks if tree is a balanced tree. A tree is balanced if its subtrees do 144 | * not differ more than 1 level in height 145 | * @return true if tree is balanced, false otherwise 146 | */ 147 | public boolean isTreeBalanced() { 148 | int diff = Math.abs(getHeight(root.left) - getHeight(root.right)); 149 | return (diff < 2); 150 | } 151 | 152 | /** 153 | * Returns the Lowest Common Ancestor (LCA) of node with xValue and node 154 | * with yValue 155 | * @param node the root node for current subtree being searched 156 | * @param xValue value of the first child node 157 | * @param yValue value of the second child node 158 | * @return the LCA or node with xValue or node with yValue or null 159 | * if nothing found 160 | */ 161 | public Node getLCA(Node node, int xValue, int yValue){ 162 | 163 | Node leftAns = null; 164 | if (node.left != null) { 165 | leftAns = getLCA(node.left, xValue, yValue); 166 | } 167 | Node rightAns = null; 168 | if (node.right != null) { 169 | rightAns = getLCA(node.right, xValue, yValue); 170 | } 171 | 172 | /* MUST BE CHECKED FIRST: else if both leftAns and rightAns are defined, 173 | * current node is LCA */ 174 | if (leftAns != null && rightAns != null) { 175 | return node; 176 | } 177 | 178 | /* if current node is either x or y*/ 179 | if (node.value == xValue || node.value == yValue) { 180 | return node; 181 | } 182 | 183 | /* else if left subtree contains only 1 (could be LCA or X or Y) */ 184 | if (leftAns != null && rightAns == null) { 185 | return leftAns; 186 | } 187 | 188 | /* else if right subtree contains only 1 (could be LCA or X or Y) */ 189 | if (rightAns != null && leftAns == null) { 190 | return rightAns; 191 | } 192 | 193 | /* if both returns null -> x and y are not found, hence LCA not found in 194 | * current subtree */ 195 | else return null; 196 | } 197 | public void getLCA(int xValue, int yValue){ 198 | Node LCAxy = getLCA(root, xValue, yValue); 199 | if (LCAxy == null) { 200 | System.out.println("both X and Y are not found in tree"); 201 | } 202 | else { 203 | if (LCAxy.value == xValue && xValue != yValue) { 204 | System.out.println("Y is not found in tree"); 205 | } 206 | else if (LCAxy.value == yValue && xValue != yValue) { 207 | System.out.println("X is not found in tree"); 208 | } 209 | else { 210 | System.out.println("LCA of " + xValue + " and " + yValue + 211 | " is " + LCAxy.value); 212 | } 213 | } 214 | } 215 | 216 | /** 217 | * prints binary tree level-wise O(N) time, O(N) space. Q will be at most 218 | * all the leaves 219 | */ 220 | public void printLevelWise(){ 221 | LinkedList> Q = new LinkedList>(); 222 | 223 | /* initial conditions */ 224 | int prevLevel = 0; 225 | Q.offer(new Pair(root, 0)); 226 | 227 | while(!Q.isEmpty()){ 228 | Pair currPair = Q.poll(); 229 | Node currNode = currPair.left; 230 | int currLevel = currPair.right; 231 | 232 | /* special handling for new levels */ 233 | if (currLevel != prevLevel){ 234 | System.out.println(""); // print new line 235 | prevLevel = currLevel; // update prevLevel 236 | } 237 | 238 | /* handle current node */ 239 | System.out.print(currNode.value + " "); 240 | 241 | if (currNode.left != null) { 242 | Q.offer(new Pair(currNode.left, currLevel + 1)); 243 | } 244 | if (currNode.right != null) { 245 | Q.offer(new Pair(currNode.right, currLevel + 1)); 246 | } 247 | } 248 | } 249 | 250 | /** 251 | * prints level-wise, the average of each level 252 | */ 253 | public void printLevelAverage(){ 254 | LinkedList> Q = 255 | new LinkedList>(); 256 | 257 | /* initial conditions */ 258 | int prevLevel = 0; 259 | int sum = 0; 260 | int levelSize = 0; 261 | Q.offer(new Pair(root, 0)); 262 | 263 | while(!Q.isEmpty()){ 264 | Pair currPair = Q.poll(); 265 | Node currNode = currPair.left; 266 | int currLevel = currPair.right; 267 | 268 | /* special handling if new level is reached */ 269 | if (currLevel != prevLevel){ 270 | System.out.println((double) sum/levelSize); 271 | 272 | /* resets sum and levelSize */ 273 | sum = 0; 274 | levelSize = 0; 275 | 276 | /* update prevLevel */ 277 | prevLevel = currLevel; 278 | } 279 | 280 | /* update sum and levelSize */ 281 | sum += currNode.value; 282 | levelSize ++; 283 | 284 | if (currNode.left != null) { 285 | Q.offer(new Pair(currNode.left, currLevel + 1)); 286 | } 287 | if (currNode.right != null) { 288 | Q.offer(new Pair(currNode.right, currLevel + 1)); 289 | } 290 | } 291 | System.out.println((double) sum/levelSize); 292 | } 293 | 294 | /** 295 | * Determines the in-order successor of a given node 296 | * @param node node of interest 297 | * @return in-order successor of node, null if non existent 298 | */ 299 | public Node getInorderSuccessor(Node node) { 300 | Node ptr = node; 301 | /* if node had right child, return leftmost node of right subtree */ 302 | if (ptr.right != null) { 303 | ptr = ptr.right; 304 | while (ptr.left != null) { 305 | ptr = ptr.left; 306 | } 307 | return ptr; 308 | } 309 | 310 | /* else find first parent where node is the left descendant */ 311 | else { 312 | while (ptr.parent != null) { 313 | if (ptr.parent.left == ptr) { 314 | return ptr.parent; 315 | } 316 | ptr = ptr.parent; 317 | } 318 | return null; // if no in-order successor 319 | } 320 | } 321 | 322 | public static void main(String[] args){ 323 | Node node1; Node node2; Node node3; Node node4; Node node5; Node node6; 324 | Node node7; Node node8; Node node9; Node node0; 325 | 326 | Node root; 327 | BinaryTree bt; 328 | 329 | /* BST: 330 | * 331 | * 5 332 | * / \ 333 | * / \ 334 | * / \ 335 | * 1 8 336 | * / \ / \ 337 | * 0 3 6 9 338 | * / \ \ 339 | * 2 4 7 340 | * 341 | */ 342 | System.out.println("*************** BST ***************"); 343 | System.out.println(); 344 | node1 = new Node(1); node2 = new Node(2); node3 = new Node(3); 345 | node4 = new Node(4); node5 = new Node(5); node6 = new Node(6); 346 | node7 = new Node(7); node8 = new Node(8); node9 = new Node(9); 347 | node0 = new Node(0); 348 | root = node5; 349 | bt = new BinaryTree(root); 350 | root.setLeft(node1); 351 | root.left.setLeft(node0); 352 | root.left.setRight(node3); 353 | root.left.right.setLeft(node2); 354 | root.left.right.setRight(node4); 355 | root.setRight(node8); 356 | root.right.setLeft(node6); 357 | root.right.left.setRight(node7); 358 | root.right.setRight(node9); 359 | 360 | bt = new BinaryTree(root); 361 | runAlgorithms(bt); 362 | 363 | 364 | /* not BST: 365 | * 366 | * 1 367 | * / \ 368 | * / \ 369 | * / \ 370 | * 2 3 371 | * / \ / \ 372 | * 4 5 6 7 373 | * / \ \ 374 | * 8 9 0 375 | * 376 | */ 377 | System.out.println(); 378 | System.out.println("************* NOT BST *************"); 379 | System.out.println(); 380 | node1 = new Node(1); node2 = new Node(2); node3 = new Node(3); 381 | node4 = new Node(4); node5 = new Node(5); node6 = new Node(6); 382 | node7 = new Node(7); node8 = new Node(8); node9 = new Node(9); 383 | node0 = new Node(0); 384 | 385 | root = node1; 386 | root.setLeft(node2); 387 | root.left.setLeft(node4); 388 | root.left.setRight(node5); 389 | root.left.right.setLeft(node8); 390 | root.left.right.setRight(node9); 391 | root.setRight(node3); 392 | root.right.setLeft(node6); 393 | root.right.left.setRight(node0); 394 | root.right.setRight(node7); 395 | 396 | bt = new BinaryTree(root); 397 | runAlgorithms(bt); 398 | 399 | } 400 | 401 | 402 | public static void runAlgorithms(BinaryTree bt) { 403 | System.out.println("=== Level-Wise ===================="); 404 | bt.printLevelWise(); 405 | System.out.println(); 406 | System.out.println("=== Level-Wise Average ============"); 407 | bt.printLevelAverage(); 408 | System.out.println("=== Traversals ===================="); 409 | System.out.print("Pre-Order: "); 410 | bt.printPreOrder(); 411 | System.out.println(); 412 | System.out.print("In-Order: "); 413 | bt.printInOrder(); 414 | System.out.println(); 415 | System.out.print("Post-Order: "); 416 | bt.printPostOrder(); 417 | System.out.println(); 418 | System.out.println("=== Lowest Common Ancestor +======="); 419 | bt.getLCA(8, 3); 420 | System.out.println("=== Inorder Successors ============"); 421 | Node node1 = bt.find(1); 422 | Node node9 = bt.find(9); 423 | Node node7 = bt.find(7); 424 | System.out.println("Successor of 1: " + bt.getInorderSuccessor(node1)); 425 | System.out.println("Successor of 9: " + bt.getInorderSuccessor(node9)); 426 | System.out.println("Successor of 7: " + bt.getInorderSuccessor(node7)); 427 | System.out.println("=== Is Valid BST? ================="); 428 | System.out.println(bt.isBST()); 429 | System.out.println("=== Tree Height ==================="); 430 | System.out.println("Height: " + bt.getHeight(bt.root)); 431 | System.out.println("Is tree balanced? " + bt.isTreeBalanced()); 432 | } 433 | 434 | public static class Node{ 435 | Integer value; 436 | Node left; 437 | Node right; 438 | Node parent; 439 | public Node(int value){ 440 | this.value = value; 441 | left = null; 442 | right = null; 443 | parent = null; 444 | } 445 | public void setLeft(Node child) { 446 | left = child; 447 | child.parent = this; 448 | } 449 | public void setRight(Node child) { 450 | right = child; 451 | child.parent = this; 452 | } 453 | public String toString() { 454 | return value.toString(); 455 | } 456 | } 457 | 458 | public static class Pair{ 459 | X left; 460 | Y right; 461 | public Pair(X left, Y right){ 462 | this.left = left; 463 | this.right = right; 464 | } 465 | } 466 | } -------------------------------------------------------------------------------- /Java/CoinChange.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | 3 | /** 4 | URL: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=615 5 | Problem Description: 6 | Suppose there are 5 types of coins: 50-cent, 25-cent, 10-cent, 5-cent, and 7 | 1-cent. We want to make changes with these coins for a given amount of money. 8 | 9 | For example, if we have 11 cents, then we can make changes with one 10-cent coin 10 | and one 1-cent coin, two 5-cent coins and one 1-cent coin, one 5-cent coin and 11 | six 1-cent coins, or eleven 1-cent coins. So there are four ways of making 12 | changes for 11 cents with the above coins. Note that we count that there is one 13 | way of making change for zero cent. 14 | 15 | Write a program to find the total number of different ways of making changes for 16 | any amount of money in cents. Your program should be able to handle up to 7489 17 | cents. 18 | */ 19 | public class CoinChange{ 20 | Integer[][] mem; // [cents][largetDenom] 21 | 22 | public CoinChange(){ 23 | mem = new Integer[7489 + 1][51]; 24 | /* Pre-process: leafs are 1 way each */ 25 | mem[0][50] = 1; 26 | mem[0][25] = 1; 27 | mem[0][10] = 1; 28 | mem[0][5] = 1; 29 | mem[0][1] = 1; 30 | } 31 | 32 | /** 33 | * Recursive method to determine number of coin combinations for value n 34 | * @param n current value left 35 | * @param largestDenom the last largest coin denomination used 36 | * @return 37 | */ 38 | public int solve(int n, int largestDenom){ 39 | if (mem[n][largestDenom] != null) { 40 | return mem[n][largestDenom]; 41 | } 42 | int totalWays = 0; 43 | 44 | /* choose 50c */ 45 | if (largestDenom == 50 && n >= 50) { 46 | totalWays += solve(n - 50, 50); 47 | } 48 | /* choose 25c */ 49 | if (largestDenom >= 25 && n >= 25) { 50 | totalWays += solve(n - 25, 25); 51 | } 52 | /* choose 10c */ 53 | if (largestDenom >= 10 && n >= 10) { 54 | totalWays += solve(n - 10, 10); 55 | } 56 | /* choose 5c */ 57 | if (largestDenom >= 5 && n >= 5) { 58 | totalWays += solve(n - 5, 5); 59 | } 60 | /* choose 1c */ 61 | if (largestDenom >= 1 && n >= 1) { 62 | totalWays += solve(n - 1, 1); 63 | } 64 | mem[n][largestDenom] = totalWays; 65 | return totalWays; 66 | } 67 | 68 | public void run(int cents){ 69 | System.out.println(solve(cents, 50)); 70 | } 71 | 72 | public static void main (String[] args){ 73 | Scanner sc = new Scanner(System.in); 74 | CoinChange cc = new CoinChange(); 75 | while(sc.hasNextInt()) { 76 | cc.run(sc.nextInt()); 77 | } 78 | sc.close(); 79 | } 80 | } -------------------------------------------------------------------------------- /Java/CountPossibleDecodings.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jin-zhe/algorithms/e51772089d29c60580abd204dfad6028aac97d8b/Java/CountPossibleDecodings.java -------------------------------------------------------------------------------- /Java/DigitPermutations.java: -------------------------------------------------------------------------------- 1 | import java.util.Arrays; 2 | import java.util.Comparator; 3 | import java.util.Scanner; 4 | 5 | public class DigitPermutations { 6 | String num; // given number 7 | char[] arr; // given array 8 | 9 | DigitPermutations(long num) { 10 | this.num = Long.toString(num); 11 | arr = (Long.toString(num)).toCharArray(); 12 | } 13 | 14 | /** 15 | * returns the next larger permutation with the given digits 16 | * N(logN) solution: Worst case 15432 17 | * 18 | */ 19 | String getNextPermutation() { 20 | int pivot = arr.length-1; // pivot position in arr 21 | for (int i=arr.length-1; i>0; i--) { 22 | char curr = arr[i]; 23 | char left = arr[i-1]; 24 | if (left < curr) { 25 | pivot = i - 1; // update pivot 26 | break; 27 | } 28 | } 29 | /* Edge case: where it is in descending order 30 | * e.g. 54321 (no next larger available) 31 | */ 32 | if (pivot == arr.length-1) { 33 | return num; 34 | } 35 | 36 | char[] arrLeft = Arrays.copyOfRange(arr, 0, pivot + 1); 37 | char[] arrRight = Arrays.copyOfRange(arr, pivot + 1, arr.length); 38 | 39 | char leftLast = arrLeft[arrLeft.length - 1]; 40 | int swapPos = 0; // position in arrRight to swap with arrLeft[arrLeft.length - 1] 41 | 42 | /* position of the minimal larger character than leftLast in right arr */ 43 | for (int i=0; i leftLast && curr < arrRight[swapPos]) { 46 | swapPos = i; 47 | } 48 | } 49 | 50 | /* swap element at arrRight[rightMinLargerPosition] with arrLeft[arr.length - 1] */ 51 | arrLeft[arrLeft.length - 1] = arrRight[swapPos]; 52 | arrRight[swapPos] = leftLast; 53 | 54 | /* sort right array from smallest to largest (ensure minimum number) */ 55 | Arrays.sort(arrRight); 56 | 57 | StringBuffer sb = new StringBuffer(); 58 | sb.append(arrLeft); 59 | sb.append(arrRight); 60 | 61 | return sb.toString(); 62 | } 63 | 64 | /** 65 | * returns the next smaller permutation with the given digits 66 | */ 67 | String getPrevPermutation() { 68 | // 14123 69 | // 14 123 70 | // 13 124 71 | // 13 421 72 | // 13421 vs 14123 73 | int pivot = arr.length - 1; 74 | /* determine pivot */ 75 | for (int i=arr.length-1; i>0; i--) { 76 | char left = arr[i - 1]; 77 | char curr = arr[i]; 78 | if (left > curr){ 79 | pivot = i - 1; 80 | break; 81 | } 82 | } 83 | /* Edge case i.e. 12345 */ 84 | if (pivot == arr.length - 1) { 85 | return num; 86 | } 87 | 88 | char[] arrLeft = Arrays.copyOfRange(arr, 0, pivot + 1); 89 | char[] arrRight = Arrays.copyOfRange(arr, pivot + 1, arr.length);; 90 | 91 | char leftLast = arrLeft[arrLeft.length - 1]; 92 | int swapPos = 0; // index in arrRight to be swapped with the last element of arrLeft 93 | 94 | for (int i=0; i arrRight[swapPos] && curr < leftLast) { 98 | swapPos = i; 99 | } 100 | } 101 | 102 | /* swap numbers */ 103 | arrLeft[arrLeft.length - 1] = arrRight[swapPos]; 104 | arrRight[swapPos] = leftLast; 105 | 106 | /* sort arrRight */ 107 | Character[] arrRightObj = new Character[arrRight.length]; // convert to Character[] 108 | for (int i=0; i() { 112 | public int compare(Character o1, Character o2) { 113 | return o2 - o1; 114 | } 115 | }); 116 | for (int i=0; i= 2) ways += solve(stepsLeft - 2); 25 | if (stepsLeft >= 1) ways += solve(stepsLeft - 1); 26 | mem[stepsLeft] = ways; 27 | return mem[stepsLeft]; 28 | } 29 | 30 | public void run(){ 31 | System.out.println(solve(n)); 32 | } 33 | public static void main(String[] args) { 34 | Scanner sc = new Scanner(System.in); 35 | FibonacciSteps steps = new FibonacciSteps(sc.nextInt()); 36 | steps.run(); 37 | sc.close(); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /Java/FizzBuzz.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jin-zhe/algorithms/e51772089d29c60580abd204dfad6028aac97d8b/Java/FizzBuzz.java -------------------------------------------------------------------------------- /Java/GameOfLife.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jin-zhe/algorithms/e51772089d29c60580abd204dfad6028aac97d8b/Java/GameOfLife.java -------------------------------------------------------------------------------- /Java/Graph.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jin-zhe/algorithms/e51772089d29c60580abd204dfad6028aac97d8b/Java/Graph.java -------------------------------------------------------------------------------- /Java/HomogeneousRows.java: -------------------------------------------------------------------------------- 1 | import java.util.HashMap; 2 | import java.util.Scanner; 3 | /** 4 | Problem Description: 5 | You are given an M by N matrix containing only the characters 'P' and 'T'. 6 | You can flip the characters in any number of columns. I.e. 'P' becomes 'T' 7 | and 'T' becomes 'P' for all characters under that column. Your aim is to 8 | maximize the number of rows for which all the characters are the same. We 9 | shall refer to such rows as being homogeneous. 10 | 11 | Given the M by N matrix as input, write a program that outputs a single 12 | number representing the maximum number of homogeneous rows achievable by 13 | flipping any number of columns. 14 | 15 | Input Format: 16 | The first line contains 2 space-separated integers M and N, denoting the 17 | number of rows and the number of columns. Then M lines follow with each line 18 | containing N characters ( not separated by any space ) 'P' or 'T'. 19 | 20 | Output Format: 21 | A single number representing the maximum number of homogeneous rows 22 | achievable 23 | 24 | Constraints 25 | 1<=M<=100000 26 | 1<=N<=500 27 | 28 | Sample Input 29 | 5 3 30 | TTP 31 | PTP 32 | TPP 33 | PTP 34 | TPT 35 | 36 | Sample Output 37 | 3 38 | 39 | Explanation 40 | Flipping column 2 yields: 41 | TPP 42 | PPP 43 | TTP 44 | PPP 45 | TTT 46 | Giving us 3 homogeneous rows. If we try to get the first row to match 47 | instead, we have to either flip columns 1 and 2 or only column 3, and this 48 | gives only 1 homogeneous row. If we want to get row 3 to match, we'd have to 49 | flip either column 1 or columns 2 and 3, again achieving only 1 homogeneous 50 | row. 51 | */ 52 | 53 | /* 54 | * Main idea behind algorithm: 55 | * Since we would like to find out the maximum number of rows which will be 56 | * homogeneous after flipping columns, it suffices to chuck all row complements 57 | * into the same bucket (e.g. 'PTP' and 'TPT') and then at the end, find out 58 | * which bucket has the most number of items. We can do this because when we 59 | * homogenize a row, we also homogenize its complement. e.g. when we turn 'PTP' 60 | * to 'PPP', we also turn the 'TPT' to 'TTT' 61 | */ 62 | public class HomogeneousRows { 63 | HashMap complementsMap; // Key: row string, Value: number of rows with the same string or complements of the string 64 | int M,N; 65 | String[] rows; 66 | int maxCount; 67 | 68 | /** 69 | * Class constructor 70 | * @param M number of rows 71 | * @param N number of columns 72 | * @param rows array rows 73 | */ 74 | HomogeneousRows(int M, int N, String[] rows){ 75 | this.M = M; 76 | this.N = N; 77 | this.rows = rows; 78 | complementsMap = new HashMap(); 79 | } 80 | 81 | /** 82 | * Main algorithm 83 | * O(MN) time complexity 84 | */ 85 | public void solve(){ 86 | /* Iterate each row in matrix (M times) */ 87 | for (String row: rows){ 88 | int count = 1; // number of occurrence for current normalized row 89 | 90 | /* 1. Normalize current row (we arbitrarily define a row to be normalized if it begins with 'P') */ 91 | String normalizedRow = row; 92 | if (row.charAt(0) != 'P') 93 | normalizedRow = getComplement(normalizedRow); // take complement of row if it is not normalized 94 | 95 | /* 2. Update hashmap for complements */ 96 | if (complementsMap.containsKey(normalizedRow)) 97 | count = complementsMap.get(normalizedRow) + 1; 98 | complementsMap.put(normalizedRow, count); 99 | 100 | /* 3. Update maxCount */ 101 | if (count > maxCount) 102 | maxCount = count; 103 | } 104 | System.out.println(maxCount); // print answer 105 | } 106 | 107 | /** 108 | * @param row 109 | * @return complement of given row string (used for row normalizations) 110 | * O(N) time complexity 111 | */ 112 | public String getComplement(String row){ 113 | StringBuffer sb = new StringBuffer(); 114 | /* Flip each character in the given row */ 115 | for (int i=0; i0) || (divisor<0 && dividend>0))? -1: 1; 18 | dividend = Math.abs(dividend); 19 | divisor = Math.abs(divisor); 20 | 21 | /* corner case */ 22 | if (dividend < divisor) 23 | return 0; 24 | 25 | ArrayList powerSeries = new ArrayList(); // power series of 2 26 | powerSeries.add(1); // 2^0 == 1 27 | int exponent = 0; // current index in power list 28 | int quotient = 0; // ans 29 | 30 | while (dividend >= divisor){ 31 | int deduct = powerSeries.get(exponent) * divisor; 32 | if (dividend >= deduct){ 33 | dividend -= deduct; 34 | quotient += powerSeries.get(exponent); 35 | 36 | /* update next value in power series if necessary */ 37 | int last = powerSeries.get(powerSeries.size()-1); // last value in power series 38 | if (powerSeries.get(exponent) == last){ 39 | powerSeries.add(last*2); 40 | } 41 | exponent++; // increment exponent 42 | } 43 | else 44 | exponent--; // decrement exponent 45 | } 46 | return quotient * polarity; 47 | } 48 | } -------------------------------------------------------------------------------- /Java/KadaneBitFlip.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | /** 3 | * URL: http://www.careercup.com/question?id=6262507668766720 4 | */ 5 | public class KadaneBitFlip { 6 | int[] arr; 7 | boolean isAllOnes; // corner case: all zeroes 8 | 9 | KadaneBitFlip(int[] arr, boolean isAllOnes) { 10 | this.arr = arr; 11 | this.isAllOnes = isAllOnes; 12 | } 13 | 14 | /** 15 | * run modified Kadane's algorithm 16 | * O(N) 17 | * @return returns optimal range (start, end) to flip 18 | */ 19 | Pair solve() { 20 | if (isAllOnes) { 21 | return new Pair(0, arr.length); // corner case 22 | } 23 | int temp_start = -1; 24 | int start = -1; // start index of flip 25 | int end = -1; // end index of flip 26 | int max = 0; 27 | 28 | int max_ending_here = 0; 29 | 30 | for (int i=0; i 0) { 37 | temp_start = i; // restart temp_start at current 38 | } 39 | /* if higher value for max_ending_here is found */ 40 | if (max_ending_here > max) { 41 | max = max_ending_here; // update max 42 | start = temp_start; // update start 43 | end = i; // update end 44 | } 45 | } 46 | 47 | return new Pair(start, end); 48 | } 49 | 50 | void run() { 51 | Pair startEnd = solve(); 52 | // System.out.println(startEnd); // check 53 | int start = startEnd.first; 54 | int end = startEnd.second; 55 | int ans = 0; 56 | for (int i=0; i= start && i <= end) { 59 | if (arr[i] == 1) ans++; // count flipped 0's 60 | } 61 | // else if not within range 62 | else { 63 | if (arr[i] == -1) ans++; // count 1's 64 | } 65 | } 66 | System.out.println(ans); 67 | } 68 | 69 | public static void main(String[] args) { 70 | Scanner sc = new Scanner(System.in); 71 | int N = sc.nextInt(); 72 | int[] arr = new int[N]; 73 | boolean isAllOnes = true; 74 | for (int i=0; i { 92 | T first; 93 | U second; 94 | public Pair(T first, U second) { 95 | this.first = first; 96 | this.second = second; 97 | } 98 | public String toString() { 99 | return "(" + first + ", " + second + ")"; 100 | } 101 | } 102 | } -------------------------------------------------------------------------------- /Java/Karatsuba.java: -------------------------------------------------------------------------------- 1 | import java.util.Arrays; 2 | import java.util.Scanner; 3 | 4 | /* 5 | * Implementation of Karatsuba's multiplication algorithm 6 | * This code supports non-negative numeric multiplications of up to base 36 ('Z' is max permitted by alphabets) 7 | */ 8 | public class Karatsuba { 9 | 10 | public static void main(String[] args) { 11 | Scanner sc = new Scanner(System.in); 12 | int base = sc.nextInt(); // base in decimal 13 | sc.nextLine(); 14 | String x = sc.nextLine(); 15 | String y = sc.nextLine(); 16 | System.out.println(multiply(x, y, base)); 17 | sc.close(); 18 | } 19 | /** 20 | * Converts a numeric string into an array of int, preserving right-left order and ignoring radix 21 | */ 22 | private static int[] toIntArray(String num, boolean hasRadix){ 23 | int[] arr = (hasRadix)? new int[num.length()-1]: new int[num.length()]; 24 | int index = 0; 25 | for (int i=0; i ans_arr.length){ 72 | char[] shiftZeros = new char[radix_pos - ans_arr.length]; 73 | Arrays.fill(shiftZeros, '0'); // string of amount number of '0's 74 | sb.insert(0, shiftZeros); 75 | } 76 | sb.insert(ans_arr.length - radix_pos - 1, '.'); 77 | } 78 | 79 | return trimZeros(sb.toString()); 80 | } 81 | 82 | /** 83 | * Karatsuba's multiplication algorithm (recursive) 84 | */ 85 | private static int[] karatsubaMultiply(int[] x, int[] y, int base){ 86 | 87 | // equalize string lengths by prepending '0's to shorter string 88 | if (x.length > y.length) 89 | y = shift("right", y, x.length - y.length); 90 | else if (y.length > x.length) 91 | x = shift("right", x, y.length - x.length); 92 | 93 | // base case: less than or equal to 61 digits 94 | // Reason: Karatsuba works best for multiplicands above 320 bits ~ 186 digits for decimal 95 | if (x.length <= 141 && y.length <= 141){ 96 | return longMultiplication(x, y, base); 97 | } 98 | int n = x.length; 99 | int nHalf = x.length - n/2; 100 | int[] x1 = copyOfRange(x, 0, n/2); 101 | int[] x0 = copyOfRange(x, n/2, x.length); 102 | int[] y1 = copyOfRange(y, 0, n/2); 103 | int[] y0 = copyOfRange(y, n/2, y.length); 104 | 105 | // 3 recursive calls 106 | int[] x1y1 = karatsubaMultiply(x1, y1, base); // x1 * y1 107 | int[] x1x0y1y0 = karatsubaMultiply(addition(x1, x0, base), addition(y1 , y0, base), base); // (x1 + x0)*(y1 * y0) 108 | int[] x0y0 = karatsubaMultiply(x0, y0, base); // x0 * y0 109 | 110 | // System.out.println("x = " + x + ", y = " + y + ", n/2 = " + n/2); // check 111 | // System.out.println("x1 = " + x1 + ", x0 = " + x0 + ", y1 = " + y1 + ", y0 = " + y0); // check 112 | // System.out.println("x1y1 = " + x1y1 + ", x1x0y1y0 = " + x1x0y1y0 + ", x0y0 = " + x0y0); // check 113 | // System.out.println("------------------------------"); // check 114 | int[] part1 = shift("left", x1y1, 2*nHalf); 115 | int[] part2 = shift("left", subtraction(subtraction(x1x0y1y0, x1y1, base), x0y0, base), nHalf); 116 | 117 | return addition(addition(part1, part2, base), x0y0, base); 118 | } 119 | 120 | /** 121 | * Long multiplication algorithm 122 | */ 123 | private static int[] longMultiplication(int[] x, int[] y, int base){ 124 | int[] top, bot; // top and bottom operands in long multiplication 125 | if (x.length >= y.length){ 126 | top = x; 127 | bot = y; 128 | } 129 | else{ 130 | top = y; 131 | bot = x; 132 | } 133 | int[] ans = new int[x.length + y.length]; 134 | int offset = 0; // right offset when adding the rows 135 | 136 | // for each digit in bot string from right to left 137 | for (int i=bot.length-1; i>=0; i--){ 138 | int carryOver_product = 0; // carryover due to multiplication 139 | int carryOver_add = 0; // carryover due to addition 140 | 141 | // for each digit in top string from right to left 142 | for (int j=top.length-1; j>=0; j--){ 143 | /* derive product of 2 digits */ 144 | int product = bot[i] * top[j] + carryOver_product; // multiply top digit with bottom digit and add with carryover 145 | // System.out.println("top[j] = " + top[j] + ", bot[i] = " + bot[i] + ", carryOver = " + carryOver + ", product = " + product); // check 146 | carryOver_product = product/base; // carry over from product 147 | product %= base; // product after forwarding carryover 148 | 149 | /* add product to ans[] */ 150 | int ans_index = ans.length - (top.length - j) - offset; // corresponding index in ans[] 151 | ans[ans_index] += product + carryOver_add; 152 | carryOver_add = ans[ans_index]/base; 153 | ans[ans_index] = ans[ans_index]%base; 154 | } 155 | // handle final carryovers 156 | if (carryOver_product != 0 || carryOver_add != 0){ 157 | // NOTE: ans[ans_index] is definitely == 0, mathematically (carryOver_product + carryOver_add < base) is guaranteed 158 | int ans_index = ans.length - (top.length + 1) - offset; 159 | ans[ans_index] += carryOver_product + carryOver_add; 160 | } 161 | offset++; // update: pad one more '0' to the right of next row 162 | } 163 | return ans; 164 | } 165 | 166 | /** 167 | * Shifts array by amount given and in the direction stated 168 | */ 169 | private static int[] shift(String direction, int[] arr, int amount){ 170 | // System.out.println("[shift] numericString,amount: " + numericString + "," + amount); // check 171 | int[] shiftedArr = new int[arr.length + amount]; 172 | 173 | // if pad right 174 | if (direction == "left"){ 175 | for (int i=0; i=0; i--){ 197 | int sum = carryOver; 198 | int numericPos = ans.length - i; // numeric position of ans 199 | 200 | // if within region of a 201 | if (numericPos <= a.length){ 202 | sum += a[a.length - numericPos]; 203 | } 204 | 205 | // if within region of b 206 | if (numericPos <= b.length){ 207 | sum += b[b.length - numericPos]; 208 | } 209 | ans[i] = sum%base; // update ans 210 | carryOver = sum/base; // update carry over 211 | } 212 | return ans; 213 | } 214 | 215 | /** 216 | * Subtracts 'smaller' from 'greater' int arrays of the given base 217 | * will not produce negative numbers since greater and smaller are guaranteed by caller 218 | */ 219 | // 220 | private static int[] subtraction(int[] greater, int[] smaller, int base){ 221 | int borrowOver = 0; // 0 or 1 222 | for (int i=smaller.length-1; i>=0; i--){ 223 | int index_greater = greater.length - (smaller.length - i); // corresponding index in greater 224 | greater[index_greater] = greater[index_greater] - smaller[i] - borrowOver; 225 | // if need to borrow over, borrowOver = 1 226 | if (greater[index_greater] < 0){ 227 | greater[index_greater] += base; 228 | borrowOver = 1; 229 | } 230 | // else if no need to borrow over, borrowOver = 0 231 | else borrowOver = 0; 232 | } 233 | // handle final borrowOver 234 | if (borrowOver != 0) greater[greater.length - smaller.length - 1] -= borrowOver; 235 | return greater; 236 | } 237 | 238 | /** 239 | * Creates subarray from the given range 240 | */ 241 | private static int[] copyOfRange(int[] src, int start, int end){ 242 | int[] dest = new int[end - start]; 243 | System.arraycopy(src, start, dest, 0, end - start); 244 | return dest; 245 | } 246 | 247 | /** 248 | * Use to trim leading and trailing zeros on a result string. 249 | */ 250 | private static String trimZeros(String input) { 251 | int left = 0; 252 | int right = input.length()-1; 253 | int fp = input.indexOf('.'); 254 | if (fp == -1) { 255 | fp = input.length(); 256 | } 257 | 258 | while(left < fp-1) { 259 | if (input.charAt(left) != '0') 260 | break; 261 | left++; 262 | } 263 | 264 | while (right >= fp) { 265 | if (input.charAt(right) != '0') { 266 | if (input.charAt(right) == '.') 267 | right--; 268 | break; 269 | } 270 | right--; 271 | } 272 | 273 | if (left >= fp) 274 | return "0" + input.substring(left,right+1); 275 | return input.substring(left,right+1); 276 | } 277 | 278 | /** 279 | * Convert digit to int (for reading) 280 | */ 281 | private static int parseDigit(char c) { 282 | if (c <= '9') { 283 | return c - '0'; 284 | } 285 | return c - 'A' + 10; 286 | } 287 | 288 | /** 289 | * Convert int to digit. (for printing) 290 | */ 291 | private static char toDigit(int digit) { 292 | if (digit <= 9) { 293 | return (char)(digit + '0'); 294 | } 295 | return (char)(digit - 10 + 'A'); 296 | } 297 | 298 | /** 299 | * For checking: prints out the int array 300 | */ 301 | @SuppressWarnings("unused") 302 | private static void printIntArray(int[] arr){ 303 | System.out.print("[printIntArray]: "); 304 | for (int i: arr) System.out.print(i); 305 | System.out.println(); 306 | } 307 | } 308 | -------------------------------------------------------------------------------- /Java/KnuthShuffle.java: -------------------------------------------------------------------------------- 1 | import java.util.Random; 2 | 3 | public class KnuthShuffle { 4 | public static void main(String[] args){ 5 | int[] arr = {1,2,3,4,5,6,7,8,9,10}; 6 | Random gen = new Random(); 7 | 8 | int n = arr.length; 9 | while(n > 1){ 10 | // swap k with n 11 | int k = gen.nextInt(n--); 12 | int temp = arr[n]; 13 | arr[n] = arr[k]; 14 | arr[k] = temp; 15 | } 16 | 17 | for(int i=0; i 0){ 74 | char currA = a.charAt(i-1); // current character at a 75 | char currB = b.charAt(j-1); // current character at b 76 | if (currA == currB){ 77 | sb.append(currA); 78 | i--; 79 | j--; 80 | } 81 | else if (mem[i][j] == mem[i-1][j]) 82 | i--; 83 | else if (mem[i][j] == mem[i][j-1]) 84 | j--; 85 | } 86 | return sb.reverse().toString(); 87 | } 88 | 89 | void run(){ 90 | preprocess(); 91 | System.out.println("Top-down: " + LCS_topDown(a.length(), b.length())); 92 | preprocess(); 93 | System.out.println("Bottom-up: " + LCS_bottomUp()); 94 | System.out.println("One valid LCS is : " + backtrack_iterative()); 95 | } 96 | 97 | public static void main(String[] args) { 98 | Scanner sc = new Scanner(System.in); 99 | while(sc.hasNext()){ 100 | LongestCommonSubsequence lcs = new LongestCommonSubsequence(sc.nextLine(), sc.nextLine()); 101 | lcs.run(); 102 | } 103 | sc.close(); 104 | } 105 | } -------------------------------------------------------------------------------- /Java/LongestCommonSubstring.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | 3 | 4 | public class LongestCommonSubstring { 5 | String a; 6 | String b; 7 | Integer[][] mem; 8 | 9 | LongestCommonSubstring(String a, String b){ 10 | this.a = a; 11 | this.b = b; 12 | } 13 | 14 | /** 15 | * Methodology: 16 | * Line up two strings using an implicit slot using 2 starting pointers, one for each string. 17 | * e.g. 18 | * string 1: aba123 19 | * string 2: 456789aba 20 | * ^ 21 | * The starting pointer for string 1 is 0 and the one for string 2 is 6. 22 | * That is our slot, as indicated by the caret. 23 | * We define mem[i][j] as the length of the common substring, 24 | * with starting pointer i in string 1 and j in string 2. 25 | * If the two characters in the slot matches, mem[i][j] = 1 + mem[j+1][j+1]. 26 | * Think of it as dialing the slot down by one for both strings and continuing the comparison 27 | * If the two characters don't match, mem[i][j] = 0 28 | * Also if either starting pointers has exceeded the length of its string, mem[i][j] is also 0. 29 | * We try all slots by trying all possible pointer combinations and this populates the table mem[j][j]. 30 | * We simply get the largest value from the table and that is our answer 31 | */ 32 | /* O(MN) bottom-up DP */ 33 | int LCS(){ 34 | /* preprocess */ 35 | mem = new Integer[a.length()+1][b.length()+1]; 36 | /* when start pointer for b exceeded */ 37 | for (int i=0; i=0; i--) 47 | /* starting points of b from left to right */ 48 | for (int j=0; j max){ 75 | max = mem[i][j]; 76 | iMax = i; 77 | jMax = j; 78 | } 79 | 80 | /* reconstructs longest substring by moving down diagonally */ 81 | while (mem[iMax][jMax] > 0){ 82 | if (mem[iMax][jMax] == 0) 83 | break; 84 | sb.append(a.charAt(iMax)); 85 | iMax++; 86 | jMax++; 87 | } 88 | return sb.toString(); 89 | } 90 | 91 | void run(){ 92 | System.out.println(LCS()); 93 | System.out.print("One valid LCS is: " + backtrack()); 94 | } 95 | 96 | public static void main(String[] args) { 97 | Scanner sc = new Scanner(System.in); 98 | (new LongestCommonSubstring(sc.nextLine(), sc.nextLine())).run(); 99 | sc.close(); 100 | } 101 | 102 | } -------------------------------------------------------------------------------- /Java/LongestIncreasingSequence.java: -------------------------------------------------------------------------------- 1 | public class LongestIncreasingSequence { 2 | int[] arr = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15}; 3 | int[] mem = new int[100]; 4 | 5 | /* Longest Increasing Sequence */ 6 | int LIS(){ 7 | // initial conditions 8 | int globalMax = (arr.length > 0)? 1: 0; // maximum increasing sequence recorded 9 | int i = 0; 10 | 11 | /* O(N) single pass */ 12 | while (i curr){ 18 | localMax++; // increment test 19 | curr = arr[j]; // update new current 20 | } 21 | else break; // break if sequence cannot continue 22 | } 23 | 24 | globalMax = Math.max(localMax, globalMax); // update globalMax 25 | i += localMax; // **SMART** increment index by length of local increasing subsequence 26 | } 27 | return globalMax; 28 | } 29 | 30 | void run(){ 31 | System.out.println(LIS()); 32 | } 33 | 34 | public static void main(String[] args) { 35 | LongestIncreasingSequence lis = new LongestIncreasingSequence(); 36 | lis.run(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Java/LongestIncreasingSubsequence.java: -------------------------------------------------------------------------------- 1 | import java.util.Arrays; 2 | 3 | /* Longest Increasing Subsequence */ 4 | /* O(N^2) because 1+2+3+4...*/ 5 | public class LongestIncreasingSubsequence { 6 | int[] arr = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15}; 7 | // int[] arr = {99,1,2,3}; 8 | // int[] arr = {1,2,3}; 9 | // int[] arr = {3,2,1}; 10 | // int[] arr = {1}; 11 | 12 | int[] mem = new int[arr.length]; 13 | 14 | /* recursive: define endIndex as the last item that is picked for the sequence */ 15 | int LIS_topDown(int endIndex){ 16 | if (mem[endIndex] != 0) 17 | return mem[endIndex]; 18 | 19 | int curr = arr[endIndex]; 20 | int max = 1; // an individual item is a sequence of 1 21 | // from previous item down to first item 22 | for (int i=endIndex-1; i>=0; i--){ 23 | // try choosing previous item iff it is lower than curr 24 | if (arr[i] < curr) 25 | max = Math.max(1 + LIS_topDown(i), max); // update max 26 | } 27 | mem[endIndex] = max; // memorize 28 | return max; 29 | } 30 | // driver function 31 | int LIS_topDown(){ 32 | mem = new int[arr.length]; // initialize memory table 33 | int max = 1; 34 | for (int i=0; i len){ 64 | len = mem[i]; 65 | iMax = i; 66 | } 67 | } 68 | 69 | int[] subsequence = new int[len]; 70 | subsequence[--len] = arr[iMax]; 71 | /* determines subsequence from back to front */ 72 | for (int i=iMax-1; i>=0; i--){ 73 | int prevVal = subsequence[len]; // the succeeding subsequence value chosen in previous iteration 74 | int curr = arr[i]; 75 | /* if curr is a possible candidate */ 76 | if (len == mem[i] && prevVal > curr){ 77 | subsequence[len-1] = curr; // assign value 78 | len--; // decrement len (also array pointer) 79 | prevVal = curr; // update prevVal 80 | } 81 | } 82 | 83 | return subsequence; 84 | 85 | } 86 | void run(){ 87 | System.out.println("Top-down: " + LIS_topDown()); 88 | System.out.println("Bottom-up: " + LIS_bottomUp()); 89 | System.out.println("One valid LIS is: " + Arrays.toString(backtrack())); 90 | } 91 | 92 | public static void main(String[] args) { 93 | LongestIncreasingSubsequence lis = new LongestIncreasingSubsequence(); 94 | lis.run(); 95 | } 96 | } -------------------------------------------------------------------------------- /Java/LongestPalindromicSubsequence.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | 3 | public class LongestPalindromicSubsequence { 4 | Integer[][] mem; // memory hashmap 5 | String string; 6 | 7 | /* constructor */ 8 | public LongestPalindromicSubsequence(String string){ 9 | this.string = string; 10 | } 11 | 12 | /* preprocess */ 13 | public void preprocess(){ 14 | mem = new Integer[string.length()][string.length()]; 15 | /* i: start index, j: end index (inclusive)*/ 16 | for (int i=0; i j) 21 | mem[i][j] = 0; // base case: invalid start-end indices (when pointers cross) 22 | } 23 | } 24 | 25 | /* DP recursion for substring from startIndex to endIndex (inclusive) */ 26 | public int LPS_topDown(int startIndex, int endIndex){ 27 | if (mem[startIndex][endIndex] != null) 28 | return mem[startIndex][endIndex]; 29 | 30 | int ans = 0; 31 | /* if start and end characters are the same */ 32 | if (string.charAt(startIndex) == string.charAt(endIndex)) 33 | ans = 2 + LPS_topDown(startIndex + 1, endIndex - 1); 34 | else 35 | ans = Math.max(LPS_topDown(startIndex + 1, endIndex), LPS_topDown(startIndex, endIndex - 1)); 36 | 37 | mem[startIndex][endIndex] = ans; // memorize 38 | return ans; 39 | } 40 | /* driver function */ 41 | public int LPS_topDown(){ 42 | preprocess(); 43 | return LPS_topDown(0, string.length()-1); 44 | } 45 | 46 | /* DP iterative */ 47 | public int LPS_bottomUp(){ 48 | preprocess(); 49 | 50 | /* i: start index, j: end index (inclusive) */ 51 | for (int i=string.length(); i>=0; i--) // row from bottom to top 52 | for (int j=0; j i) 55 | if (string.charAt(i) == string.charAt(j)) 56 | mem[i][j] = 2 + mem[i+1][j-1]; 57 | else 58 | mem[i][j] = Math.max(mem[i+1][j], mem[i][j-1]); 59 | /* skip bottom-half triangle (including diagonal) as they were preprocessed */ 60 | else 61 | continue; 62 | } 63 | 64 | return mem[0][string.length()-1]; 65 | } 66 | 67 | /* Reconstructs the LPS */ 68 | String backtrack(){ 69 | StringBuffer sb1 = new StringBuffer(); 70 | StringBuffer sb2 = new StringBuffer(); 71 | int i=0; 72 | int j=string.length()-1; 73 | while(mem[i][j]>0){ 74 | char front = string.charAt(i); 75 | char back = string.charAt(j); 76 | if (front == back){ 77 | sb1.append(string.charAt(i)); 78 | sb2.append(string.charAt(i)); 79 | i++; 80 | j--; 81 | } 82 | else if (mem[i][j] == mem[i+1][j]) 83 | i++; 84 | else if (mem[i][j] == mem[i][j-1]) 85 | j--; 86 | } 87 | 88 | /* generate palindrome */ 89 | sb2.reverse(); 90 | /* if palindrome length is even */ 91 | if (mem[0][string.length()-1] % 2 == 0) 92 | sb1.append(sb2); 93 | else{ 94 | sb1.append(sb2.substring(1)); // ignore duplicated first character (present in sb1) 95 | } 96 | 97 | return sb1.toString(); 98 | } 99 | 100 | public void run(){ 101 | if (string.isEmpty()) 102 | System.out.println("0"); 103 | else{ 104 | System.out.println("Top-down: " + LPS_topDown()); 105 | System.out.println("Bottom-up: " + LPS_bottomUp()); 106 | System.out.println("One valid LPS is: " + backtrack()); 107 | } 108 | } 109 | 110 | public static void main(String[] args) { 111 | Scanner sc = new Scanner(System.in); 112 | LongestPalindromicSubsequence LPS = new LongestPalindromicSubsequence(sc.nextLine()); 113 | LPS.run(); 114 | sc.close(); 115 | } 116 | } -------------------------------------------------------------------------------- /Java/LongestPalindromicSubstring.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | 3 | public class LongestPalindromicSubstring { 4 | String string; // string to be tested 5 | Boolean[][] mem; // [startIndex][endIndex] 6 | 7 | // constructor 8 | public LongestPalindromicSubstring(String aString){ 9 | string = aString; 10 | } 11 | 12 | /* O(N^2) DP test substring from startIndex to endIndex inclusive for palindrome */ 13 | public boolean LPS_DP(int startIndex, int endIndex){ 14 | /* if answer is in memory */ 15 | if (mem[startIndex][endIndex] != null) 16 | return mem[startIndex][endIndex]; 17 | 18 | boolean ans = false; 19 | /* if outermost characters match, recurse inwards */ 20 | if (string.charAt(startIndex) == string.charAt(endIndex)) 21 | ans = LPS_DP(startIndex + 1, endIndex - 1); /* |-> ... <-| */ 22 | mem[startIndex][endIndex] = ans; 23 | return ans; 24 | } 25 | 26 | /* driver function */ 27 | public int LPS_DP(){ 28 | /* preprocess */ 29 | mem = new Boolean [string.length()][string.length()]; 30 | for (int i=0; i= j) 34 | mem[i][j] = true; 35 | 36 | 37 | int max = 0; 38 | // for each possible substring in string 39 | for (int i=0; i max) 43 | max = j - i + 1; 44 | } 45 | return max; 46 | } 47 | 48 | /* O(N^2) solution by expanding around possible palindrome centers */ 49 | public int LPS(){ 50 | int maxLen = 1; // maximum palindrome length recorded 51 | 52 | /* test the N possible single centers (each character as a center) */ 53 | for (int i=1; i=0 && r 65 | } 66 | else 67 | break; 68 | } 69 | maxLen = Math.max(len, maxLen); 70 | } 71 | 72 | /* test the N-1 possible paired centers (each pair of matching character as a center) */ 73 | for (int i=0; i=0 && r 86 | } 87 | else 88 | break; 89 | } 90 | 91 | maxLen = Math.max(len, maxLen); 92 | } 93 | } 94 | 95 | return maxLen; 96 | } 97 | 98 | public void run(){ 99 | System.out.println(LPS()); 100 | System.out.println(LPS_DP()); 101 | } 102 | 103 | public static void main(String[] args) { 104 | Scanner sc = new Scanner(System.in); 105 | int T = sc.nextInt(); // number of test cases 106 | sc.nextLine(); 107 | for (int i=0; i 0){ 22 | isAllNegative = false; 23 | break; 24 | } 25 | } 26 | if (isAllNegative) { 27 | System.out.println("All array elements are negative! Answer is indeterminate!"); 28 | return; 29 | } 30 | 31 | for (int i=0; i globalMax) { 36 | globalMax = localMax; 37 | endPointGlobal = i; 38 | startPointGlobal = startPointLocal; 39 | } 40 | else if (localMax < 0) { 41 | localMax = 0; // resets localMax 42 | startPointLocal = i+1; // update new start point as next index (Note it's okay if i+1 = arr.length because its the end of loop anyway) 43 | } 44 | } 45 | 46 | System.out.println("Maximum subarray is " + globalMax + 47 | " from positions " + startPointGlobal + " to " + 48 | endPointGlobal + " inclusive"); 49 | } 50 | } -------------------------------------------------------------------------------- /Java/MergeSort.java: -------------------------------------------------------------------------------- 1 | import java.util.Arrays; 2 | 3 | /** 4 | * This is an implementation of the Mergesort 5 | */ 6 | public class MergeSort { 7 | 8 | public static void main(String[] args) { 9 | int[] arr = {4, 223, 343, 62, 11, 29, 306, 247, 244, 78}; 10 | System.out.println(Arrays.toString(sort(arr))); 11 | } 12 | 13 | /** 14 | * Sorts the given array 15 | * @param arr the given array to be sorted 16 | * @return the sorted array 17 | */ 18 | static int[] sort(int[] arr){ 19 | /* base case */ 20 | if (arr.length <= 2){ 21 | if (arr.length == 2 && arr[0] > arr[1]){ 22 | int temp = arr[0]; 23 | arr[0] = arr[1]; 24 | arr[1] = temp; 25 | } 26 | return arr; 27 | } 28 | 29 | int[] arr1 = sort(copyOfRange(arr, 0, arr.length/2)); 30 | int[] arr2 = sort(copyOfRange(arr, arr.length/2, arr.length)); 31 | 32 | return merge(arr1, arr2); 33 | } 34 | 35 | /** 36 | * Merges the two given sorted arrays 37 | * @param arr1 first sorted array 38 | * @param arr2 second sorted array 39 | * @return the merged array 40 | */ 41 | static int[] merge(int[] arr1, int[] arr2){ 42 | int[] arrMerge = new int[arr1.length + arr2.length]; 43 | int ptrMerge = 0; // ptr for arrMerge 44 | int ptr1 = 0; // ptr for arr1 45 | int ptr2 = 0; // ptr for arr2 46 | 47 | while (ptr1 < arr1.length || ptr2 < arr2.length){ 48 | /* if both array not depleted */ 49 | if (ptr1 < arr1.length && ptr2 < arr2.length){ 50 | int curr1 = arr1[ptr1]; // value at ptr1 51 | int curr2 = arr2[ptr2]; // value at ptr2 52 | 53 | if (curr1 < curr2){ 54 | arrMerge[ptrMerge] = curr1; // insert curr1 into arrMerge at ptrMerge 55 | ptr1++; // increment ptr1 56 | } 57 | else { 58 | arrMerge[ptrMerge] = curr2; // insert curr2 into arrMerge at ptrMerge 59 | ptr2++; // increment ptr2 60 | } 61 | } 62 | /* if array 2 depleted */ 63 | else if (ptr1 < arr1.length){ 64 | arrMerge[ptrMerge] = arr1[ptr1]; 65 | ptr1++; 66 | } 67 | /* if array 1 depleted */ 68 | else{ 69 | arrMerge[ptrMerge] = arr2[ptr2]; 70 | ptr2++; 71 | } 72 | ptrMerge++; // increment ptrMerge 73 | } 74 | return arrMerge; 75 | } 76 | 77 | static int[] copyOfRange(int[] arr, int start, int end){ 78 | int length = end - start; 79 | int[] arrDest = new int[length]; 80 | System.arraycopy(arr, start, arrDest, 0, length); 81 | return arrDest; 82 | } 83 | } -------------------------------------------------------------------------------- /Java/MinimumStack.java: -------------------------------------------------------------------------------- 1 | import java.util.Stack; 2 | 3 | /** 4 | * Task Description: 5 | * Implement a data structure that supports "find minimum" on top of the other 6 | * stack operations "push", "peek" and "pop" in O(1). Also, space Complexity for 7 | * finding minimum element should be O(1) 8 | */ 9 | public class MinimumStack { 10 | Stack mainStack, minStack; 11 | 12 | public MinimumStack() { 13 | mainStack = new Stack(); 14 | minStack = new Stack(); 15 | } 16 | 17 | /** 18 | * Push an item to the stack 19 | * @param num item to be pushed 20 | */ 21 | public void push (Integer num) { 22 | if (minStack.empty()) { 23 | minStack.push(num); 24 | mainStack.push(num); 25 | } 26 | else { 27 | int min = minStack.peek(); 28 | if (num <= min) { 29 | minStack.push(num); 30 | mainStack.push(num); 31 | } 32 | else { mainStack.push(num); } 33 | } 34 | } 35 | 36 | /** 37 | * Get the most recently pushed item 38 | * @return the most recently pushed item 39 | */ 40 | public Integer peek() { 41 | return mainStack.peek(); 42 | } 43 | 44 | /** 45 | * Remove the most recently pushed item 46 | * @return the most recently pushed item 47 | */ 48 | public Integer pop() { 49 | if (mainStack.peek() == minStack.peek()) { minStack.pop(); } 50 | return mainStack.pop(); 51 | } 52 | 53 | /** 54 | * Gets the minimum item in the current stack 55 | * @return minimum item 56 | */ 57 | public Integer getMin() { 58 | return minStack.peek(); 59 | } 60 | 61 | public static void main(String[] args) { 62 | MinimumStack ms = new MinimumStack(); 63 | ms.push(2); 64 | System.out.println(ms.peek()); // should print 2 65 | ms.push(3); 66 | System.out.println(ms.peek()); // should print 3 67 | System.out.println(ms.getMin()); // should print 2 68 | ms.push(1); 69 | System.out.println(ms.peek()); // should print 1 70 | System.out.println(ms.getMin()); // should print 1 71 | ms.pop(); // pop 1 72 | System.out.println(ms.peek()); // should print 3 73 | System.out.println(ms.getMin()); // should print 2 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Java/MissingRanges.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This question is taken from Leetcode's Q163 3 | * URL: https://leetcode.com/problems/missing-ranges/ 4 | * Given a sorted list of numbers, write a function to return a string 5 | * representing the missing numbers from 0 to 99 inclusive. 6 | * e.g. 7 | * Given [0, 1, 2, 3, 5, 40, 90] 8 | * The function should return "4, 6-39, 41-89, 91-99" 9 | */ 10 | public class MissingRanges { 11 | 12 | public static void main(String[] args) { 13 | int[] arr = {0, 1, 2, 3, 5, 40, 90}; 14 | // int[] arr = {1, 98}; 15 | // int[] arr = {5}; 16 | // int[] arr = new int[0]; 17 | System.out.println(getGaps(arr)); 18 | } 19 | 20 | public static String getGaps(int[] arr){ 21 | /* corner case */ 22 | if (arr.length == 0){ 23 | return "0-99"; 24 | } 25 | 26 | StringBuffer sb = new StringBuffer(); 27 | 28 | /* check starting missing numbers */ 29 | int first = arr[0]; 30 | int gap = first - 0; 31 | if (gap >= 1) { 32 | /* if just missing 0 */ 33 | if (gap == 1) 34 | sb.append(0); 35 | /* else if missing initial range */ 36 | else { 37 | sb.append("0-" + (arr[0] - 1) ); 38 | } 39 | sb.append(", "); 40 | } 41 | 42 | for (int i=0; i 1){ 48 | /* if exactly one number is missing in progression */ 49 | if (gap == 2){ 50 | sb.append(curr + 1); 51 | } 52 | /* else if a range is missing */ 53 | else { 54 | sb.append((curr + 1) + "-" + (next - 1)); 55 | } 56 | sb.append(", "); 57 | } 58 | } 59 | 60 | /* check ending missing numbers */ 61 | int last = arr[arr.length - 1]; 62 | gap = 99 - last; 63 | if (gap > 0) { 64 | /* if just missing the previous number */ 65 | if (gap == 1) { 66 | sb.append(99); 67 | } 68 | else { 69 | sb.append((last + 1) + "-99"); 70 | } 71 | sb.append(", "); 72 | } 73 | 74 | 75 | if (sb.length() > 0){ 76 | return sb.substring(0, sb.length()-2); 77 | } 78 | 79 | return sb.toString(); 80 | } 81 | } -------------------------------------------------------------------------------- /Java/NearestNeighbor.java: -------------------------------------------------------------------------------- 1 | import java.util.Arrays; 2 | import java.util.Comparator; 3 | 4 | /** 5 | * URL: http://algogeeks.narkive.com/SakzFz8P/nearest-neighbour 6 | * Problem Description: 7 | * You have an array containing information regarding n people. Each person 8 | * is described using a string (their name) and a number (their position along 9 | * a number line). Each person has three friends, which are the three people 10 | * whose number is nearest their own. Describe an algorithm to identify each 11 | * person's three friends. 12 | * 13 | */ 14 | public class NearestNeighbor { 15 | 16 | /** 17 | * Prints the friends for each person 18 | * @param people 19 | */ 20 | public static void printFriends(Person[] people) { 21 | Arrays.sort(people); // sort people by their number 22 | for (int i=0; i= 0 && ptr >= i - 3) { 51 | neighbors[size] = people[ptr]; 52 | size++; 53 | ptr--; 54 | } 55 | 56 | /* get next 3 neighbors */ 57 | ptr = i + 1; 58 | while (ptr < people.length && ptr <= i + 3) { 59 | neighbors[size] = people[ptr]; 60 | size++; 61 | ptr++; 62 | } 63 | 64 | /* get closest 3 neighbors */ 65 | Person curr = people[i]; 66 | neighbors = Arrays.copyOfRange(neighbors, 0, size); 67 | Arrays.sort(neighbors, new Comparator(){ 68 | public int compare(Person a, Person b) { 69 | return Math.abs(a.number - curr.number) - 70 | Math.abs(b.number - curr.number); 71 | } 72 | }); 73 | friends = (Person[]) Arrays.copyOfRange(neighbors, 0, 3); 74 | return friends; 75 | } 76 | 77 | public static void main (String[] args) { 78 | Person[] people = { new Person("John", 92), 79 | new Person("Mary", 23), 80 | new Person("Tom", 21), 81 | new Person("Dick", 7), 82 | new Person("Harry", 5), 83 | new Person("Jane", 57), 84 | new Person("Peter", 64), 85 | new Person("Ron", 12), 86 | new Person("Dexter", 43), 87 | new Person("James", 97)}; 88 | printFriends(people); 89 | } 90 | 91 | 92 | /** 93 | * Person class 94 | */ 95 | public static class Person implements Comparable{ 96 | String name; 97 | int number; 98 | 99 | public Person (String name, int number) { 100 | this.name = name; 101 | this.number = number; 102 | } 103 | 104 | public int compareTo(Person aPerson) { 105 | return this.number - aPerson.number; 106 | } 107 | 108 | public String toString() { 109 | return name + ":" + number; 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /Java/NeedleHaystack.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | 3 | /** 4 | * Write a function strstr (char[] haystack, char[] needle) to return the first 5 | * index occurrence of needle in haystack. * If needle is not present in 6 | * haystack, return -1 7 | */ 8 | 9 | public class NeedleHaystack { 10 | // implement String indexOf method O(MN) 11 | int strstr(char[] haystack, char[] needle){ 12 | int ans = -1; 13 | // edge cases 14 | if (needle.length > haystack.length || needle.length == 0 || haystack.length == 0) 15 | return ans; 16 | 17 | // loop N-M times 18 | for (int i=0; i<=haystack.length-needle.length; i++){ 19 | // loop M times 20 | for (int j=0; j b.length()) { 9 | int diff = a.length() - b.length(); 10 | StringBuffer sb = new StringBuffer(); 11 | for (int i=0; i a.length()) { 17 | int diff = b.length() - a.length(); 18 | StringBuffer sb = new StringBuffer(); 19 | for (int i=0; i=0; i--) { 27 | int digitA = a.charAt(i) - '0'; 28 | int digitB = b.charAt(i) - '0'; 29 | 30 | int sum = carry + digitA + digitB; 31 | if (sum >= 10) { 32 | carry = sum/10; 33 | int curr = sum%10 + '0'; 34 | sb.append((char) curr); 35 | } 36 | else { 37 | carry = 0; 38 | int curr = sum + '0'; 39 | sb.append((char) curr); 40 | } 41 | } 42 | /* handle final carry if any */ 43 | if (carry != 0) { 44 | int curr = carry + '0'; 45 | sb.append((char) curr); 46 | } 47 | sb.reverse(); 48 | System.out.println(sb.toString()); 49 | } 50 | 51 | void addBinary(int intA, int intB) { 52 | String a = Integer.toBinaryString(intA); 53 | String b = Integer.toBinaryString(intB); 54 | 55 | // equalize strings by prepending 0's 56 | if (a.length() > b.length()) { 57 | int diff = a.length() - b.length(); 58 | StringBuffer sb = new StringBuffer(); 59 | for (int i=0; i a.length()) { 64 | int diff = b.length() - a.length(); 65 | StringBuffer sb = new StringBuffer(); 66 | for (int i=0; i=0; i--) { 73 | int aBit = a.charAt(i) - '0'; 74 | int bBit = b.charAt(i) - '0'; 75 | int sum = carry + aBit + bBit; 76 | if (sum == 3) { 77 | sb.append('1'); 78 | carry = 1; 79 | } 80 | else if (sum == 2) { 81 | sb.append('0'); 82 | carry = 1; 83 | } 84 | else { 85 | sb.append((char)((char) sum + '0')); // '1' or '0' 86 | carry = 0; 87 | } 88 | } 89 | if (carry == 1) sb.append('1'); 90 | sb.reverse(); 91 | System.out.println(Integer.parseInt(sb.toString(),2)); 92 | } 93 | 94 | void run(){ 95 | 96 | } 97 | 98 | public static void main(String[] args) { 99 | Scanner sc = new Scanner(System.in); 100 | int a = sc.nextInt(); 101 | int b = sc.nextInt(); 102 | sc.close(); 103 | NumericAddition na = new NumericAddition(); 104 | System.out.println("Binary add:"); 105 | na.addBinary(a, b); 106 | System.out.println("Decimal add:"); 107 | na.addDecimal(a, b); 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /Java/OddManOut.java: -------------------------------------------------------------------------------- 1 | import java.util.HashSet; 2 | 3 | /** 4 | * Problem Description: 5 | * An array is given consisting of integer numbers. Each number except one 6 | * appears exactly twice. The remaining number appears only once in the array. 7 | * Write a function which returns a number which appears only once in the array. 8 | * What if we have a different array where every number appears thrice except 9 | * one number which appear once? 10 | */ 11 | public class OddManOut { 12 | /** 13 | * Gets the single number out from an array of pairs 14 | * @param arr the given array 15 | * @return the odd one out 16 | */ 17 | public static int getOddOneOutOfDoubles(int [] arr) { 18 | int oddOneOut = 0; 19 | for (int i: arr) { oddOneOut ^= i; } 20 | return oddOneOut; 21 | } 22 | 23 | /** 24 | * Gets the single number out from an array of triples 25 | * @param arr the given array 26 | * @return the odd one out 27 | */ 28 | public static int getOddOneOutOfTriples(int[] arr) { 29 | int sum = 0; // sum of all numbers in arr 30 | int temp = 0; 31 | HashSet map = new HashSet(); 32 | for (int i: arr) { 33 | sum += i; 34 | if (!map.contains(i)) { 35 | map.add(i); 36 | temp += i; 37 | } 38 | else { 39 | temp -= i; 40 | } 41 | } 42 | return (temp*3 + sum)/4; 43 | } 44 | 45 | public static void main(String[] args) { 46 | int[] arrDoubles = {1, 4, 2, 1, 3, 4, 2}; 47 | System.out.println("Odd one out of doubles: " + 48 | getOddOneOutOfDoubles(arrDoubles)); 49 | int[] arrTriples = {1, 4, 2, 2, 1, 4, 3, 1, 4, 2}; 50 | System.out.println("Odd one out of triples: " + 51 | getOddOneOutOfTriples(arrTriples)); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /Java/OrderStatistics.java: -------------------------------------------------------------------------------- 1 | import java.util.Random; 2 | 3 | /** 4 | * Comprises of the following algorithms: 5 | * get Kth smallest 6 | * get median 7 | */ 8 | public class OrderStatistics { 9 | 10 | public static void main(String[] args) { 11 | int[] arr = {92, 23, 21, 5, 57, 63, 7, 12, 21, 43, 25, 24, 1}; 12 | int k = 6; // kth smallest or equivalently k-1 rank 13 | System.out.println(k + "th smallest: " + getKthSmallest(arr, k)); 14 | System.out.println("Median: " + getMedian(arr)); 15 | } 16 | 17 | /** 18 | * Given an array of numbers, return the Kth smallest number in the list 19 | * (where 1st smallest refers to the smallest item) 20 | * @param arr given array 21 | * @return Kth smallest item 22 | */ 23 | public static int getKthSmallest (int[] arr, int k) { 24 | return getRankItem(arr, 0, arr.length, k-1); 25 | } 26 | 27 | public static double getMedian(int[] arr) { 28 | /* odd number of items */ 29 | if (arr.length % 2 != 0) { 30 | return getRankItem(arr, 0, arr.length, arr.length/2); 31 | } 32 | 33 | /* even number of items */ 34 | int val1 = getRankItem(arr, 0, arr.length, arr.length/2); 35 | int val2 = getRankItem(arr, arr.length/2 + 1, arr.length, arr.length/2 + 1); 36 | return (double) (val1 + val2)/2; 37 | } 38 | 39 | /** 40 | * Gets the item corresponding to the given rank i from the array. 41 | * O(N) average case where N = end - start 42 | * @param arr the array of interest 43 | * @param start start point of subarray (inclusive) 44 | * @param end end point of subarray (exclusive) 45 | * @param rank the rank of interest in the array. Note that this is 46 | * absolute and not relative to the current range 47 | * @return the item at rank 48 | */ 49 | static int getRankItem(int[] arr, int start, int end, int rank) { 50 | /* if rank exceeds range */ 51 | if (rank < start || rank >= end) { 52 | return -1; 53 | } 54 | setPivot(arr, start, end); // generate random pivot 55 | int pivotPtr = partition(arr, start, end); // partition array based on pivot 56 | 57 | /* if rank is found */ 58 | if (rank == pivotPtr) { 59 | return arr[rank]; 60 | } 61 | /* else if rank is on right partition */ 62 | else if (rank > pivotPtr) { 63 | return getRankItem(arr, pivotPtr + 1, end, rank); 64 | } 65 | /* else if rank is on left partition */ 66 | else { 67 | return getRankItem(arr, start, pivotPtr, rank); 68 | } 69 | } 70 | 71 | /** 72 | * Randomly selects a pivot and set it to be the first element in array. 73 | * O(1) 74 | * @param arr the array of interest 75 | * @param start start point of subarray (inclusive) 76 | * @param end end point of subarray (exclusive) 77 | */ 78 | static void setPivot(int[] arr, int start, int end) { 79 | Random gen = new Random(); 80 | int pivot = gen.nextInt(end - start) + start; // generate random pivot 81 | 82 | /* swap pivot item with start item */ 83 | int pivotVal = arr[pivot]; 84 | arr[pivot] = arr[start]; 85 | arr[start] = pivotVal; 86 | } 87 | 88 | /** 89 | * Partitions array using first item as pivot. O(end - start) 90 | * @param arr the array of interest 91 | * @param start start point of subarray (inclusive) 92 | * @param end end point of subarray (exclusive) 93 | * @return final rank of pivot 94 | */ 95 | static int partition(int[] arr, int start, int end) { 96 | int i = start; // right boundary for left partition 97 | int pivotVal = arr[start]; // value of pivot 98 | 99 | for (int j=i+1; j { 7 | Stack stackIn; 8 | Stack stackOut; 9 | 10 | /** 11 | * constructor 12 | */ 13 | public QueueStack(){ 14 | stackIn = new Stack(); 15 | stackOut = new Stack(); 16 | } 17 | 18 | public void offer(T item){ 19 | stackIn.push(item); 20 | } 21 | 22 | public T poll(){ 23 | if (!stackOut.empty()) 24 | return stackOut.pop(); 25 | else if (!stackIn.empty()){ 26 | transfer(); 27 | return stackOut.pop(); 28 | } 29 | else 30 | return null; 31 | } 32 | 33 | public T peek(){ 34 | if (!stackOut.empty()) 35 | return stackOut.peek(); 36 | else if (!stackIn.empty()){ 37 | transfer(); 38 | return stackOut.peek(); 39 | } 40 | else 41 | return null; 42 | } 43 | 44 | /** 45 | * @return true if the queue is empty, false otherwise 46 | */ 47 | public boolean isEmpty(){ 48 | return (stackIn.empty() && stackOut.empty()); 49 | } 50 | 51 | /** 52 | * Transfers all items in stackIn to stackOut 53 | */ 54 | public void transfer(){ 55 | while (!stackIn.empty()){ 56 | stackOut.push(stackIn.pop()); 57 | } 58 | } 59 | public static void main(String[] args) { 60 | QueueStack qs = new QueueStack(); 61 | qs.offer('a'); 62 | qs.offer('b'); 63 | System.out.println(qs.peek()); // should print 'a' 64 | qs.offer('c'); 65 | qs.offer('d'); 66 | System.out.println(qs.poll()); // should print 'a' 67 | System.out.println(qs.poll()); // should print 'b' 68 | System.out.println(qs.poll()); // should print 'c' 69 | System.out.println(qs.poll()); // should print 'd' 70 | System.out.println(qs.isEmpty()); // should print true 71 | qs.offer('e'); 72 | System.out.println(qs.poll()); // should print 'e' 73 | } 74 | } -------------------------------------------------------------------------------- /Java/QuickSort.java: -------------------------------------------------------------------------------- 1 | import java.util.Arrays; 2 | import java.util.Random; 3 | 4 | /** 5 | * This is an implementation of the Quicksort algorithm 6 | */ 7 | public class QuickSort { 8 | 9 | public static void main(String[] args) { 10 | int[] arr = {92, 23, 21, 5, 57, 63, 7, 12, 21, 43, 25, 24, 1}; 11 | sort(arr, 0, arr.length); 12 | System.out.println(Arrays.toString(arr)); 13 | } 14 | 15 | /** 16 | * Sorts the array using for the index range from start to end (exclusive). O(NlgN) average case 17 | * @param arr array to be sorted 18 | * @param start start index for range in array (inclusive) 19 | * @param end end index for range in array (exclusive) 20 | */ 21 | static void sort(int[] arr, int start, int end){ 22 | if (start != end){ 23 | setPivot(arr, start, end); // set the pivot 24 | int rankPivot = partition(arr, start, end); // partition array range based on pivot 25 | /* recurse down */ 26 | sort(arr, start, rankPivot); // sort left (lower half) 27 | sort(arr, rankPivot + 1, end); // sort right (larger half) 28 | } 29 | } 30 | 31 | /** 32 | * Choose a random index in the range [start,end) and sets it to be the pivot. O(1) 33 | * @param arr the given array 34 | * @param start start index for range in array (inclusive) 35 | * @param end end index for range in array (exclusive) 36 | */ 37 | static void setPivot(int[] arr, int start, int end){ 38 | Random gen = new Random(); 39 | int pivot = start + gen.nextInt(end - start); // generate random pivot 40 | 41 | /* swaps pivot item with that at start index */ 42 | int pivotVal = arr[pivot]; 43 | arr[pivot] = arr[start]; 44 | arr[start] = pivotVal; 45 | } 46 | 47 | /** 48 | * Partitions the array for range [start,end) using start item as pivot. O(end - start) 49 | * @param arr array for in-place partitioning 50 | * @param start start index for range in array (inclusive) 51 | * @param end end index for range in array (exclusive) 52 | * @return final ranking for the pivot 53 | */ 54 | static int partition(int arr[], int start, int end){ 55 | int pivotVal = arr[start]; 56 | int i = start; // last index of left partition (<= pivotVal). Also rank for pivot at the end 57 | 58 | /* for each subsequent item till the end */ 59 | for (int j=i+1; ji){ 11 | // swap arr[i] with arr[j] 12 | int temp = arr[i]; 13 | arr[i] = arr[j]; 14 | arr[j] = temp; 15 | 16 | // update indexes 17 | i++; 18 | j--; 19 | } 20 | 21 | for (int k: arr) 22 | System.out.print(k + " "); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Java/ReverseWords.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jin-zhe/algorithms/e51772089d29c60580abd204dfad6028aac97d8b/Java/ReverseWords.java -------------------------------------------------------------------------------- /Java/RotateMatrix.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | 3 | 4 | public class RotateMatrix { 5 | int[][] matrix; 6 | 7 | RotateMatrix(int[][] arr){ 8 | matrix = arr; 9 | } 10 | 11 | // rotate matrix clockwise by 90 deg 12 | void rotate(){ 13 | // layer increments inwards 14 | for(int layer = 0; matrix.length - layer*2 >= 1; layer++){ 15 | int length = matrix.length - layer*2; // length of current layer 16 | 17 | // swap top with right 18 | for (int i=layer; i0) { 24 | // if either has reached the end of its list, progress down the other list 25 | if (i<0 || j<0) { 26 | if (i<0) { 27 | KMax = arr2[j]; 28 | j--; 29 | } 30 | if (j<0) { 31 | KMax = arr1[i]; 32 | i--; 33 | } 34 | } 35 | // else, always choose the larger element and progress down chosen list 36 | else { 37 | if (arr1[i] > arr2[j]) { 38 | KMax = arr1[i]; 39 | i--; // progress arr1 40 | } 41 | else if (arr2[j] > arr1[i]) { 42 | KMax = arr2[j]; 43 | j--; // progress arr2 44 | } 45 | } 46 | k--; 47 | } 48 | return KMax; 49 | } 50 | 51 | void run(int k) { 52 | System.out.println(solve(k)); 53 | } 54 | 55 | public static void main(String[] args) { 56 | int[] arr1 = {1,3,5,7,9}; 57 | int[] arr2 = {2,4,6,8,10}; 58 | (new SortedArrayUnion(arr1, arr2)).run(10); 59 | } 60 | } -------------------------------------------------------------------------------- /Java/Sqrt.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | 3 | 4 | public class Sqrt { 5 | 6 | public static void main(String[] args) { 7 | Scanner sc = new Scanner(System.in); 8 | int N = sc.nextInt(); 9 | if (N < 0) System.out.println("Negative number!"); 10 | else if (N == 0) System.out.println(0); 11 | else{ 12 | int max = N; 13 | int min = 1; 14 | // while difference between max and min is larger than 1 15 | while (max - min > 1){ 16 | int mid = (min + max)/2; 17 | int square = mid*mid; 18 | // if new upper bound is found, update max 19 | if (square > N) max = (min + max)/2; 20 | // else if new lower bound is found, update min 21 | else min = (min + max)/2; 22 | } 23 | System.out.println(min); 24 | } 25 | sc.close(); 26 | 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Java/Steps.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | /** 3 | * Question: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=787 4 | */ 5 | public class Steps { 6 | int steps; // number of steps 7 | Integer mem[][]; // memorization array where [i] holds answer for i steps left 8 | int max; // unattainable upper bound for value 9 | 10 | // constructor 11 | public Steps(int steps){ 12 | this.steps = steps; 13 | max = (int) Math.sqrt(steps); 14 | mem = new Integer[steps + 1][max + 1]; 15 | } 16 | 17 | // flag to indicate if the last step can be reached under current circumstances 18 | boolean canReachLastStep(int stepsLeft, int previousStep){ 19 | // if it satisfies worst case: when every subsequent step has to be smallerStep 20 | return ((previousStep - 1) - stepsLeft <= 0); 21 | } 22 | 23 | public int solve(int stepsLeft, int previousStep){ 24 | System.out.println(stepsLeft+", "+previousStep); 25 | if (mem[stepsLeft][previousStep] != null) return mem[stepsLeft][previousStep]; 26 | // base cases 27 | // if we are currently at the last step and the next step can be 1 28 | if (stepsLeft == 1 && previousStep <= 2){ 29 | mem[stepsLeft][previousStep] = 1; 30 | return 1; 31 | } 32 | // else if we can never reach the last step OR we can never cross the last step with 1 step 33 | if (!canReachLastStep(stepsLeft, previousStep)){ 34 | mem[stepsLeft][previousStep] = steps; 35 | return steps; 36 | } 37 | 38 | int min = steps; 39 | if (previousStep > 1){ 40 | int smallerStep = 1 + solve(stepsLeft - (previousStep - 1), previousStep - 1); 41 | min = (smallerStep < min)? smallerStep: min; // update min 42 | // System.out.println(stepsLeft+","+previousStep+" (smallerStep):" + smallerStep); 43 | } 44 | if (previousStep > 0 && stepsLeft - previousStep >= 1){ 45 | int sameStep = 1 + solve(stepsLeft - previousStep, previousStep); 46 | min = (sameStep < min)? sameStep: min; // update min 47 | // System.out.println(stepsLeft+","+previousStep+" (sameStep):" + sameStep); 48 | } 49 | if ((previousStep + 1) <= max){ 50 | int largerStep = 1 + solve(stepsLeft - (previousStep + 1), previousStep + 1); 51 | min = (largerStep < min)? largerStep: min; // update min 52 | // System.out.println(stepsLeft+","+previousStep+" (largerStep):" + largerStep); 53 | } 54 | mem[stepsLeft][previousStep] = min; 55 | return min; 56 | } 57 | 58 | public void run(){ 59 | System.out.println(solve(steps, 0)); 60 | } 61 | public static void main(String[] args) { 62 | Scanner sc = new Scanner(System.in); 63 | int N = sc.nextInt(); 64 | for (int i=0; i "a1b2" buffer overflow.. such inputs will not be given. 9 | */ 10 | public class StringCompression { 11 | public static void main(String[] args) { 12 | Scanner sc = new Scanner(System.in); 13 | System.out.println(compress(sc.nextLine().toCharArray())); 14 | sc.close(); 15 | } 16 | 17 | /** 18 | * Compresses a character array 19 | * @param str character array to be compressed 20 | * @return character array representing the compressed str 21 | */ 22 | public static String compress(char[] str) { 23 | if (str.length <= 1) { 24 | return new String(str); 25 | } 26 | char prevChar = str[0]; // character to keep count of 27 | int count = 1; // count of prevChar encountered 28 | int nxtPos = 1; // next position to write 29 | for (int i=1; i 1) { 44 | nxtPos = writeCount(str, count, nxtPos); 45 | } 46 | return new String(str, 0, nxtPos); 47 | } 48 | 49 | /** 50 | * Writes the value of count to the array at current position for writing 51 | * and returns the next position for writing 52 | * @param str character array 53 | * @param count the character representation of count to be written 54 | * @param start the starting position in str to write at 55 | * @return the next available position for writing 56 | */ 57 | public static int writeCount(char[] str, int count, int start) { 58 | int places = getPlaces(count); 59 | int pos = places; 60 | while(pos-- > 0) { 61 | str[start+pos] = Character.forDigit(count%10, 10); 62 | count /= 10; 63 | } 64 | return start + places; 65 | } 66 | 67 | /** 68 | * Gets the number of decimal digit places that count needs 69 | * @param count number of interest 70 | * @return number of decimal positions that count requires 71 | */ 72 | public static int getPlaces(int count) { 73 | int places = 0; 74 | while (count > 0) { 75 | places++; 76 | count /= 10; 77 | } 78 | return places; 79 | } 80 | } -------------------------------------------------------------------------------- /Java/StringPermutations.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.Scanner; 3 | /** 4 | * Problem Description: 5 | * Given a string, return a list of all its permutations 6 | * 7 | * Note: 8 | * These implementations do not differentiate between strings of same sequences 9 | * i.e. "aaa" will generate 6 permutations despite them all being "aaa" 10 | */ 11 | public class StringPermutations { 12 | 13 | public static void main(String[] args) { 14 | ArrayList permutations; 15 | Scanner sc = new Scanner(System.in); 16 | String str = sc.nextLine(); 17 | sc.close(); 18 | System.out.println("== Method 1 ========"); 19 | permutations = permutate1(str); 20 | printPermutations(permutations); 21 | System.out.println("== Method 2 ========"); 22 | permutations = permutate2(str); 23 | printPermutations(permutations); 24 | } 25 | 26 | /** 27 | * Method 1: 28 | * To get all permutations of String: 29 | * 1. For each character in current range 30 | * 1.1 let it be the suffix by swapping with the last character 31 | * 1.2 Fix suffix character by recursing down with decremented range 32 | * 1.3 Swap back character to restore configuration for next iteration 33 | * @param str character array representing string to be permutated 34 | * @param len defines implicit range [0, len-1] in str to be permutated 35 | * @param permutations string array to be populated at the base case 36 | */ 37 | public static void permutate1(char[] str, int len, 38 | ArrayList permutations) { 39 | /* base case: single character left */ 40 | if (len == 1) { 41 | permutations.add(new String(str)); 42 | } 43 | else { 44 | int lastPos = len - 1; // index of the last position in current range 45 | /* let every character in current range be the suffix */ 46 | for (int i=0; i permutate1(String str) { 54 | ArrayList permutations = new ArrayList(); 55 | permutate1(str.toCharArray(), str.length(), permutations); 56 | return permutations; 57 | } 58 | 59 | /** 60 | * Method 2: 61 | * To get all permutations of string: 62 | * 1. For each character in string 63 | * 1.1 Remove character from string, we call it current prefix 64 | * 1.2 Recurse: For each permutation of string (exclusive of prefix), 65 | * prepend prefix to it to form new string 66 | * E.g. 67 | * perm("avx") 68 | * 'a': perm("vx") // denotes 'a' as prefix for every permutation of "vx" 69 | * 'v': perm("x") 70 | * "avx" // 1 71 | * 'x': perm("v") 72 | * "axv" // 2 73 | * 'v': perm("ax") 74 | * 'a': perm("x") 75 | * "vax" // 3 76 | * 'x': perm("a") 77 | * "vxa" // 4 78 | * 'x': perm("av") 79 | * 'a': perm("v") 80 | * "xav" // 5 81 | * 'v': perm("a") 82 | * "xva" // 6 total permutations 83 | * @param prefix accumulated prefixes 84 | * @param str string to be permutated 85 | * @param permutations string array to be populated at the base case 86 | */ 87 | public static void permutate2(String prefix, String str, 88 | ArrayList permutations) { 89 | /* base case */ 90 | if (str.length() == 1) { 91 | permutations.add(prefix + str); 92 | } 93 | else { 94 | /* every character as a prefix candidate */ 95 | for (int i=0; i permutate2(String str) { 106 | ArrayList permutations = new ArrayList(); 107 | permutate2("", str, permutations); 108 | return permutations; 109 | } 110 | 111 | /* helper methods */ 112 | /** 113 | * Prints each permutation line by line 114 | * @param permutations list of StringBuffers representing permutations 115 | */ 116 | public static void printPermutations (ArrayList permutations) { 117 | System.out.println(permutations.size() + " permutations: "); 118 | for (String i: permutations) { 119 | System.out.println(i); 120 | } 121 | } 122 | 123 | /** 124 | * Swaps item at position x with item at position y in array arr 125 | * @param arr array to perform swapping on 126 | * @param x first position 127 | * @param y second position 128 | */ 129 | public static void swap(char[] arr, int x, int y) { 130 | char temp = arr[x]; 131 | arr[x] = arr[y]; 132 | arr[y] = temp; 133 | } 134 | } -------------------------------------------------------------------------------- /Java/StringToInteger.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | 3 | /** 4 | * Task Description: 5 | * Write a function that parses a string into integer 6 | */ 7 | public class StringToInteger { 8 | /** 9 | * Converts ASCII to Integer 10 | * @param str target string 11 | * @return parsed integer 12 | */ 13 | public static int atoi(String str) { 14 | int ans = 0; 15 | boolean isNeg = (str.charAt(0) == '-'); 16 | int start = (isNeg)? 1: 0; 17 | for (int i=start; i map = new HashSet(); 12 | ArrayList temp = new ArrayList(); 13 | 14 | for(int i=0; i list){ 26 | // base case 27 | if (length == 0){ 28 | System.out.println(list.toString()); // prints the subset 29 | return; 30 | } 31 | 32 | for (int i=start; i + (length-1) < newArr.length - length + 1 ; i++){ 33 | ArrayList newList = new ArrayList(list); // create new list for thread safety 34 | newList.add(newArr[i]); // add current item 35 | getAllSubsets(i + 1, length - 1, newList); // recurse with current item added 36 | } 37 | } 38 | 39 | void run(){ 40 | preprocess(); 41 | getAllSubsets(0, 5, new ArrayList()); 42 | } 43 | 44 | public static void main(String[] args) { 45 | (new SubsetsN()).run(); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /Java/SummedAreaTable.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Implement Summed Area Table of a given matrix. 3 | * URL: http://stackoverflow.com/questions/2277749/calculate-the-sum-of-elements-in-a-matrix-efficiently 4 | * 5 | * Task: 6 | * Given an n*m matrix, for each cell, calculate the sum of values in its 7 | * implicit sub-matrix where the top-left coordinate is (0, 0) and bottom right 8 | * corner is the cell itself. Can you do it in-place? 9 | * Example: 10 | * 11 | * Input: 12 | * 3 1 2 1 13 | * 2 1 1 1 14 | * 3 1 2 1 15 | * 16 | * Output: 17 | * 3 4 6 7 18 | * 5 7 10 12 19 | * 8 11 16 19 20 | */ 21 | public class SummedAreaTable { 22 | /** 23 | * Get the summed area table for given matrix 24 | * O(MN) time, O(MN) space 25 | * @param matrix source matrix 26 | * @return summed area table 27 | */ 28 | public static int[][] getSummedAreaTable(int[][] matrix) { 29 | int rowSize = matrix.length; 30 | int colSize = matrix[0].length; 31 | int[][] cumulativeMatrix = new int[rowSize][colSize]; 32 | for (int i=0; i n || (len > 1 && (arr[len-1] + arr[len-2] < n))) { 72 | return null; 73 | } 74 | 75 | int front = start; 76 | int rear = arr.length - 1; 77 | 78 | while (front < rear) { 79 | int sum = arr[front] + arr[rear]; 80 | /* if pair found, return */ 81 | if (sum == n) { return new Pair(arr[front], arr[rear]); } 82 | /* if too low, increment front index */ 83 | if (sum < n) { front++; } 84 | /* if too large, decrement rear index */ 85 | else { rear--; } 86 | } 87 | return null; 88 | } 89 | 90 | /** 91 | * Alternative O(N) implementation of obtain2 92 | */ 93 | public static Pair obtain2_alternative(int n, int[] arr){ 94 | /* preprocess hashmap */ 95 | HashMap map = new HashMap(); 96 | for (int i: arr){ 97 | if (map.containsKey(i)) 98 | map.put(i, map.get(i)+1); 99 | else 100 | map.put(i, 0); 101 | } 102 | /* iterates each number i array to test if n-i also exists */ 103 | for (int i: arr){ 104 | if (map.containsKey(n-i)) 105 | if (i != n-i || (i==n-i && map.get(n-i)>1)) 106 | return new Pair(i, n-i); 107 | } 108 | 109 | return null; 110 | } 111 | 112 | /* helper classes */ 113 | public static class Triplet{ 114 | int one; 115 | int two; 116 | int three; 117 | public Triplet (int one, int two, int three){ 118 | this.one = one; 119 | this.two = two; 120 | this.three = three; 121 | } 122 | public String toString(){ 123 | return one + " + " + two + " + " + three; 124 | } 125 | } 126 | 127 | static class Pair{ 128 | int one; 129 | int two; 130 | public Pair (int one, int two){ 131 | this.one = one; 132 | this.two = two; 133 | } 134 | public String toString(){ 135 | return one + " + " + two; 136 | } 137 | } 138 | } -------------------------------------------------------------------------------- /Java/Thing.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.HashSet; 3 | 4 | /** 5 | * Implement deep-copy on the class Thing 6 | */ 7 | public class Thing { 8 | String label; 9 | public final ArrayList things; 10 | 11 | /* constructor */ 12 | public Thing(String label){ 13 | this.label = label; 14 | things = new ArrayList(); 15 | } 16 | 17 | // add a reachable neighbor to the list of things 18 | public void addReachableNode(Thing aThing){ 19 | things.add(aThing); 20 | } 21 | 22 | /* Return a deep copy of this. The object graph formed by the copy 23 | * should have the same structure as the object graph of the original, 24 | * but they should share no references. 25 | */ 26 | 27 | // driver function 28 | public Thing deepCopy() { 29 | // implement this 30 | return deepCopyHelper(new HashSet()); 31 | } 32 | // deep-copy function 33 | private Thing deepCopyHelper(HashSet set) { 34 | set.add(this); // add caller to set 35 | Thing newThing = new Thing(this.label); // to be returned 36 | // for each child 37 | for (Thing aThing: things){ 38 | if (!set.contains(aThing)){ // if node not yet processed 39 | Thing childThing = aThing.deepCopyHelper(set); // recursion step: get deep copied child 40 | newThing.things.add(childThing); // append deep copied child to list of things 41 | } 42 | } 43 | return newThing; 44 | } 45 | 46 | // Depth-first search which prints node label 47 | public void dfs_label(){ 48 | dfs_label(new HashSet()); 49 | } 50 | public void dfs_label(HashSet set){ 51 | set.add(this); 52 | System.out.print(label + " "); 53 | for (Thing aThing: things) 54 | if (!set.contains(aThing)) 55 | aThing.dfs_label(set); 56 | } 57 | 58 | // Depth-first search which prints node references 59 | public void dfs_ref(){ 60 | dfs_ref(new HashSet()); 61 | } 62 | public void dfs_ref(HashSet set){ 63 | set.add(this); 64 | System.out.print(this + " "); 65 | for (Thing aThing: things) 66 | if (!set.contains(aThing)) 67 | aThing.dfs_ref(set); 68 | } 69 | public static void main(String[] args) { 70 | 71 | /* Create Graph: 72 | * A --> B --> E --> H 73 | * ^ | | 74 | * | v v 75 | * D <-- C <-- F --> G 76 | */ 77 | Thing thingA = new Thing("A"); 78 | Thing thingB = new Thing("B"); 79 | Thing thingC = new Thing("C"); 80 | Thing thingD = new Thing("D"); 81 | Thing thingE = new Thing("E"); 82 | Thing thingF = new Thing("F"); 83 | Thing thingG = new Thing("G"); 84 | Thing thingH = new Thing("H"); 85 | 86 | thingA.addReachableNode(thingB); // A --> B 87 | thingB.addReachableNode(thingC); // B --> C 88 | thingC.addReachableNode(thingD); // C --> D 89 | thingD.addReachableNode(thingA); // D --> A 90 | thingB.addReachableNode(thingE); // B --> E 91 | thingE.addReachableNode(thingF); // E --> F 92 | thingF.addReachableNode(thingC); // F --> C 93 | thingF.addReachableNode(thingG); // F --> G 94 | thingE.addReachableNode(thingH); // E --> H 95 | 96 | /* Run DFS on original and deep-copied Thing and juxtapose results */ 97 | System.out.println("thingA labels:"); 98 | thingA.dfs_label(); 99 | System.out.println(); 100 | 101 | System.out.println("deep-copied thingA labels:"); 102 | Thing thingACopied = thingA.deepCopy(); 103 | thingACopied.dfs_label(); 104 | System.out.println(); 105 | 106 | System.out.println("thingA references:"); 107 | thingA.dfs_ref(); 108 | System.out.println(); 109 | 110 | System.out.println("deep-copied thingA references:"); 111 | thingACopied = thingA.deepCopy(); 112 | thingACopied.dfs_ref(); 113 | } 114 | } -------------------------------------------------------------------------------- /Java/UniqueStringSubsets.java: -------------------------------------------------------------------------------- 1 | import java.util.Collections; 2 | import java.util.HashMap; 3 | import java.util.Scanner; 4 | import java.util.Vector; 5 | 6 | /** 7 | * Given a string, write a function which prints all the subsets of the string. 8 | * Now make the function to return only unique solutions 9 | */ 10 | public class UniqueStringSubsets { 11 | char[] arr; 12 | HashMap map; 13 | Vector outputList; 14 | boolean mem[][]; 15 | 16 | UniqueStringSubsets(String string){ 17 | arr = string.toCharArray(); 18 | map = new HashMap(); 19 | mem = new boolean[arr.length + 1][arr.length + 1]; 20 | outputList = new Vector(); 21 | } 22 | 23 | void printSubsets(int start, int end){ 24 | if (mem[start][end] == true) return; 25 | // prints current subset if not already done so (ensure uniqueness) 26 | StringBuffer sb = new StringBuffer(); 27 | sb.append(arr, start, end - start + 1); 28 | String curr = sb.toString(); 29 | if (!map.containsKey(curr)){ 30 | System.out.println(curr); 31 | map.put(curr, true); 32 | } 33 | 34 | // base case 35 | if (end - start == 0) return; 36 | 37 | printSubsets(start + 1, end); 38 | printSubsets(start, end - 1); 39 | mem[start][end] = true; 40 | } 41 | 42 | // prints all subsequences at the end of recursion O(2^N) solution 43 | void populateSubsequences(int curr, StringBuffer sb){ 44 | // base case 45 | if (curr == arr.length){ 46 | String output = sb.toString(); 47 | // if not printed before, print 48 | if (!map.containsKey(output)){ 49 | map.put(output, true); 50 | outputList.add(output); 51 | } 52 | // else do nothing 53 | return; // terminate recursion 54 | } 55 | 56 | // do not include current character 57 | populateSubsequences(curr + 1, sb); 58 | 59 | // include current character 60 | StringBuffer includeCurrent = new StringBuffer(sb); 61 | includeCurrent.append(arr[curr]); 62 | populateSubsequences(curr + 1, includeCurrent); 63 | } 64 | 65 | void run(){ 66 | System.out.println("Substrings:"); 67 | printSubsets(0, arr.length - 1); 68 | System.out.println("Subsequences:"); 69 | map = new HashMap(); 70 | populateSubsequences(0, new StringBuffer()); 71 | // sort outputs 72 | Collections.sort(outputList); 73 | for(String i: outputList) System.out.println(i); 74 | } 75 | public static void main(String[] args) { 76 | Scanner sc = new Scanner(System.in); 77 | UniqueStringSubsets uss = new UniqueStringSubsets(sc.next()); 78 | uss.run(); 79 | sc.close(); 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /Java/WordBreak.java: -------------------------------------------------------------------------------- 1 | import java.util.HashSet; 2 | 3 | /** 4 | * URL: http://thenoisychannel.com/2011/08/08/retiring-a-great-interview-problem 5 | * Problem description: 6 | * Given an input string and a dictionary of words, segment the input string 7 | * into a space-separated sequence of dictionary words if possible. For example, 8 | * if the input string is "applepie" and dictionary contains a standard set of 9 | * English words, then we would return the string "apple pie" as output. 10 | */ 11 | public class WordBreak { 12 | HashSet dictionary; 13 | 14 | public WordBreak (String[] words) { 15 | dictionary = new HashSet(); 16 | for (String word: words) { dictionary.add(word); } 17 | } 18 | 19 | /** 20 | * Prints out all possible word breaks for given string 21 | * @param str string of interest 22 | */ 23 | public void printPossibleSentences(String str) { 24 | printPossibleSentences("", str, 0); 25 | } 26 | /** 27 | * Recursive method 28 | * @param sentence the sentence of words formed thus far 29 | * @param str the original string 30 | * @param start the starting index of current substring to examine 31 | */ 32 | public void printPossibleSentences(String sentence, String str, int start) { 33 | if (start == str.length()) { System.out.println(sentence); } 34 | for (int end=start+1; end<=str.length(); end++) { 35 | String substr = str.substring(start, end); 36 | if (isWord(substr)) { 37 | printPossibleSentences(sentence + substr + " ", str, end); 38 | } 39 | } 40 | } 41 | 42 | /** 43 | * Get a valid instance of sentence given the input string 44 | * O(N^2) 45 | * @param str string of interest 46 | * @return a valid instance of sentence of words 47 | */ 48 | public String getValidInstance(String str) { 49 | String[] mem = new String[str.length()]; 50 | /* pre-process. Note: we cannot use null as that is a valid memorization */ 51 | for (int i=0; i error): 23 | if (mid**2 > n): 24 | hi = mid 25 | else: 26 | lo = mid 27 | mid = middle(lo, hi) # Update new mid 28 | return mid 29 | 30 | def main(): 31 | message = "Input float to carry out square root. Use a negative number to terminate." 32 | val = input_val(message) 33 | while val > 0: 34 | print("Float of {} is {}".format(val, sqrt(val))) 35 | val = input_val(message) 36 | 37 | if __name__ == '__main__': main() -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Algorithms 2 | My personal Java practises for some well-studied algorithms and problems commonly asked in technical interviews 3 | 4 | ## My Solutions 5 | * Given a number, return all possible strings that the number could represent if `0 -> {A, B, C}, 2 -> {D, E, F}`, and so on. (Modified from [*Original question*](http://www.glassdoor.com/Interview/phone-numbers-provided-a-phone-number-654-876-0987-return-all-possible-strings-that-the-phone-number-could-represent-QTN_361642.htm)) Solutions: [**Java**](Java/AllPossibleStrings.java) 6 | * You have a room-full of balances and weights. Each balance weighs ten pounds and is considered perfectly balanced when the sum of weights on its left and right sides are exactly the same. You have placed some weights on some of the balances, and you have placed some of the balances on other balances. Given a description of how the balances are arranged and how much additional weight is on each balance, determine how to add weight to the balances so that they are all perfectly balanced. ([*Original question*](http://www.careercup.com/question?id=12150672)) Solutions: [**Java**](Java/Balance.java) 7 | * Algorithms on binary trees ([**Java**](Java/BinaryTree.java)). Comprises of the following algorithms: 8 | * Given a node value, finds the node in tree using dfs 9 | * Pre-order traversal 10 | * In-order traversal 11 | * Post-order traversal 12 | * Checks if tree is a BST 13 | * Gets the height of the BST 14 | * Checks if the tree is height balanced 15 | * Determines the Lowest Common Ancestor (LCA) of two nodes 16 | * Prints the tree level wise using BFS 17 | * Prints the average value for each level in tree 18 | * Determines the in-order successor for a node 19 | * Suppose there are 5 types of coins: 50-cent, 25-cent, 10-cent, 5-cent, and 1-cent. Write a program to find the total number of different ways of making changes for any amount of money in cents. ([*Original question*](http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=615)) Solutions: [**Java**](Java/CoinChange.java) 20 | * Let 1 represent ‘A’, 2 represents ‘B’, etc. Given a digit sequence, count the number of possible decodings of the given digit sequence. ([*Original question*](http://www.geeksforgeeks.org/count-possible-decodings-given-digit-sequence/)) Solutions: [**Java**](Java/CountPossibleDecodings.java) 21 | * Given a number, obtain the next larger permutation and next lower permutation by swapping around the digits in the number. Solutions: [**Java**](Java/DigitPermutations.java) 22 | * Implement Fibonacci in bottom-up dynamic programming fashion. Solutions: [**Java**](Java/Fibonacci.java) 23 | * Given n stairs, how many number of ways can you climb if u use either 1 or 2 at a time? ([*Original question*](http://www.careercup.com/question?id=3590768)) Solutions: [**Java**](Java/FibonacciSteps.java) 24 | * Solve the “FizzBuzz” problem (*needs no introduction*). Solutions: [**Java**](Java/FizzBuzz.java) 25 | * Implement Conway's game of life by predicting the next state of a matrix given its current state. Solutions: [**Java**](Java/GameOfLife.java) 26 | * Algorithms on Graphs ([**Java**](Java/Graph.java)). Comprises of the following algorithms: 27 | * BFS 28 | * DFS 29 | * Kruskal (MST) 30 | * Prim (MST) 31 | * Modified Dijkstra (SSSP) 32 | * Bellman-Ford (SSSP) 33 | * Floyd-Warshall (APSP) 34 | * You are given an M by N matrix containing only the characters 'P' and 'T'. You can flip the characters in any number of columns. I.e. 'P' becomes 'T' and 'T' becomes 'P' for all characters under that column. Your aim is to maximize the number of rows for which all the characters are the same.Solutions: [**Java**](Java/HomogeneousRows.java) 35 | * Implement integer division without using `/` or `%` in O(logN). Solutions: [**Java**](Java/IntegerDivision.java) 36 | * You are given a binary array with N elements: `d[0], d[1], ... d[N - 1]`. You can perform AT MOST one move on the array: choose any two integers and flip all the elements between (and including) them. What is the maximum number of '1'-bits which you can obtain in the final bit-string? ([*Original question*](http://www.careercup.com/question?id=6262507668766720)) Solutions: [**Java**](Java/KadaneBitFlip.java) 37 | * Implement Karatsuba's multiplication algorithm. *(Just a practice. No way this question will be tested)* Solutions: [**Java**](Java/Karatsuba.java) 38 | * Implement Knuth shuffle. Solutions: [**Java**](Java/KnuthShuffle.java) 39 | * Given two strings, find the Longest Common Subsequence between them. Solutions: [**Java**](Java/LongestCommonSubsequence.java) 40 | * Given two strings, find the Longest Common Substring between them. Solutions: [**Java**](Java/LongestCommonSubstring.java) 41 | * Given an array of integers, find the Longest Increasing Subsequence of its items. Solutions: [**Java**](Java/LongestIncreasingSubsequence.java) 42 | * Given two strings, find the Longest Palindromic Subsequence between them. Solutions: [**Java**](Java/LongestPalindromicSubsequence.java) 43 | * Given two strings, find the Longest Palindromic Substring between them. Solutions: [**Java**](Java/LongestPalindromicSubstring.java) 44 | * Implement Kadane's algorithm, returning the maximum subarray sum as well as the start and end indexes representing the maximum subarray. Solutions: [**Java**](Java/MaximumSubarray.java) 45 | * Implement merge sort. Solutions: [**Java**](Java/MergeSort.java) 46 | * Implement a data structure that supports "find minimum" on top of the other stack operations "push" and "pop" in O(1). Space Complexity for finding minimum element should be O(1) Solutions: [**Java**](Java/MinimumStack.java) 47 | * Given a sorted list of numbers, write a function to return a string representing the missing numbers from 0 to 99 inclusive. ([*Original question*](https://leetcode.com/problems/missing-ranges/)) Solutions: [**Java**](Java/MissingRanges.java) 48 | * You have an array containing information regarding n people. Each person is described using a string (their name) and a number (their position along a number line). Each person has three friends, which are the three people whose number is nearest to their own. Describe an algorithm to identify each person's three friends. ([*Original question*](http://algogeeks.narkive.com/SakzFz8P/nearest-neighbour)) Solutions: [**Java**](Java/NearestNeighbors.java) 49 | * Write a function `strstr (char[] haystack, char[] needle)` to return the first index occurrence of needle in haystack. If needle is not present in haystack, return -1. ([*Original question*](http://www.programcreek.com/2012/12/leetcode-implement-strstr-java/)) Solutions: [**Java**](Java/NeedleHaystack.java) 50 | * Implement numeric addition of two numbers in both decimal as well as binary. Solutions: [**Java**](Java/NumericAddition.java) 51 | * An array is given consisting of integer numbers. Each number except one appears exactly twice. The remaining number appears only once in the array. Write a function which returns a number which appears only once in the array. What if we have a different array where every number appears thrice except one number which appear once?. Solutions: [**Java**](Java/OddManOut.java) 52 | * [**Order Statistics**](Java/OrderStatistics.java). Comprises of the following algorithms: 53 | * Kth smallest 54 | * median 55 | * Implement a queue using 2 stacks. Solutions: [**Java**](Java/QueueStack.java) 56 | * Implement quick sort. Solutions: [**Java**](Java/QuickSort.java) 57 | * A kidnaper wishes to write a ransom note using letters from a magazine article. You are given with the ransom note and magazine article find whether kidnaper can write a note using the article or not. ([*Original question*](http://www.careercup.com/question?id=67086)) Solutions: [**Java**](Java/RansomNote.java) 58 | * Reverse an array in-place. Solutions: [**Java**](Java/ReverseArray.java) 59 | * Reverse the order of words in a sentence, but keep words themselves unchanged. Words in a sentence are divided by blanks. For instance, the reversed output should be `"student. a am I"` when the input is `"I am a student."`. ([*Original question*](http://www.geeksforgeeks.org/reverse-words-in-a-given-string/)) Solutions: [**Java**](Java/ReverseWords.java) 60 | * Given a matrix, rotate it clockwise by 90 degrees. Solutions: [**Java**](Java/RotateMatrix.java) 61 | * [**Algorithms for set operations**](Java/SetOperations.java). Comprises of the following operations: 62 | * Intersection of two lists 63 | * Union of two lists 64 | * n-way intersection of n lists 65 | * Given two sorted arrays and a number k, find the kth largest number in the union of the two arrays. Do it in place. Solutions: [**Java**](Java/SortedArrayUnion.java) 66 | * Implement square-root method wihtout using the Math library. Solutions: [**Java**](Java/Sqrt.java) [**Python**](Python/sqrt.py) 67 | * One steps through integer points of the straight line. The length of a step must be nonnegative and can be by one bigger than, equal to, or by one smaller than the length of the previous step. What is the minimum number of steps in order to get from x to y? The length of the first and the last step must be 1. ([*Original question*](https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=787)) Solutions: [**Java**](Java/Steps.java) 68 | * Given a string `"aaabbbcc"`, compress it into `"a3b3c2"` in-place. ([*Original question*](http://www.careercup.com/question?id=7449675)) Solutions: [**Java**](Java/StringCompression.java) 69 | * Given a string, print out all its permutations. Solutions: [**Java**](Java/StringPermutations.java) 70 | * Write a function that parses a string into integer. Solutions: [**Java**](Java/StringToInteger.java) 71 | * Given an array of integers, return all possible subsets of length n. Solutions: [**Java**](Java/SubsetsN.java) 72 | * Given an n*m matrix, for each cell, calculate the sum of values in its implicit sub-matrix where the top-left coordinate is (0, 0) and bottom right corner is the cell itself. Can you do it in-place? ([*Original question*](http://stackoverflow.com/questions/2277749/calculate-the-sum-of-elements-in-a-matrix-efficiently)) Solutions: [**Java**](Java/SummedAreaTable.java) 73 | * Given an array and a number n, can you obtain n using a 2 numbers in the array? What about 3 numbers? Solutions: [**Java**](Java/TargetSum.java) 74 | * Implement a deep-copy method for the class Thing which has a list of Thing objects. Solutions: [**Java**](Java/Thing.java) 75 | * Given a string, write a function which prints all the subsets of the string. Now make the function to return only unique solutions. Solutions: [**Java**](Java/UniqueStringSubsets.java) 76 | * Given an input string and a dictionary of words, segment the input string into a space-separated sequence of dictionary words if possible. For example, if the input string is `"applepie"` and dictionary contains a standard set of English words, then we would return the string `"apple pie"` as output. ([*Original question*](http://thenoisychannel.com/2011/08/08/retiring-a-great-interview-problem)) Solutions: [**Java**](Java/WordBreak.java) 77 | --------------------------------------------------------------------------------