├── .gitignore ├── LICENSE ├── README.txt ├── ch01 ├── 1.01_-_Is_Unique │ └── IsUnique.java ├── 1.02_-_Check_Permutations │ └── CheckPermutations.java ├── 1.03_-_URLify │ └── URLify.java ├── 1.04_-_Palindrome_Permutation │ └── PalindromePermutation.java ├── 1.05_-_One_Away │ └── OneAway.java ├── 1.06_-_String_Compression │ └── StringCompression.java ├── 1.07_-_Rotate_Matrix │ └── RotateMatrix.java ├── 1.08_-_Zero_Matrix │ └── ZeroMatrix.java └── 1.09_-_String_Rotation │ └── StringRotation.java ├── ch02 ├── 2.01_-_RemoveDups │ └── RemoveDups.java ├── 2.02_-_ReturnKth │ └── ReturnKth.java ├── 2.03_-_DeleteMiddle │ └── DeleteMiddle.java ├── 2.04_-_Partition │ └── Partition.java ├── 2.05_-_Sum_Lists │ └── SumLists.java ├── 2.06_-_Palindrome │ └── Palindrome.java ├── 2.07_-_Intersection │ └── Intersection.java └── 2.08_-_LoopDetection │ └── LoopDetection.java ├── ch03 ├── 3.01_-_Three_in_One │ └── FixedMultiStack.java ├── 3.02_-_Stack_Min │ └── StackMin.java ├── 3.03_-_Stack_of_Plates │ └── SetOfStacks.java ├── 3.04_-_Queue_via_Stacks │ └── MyQueue.java ├── 3.05_-_Sort_Stack │ └── SortStack.java └── 3.06_-_Animal_Shelter │ └── AnimalQueue.java ├── ch04 ├── 4.01_-_Route_Between_Nodes │ ├── Graph.java │ ├── Node.java │ └── RouteBetweenNodes.java ├── 4.02_-_Minimal_Tree │ └── MinimalTree.java ├── 4.03_-_List_of_Depths │ └── ListOfDepths.java ├── 4.04_-_Check_Balanced │ └── CheckBalanced.java ├── 4.05_-_Validate_BST │ └── ValidateBST.java ├── 4.06_-_Successor │ └── Successor.java ├── 4.07_-_Build_Order │ └── BuildOrder.java ├── 4.08_-_First_Common_Ancestor │ └── FirstCommonAncestor.java ├── 4.09_-_BST_Sequences │ └── BSTSequences.java ├── 4.10_-_Check_Subtree │ └── CheckSubtree.java ├── 4.11_-_Random_Node │ └── RandomNode.java └── 4.12_-_Paths_with_Sum │ ├── PathsWithSum.java │ └── README ├── ch05 ├── 5.01_-_Insertion │ └── Insertion.java ├── 5.02_-_Binary_to_String │ └── BinaryToString.java ├── 5.03_-_Flip_Bit_to_Win │ ├── FlipBitToWin.java │ └── README ├── 5.05_-_Debugger │ └── Debugger.txt ├── 5.06_-_Conversion │ └── Conversion.java └── 5.07_-_Pairwise_Swap │ └── PairwiseSwap.java ├── ch06 └── 6.01_-_The_Heavy_Pill │ └── The_Heavy_Pill.md ├── ch07 ├── 7.01_-_Deck_of_Cards │ ├── Card.java │ ├── Deck.java │ ├── Hand.java │ └── Suit.java └── 7.09_-_Circular_Array │ └── CircularArray.java ├── ch08 ├── 8.01_-_TripleStep │ └── TripleStep.java ├── 8.03_-_Magic_Index │ └── MagicIndex.java ├── 8.04_-_Power_Set │ └── PowerSet.java ├── 8.05_-_Recursive_Multiply │ └── RecursiveMultiply.java ├── 8.07_-_Permutations_without_Dups │ └── Permutations.java ├── 8.08_-_Permutations_with_Duplicates │ ├── Permutations.java │ └── README ├── 8.09_-_Parens │ └── Parens.java ├── 8.10_-_Paint_Fill │ └── PaintFill.java ├── 8.11_-_Coins │ └── Coins.java └── 8.12_-_Eight_Queens │ └── EightQueens.java ├── ch10 ├── 10.01_-_Sorted_Merge │ └── SortedMerge.java ├── 10.02_-_Group_Anagrams │ └── GroupAnagrams.java ├── 10.03_-_Search_in_Rotated_Array │ └── SearchInSortedArray.java ├── 10.04_-_Sorted_Search,_No_Size │ └── SortedSearch.java ├── 10.06_-_Sort_Big_File │ └── SortBigFile.txt ├── 10.08_-_Find_Duplicates │ └── FindDuplicates.java └── 10.09_-_Sorted_Matrix_Search │ └── SortedMatrixSearch.java ├── ch11 ├── 11.01_-_Mistake │ └── Mistake.txt └── 11.02_-_Random_Crashes │ └── RandomCrashes.txt ├── ch12 ├── 12.01_-_Last_K_Lines │ ├── file.txt │ ├── file2.txt │ ├── klines │ └── klines.cpp ├── 12.02_-_Reverse_String │ └── reverse_string.c ├── 12.03_-_Hash_Table_vs_STL_Map │ └── HashTableVsSTLMap.md ├── 12.04_-_Virtual_Functions │ └── VirtualFunctions.md └── 12.05_-_Shallow_vs_Deep_Copy │ └── Shallow_vs_Deep.md ├── ch13 ├── 13.01_-_Private_Constructor │ └── PrivateConstructor.md ├── 13.02_-_Return_From_Finally │ └── ReturnFromFinally.md ├── 13.03_-_Final,_etc │ └── Final,etc.md ├── 13.04_-_Generics_vs_Templates │ └── GenericsVsTemplates.md ├── 13.05_-_TreeMap,HashMap,LinkedHashMap │ └── Maps.txt ├── 13.06_-_Object_Reflection │ └── ObjectReflection.md ├── 13.07_-_Lambda_Expressions │ └── LambdaExpressions.java └── 13.08_-_Lambda_Random │ └── LambdaRandom.java ├── ch14 ├── 14.01_-_Multiple_Apartments │ └── multiple_apartments.sql └── 14.05_-_Denormalization │ └── Denormalization.md ├── ch15 ├── 15.01_-_Threads_vs._Processes │ └── ThreadsVsProcesses.md └── 15.02_-_Context_Switch │ └── ContextSwitch.md ├── ch16 ├── 16.01_-_NumberSwapper │ └── NumberSwapper.java ├── 16.02_-_Word_Frequencies │ └── WordFrequencies.java ├── 16.04_-_Tic_Tac_Win │ └── TicTacWin.java ├── 16.05_-_LRU_Cache │ └── LRUCache.java ├── 16.07_-_Number_Max │ └── NumberMax.java └── 16.24_-_Pairs_with_Sum │ └── PairsWithSum.java ├── ch17 ├── 17.01_-_Add_Without_Plus │ └── AddWithoutPlus.java └── 17.10_-_Majority_Element │ └── MajorityElement.java └── count.sh /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Mobile Tools for Java (J2ME) 4 | .mtj.tmp/ 5 | 6 | # Package Files # 7 | *.jar 8 | *.war 9 | *.ear 10 | 11 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 12 | hs_err_pid* 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Austin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | Cracking the Coding Interview problems 2 | 3 | ch01 - 9 / 9 4 | ch02 - 8 / 8 5 | ch03 - 6 / 6 6 | ch04 - 12 / 12 7 | ch05 - 6 / 8 8 | ch06 - 1 / 10 9 | ch07 - 2 / 9 10 | ch08 - 10 / 14 11 | ch09 - 0 / 8 12 | ch10 - 7 / 11 13 | ch11 - 2 / 6 14 | ch12 - 5 / 11 15 | ch13 - 8 / 8 16 | ch14 - 2 / 7 17 | ch15 - 2 / 7 18 | ch16 - 6 / 26 19 | ch17 - 2 / 26 20 | 21 | Total 22 | 88 / 186 problems 23 | 24 | Feel free to submit your own solutions! All pull requests welcome! 25 | -------------------------------------------------------------------------------- /ch01/1.01_-_Is_Unique/IsUnique.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | 4 | public class IsUnique { 5 | public static boolean isUniqueUsingHash(String word) { 6 | char[] chars = word.toCharArray(); 7 | Set set = new HashSet(); 8 | for (char c : chars) 9 | if (set.contains(c)) 10 | return false; 11 | else 12 | set.add(c); 13 | return true; 14 | } 15 | 16 | public static boolean isUniqueUsingSort(String word) { 17 | char[] chars = word.toCharArray(); 18 | if (chars.length <= 1) return true; 19 | Arrays.sort(chars); 20 | char temp = chars[0]; 21 | for (int i = 1; i < chars.length; i++) { 22 | if (chars[i] == temp) return false; 23 | temp = chars[i]; 24 | } 25 | return true; 26 | } 27 | 28 | public static void main(String[] args) throws IOException { 29 | System.out.println(isUniqueUsingHash("Word") ? "Unique" : "Not Unique"); 30 | System.out.println(isUniqueUsingSort("Nootunique") ? "Unique" : "Not Unique"); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ch01/1.02_-_Check_Permutations/CheckPermutations.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | 4 | public class CheckPermutations { 5 | public static boolean isPermutation(String s1, String s2) { 6 | char[] a = s1.toCharArray(); 7 | char[] b = s2.toCharArray(); 8 | Arrays.sort(a); 9 | Arrays.sort(b); 10 | if (a.length != b.length) return false; 11 | for (int i = 0; i < a.length; i++) { 12 | if (a[i] != b[i]) return false; 13 | } 14 | return true; 15 | } 16 | public static void main(String[] args) { 17 | System.out.println(isPermutation("abc", "cba") ? "It is a permutation" : "It is not a permutation"); 18 | System.out.println(isPermutation("test", "estt") ? "It is a permutation" : "It is not a permutation"); 19 | System.out.println(isPermutation("testt", "estt") ? "It is a permutation" : "It is not a permutation"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ch01/1.03_-_URLify/URLify.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | 4 | public class URLify { 5 | public static char[] URLify(char[] chars, int len) { 6 | int spaces = countSpaces(chars, len); 7 | int end = len - 1 + spaces * 2; 8 | for (int i = len - 1; i >= 0; i--) { 9 | if (chars[i] == ' ') { 10 | chars[end - 2] = '%'; 11 | chars[end - 1] = '2'; 12 | chars[end] = '0'; 13 | end -= 3; 14 | } else { 15 | chars[end] = chars[i]; 16 | end--; 17 | } 18 | } 19 | return chars; 20 | } 21 | 22 | static int countSpaces(char[] chars, int len) { 23 | int count = 0; 24 | for (int i = 0; i < len; i++) 25 | if (chars[i] == ' ') 26 | count++; 27 | return count; 28 | } 29 | 30 | public static void main(String[] args) throws IOException { 31 | char[] chars = "Mr John Smith ".toCharArray(); 32 | System.out.println(URLify(chars, 13)); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ch01/1.04_-_Palindrome_Permutation/PalindromePermutation.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class PalindromePermutation { 4 | public static boolean permuteHash(String str) { 5 | Map map = new HashMap(); 6 | for (int i = 0; i < str.length(); i++) { 7 | Character c = Character.toLowerCase(str.charAt(i)); 8 | if (!Character.isLetter(c)) 9 | continue; 10 | if (map.containsKey(c)) 11 | map.put(c, map.get(c) + 1); 12 | else 13 | map.put(c, 1); 14 | } 15 | 16 | int odd = 0; 17 | for (Character key : map.keySet()) 18 | if (map.get(key) % 2 != 0) 19 | odd++; 20 | 21 | if (odd > 1) 22 | return false; 23 | else 24 | return true; 25 | } 26 | public static void main(String[] args) { 27 | System.out.println(permuteHash("Tact Coa") ? "True" : "False"); 28 | System.out.println(permuteHash("test") ? "True" : "False"); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /ch01/1.05_-_One_Away/OneAway.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class OneAway { 4 | public static boolean oneReplace(String a, String b) { 5 | int differences = 0; 6 | for (int i = 0; i < a.length(); i++) { 7 | if (a.charAt(i) != b.charAt(i)) 8 | differences++; 9 | if (differences > 1) 10 | return false; 11 | } 12 | return true; 13 | } 14 | 15 | public static boolean oneInsert(String a, String b) { 16 | // a.length() < b.length() 17 | int i, j = 0; 18 | int differences = 0; 19 | for (i = 0; i < a.length(); i++) { 20 | if (a.charAt(i) != b.charAt(j)) { 21 | j++; 22 | differences++; 23 | } 24 | if (differences > 1) 25 | return false; 26 | j++; 27 | } 28 | return true; 29 | } 30 | 31 | public static boolean oneAway(String a, String b) { 32 | if (a.length() < b.length()) 33 | return oneInsert(a, b); 34 | else if (a.length() > b.length()) 35 | return oneInsert(b, a); 36 | else 37 | return oneReplace(a, b); 38 | } 39 | 40 | public static void main(String[] args) { 41 | System.out.println(oneAway("pale", "ple") ? "true" : "false"); 42 | System.out.println(oneAway("pales", "pale") ? "true" : "false"); 43 | System.out.println(oneAway("pale", "bale") ? "true" : "false"); 44 | System.out.println(oneAway("ale", "bale") ? "true" : "false"); 45 | System.out.println(oneAway("xale", "xal") ? "true" : "false"); 46 | System.out.println(oneAway("pale", "bake") ? "true" : "false"); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /ch01/1.06_-_String_Compression/StringCompression.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class StringCompression { 4 | public static String compress(String str) { 5 | StringBuilder sb = new StringBuilder(); 6 | int count = 1; 7 | for (int i = 0; i < str.length() - 1; i++) { 8 | if (str.charAt(i) != str.charAt(i + 1)) { 9 | sb.append(str.charAt(i)); 10 | sb.append(count); 11 | // reset count to 1 12 | count = 1; 13 | } else 14 | count++; 15 | } 16 | // add last set of characters 17 | sb.append(str.charAt(i)); 18 | sb.append(count); 19 | 20 | String x = sb.toString(); 21 | if (x.length() > str.length()) 22 | return str; 23 | else 24 | return x; 25 | } 26 | 27 | public static void main(String[] args) { 28 | System.out.println(compress("aabccccaaa")); 29 | System.out.println(compress("abcdef")); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ch01/1.07_-_Rotate_Matrix/RotateMatrix.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | public class RotateMatrix { 3 | public static void rotate(int[][] matrix) { 4 | int n = matrix.length; 5 | for (int layer = 0; layer < n / 2; layer++) { 6 | int first = layer; 7 | int last = n - 1 - layer; 8 | for (int i = first; i < last; i++) { 9 | int offset = i - first; 10 | int top = matrix[first][i]; 11 | 12 | // left -> top 13 | matrix[first][i] = matrix[last-offset][first]; 14 | 15 | // bottom -> left 16 | matrix[last-offset][first] = matrix[last][last-offset]; 17 | 18 | // right -> bottom 19 | matrix[last][last-offset] = matrix[i][last]; 20 | 21 | // top -> right 22 | matrix[i][last] = top; 23 | } 24 | } 25 | } 26 | public static void main(String[] args) { 27 | int[][] arr = new int[][]{ 28 | {1, 2, 3, 4, 5}, 29 | {6, 7, 8, 9, 10}, 30 | {11, 12, 13, 14, 15}, 31 | {16, 17, 18, 19, 20}, 32 | {21, 22, 23, 24, 25} 33 | }; 34 | rotate(arr); 35 | for (int[] a : arr) 36 | System.out.println(Arrays.toString(a)); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ch01/1.08_-_Zero_Matrix/ZeroMatrix.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class ZeroMatrix { 4 | public static void zero(int[][] matrix) { 5 | int m = matrix.length; 6 | int n = matrix[0].length; 7 | boolean[] row = new boolean[m]; 8 | boolean[] col = new boolean[n]; 9 | for (int i = 0; i < m; i++) { 10 | for (int j = 0; j < n; j++) { 11 | if (matrix[i][j] == 0) { 12 | row[i] = true; 13 | col[j] = true; 14 | } 15 | } 16 | } 17 | 18 | for (int i = 0; i < m; i++) { 19 | for (int j = 0; j < n; j++) { 20 | if (row[i] == true || col[j] == true) 21 | matrix[i][j] = 0; 22 | } 23 | } 24 | 25 | return; 26 | } 27 | public static void main(String[] args) { 28 | int[][] matrix = new int[][]{ 29 | {0, 1, 1, 1, 0}, 30 | {1, 0, 1, 0, 1}, 31 | {1, 1, 1, 1, 1}, 32 | {1, 0, 1, 1, 1}, 33 | {1, 1, 1, 1, 1} 34 | }; 35 | for (int i = 0; i < matrix.length; i++) 36 | System.out.println(Arrays.toString(matrix[i])); 37 | zero(matrix); 38 | System.out.println(); 39 | for (int i = 0; i < matrix.length; i++) 40 | System.out.println(Arrays.toString(matrix[i])); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /ch01/1.09_-_String_Rotation/StringRotation.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class StringRotation { 4 | public static boolean isRotation(String s1, String s2) { 5 | if (s1.length() != s2.length()) 6 | return false; 7 | 8 | String s3 = s1 + s1; 9 | return s3.contains(s2); 10 | } 11 | public static void main(String[] args) { 12 | System.out.println(isRotation("waterbottle", "erbottlewat") ? "True" : "False"); 13 | System.out.println(isRotation("waterbottl", "erbottlewat") ? "True" : "False"); 14 | System.out.println(isRotation("pandeesh", "deeshpand") ? "True" : "False"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ch02/2.01_-_RemoveDups/RemoveDups.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class RemoveDups { 4 | public static class Node { 5 | Node next; 6 | char val; 7 | public Node(char val) { 8 | this.val = val; 9 | } 10 | public String toString() { 11 | StringBuilder sb = new StringBuilder(); 12 | Node temp = this; 13 | while (temp != null) { 14 | sb.append(temp.val); 15 | temp = temp.next; 16 | } 17 | return sb.toString(); 18 | } 19 | } 20 | public static void removeDupes(Node node) { 21 | Set set = new HashSet(); 22 | set.add(node.val); 23 | Node prev = node; 24 | Node temp = node.next; 25 | while (temp != null) { 26 | if (set.contains(temp.val)) { 27 | prev.next = temp.next; 28 | } 29 | else { 30 | set.add(temp.val); 31 | prev = temp; 32 | } 33 | temp = temp.next; 34 | } 35 | } 36 | public static void main(String[] args) { 37 | Node a = new Node('F'); 38 | Node b = new Node('O'); 39 | Node c = new Node('L'); 40 | Node d = new Node('L'); 41 | Node e = new Node('O'); 42 | Node f = new Node('W'); 43 | Node g = new Node(' '); 44 | Node h = new Node('U'); 45 | Node i = new Node('P'); 46 | a.next = b; 47 | b.next = c; 48 | c.next = d; 49 | d.next = e; 50 | e.next = f; 51 | f.next = g; 52 | g.next = h; 53 | h.next = i; 54 | System.out.println(a); 55 | removeDupes(a); 56 | System.out.println(a); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /ch02/2.02_-_ReturnKth/ReturnKth.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class ReturnKth { 4 | public static class Node { 5 | Node next; 6 | char val; 7 | public Node(char val) { 8 | this.val = val; 9 | } 10 | public String toString() { 11 | StringBuilder sb = new StringBuilder(); 12 | Node temp = this; 13 | while (temp != null) { 14 | sb.append(temp.val); 15 | temp = temp.next; 16 | } 17 | return sb.toString(); 18 | } 19 | } 20 | public static Node returnKth(Node node, int k) { 21 | k--; 22 | Node first = node; 23 | Node last = node; 24 | for (int i = 0; i < k; i++) 25 | last = last.next; 26 | while (last.next != null) { 27 | last = last.next; 28 | first = first.next; 29 | } 30 | return first; 31 | } 32 | public static void main(String[] args) { 33 | Node a = new Node('a'); 34 | Node b = new Node('b'); 35 | Node c = new Node('c'); 36 | Node d = new Node('d'); 37 | Node e = new Node('e'); 38 | a.next = b; 39 | b.next = c; 40 | c.next = d; 41 | d.next = e; 42 | System.out.println(a); 43 | System.out.println(returnKth(a, 2).val); // should be d 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ch02/2.03_-_DeleteMiddle/DeleteMiddle.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class DeleteMiddle { 4 | public static class Node { 5 | Node next; 6 | char val; 7 | public Node(char val) { 8 | this.val = val; 9 | } 10 | public String toString() { 11 | StringBuilder sb = new StringBuilder(); 12 | Node temp = this; 13 | while (temp != null) { 14 | sb.append(temp.val); 15 | temp = temp.next; 16 | } 17 | return sb.toString(); 18 | } 19 | } 20 | 21 | public static boolean deleteMiddle(Node node) { 22 | if (node == null || node.next == null) { 23 | return false; 24 | } else { 25 | node.val = node.next.val; 26 | node.next = node.next.next; 27 | return true; 28 | } 29 | } 30 | 31 | public static void main(String[] args) { 32 | Node a = new Node('a'); 33 | Node b = new Node('b'); 34 | Node c = new Node('c'); 35 | Node d = new Node('d'); 36 | Node e = new Node('e'); 37 | a.next = b; 38 | b.next = c; 39 | c.next = d; 40 | d.next = e; 41 | System.out.println(a); 42 | deleteMiddle(c); 43 | System.out.println(a); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ch02/2.04_-_Partition/Partition.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Partition { 4 | public static class Node { 5 | Node next; 6 | int val; 7 | public Node(int val) { 8 | this.val = val; 9 | } 10 | public String toString() { 11 | StringBuilder sb = new StringBuilder(); 12 | Node temp = this; 13 | while (temp != null) { 14 | sb.append(temp.val); 15 | sb.append(' '); 16 | temp = temp.next; 17 | } 18 | return sb.toString(); 19 | } 20 | } 21 | 22 | public static Node partition(Node node, int partition) { 23 | Node prev = null; 24 | Node temp = node; 25 | Node next = node.next; 26 | 27 | Node less = null; 28 | Node more = null; 29 | Node lessHead = null; 30 | Node moreHead = null; 31 | 32 | while (temp != null) { 33 | next = temp.next; 34 | temp.next = null; 35 | if (temp.val < partition) { 36 | if (less == null) { 37 | less = temp; 38 | lessHead = less; 39 | } else { 40 | less.next = temp; 41 | } 42 | if (less.next != null) 43 | less = less.next; 44 | } else { 45 | if (more == null) { 46 | more = temp; 47 | moreHead = more; 48 | } else { 49 | more.next = temp; 50 | } 51 | if (more.next != null) 52 | more = more.next; 53 | } 54 | prev = temp; 55 | temp = next; 56 | } 57 | 58 | less.next = moreHead; 59 | return lessHead; 60 | } 61 | 62 | public static void main(String[] args) { 63 | Node a = new Node(3); 64 | Node b = new Node(5); 65 | Node c = new Node(8); 66 | Node d = new Node(5); 67 | Node e = new Node(10); 68 | Node f = new Node(2); 69 | Node g = new Node(1); 70 | a.next = b; 71 | b.next = c; 72 | c.next = d; 73 | d.next = e; 74 | e.next = f; 75 | f.next = g; 76 | System.out.println(a); 77 | Node x = partition(a, 5); 78 | System.out.println(x); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /ch02/2.05_-_Sum_Lists/SumLists.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class SumLists { 4 | public static class Node { 5 | Node next; 6 | int val; 7 | public Node(int val) { 8 | this.val = val; 9 | } 10 | @Override 11 | public String toString() { 12 | StringBuilder sb = new StringBuilder(); 13 | Node temp = this; 14 | while (temp != null) { 15 | sb.append(temp.val); 16 | sb.append(' '); 17 | temp = temp.next; 18 | } 19 | return sb.toString(); 20 | } 21 | } 22 | 23 | public static Node nodeSum(Node a, Node b, int carry) { 24 | if (a == null && b == null && carry == 0) 25 | return null; 26 | 27 | int value = carry; 28 | if (a != null) 29 | value += a.val; 30 | if (b != null) 31 | value += b.val; 32 | Node result = new Node(value % 10); 33 | if (a != null || b != null) { 34 | Node next = nodeSum(a == null ? null : a.next, 35 | b == null ? null : b.next, 36 | value / 10); 37 | result.next = next; 38 | } 39 | return result; 40 | } 41 | 42 | public static void main(String[] args) { 43 | Node a = new Node(7); 44 | Node b = new Node(1); 45 | Node c = new Node(6); 46 | a.next = b; 47 | b.next = c; 48 | 49 | Node d = new Node(5); 50 | Node e = new Node(9); 51 | Node f = new Node(2); 52 | d.next = e; 53 | e.next = f; 54 | 55 | Node x = nodeSum(a, d, 0); 56 | System.out.println(x); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /ch02/2.06_-_Palindrome/Palindrome.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Palindrome { 4 | public static class Node { 5 | Node next; 6 | char val; 7 | public Node(char val) { 8 | this.val = val; 9 | } 10 | public String toString() { 11 | StringBuilder sb = new StringBuilder(); 12 | Node temp = this; 13 | while (temp != null) { 14 | sb.append(temp.val); 15 | temp = temp.next; 16 | } 17 | return sb.toString(); 18 | } 19 | } 20 | 21 | public static void reverse(Node node) { 22 | Node prev = null; 23 | Node current = node; 24 | Node next; 25 | while (current != null) { 26 | next = current.next; 27 | current.next = prev; 28 | prev = current; 29 | current = next; 30 | } 31 | node = prev; 32 | } 33 | 34 | public static boolean isPalindrome(Node node) { 35 | Deque stack = new ArrayDeque(); 36 | Node head = node; 37 | Node temp = head; 38 | while (temp != null) { 39 | stack.push(temp.val); 40 | temp = temp.next; 41 | } 42 | temp = head; 43 | while (temp != null) { 44 | char a = stack.pop(); 45 | if (temp.val != a) 46 | return false; 47 | temp = temp.next; 48 | } 49 | return true; 50 | } 51 | 52 | public static void main(String[] args) { 53 | Node a = new Node('r'); 54 | Node b = new Node('a'); 55 | Node c = new Node('r'); 56 | a.next = b; 57 | b.next = c; 58 | System.out.println(isPalindrome(a) ? "True" : "False"); 59 | System.out.println(isPalindrome(b) ? "True" : "False"); 60 | 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /ch02/2.07_-_Intersection/Intersection.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Intersection { 4 | public static class Node { 5 | Node next; 6 | int val; 7 | public Node(int val) { 8 | this.val = val; 9 | } 10 | public String toString() { 11 | StringBuilder sb = new StringBuilder(); 12 | Node temp = this; 13 | while (temp != null) { 14 | sb.append(temp.val); 15 | sb.append(" "); 16 | temp = temp.next; 17 | } 18 | return sb.toString(); 19 | } 20 | } 21 | 22 | public static Node intersection(Node a, Node b) { 23 | int alength = 0; 24 | int blength = 0; 25 | Node ahead = a; 26 | Node bhead = b; 27 | while (a != null) { 28 | alength++; 29 | a = a.next; 30 | } 31 | while (b != null) { 32 | blength++; 33 | b = b.next; 34 | } 35 | 36 | Node shorter; 37 | Node longer; 38 | int diff; 39 | if (alength > blength) { 40 | longer = ahead; 41 | shorter = bhead; 42 | diff = alength - blength; 43 | } else { 44 | longer = bhead; 45 | shorter = ahead; 46 | diff = blength - alength; 47 | } 48 | 49 | while (diff-- > 0) 50 | longer = longer.next; 51 | 52 | while (longer != shorter) { 53 | longer = longer.next; 54 | shorter = shorter.next; 55 | } 56 | 57 | return longer; 58 | } 59 | 60 | public static void main(String[] args) { 61 | Node a = new Node(3); 62 | Node b = new Node(1); 63 | Node c = new Node(5); 64 | Node d = new Node(9); 65 | Node e = new Node(7); 66 | Node f = new Node(2); 67 | Node g = new Node(1); 68 | a.next = b; 69 | b.next = c; 70 | c.next = d; 71 | d.next = e; 72 | e.next = f; 73 | f.next = g; 74 | Node h = new Node(4); 75 | Node i = new Node(6); 76 | h.next = i; 77 | i.next = e; 78 | 79 | Node x = intersection(a, h); 80 | System.out.println(x); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /ch02/2.08_-_LoopDetection/LoopDetection.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class LoopDetection { 4 | public static class Node { 5 | Node next; 6 | int val; 7 | public Node(int val) { 8 | this.val = val; 9 | } 10 | public String toString() { 11 | return this.val + ""; 12 | } 13 | } 14 | 15 | public static Node findBeginning(Node head) { 16 | Node slow = head; 17 | Node fast = head; 18 | while (fast != null && fast.next != null) { 19 | slow = slow.next; 20 | fast = fast.next.next; 21 | if (fast == slow) 22 | break; 23 | } 24 | 25 | if (fast == null || fast.next == null) 26 | return null; 27 | 28 | slow = head; 29 | while (slow != fast) { 30 | slow = slow.next; 31 | fast = fast.next; 32 | } 33 | return fast; 34 | } 35 | 36 | public static void main(String[] args) { 37 | Node a = new Node(1); 38 | Node b = new Node(2); 39 | Node c = new Node(3); 40 | Node d = new Node(4); 41 | Node e = new Node(5); 42 | Node f = new Node(6); 43 | Node g = new Node(7); 44 | Node h = new Node(8); 45 | Node i = new Node(9); 46 | Node j = new Node(10); 47 | Node k = new Node(11); 48 | a.next = b; 49 | b.next = c; 50 | c.next = d; 51 | d.next = e; 52 | e.next = f; 53 | f.next = g; 54 | g.next = h; 55 | h.next = i; 56 | i.next = j; 57 | j.next = k; 58 | k.next = c; 59 | 60 | System.out.println(a); 61 | System.out.println(findBeginning(a)); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /ch03/3.01_-_Three_in_One/FixedMultiStack.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class FixedMultiStack { 4 | private int numberOfStacks = 3; 5 | private int stackCapacity; 6 | private int[] values; 7 | private int[] sizes; 8 | 9 | public FixedMultiStack(int stackSize) { 10 | stackCapacity = stackSize; 11 | values = new int[stackSize * numberOfStacks]; 12 | sizes = new int[numberOfStacks]; 13 | } 14 | 15 | public void push(int stackNum, int value) throws FullStackException { 16 | if (isFull(stackNum)) 17 | throw new FullStackException(); 18 | sizes[stackNum]++; 19 | values[indexOfTop(stackNum)] = value; 20 | } 21 | 22 | public int pop(int stackNum) throws EmptyStackException { 23 | if (isEmpty(stackNum)) 24 | throw new EmptyStackException(); 25 | int val = values[indexOfTop(stackNum)]; 26 | sizes[stackNum]--; 27 | return val; 28 | } 29 | 30 | public int peek(int stackNum) throws EmptyStackException { 31 | if (isEmpty(stackNum)) 32 | throw new EmptyStackException(); 33 | return values[indexOfTop(stackNum)]; 34 | } 35 | 36 | public boolean isEmpty(int stackNum) { 37 | return sizes[stackNum] == 0; 38 | } 39 | 40 | public boolean isFull(int stackNum) { 41 | return sizes[stackNum] == stackCapacity; 42 | } 43 | 44 | private int indexOfTop(int stackNum) { 45 | int offset = stackNum * stackCapacity; 46 | int size = sizes[stackNum]; 47 | return offset + size; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /ch03/3.02_-_Stack_Min/StackMin.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class StackMin extends Stack { 4 | Stack s2; 5 | public StackMin() { 6 | s2 = new Stack(); 7 | } 8 | 9 | public void push(int value) { 10 | if (value <= min()) { 11 | s2.push(value); 12 | } 13 | super.push(value); 14 | } 15 | 16 | public Integer pop() { 17 | int value = super.pop(); 18 | if (value == min()) { 19 | s2.pop(); 20 | } 21 | return value; 22 | } 23 | 24 | public int min() { 25 | if (s2.isEmpty()) { 26 | return Integer.MAX_VALUE; 27 | } else { 28 | return s2.peek(); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ch03/3.03_-_Stack_of_Plates/SetOfStacks.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class SetOfStacks { 4 | List> stacks = new ArrayList>(); 5 | 6 | public void push(int v) { 7 | Stack last = getLastStack(); 8 | if (last != null) { 9 | last.push(v); 10 | } else { 11 | Stack stack = new Stack(); 12 | stack.push(v); 13 | stacks.add(stack); 14 | } 15 | } 16 | 17 | public int pop() throws EmptyStackException { 18 | Stack last = getLastStack(); 19 | if (last == null) 20 | throw EmptyStackException(); 21 | int v = last.pop(); 22 | if (last.size() == 0) 23 | stacks.remove(stacks.size() - 1); 24 | return v; 25 | } 26 | 27 | public Stack getLastStack() { 28 | int size = stacks.size(); 29 | if (size == 0) return null; 30 | return stacks.get(size - 1); 31 | } 32 | 33 | public boolean isEmpty() { 34 | Stack last = getLastStack(); 35 | return last == null || last.isEmpty(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ch03/3.04_-_Queue_via_Stacks/MyQueue.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class MyQueue { 4 | Stack stackNew, stackOld; 5 | 6 | public MyQueue() { 7 | stackNew = new Stack(); 8 | stackOld = new Stack(); 9 | } 10 | 11 | public int size() { 12 | return stackNew.size() + stackOld.size(); 13 | } 14 | 15 | public void add (T value) { 16 | stackNew.push(value); 17 | } 18 | 19 | public void shiftStacks() { 20 | if (stackOld.isEmpty()) 21 | while (!stackNew.isEmpty()) { 22 | stackOld.push(stackNew.pop()); 23 | } 24 | } 25 | } 26 | 27 | public T peek() { 28 | shiftStacks(); 29 | return stackOld.peek(); 30 | } 31 | 32 | public T remove() { 33 | shiftStacks(); 34 | return stackOld.pop(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ch03/3.05_-_Sort_Stack/SortStack.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class SortStack { 4 | public Stack sort(Stack s) { 5 | Stack r = new Stack(); 6 | while (!s.isEmpty()) { 7 | int tmp = s.pop(); 8 | while (!r.isEmpty() && r.peek() > tmp) { 9 | s.push(r.pop()); 10 | } 11 | r.push(tmp); 12 | } 13 | return r; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ch03/3.06_-_Animal_Shelter/AnimalQueue.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | abstract class Animal { 4 | private int order; 5 | protected String name; 6 | public Animal(String n) { name = n; } 7 | public void setOrder(int order) { order = order; } 8 | public int getOrder() { return order; } 9 | 10 | public boolean isOlderThan(Animal a) { 11 | return this.order < a.getOrder(); 12 | } 13 | } 14 | 15 | public class AnimalQueue { 16 | LinkedList dogs = new LinkedList(); 17 | LinkedList cats = new LinkedList(); 18 | private int order = 0; 19 | 20 | public void enqueue(Animal a) { 21 | a.setOrder(order); 22 | order++; 23 | 24 | if (a instanceof Dog) 25 | dogs.addLast((Dog)a); 26 | else 27 | cats.addLast((Cat)a); 28 | } 29 | 30 | public Animal dequeueAny() throws EmptyQueueException { 31 | if (dogs.size() == 0 && cats.size() == 0) 32 | throw new EmptyQueueException(); 33 | if (dogs.size() == 0) 34 | return dequeueCat(); 35 | if (cats.size() == 0) 36 | return dequeueDog(); 37 | 38 | Cat oldestCat = cats.peek(); 39 | Dog oldestDog = dogs.peek(); 40 | if (oldestCat.isOlderThan(oldestDog)) 41 | return dequeueCat(); 42 | else 43 | return dequeueDog(); 44 | } 45 | 46 | public Animal peek() throws EmptyQueueException { 47 | if (dogs.size() == 0 && cats.size() == 0) 48 | throw new EmptyQueueException(); 49 | if (dogs.size() == 0) 50 | return cats.peek(); 51 | if (cats.size() == 0) 52 | return dogs.peek(); 53 | 54 | Cat oldestCat = cats.peek(); 55 | Dog oldestDog = dogs.peek(); 56 | if (oldestCat.isOlderThan(oldestDog)) 57 | return oldestCat; 58 | else 59 | return oldestDog; 60 | } 61 | 62 | public Dog dequeueDog() { 63 | dogs.poll(); 64 | } 65 | 66 | public Cat dequeueCat() { 67 | cats.poll(); 68 | } 69 | } 70 | 71 | public class Dog extends Animal { 72 | public Dog(String n) { super(n); } 73 | } 74 | 75 | public class Cat extends Animal { 76 | public Cat(String n) { super(n); } 77 | } 78 | -------------------------------------------------------------------------------- /ch04/4.01_-_Route_Between_Nodes/Graph.java: -------------------------------------------------------------------------------- 1 | public class Graph { 2 | public Node vertices[]; 3 | public int count; 4 | 5 | public Graph() { 6 | count = 0; 7 | } 8 | 9 | public void add(Node x) { 10 | vertices[count] = x; 11 | count++; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ch04/4.01_-_Route_Between_Nodes/Node.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Node { 4 | public List adjacent; 5 | private String vertex; 6 | public enum State { Unvisited, Visited, Visiting } 7 | public State state; 8 | 9 | public Node(String vertex) { 10 | this.vertex = vertex; 11 | adjacent = new ArrayList(); 12 | } 13 | public void addAdjacent(Node x) { 14 | adjacent.add(x); 15 | } 16 | public int adjacentCount() { 17 | return adjacent.size(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /ch04/4.01_-_Route_Between_Nodes/RouteBetweenNodes.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class RouteBetweenNodes { 4 | public static boolean search(Graph g, Node start, Node end) { 5 | if (start == end) return true; 6 | 7 | Queue queue = new ArrayDeque(); 8 | 9 | for (Node node : g.vertices) { 10 | node.state = Node.State.Unvisited; 11 | } 12 | 13 | start.state = Node.State.Visiting; 14 | queue.add(start); 15 | Node temp; 16 | while (!queue.isEmpty()) { 17 | temp = queue.remove(); 18 | if (temp != null) { 19 | for (Node adjacent : temp.adjacent) { 20 | if (adjacent.state == Node.State.Unvisited) { 21 | if (adjacent == end) { 22 | return true; 23 | } else { 24 | adjacent.state = Node.State.Visiting; 25 | queue.add(adjacent); 26 | } 27 | } 28 | } 29 | } 30 | temp.state = Node.State.Visited; 31 | } 32 | 33 | return false; 34 | } 35 | 36 | public static void main(String[] args) { 37 | Graph g = new Graph(); 38 | Node[] nodes = new Node[6]; 39 | 40 | // This graph is taken from page 107 41 | nodes[0] = new Node("0"); 42 | nodes[1] = new Node("1"); 43 | nodes[2] = new Node("2"); 44 | nodes[3] = new Node("3"); 45 | nodes[4] = new Node("4"); 46 | nodes[5] = new Node("5"); 47 | 48 | nodes[0].addAdjacent(nodes[1]); 49 | nodes[0].addAdjacent(nodes[4]); 50 | nodes[0].addAdjacent(nodes[5]); 51 | nodes[1].addAdjacent(nodes[4]); 52 | nodes[1].addAdjacent(nodes[3]); 53 | nodes[2].addAdjacent(nodes[1]); 54 | nodes[3].addAdjacent(nodes[2]); 55 | nodes[3].addAdjacent(nodes[4]); 56 | 57 | g.vertices = nodes; 58 | g.count = 6; 59 | 60 | System.out.println(search(g, nodes[0], nodes[3])); 61 | System.out.println(search(g, nodes[3], nodes[5])); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /ch04/4.02_-_Minimal_Tree/MinimalTree.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class MinimalTree { 4 | public class Node { 5 | public int key; 6 | public Node left; 7 | public Node right; 8 | public Node(int a) { 9 | this.key = a; 10 | } 11 | } 12 | public Node createBST(int[] array) { 13 | return createBST(array, 0, array.length - 1); 14 | } 15 | public Node createBST(int[] array, int start, int end) { 16 | if (end < start) return null; 17 | 18 | //int mid = (start + end) / 2; // don't do this 19 | int mid = start + ((end - start) / 2); 20 | 21 | Node node = new Node(array[mid]); 22 | node.left = createBST(array, start, mid - 1); 23 | node.right = createBST(array, mid + 1, end); 24 | return node; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ch04/4.03_-_List_of_Depths/ListOfDepths.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class ListOfDepths { 4 | public static class TreeNode { 5 | public TreeNode left; 6 | public TreeNode right; 7 | public int val; 8 | public TreeNode(int val) { 9 | this.val = val; 10 | } 11 | } 12 | 13 | public static ArrayList> createList(TreeNode root) { 14 | ArrayList> res = new ArrayList>(); 15 | 16 | LinkedList current = new LinkedList(); 17 | if (root != null) 18 | current.add(root); 19 | 20 | while (current.size() > 0) { 21 | res.add(current); 22 | LinkedList parents = current; 23 | 24 | current = new LinkedList(); 25 | for (TreeNode parent : parents) { 26 | if (parent.left != null) 27 | current.add(parent.left); 28 | if (parent.right != null) 29 | current.add(parent.right); 30 | } 31 | } 32 | return res; 33 | } 34 | 35 | public static void main(String[] args) { 36 | TreeNode a = new TreeNode(1); 37 | TreeNode b = new TreeNode(2); 38 | TreeNode c = new TreeNode(3); 39 | TreeNode d = new TreeNode(4); 40 | TreeNode e = new TreeNode(5); 41 | TreeNode f = new TreeNode(5); 42 | a.left = b; 43 | a.right = c; 44 | c.left = d; 45 | c.right = e; 46 | e.right = f; 47 | ArrayList> list = createList(a); 48 | for (LinkedList ll : list) { 49 | for (TreeNode node : ll) 50 | System.out.print(node.val + " "); 51 | System.out.println(); 52 | } 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /ch04/4.04_-_Check_Balanced/CheckBalanced.java: -------------------------------------------------------------------------------- 1 | public class CheckBalanced { 2 | public class TreeNode { 3 | public TreeNode left; 4 | public TreeNode right; 5 | public int val; 6 | public TreeNode(int val) { 7 | this.val = val; 8 | } 9 | } 10 | public int checkHeight(TreeNode root) { 11 | if (root == null) return 0; 12 | 13 | int left = checkHeight(root.left); 14 | if (left == -1) return -1; 15 | 16 | int right = checkHeight(root.left); 17 | if (right == -1) return -1; 18 | 19 | int diff = Math.abs(left - right); 20 | if (diff > 1) 21 | return -1; 22 | else 23 | return Math.max(left, right) + 1; 24 | } 25 | 26 | public boolean isBalanced(TreeNode root) { 27 | return (checkHeight(root) == -1); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ch04/4.05_-_Validate_BST/ValidateBST.java: -------------------------------------------------------------------------------- 1 | public class ValidateBST { 2 | public boolean validateBST(TreeNode root) { 3 | return validateBST(root, Integer.MIN_VALUE, Integer.MAX_VALUE); 4 | } 5 | 6 | public boolean validateBST(TreeNode root, int min, int max) { 7 | if (root == null) 8 | return true; 9 | 10 | if (root.val < min || root.val >= max) 11 | return false; 12 | 13 | return validateBST(root.left, min, root.val) && 14 | validateBST(root.right, root.val, max); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ch04/4.06_-_Successor/Successor.java: -------------------------------------------------------------------------------- 1 | public class Successor { 2 | public static class TreeNode { 3 | public int val; 4 | public TreeNode right; 5 | public TreeNode left; 6 | public TreeNode parent; 7 | public TreeNode(int val) { 8 | this.val = val; 9 | } 10 | } 11 | public static TreeNode successor(TreeNode n) { 12 | if (n == null) return null; 13 | 14 | if (n.right != null) { 15 | return leftMostChild(n.right); 16 | } else { 17 | TreeNode temp = n; 18 | TreeNode parent = n.parent; 19 | while (parent.right == temp) { 20 | temp = parent; 21 | parent = parent.parent; 22 | } 23 | return temp; 24 | } 25 | } 26 | 27 | public static TreeNode leftMostChild(TreeNode n) { 28 | if (n == null) return null; 29 | while (n.left != null) { 30 | n = n.left; 31 | } 32 | return n; 33 | } 34 | 35 | public static void main(String[] args) { 36 | /* 20 37 | * / \ 38 | * 10 30 39 | * / \ 40 | * 5 15 41 | * / \ \ 42 | * 3 7 17 43 | */ 44 | TreeNode a = new TreeNode(20); 45 | TreeNode b = new TreeNode(10); 46 | TreeNode c = new TreeNode(30); 47 | TreeNode d = new TreeNode(5); 48 | TreeNode e = new TreeNode(15); 49 | TreeNode f = new TreeNode(3); 50 | TreeNode g = new TreeNode(7); 51 | TreeNode h = new TreeNode(17); 52 | a.left = b; 53 | a.right = c; 54 | b.left = d; 55 | b.right = e; 56 | d.left = f; 57 | d.right = g; 58 | e.right = h; 59 | h.parent = e; 60 | g.parent = d; 61 | f.parent = d; 62 | e.parent = b; 63 | d.parent = b; 64 | b.parent = a; 65 | c.parent = a; 66 | System.out.println(successor(b).val); 67 | System.out.println(successor(d).val); 68 | System.out.println(successor(a).val); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /ch04/4.07_-_Build_Order/BuildOrder.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.io.*; 3 | 4 | public class BuildOrder { 5 | public static int[] visited; 6 | public static int[][] matrix; 7 | public static LinkedList out; 8 | 9 | public static void dfs(int u, int V) { 10 | if (visited[u] == 0) { 11 | visited[u] = 1; 12 | for (int i = 0; i < V; i++) { 13 | if (matrix[u][i] == 1 && visited[i] == 0) 14 | dfs(i, V); 15 | } 16 | out.addFirst(u); 17 | } 18 | } 19 | 20 | public static List build(int[] projects, int[][] dependencies, int V, int E) { 21 | out = new LinkedList(); 22 | visited = new int[V]; 23 | Arrays.fill(visited, 0); 24 | matrix = new int[V][V]; 25 | for (int i = 0; i < V; i++) 26 | Arrays.fill(matrix[i], 0); 27 | for (int i = 0; i < E; i++) { 28 | int edge1 = dependencies[i][0]; 29 | int edge2 = dependencies[i][1]; 30 | matrix[edge2][edge1] = 1; 31 | } 32 | for (int i = 0; i < V; i++) { 33 | if (visited[i] == 0) 34 | dfs(i, V); 35 | } 36 | return out; 37 | } 38 | public static void main(String[] args) { 39 | int[] projects1 = new int[]{1, 2, 3, 4, 5, 6}; 40 | int[][] dependencies1 = new int[][]{{3, 0}, {1, 5}, {3, 1}, {0, 5}, {2, 3}}; 41 | int V = 6; 42 | int E = 5; 43 | List list = build(projects1, dependencies1, V, E); 44 | for (int i = 0; i < V; i++) { 45 | System.out.print(projects1[list.get(i)]); 46 | if (i < V - 1) 47 | System.out.print(" "); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ch04/4.08_-_First_Common_Ancestor/FirstCommonAncestor.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | class TreeNode { 4 | int val; 5 | TreeNode left, right; 6 | TreeNode(int val) { 7 | this.val = val; 8 | } 9 | } 10 | public class FirstCommonAncestor { 11 | public static TreeNode commonAncestor(TreeNode root, TreeNode p, TreeNode q) { 12 | if (root == null || p == null || q == null) return null; 13 | if (p == q) return null; 14 | 15 | if (root == q && root == p) 16 | return root; 17 | 18 | TreeNode left = commonAncestor(root.left, p, q); 19 | if (left != null && left != p && left != q) { 20 | return left; 21 | } 22 | 23 | TreeNode right = commonAncestor(root.right, p, q); 24 | if (right != null && right != p && right != q) { 25 | return right; 26 | } 27 | 28 | if (left != null && right != null) 29 | return root; 30 | else if (root == p || root == q) 31 | return root; 32 | else 33 | return left == null ? right : left; 34 | } 35 | public static void main(String[] args) { 36 | TreeNode a = new TreeNode(20); 37 | TreeNode b = new TreeNode(10); 38 | TreeNode c = new TreeNode(30); 39 | TreeNode d = new TreeNode(5); 40 | TreeNode e = new TreeNode(15); 41 | TreeNode f = new TreeNode(3); 42 | TreeNode g = new TreeNode(7); 43 | TreeNode h = new TreeNode(17); 44 | a.left = b; 45 | a.right = c; 46 | b.left = d; 47 | b.right = e; 48 | e.right = h; 49 | d.left = f; 50 | d.right = g; 51 | TreeNode ancestor = commonAncestor(a, g, h); 52 | System.out.println(ancestor.val); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /ch04/4.09_-_BST_Sequences/BSTSequences.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Solution is mostly line for line from the book 3 | */ 4 | 5 | import java.util.*; 6 | 7 | class Node { 8 | public Node left; 9 | public Node right; 10 | public int val; 11 | public Node(int val) { 12 | this.val = val; 13 | } 14 | } 15 | 16 | public class BSTSequences { 17 | public static void weaveLists(LinkedList first, LinkedList second, 18 | ArrayList> results, LinkedList prefix) { 19 | /* One list is empty. Add resmainer to [a cloned] prefix and store result. */ 20 | if (first.size() == 0 || second.size() == 0) { 21 | LinkedList result = (LinkedList)prefix.clone(); 22 | result.addAll(first); 23 | result.addAll(second); 24 | results.add(result); 25 | return; 26 | } 27 | 28 | /* Recurse with head of first added to the prefix. Removing the head will damage first, 29 | * so we'll need to put it back where we found it after. */ 30 | int headFirst = first.removeFirst(); 31 | prefix.addLast(headFirst); 32 | weaveLists(first, second, results, prefix); 33 | prefix.removeLast(); 34 | first.addFirst(headFirst); 35 | 36 | /* Do the same thing with second, damaging and then restoring the list. */ 37 | int headSecond = second.removeFirst(); 38 | prefix.addLast(headSecond); 39 | weaveLists(first, second, results, prefix); 40 | prefix.removeLast(); 41 | second.addFirst(headSecond); 42 | 43 | return; 44 | } 45 | 46 | public static ArrayList> bstSequences(Node root) { 47 | ArrayList> list = new ArrayList>(); 48 | if (root == null) { 49 | list.add(new LinkedList()); 50 | return list; 51 | } 52 | 53 | LinkedList prefix = new LinkedList(); 54 | prefix.add(root.val); 55 | 56 | ArrayList> leftList = bstSequences(root.left); 57 | ArrayList> rightList = bstSequences(root.right); 58 | 59 | /* Weave together each list from the left and right sides */ 60 | for (LinkedList left : leftList) { 61 | for (LinkedList right : rightList) { 62 | ArrayList> weaved = new ArrayList>(); 63 | weaveLists(left, right, weaved, prefix); 64 | list.addAll(weaved); 65 | } 66 | } 67 | return list; 68 | } 69 | 70 | public static void main(String[] args) { 71 | /* 50 72 | * / \ 73 | * 20 60 74 | * / \ \ 75 | * 10 25 70 76 | * / \ / \ 77 | * 5 15 65 80 78 | */ 79 | Node a = new Node(50); 80 | Node b = new Node(20); 81 | Node c = new Node(60); 82 | Node d = new Node(10); 83 | Node e = new Node(25); 84 | Node f = new Node(70); 85 | Node g = new Node(5); 86 | Node h = new Node(15); 87 | Node i = new Node(65); 88 | Node j = new Node(80); 89 | a.left = b; 90 | a.right = c; 91 | b.left = d; 92 | b.right = e; 93 | c.right = f; 94 | d.left = g; 95 | d.right = h; 96 | f.left = i; 97 | f.right = j; 98 | ArrayList> lists = bstSequences(a); 99 | for (LinkedList sequence : lists) 100 | System.out.println(sequence); 101 | 102 | /* 2 103 | * / \ 104 | * 1 3 105 | */ 106 | a = new Node(2); 107 | b = new Node(1); 108 | c = new Node(3); 109 | a.left = b; 110 | a.right = c; 111 | lists = bstSequences(a); 112 | for (LinkedList sequence : lists) 113 | System.out.println(sequence); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /ch04/4.10_-_Check_Subtree/CheckSubtree.java: -------------------------------------------------------------------------------- 1 | public class CheckSubtree { 2 | public class Node { 3 | public Node left; 4 | public Node right; 5 | public int val; 6 | public Node(int val) { 7 | this.val = val; 8 | } 9 | } 10 | 11 | // Larger tree = T1 12 | public boolean containsTree(Node T1, Node T2) { 13 | if (T2 == null) 14 | return true; 15 | return subTree(T1, T2); 16 | } 17 | 18 | // Larger tree = T1 19 | public boolean subTree(Node T1, Node T2) { 20 | if (T1 == null) 21 | return false; 22 | else if (T1.val == T2.val && matchTree(T1, T2)) 23 | return true; 24 | return subTree(T1.left, T2) || 25 | subTree(T1.right, T2); 26 | } 27 | 28 | public boolean matchTree(Node T1, Node T2) { 29 | if (T1 == null && T2 == null) 30 | return true; 31 | else if (T1 == null || T2 == null) 32 | return false; 33 | else if (T1.val != T2.val) 34 | return false; 35 | else 36 | return matchTree(T1.left, T2.left) && 37 | matchTree(T1.right, T2.right); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ch04/4.11_-_Random_Node/RandomNode.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | class TreeNode { 4 | int val; 5 | TreeNode left, right; 6 | int size = 0; 7 | public TreeNode(int val) { 8 | this.val = val; 9 | size = 1; 10 | } 11 | public TreeNode getRandomNode() { 12 | int leftSize = (left == null ? 0 : left.size); 13 | Random random = new Random(); 14 | int index = random.nextInt(size); 15 | if (index < leftSize) 16 | return left.getRandomNode(); 17 | else if (index == leftSize) 18 | return this; 19 | else 20 | return right.getRandomNode(); 21 | } 22 | } 23 | 24 | public class RandomNode { 25 | public static void main(String[] args) { 26 | TreeNode a = new TreeNode(8); 27 | TreeNode b = new TreeNode(4); 28 | TreeNode c = new TreeNode(13); 29 | TreeNode d = new TreeNode(2); 30 | TreeNode e = new TreeNode(6); 31 | a.left = b; 32 | a.right = c; 33 | b.left = d; 34 | b.right = e; 35 | a.size = 5; 36 | b.size = 3; 37 | System.out.println(a.getRandomNode().val); 38 | System.out.println(a.getRandomNode().val); 39 | System.out.println(a.getRandomNode().val); 40 | System.out.println(a.getRandomNode().val); 41 | System.out.println(a.getRandomNode().val); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /ch04/4.12_-_Paths_with_Sum/PathsWithSum.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | class Node { 4 | Node left; 5 | Node right; 6 | int val; 7 | public Node(int val) { 8 | this.val = val; 9 | } 10 | } 11 | public class PathsWithSum { 12 | public static int countPathsWithSum(Node root, int sum) { 13 | if (root == null) return 0; 14 | 15 | int pathsFromRoot = countPathsWithSumFromNode(root, sum, 0); 16 | 17 | int pathsOnLeft = countPathsWithSum(root.left, sum); 18 | int pathsOnRight = countPathsWithSum(root.right, sum); 19 | 20 | return pathsFromRoot + pathsOnLeft + pathsOnRight; 21 | } 22 | 23 | public static int countPathsWithSumFromNode(Node root, int target, int current) { 24 | if (root == null) return 0; 25 | 26 | current += root.val; 27 | 28 | int total = 0; 29 | if (current == target) { 30 | total++; 31 | } 32 | 33 | total += countPathsWithSumFromNode(root.left, target, current); 34 | total += countPathsWithSumFromNode(root.right, target, current); 35 | 36 | return total; 37 | } 38 | public static void main(String[] args) { 39 | Node a = new Node(10); 40 | Node b = new Node(5); 41 | Node c = new Node(-3); 42 | Node d = new Node(3); 43 | Node e = new Node(2); 44 | Node f = new Node(11); 45 | Node g = new Node(3); 46 | Node h = new Node(-2); 47 | Node i = new Node(1); 48 | a.left = b; 49 | a.right = c; 50 | b.left = d; 51 | b.right = e; 52 | c.right = f; 53 | d.left = g; 54 | d.right = h; 55 | e.right = i; 56 | System.out.println(countPathsWithSum(a, 8)); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /ch04/4.12_-_Paths_with_Sum/README: -------------------------------------------------------------------------------- 1 | Note: This is O(n^2). There is another solution in the book with O(n) time + O(n) space complexity. 2 | -------------------------------------------------------------------------------- /ch05/5.01_-_Insertion/Insertion.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Insertion { 4 | public static int updateBit(int num, int i, boolean bitIs1) { 5 | int value = bitIs1 ? 1 : 0; 6 | int mask = ~(1 << i); 7 | return (num & mask) | (value << i); 8 | } 9 | 10 | public static int insertion(int N, int M, int i, int j) { 11 | int k = 0; 12 | for (; i <= j; i++) { 13 | N = updateBit(N, i, ((M & (1 << k)) != 0) ? true : false); 14 | k++; 15 | } 16 | return N; 17 | } 18 | 19 | public static void main(String[] args) { 20 | System.out.println(insertion(1024, 19, 2, 6)); // 1100 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ch05/5.02_-_Binary_to_String/BinaryToString.java: -------------------------------------------------------------------------------- 1 | public class BinaryToString { 2 | 3 | public static String binaryToString(double x) { 4 | if (x > 1 || x < 0) return "ERROR"; 5 | 6 | StringBuilder sb = new StringBuilder(); 7 | sb.append("."); 8 | while (x > 0) { 9 | double r = x * 2; 10 | if (r >= 1) { 11 | sb.append(1); 12 | x = r - 1; 13 | } else{ 14 | sb.append(0); 15 | x = r; 16 | } 17 | } 18 | return sb.toString(); 19 | } 20 | 21 | public static void main(String[] args) { 22 | System.out.println(binaryToString(0.72)); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ch05/5.03_-_Flip_Bit_to_Win/FlipBitToWin.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class FlipBitToWin { 4 | public static int longestSequence(int n) { 5 | int maxSeq = 0; 6 | 7 | for (int i = 0; i < 32; i++) { 8 | maxSeq = Math.max(maxSeq, longestSequenceOfOnes(n, i)); 9 | } 10 | 11 | return maxSeq; 12 | } 13 | 14 | public static int longestSequenceOfOnes(int n, int ignore) { 15 | int longestSeq = 0; 16 | int seq = 0; 17 | for (int i = 0; i < 32; i++) { 18 | // count sequence of 1s starting from i, ignoring ignore 19 | if (getBit(n, i) || i == ignore) { 20 | seq++; 21 | longestSeq = Math.max(seq, longestSeq); 22 | } else { 23 | seq = 0; 24 | } 25 | } 26 | return longestSeq; 27 | } 28 | 29 | public static boolean getBit(int num, int i) { 30 | return ((num & (1 << i)) != 0); // or ((num >> i) & 1) 31 | } 32 | 33 | public static void main(String[] args) { 34 | System.out.println(longestSequence(1775)); // 11011101111 35 | System.out.println(longestSequence(122)); // 1111010 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ch05/5.03_-_Flip_Bit_to_Win/README: -------------------------------------------------------------------------------- 1 | There are 3 solutions in the book for this. 2 | First is O(b^2) time, where b is the length of the sequence 3 | Second is O(b) time, O(b) space 4 | Third is O(b) time, O(1) space 5 | -------------------------------------------------------------------------------- /ch05/5.05_-_Debugger/Debugger.txt: -------------------------------------------------------------------------------- 1 | ((n & (n-1)) == 0) checks if n is a power of 2 (or if n is 0) 2 | -------------------------------------------------------------------------------- /ch05/5.06_-_Conversion/Conversion.java: -------------------------------------------------------------------------------- 1 | public class Conversion { 2 | public static int conversion(int a, int b) { 3 | if (b > a) { 4 | int temp = a; 5 | a = b; 6 | b = temp; 7 | } 8 | int count = 0; 9 | while (a > 0) { 10 | int aBit = a & 1; 11 | int bBit = b & 1; 12 | if (aBit != bBit) 13 | count++; 14 | a >>= 1; 15 | b >>= 1; 16 | } 17 | return count; 18 | } 19 | 20 | public static int conversionBetter(int a, int b) { 21 | int count = 0; 22 | for (int c = a ^ b; c > 0; c = c >> 1) { 23 | count += c & 1; 24 | } 25 | return count; 26 | } 27 | 28 | public static void main(String[] args) { 29 | System.out.println(conversion(29, 15)); 30 | System.out.println(conversion(1024, 15)); 31 | System.out.println(conversionBetter(1024, 15)); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ch05/5.07_-_Pairwise_Swap/PairwiseSwap.java: -------------------------------------------------------------------------------- 1 | public class PairwiseSwap { 2 | public static int swapOddEvenBits(int x) { 3 | return (((x & 0xaaaaaaaa) >>> 1) | 4 | ((x & 0x55555555) << 1)); 5 | } 6 | public static void main(String[] args) { 7 | System.out.println(swapOddEvenBits(538)); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /ch06/6.01_-_The_Heavy_Pill/The_Heavy_Pill.md: -------------------------------------------------------------------------------- 1 | 6.1 You have 20 bottles of pills. 19 bottles have 1.0 gram pills, but one has pills of weight 1.1 grams. Given a scale that provides an accurate measurement, how would you find the heavy bottle? You can only use the scale once. 2 | ------- 3 | 4 | Take one pill from Bottle #1, two pills from Bottle #2, three pills from Bottle #3, etc. Weigh these pills together. If all the pills were one gram each, then the scale would read 210 grams (1 + 2 + 3 + 4 + ... + 20 = 210) or (20 * 21)/2 = 210. Any weight over 210 must come from the heavier pills. 5 | 6 | Then use this formula to find the bottle number. ((weight - 210) / 0.1). So if the set of pills weighed 211.5 grams, then bottle #15 would have the 1.1g pills. 7 | -------------------------------------------------------------------------------- /ch07/7.01_-_Deck_of_Cards/Card.java: -------------------------------------------------------------------------------- 1 | public abstract class Card { 2 | private boolean available = true; 3 | protected in faceValue; 4 | protected Suit suit; 5 | 6 | public Card(int c, Suit s) { 7 | faceValue = c; 8 | suit = s; 9 | } 10 | 11 | public abstract int value(); 12 | public Suit suite() { return suit; } 13 | 14 | public boolean isAvailable() { return available; } 15 | public void mark(boolean a) { available = a; } 16 | } 17 | -------------------------------------------------------------------------------- /ch07/7.01_-_Deck_of_Cards/Deck.java: -------------------------------------------------------------------------------- 1 | public class Deck { 2 | private ArrayList cards; 3 | private int dealtIndex = 0; 4 | 5 | public int remainingCards() { 6 | return cards.size() - dealtIndex; 7 | } 8 | 9 | public void shuffle() { 10 | } 11 | 12 | public int remainingCards() { 13 | return cards.size() - dealtIndex; 14 | } 15 | 16 | public T[] dealHand(int number) { 17 | // Check Gayle's git repo, or the book for most of these methods 18 | // I can't see myself getting much out of rote copying these 19 | } 20 | 21 | public T dealCard() {} 22 | 23 | public void print() { 24 | for (T card : cards) { 25 | card.print(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ch07/7.01_-_Deck_of_Cards/Hand.java: -------------------------------------------------------------------------------- 1 | public class Hand { 2 | protected ArrayList cards = new ArrayList(); 3 | 4 | public int score() { 5 | int score = 0; 6 | for (T card : cards) { 7 | score += card.value(); 8 | } 9 | return score; 10 | } 11 | 12 | public void add(T card) { 13 | cards.add(card); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ch07/7.01_-_Deck_of_Cards/Suit.java: -------------------------------------------------------------------------------- 1 | public enum Suit { 2 | Club (0), 3 | Diamond (1), 4 | Heart (2), 5 | Spade (3); 6 | 7 | private int value; 8 | private Suit(int v) { 9 | value = v; 10 | } 11 | 12 | public int getValue() { 13 | return value; 14 | } 15 | 16 | public static Suit getSuitFromvalue(int value) { 17 | switch (value) { 18 | case 0: 19 | return Suit.Club; 20 | case 1: 21 | return Suit.Diamond; 22 | case 2: 23 | return Suit.Heart; 24 | case 3: 25 | return Suit.Spade; 26 | } 27 | return null; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ch07/7.09_-_Circular_Array/CircularArray.java: -------------------------------------------------------------------------------- 1 | import java.util.Iterator; 2 | 3 | public class CircularArray implements Iterable { 4 | private T[] items; 5 | private int head = 0; 6 | 7 | public CircularArray(int size) { 8 | items = (T[]) new Object[size]; 9 | } 10 | 11 | private int convert(int index) { 12 | if (index < 0) { 13 | index += items.length; 14 | } 15 | return (head + index) % items.length; 16 | } 17 | 18 | public void rotate(int shiftRight) { 19 | head = convert(shiftRight); 20 | } 21 | 22 | public T get(int i) { 23 | if (i < 0 || i >= items.length) { 24 | throw new java.lang.IndexOutOfBoundsException("..."); 25 | } 26 | return items[convert(i)]; 27 | } 28 | 29 | public void set(int i, T item) { 30 | items[convert(i)] = item; 31 | } 32 | 33 | public Iterator iterator() { 34 | return new CircularArrayIterator(this); 35 | } 36 | 37 | private class CircularArrayIterator implements Iterator{ 38 | private int _current = -1; 39 | private TI[] _items; 40 | 41 | public CircularArrayIterator(CircularArray array) { 42 | _items = array.items; 43 | } 44 | 45 | @Override 46 | public boolean hasNext() { 47 | return _current < items.length - 1; 48 | } 49 | 50 | @Override 51 | public TI next() { 52 | _current++; 53 | TI item = (TI) _items[convert(_current)]; 54 | return item; 55 | } 56 | 57 | @Override 58 | public void remove() { 59 | throw new UnsupportedOperationException("..."); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /ch08/8.01_-_TripleStep/TripleStep.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class TripleStep { 4 | public static int memo[] = new int[1024]; 5 | 6 | public static int ways(int n) { 7 | if (n < 0) 8 | return 0; 9 | else if (n == 0) 10 | return 1; 11 | else if (memo[n] > 0) 12 | return memo[n]; 13 | else { 14 | memo[n] = ways(n-1) + ways(n-2) + ways(n-3); 15 | return memo[n]; 16 | } 17 | } 18 | public static void main(String[] args) { 19 | System.out.println(ways(5)); 20 | System.out.println(ways(12)); 21 | System.out.println(ways(30)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ch08/8.03_-_Magic_Index/MagicIndex.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class MagicIndex { 4 | public static int magicSlow(int[] arr) { 5 | for (int i = 0; i < arr.length; i++) { 6 | if (arr[i] == i) 7 | return i; 8 | } 9 | return -1; 10 | } 11 | 12 | public static int magicFast(int[] arr, int low, int high) { 13 | int pivot; 14 | if (high >= low) { 15 | pivot = low + ((high - low) / 2); 16 | if (arr[pivot] == pivot) 17 | return pivot; 18 | else if (arr[pivot] < pivot) 19 | return magicFast(arr, pivot + 1, high); 20 | else 21 | return magicFast(arr, low, pivot - 1); 22 | } 23 | return -1; 24 | } 25 | 26 | public static void main(String[] args) { 27 | int[] arr = new int[]{-5, -2, 1, 3, 5, 9}; // arr[3] = 3 28 | int[] arr2 = new int[]{-5, -2, 1, 2, 3, 5}; // arr[5] = 5 29 | System.out.println(magicSlow(arr)); 30 | System.out.println(magicFast(arr2, 0, arr2.length - 1)); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ch08/8.04_-_Power_Set/PowerSet.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class PowerSet { 4 | public static ArrayList> getSubsets(ArrayList set, int index) { 5 | ArrayList> all; 6 | if (set.size() == index) { // base case - add empty set 7 | all = new ArrayList>(); 8 | all.add(new ArrayList()); 9 | } else { 10 | all = getSubsets(set, index + 1); 11 | int item = set.get(index); 12 | ArrayList> more = new ArrayList>(); 13 | for (ArrayList subset : all) { 14 | ArrayList newSubset = new ArrayList(); 15 | newSubset.addAll(subset); 16 | newSubset.add(item); 17 | more.add(newSubset); 18 | } 19 | all.addAll(more); 20 | } 21 | return all; 22 | } 23 | 24 | public static void main(String[] args) { 25 | ArrayList set = new ArrayList(); 26 | set.add(1); 27 | set.add(2); 28 | set.add(3); 29 | ArrayList> subsets = getSubsets(set, 0); 30 | for (ArrayList subset : subsets) 31 | System.out.println(subset); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ch08/8.05_-_Recursive_Multiply/RecursiveMultiply.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class RecursiveMultiply { 4 | 5 | public static int multiply(int a, int b) { 6 | if (b == 1) 7 | return a; 8 | else 9 | return a + multiply(a, b - 1); 10 | } 11 | 12 | public static void main(String[] args) { 13 | System.out.println(multiply(5, 3)); 14 | System.out.println(multiply(25, 1)); 15 | System.out.println(multiply(9, 9)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ch08/8.07_-_Permutations_without_Dups/Permutations.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | public class Permutations { 3 | public static List permute(String str) { 4 | return permuteHelper(str, str.length()); 5 | } 6 | 7 | public static List permuteHelper(String str, int i) { 8 | List ret = new ArrayList(); 9 | if (i == 0) { 10 | ret.add(""); 11 | } else { 12 | List prev = permuteHelper(str, i-1); 13 | for (String a : prev) { 14 | List lst = insertInto(a, str.charAt(i - 1)); 15 | ret.addAll(lst); 16 | } 17 | } 18 | return ret; 19 | } 20 | 21 | public static List insertInto(String a, char b) { 22 | List ret = new ArrayList(); 23 | for (int i = 0; i < a.length(); i++) { 24 | String newString = a.substring(0, i) + b + a.substring(i); 25 | ret.add(newString); 26 | } 27 | ret.add(a + b); 28 | return ret; 29 | } 30 | 31 | public static void main(String[] args) { 32 | List permutations = permute("abcd"); 33 | for (String p : permutations) 34 | System.out.println(p); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ch08/8.08_-_Permutations_with_Duplicates/Permutations.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | public class Permutations { 3 | public static Set permute(String str) { 4 | return permuteHelper(str, str.length()); 5 | } 6 | 7 | public static Set permuteHelper(String str, int i) { 8 | Set ret = new HashSet(); 9 | if (i == 0) { 10 | ret.add(""); 11 | } else { 12 | Set prev = permuteHelper(str, i-1); 13 | for (String a : prev) { 14 | Set lst = insertInto(a, str.charAt(i - 1)); 15 | ret.addAll(lst); 16 | } 17 | } 18 | return ret; 19 | } 20 | 21 | public static Set insertInto(String a, char b) { 22 | Set ret = new HashSet(); 23 | for (int i = 0; i < a.length(); i++) { 24 | String newString = a.substring(0, i) + b + a.substring(i); 25 | ret.add(newString); 26 | } 27 | ret.add(a + b); 28 | return ret; 29 | } 30 | 31 | public static void main(String[] args) { 32 | Set permutations = permute("aaaaaab"); 33 | for (String p : permutations) 34 | System.out.println(p); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ch08/8.08_-_Permutations_with_Duplicates/README: -------------------------------------------------------------------------------- 1 | Literally the same code as 9.08, but using a set. 2 | See the book for an additional solution. 3 | -------------------------------------------------------------------------------- /ch08/8.09_-_Parens/Parens.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Parens { 4 | public static Set generateParens(int index) { 5 | Set set = new HashSet(); 6 | if (index == 0) { 7 | set.add(""); 8 | } else { 9 | Set prev = generateParens(index - 1); 10 | for (String a : prev) { 11 | for (int i = 0; i < a.length(); i++) 12 | if (a.charAt(i) == '(') 13 | set.add(insertInside(a, i)); 14 | set.add("()" + a); 15 | } 16 | } 17 | return set; 18 | } 19 | 20 | public static String insertInside(String str, int leftParen) { 21 | String left = str.substring(0, leftParen + 1); 22 | String right = str.substring(leftParen + 1); 23 | return left + "()" + right; 24 | } 25 | 26 | public static void main(String[] args) { 27 | for (int i = 1; i < 5; i++) { 28 | Set test = generateParens(i); 29 | for (String str : test) 30 | System.out.println(str); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ch08/8.10_-_Paint_Fill/PaintFill.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class PaintFill { 4 | public static boolean fill(int[][] colors, int r, int c, int newColor) { 5 | if (colors[r][c] == newColor) return false; 6 | return fillHelper(colors, r, c, colors[r][c], newColor); 7 | } 8 | 9 | public static boolean fillHelper(int[][] colors, int r, int c, int oldColor, int newColor) { 10 | if (r < 0 || r > colors.length - 1 || c < 0 || c > colors[0].length - 1) { 11 | return false; 12 | } 13 | if (colors[r][c] == oldColor) { 14 | colors[r][c] = newColor; 15 | fillHelper(colors, r + 1, c, oldColor, newColor); 16 | fillHelper(colors, r - 1, c, oldColor, newColor); 17 | fillHelper(colors, r, c + 1, oldColor, newColor); 18 | fillHelper(colors, r, c - 1, oldColor, newColor); 19 | } 20 | return true; 21 | } 22 | 23 | public static void main(String[] args) { 24 | int[][] colors = new int[][]{ 25 | {0, 1, 2, 1, 1, 0}, 26 | {0, 1, 1, 1, 2, 3}, 27 | {1, 1, 2, 2, 2, 1}, 28 | {1, 2, 1, 1, 3, 0}, 29 | {1, 1, 1, 0, 0, 0} 30 | }; 31 | for (int[] line : colors) { 32 | for (int num : line) 33 | System.out.print(num + " "); 34 | System.out.println(); 35 | } 36 | System.out.println(); 37 | fill(colors, 1, 3, 4); 38 | for (int[] line : colors) { 39 | for (int num : line) 40 | System.out.print(num + " "); 41 | System.out.println(); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /ch08/8.11_-_Coins/Coins.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Coins { 4 | public static int[] S = new int[]{1, 5, 10, 25}; 5 | public static int countWays(int m, int n) { 6 | if (n == 0) 7 | return 1; 8 | 9 | if (n < 0) 10 | return 0; 11 | 12 | if (m <= 0 && n >= 1) 13 | return 0; 14 | 15 | return countWays(m - 1, n) + countWays(m, n - S[m-1]); 16 | } 17 | public static void main(String[] args) { 18 | System.out.println(countWays(4, 67)); 19 | System.out.println(countWays(4, 1)); 20 | System.out.println(countWays(4, 4)); 21 | System.out.println(countWays(4, 15)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ch08/8.12_-_Eight_Queens/EightQueens.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class EightQueens { 4 | public int GRID_SIZE = 8; 5 | 6 | public void placeQueens(int row, Integer[] columns, ArrayList results) { 7 | if (row == GRID_SIZE) 8 | results.add(columns.clone()); 9 | else { 10 | for (int col = 0; col < GRID_SIZE; col++) { 11 | if (checkValid(columns, row, col)) { 12 | columns[row] = col; 13 | placeQueens(row + 1, columns, results); 14 | } 15 | } 16 | } 17 | } 18 | 19 | public boolean checkValid(Integer[] columns, int row1, int column1) { 20 | for (int row2 = 0; row2 < row1; row2++) { 21 | int column2 = columns[row2]; 22 | 23 | if (column1 == column2) 24 | return false; 25 | 26 | int columnDist = Math.abs(column2 - column1); 27 | int rowDist = Math.abs(row1 - row2); 28 | 29 | if (columnDist == rowDist) 30 | return false; 31 | } 32 | return true; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ch10/10.01_-_Sorted_Merge/SortedMerge.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class SortedMerge { 4 | public static void merge(int[] a, int[] b, int lastA, int lastB) { 5 | int indexA = lastA - 1; 6 | int indexB = lastB - 1; 7 | int indexMerged = lastA + lastB - 1; 8 | while (indexB >= 0) { 9 | if (indexA >= 0 && a[indexA] > b[indexB]) { 10 | a[indexMerged] = a[indexA]; 11 | indexA--; 12 | } else { 13 | a[indexMerged] = b[indexB]; 14 | indexB--; 15 | } 16 | indexMerged--; 17 | } 18 | } 19 | public static void main(String[] args) { 20 | int[] a = new int[]{1, 4, 7, 8, 9, 15, -1, -1, -1, -1, -1, -1}; 21 | int[] b = new int[]{2, 3, 5, 11, 12, 16}; 22 | int lastA = 6; 23 | int lastB = 6; 24 | merge(a, b, lastA, lastB); 25 | System.out.println(Arrays.toString(a)); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ch10/10.02_-_Group_Anagrams/GroupAnagrams.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class GroupAnagrams { 4 | public static class AnagramComparator implements Comparator { 5 | public String sortChars(String s) { 6 | char[] content = s.toCharArray(); 7 | Arrays.sort(content); 8 | return new String(content); 9 | } 10 | 11 | public int compare(String s1, String s2) { 12 | return sortChars(s1).compareTo(sortChars(s2)); 13 | } 14 | 15 | public void sort(String[] array) { 16 | Map> map = new HashMap>(); 17 | for (String s : array) { 18 | String key = sortChars(s); 19 | if (map.containsKey(key)) { 20 | ArrayList lst = map.get(key); 21 | lst.add(s); 22 | } else { 23 | ArrayList lst = new ArrayList(); 24 | lst.add(s); 25 | map.put(key, lst); 26 | } 27 | } 28 | int index = 0; 29 | for (String key : map.keySet()) { 30 | ArrayList lst = map.get(key); 31 | for (String s : lst) { 32 | array[index] = s; 33 | index++; 34 | } 35 | } 36 | } 37 | } 38 | 39 | public static void main(String[] args) { 40 | String[] array = new String[]{"cats", "acre", "atcs", "fried", "race", "axe", "exa", "care"}; 41 | System.out.println(Arrays.toString(array)); 42 | Arrays.sort(array, new AnagramComparator()); 43 | System.out.println(Arrays.toString(array)); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ch10/10.03_-_Search_in_Rotated_Array/SearchInSortedArray.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class SearchInSortedArray { 4 | public static int search(int[] nums, int low, int high, int num) { 5 | int mid = low + (high - low)/2; 6 | if (num == nums[mid]) 7 | return mid; 8 | 9 | if (high < low) 10 | return -1; 11 | 12 | // left is ordered 13 | if (nums[low] < nums[mid]) { 14 | if (num >= nums[low] && num < nums[mid]) 15 | return search(nums, low, mid - 1, num); 16 | else 17 | return search(nums, mid + 1, high, num); 18 | } else if (nums[mid] < nums[low]) { 19 | // right is ordered 20 | if (num > nums[mid] && num <= nums[high]) 21 | return search(nums, mid + 1, high, num); 22 | else 23 | return search(nums, low, mid - 1, num); 24 | } else { // left half is all duplicates or small array 25 | if (nums[mid] != nums[high]) { 26 | return search(nums, mid+1, high, num); 27 | } else { 28 | int ret = search(nums, low, mid-1, num); 29 | if (ret != -1) 30 | return ret; 31 | return search(nums, mid + 1, high, num); 32 | } 33 | } 34 | } 35 | 36 | public static void main(String[] args) { 37 | int[] array1 = new int[]{10, 15, 20, 5}; 38 | System.out.println(search(array1, 0, 3, 5)); // 3 39 | int[] array2 = new int[]{50, 5, 20, 30, 40}; 40 | System.out.println(search(array2, 0, 4, 50)); // 0 41 | int[] array3 = new int[]{15, 16, 19, 20, 25, 1, 3, 4, 5, 7, 10, 14}; 42 | System.out.println(search(array3, 0, 11, 5)); // 8 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /ch10/10.04_-_Sorted_Search,_No_Size/SortedSearch.java: -------------------------------------------------------------------------------- 1 | public class SortedSearch { 2 | public static int search(int[] arr, int val) { 3 | int index = 1; 4 | while (index < arr.length && arr[index] < val) { 5 | index *= 2; 6 | } 7 | return binarySearch(arr, val, index / 2, index); 8 | } 9 | 10 | public static int binarySearch(int[] arr, int val, int low, int high) { 11 | int mid; 12 | while (low <= high) { 13 | mid = low + (high - low) / 2; 14 | if (mid > arr.length - 1 || arr[mid] > val) 15 | high = mid - 1; 16 | else if (arr[mid] < val) 17 | low = mid + 1; 18 | else 19 | return mid; 20 | } 21 | return -1; 22 | } 23 | 24 | public static void main(String[] args) { 25 | System.out.println(search(new int[]{1, 2, 5, 8, 24, 35}, 24)); 26 | System.out.println(search(new int[]{1, 2, 5, 8, 24, 35}, 1)); 27 | System.out.println(search(new int[]{1, 2, 5, 8, 24, 35}, 35)); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ch10/10.06_-_Sort_Big_File/SortBigFile.txt: -------------------------------------------------------------------------------- 1 | Imagine you have a 20 GB file with one string per line. Explain how you would sort the file. 2 | 3 | Given the memory space requirement for traditional sorting algorithms, we should figure out a way of sorting without using much space. 4 | What we can do is only load a chunk of the file in at a time. We can load a small chunk, sort it, then save it, and repeat for all chunks. 5 | Once we sort all chunks, we use merge sort to merge and sort the chunks one by one. 6 | This is refered to as an external sort. 7 | 8 | https://en.wikipedia.org/wiki/External_sorting 9 | -------------------------------------------------------------------------------- /ch10/10.08_-_Find_Duplicates/FindDuplicates.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class FindDuplicates { 4 | public static List findDuplicates(int[] arr) { 5 | List duplicates = new ArrayList(); 6 | BitSet bs = new BitSet(32001); 7 | for (int num : arr) { 8 | if (bs.get(num) == false) 9 | bs.set(num); 10 | else 11 | duplicates.add(num); 12 | bs.set(num); 13 | } 14 | return duplicates; 15 | } 16 | public static void main(String[] args) { 17 | int[] arr = new int[]{1, 2, 3, 4, 5, 5, 6, 7, 8, 8}; 18 | List duplicates = findDuplicates(arr); 19 | for (int num : duplicates) 20 | System.out.println(num); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ch10/10.09_-_Sorted_Matrix_Search/SortedMatrixSearch.java: -------------------------------------------------------------------------------- 1 | public class SortedMatrixSearch { 2 | public static class Element { 3 | public int row; 4 | public int col; 5 | public Element(int row, int col) { 6 | this.row = row; 7 | this.col = col; 8 | } 9 | } 10 | 11 | public static Element findElement(int[][] matrix, int element) { 12 | int row = 0; 13 | int col = matrix[0].length - 1; 14 | while (row < matrix.length && col >= 0) { 15 | if (matrix[row][col] == element) 16 | return new Element(row, col); 17 | else if (matrix[row][col] > element) 18 | col--; 19 | else 20 | row++; 21 | } 22 | return null; 23 | } 24 | 25 | public static void main(String[] args) { 26 | int[][] matrix = new int[][]{ 27 | {15, 20, 40, 85}, 28 | {20, 35, 80, 95}, 29 | {30, 55, 95, 105}, 30 | {40, 80, 100, 120} 31 | }; 32 | Element e = findElement(matrix, 55); 33 | if (e == null) 34 | System.out.println("Element not found"); 35 | else 36 | System.out.println("Element at row: " + e.row + " - col: " + e.col); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ch11/11.01_-_Mistake/Mistake.txt: -------------------------------------------------------------------------------- 1 | /* Using --i means when i=0, it passes the check for i >= 0, 2 | * then subtracts 1 from i, and prints out -1. Use i++ 3 | 4 | unsigned int i = 0; 5 | for (i = 100; i >= 0; i--) 6 | printf("%d\n", i); 7 | -------------------------------------------------------------------------------- /ch11/11.02_-_Random_Crashes/RandomCrashes.txt: -------------------------------------------------------------------------------- 1 | 1. Our program may depend on some element of randomness: user input, randomly generated number, time, etc 2 | 2. If our program is using an uninitialized variable, it could be accessing data it isn't supposed to (same with accessing something outside of an arrays indices) 3 | 3. Our program may be using an external library that crashes all the time. 4 | 4. Stack overflows 5 | -------------------------------------------------------------------------------- /ch12/12.01_-_Last_K_Lines/file.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 3 4 | 4 5 | 5 6 | 6 7 | 7 8 | 8 9 | 9 10 | 10 11 | 11 12 | 12 13 | 13 14 | 14 15 | 15 16 | -------------------------------------------------------------------------------- /ch12/12.01_-_Last_K_Lines/file2.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | 3 4 | 4 5 | -------------------------------------------------------------------------------- /ch12/12.01_-_Last_K_Lines/klines: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/austinschwartz/ctci_v6/6a67b41adc25ca85ce9eda310350fd77fcb80394/ch12/12.01_-_Last_K_Lines/klines -------------------------------------------------------------------------------- /ch12/12.01_-_Last_K_Lines/klines.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | void printLast10Lines(const char* fileName) { 9 | const int k = 10; 10 | ifstream file(fileName); 11 | string L[k]; 12 | int size = 0; 13 | 14 | while (file.peek() != EOF) { 15 | getline(file, L[size % k]); 16 | size++; 17 | } 18 | 19 | int start = size > k ? (size % k) : 0; 20 | int count = min(k, size); 21 | 22 | for (int i = 0; i < count; i++) { 23 | cout << L[(start + i) % k] << endl; 24 | } 25 | } 26 | 27 | int main() { 28 | const char* fileName = "file.txt"; 29 | printLast10Lines(fileName); 30 | cout << endl; 31 | const char* fileName2 = "file2.txt"; 32 | printLast10Lines(fileName2); 33 | } 34 | -------------------------------------------------------------------------------- /ch12/12.02_-_Reverse_String/reverse_string.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void swap(char* p1, char* p2) { 4 | char temp = *p1; 5 | *p1 = *p2; 6 | *p2 = temp; 7 | } 8 | 9 | void reverse(char* str) { 10 | char* end = str; 11 | if (str) { 12 | while (*end) 13 | end++; 14 | end--; 15 | 16 | while (str < end) { 17 | swap(str, end); 18 | str++; 19 | end--; 20 | } 21 | } 22 | } 23 | 24 | int main() { 25 | char str[] = "hello"; 26 | printf("%s\n", str); 27 | reverse(str); 28 | printf("%s\n", str); 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /ch12/12.03_-_Hash_Table_vs_STL_Map/HashTableVsSTLMap.md: -------------------------------------------------------------------------------- 1 | Compare and constrast a hash table and an STL map. How is a hash table implemented? If the number of inputs is small, which data structure options can be used instead of a hash table? 2 | 3 | STL map in c++ is backed by a red black tree, and so the keys are sorted. Because its a red black tree, insert is O(log_2(n)), delete is O(log_2(n)), etc. A hash table is typically implemented using an array of linked lists. With few collisions in the hash table, a hash table gives O(1) inserts and O(1) deletes. 4 | -------------------------------------------------------------------------------- /ch12/12.04_-_Virtual_Functions/VirtualFunctions.md: -------------------------------------------------------------------------------- 1 | How do virtual functions work in C++? 2 | 3 | A virtual function depends on a "Virtual Table", or "vtable". If any function of a class is declared to be virtual, a vtable is constructed which stores addresses of the virtual functions of this class. The compiler also adds a hidden vptr variable in all such classes which points to the vtable of that class. If a virtual function is not overridden in the derived class, the vtable of the derived class stores the address of the function in its parent class. The vtable is used to resolve the address of the function when the virtual function when the virtual function is called. Dynamic binding in C++ is performed through the vtable mechanism. 4 | 5 | Thus, when we assign the derived class object to the base class pointer, the vptr variable gets to the vtable of the derived class. The assignment ensures that the most derived virtual function gets called. 6 | 7 | Note: This is word for word from the book 8 | -------------------------------------------------------------------------------- /ch12/12.05_-_Shallow_vs_Deep_Copy/Shallow_vs_Deep.md: -------------------------------------------------------------------------------- 1 | A shallow copy copies all values from one object to another. For any pointers, just the reference is copied. In a deep copy, every pointer will be followed, and whatever they point to will also be copied. 2 | 3 | Book example: 4 | 5 | struct Test { 6 | char * ptr; 7 | }; 8 | 9 | void shallow_copy(Test & src, Test & dest) { 10 | dest.ptr = src.ptr; 11 | } 12 | 13 | void deep_copy(Test & src, Test & dest) { 14 | dest.ptr = (char*)malloc(strlen(src.ptr) + 1); 15 | strcpy(dest.ptr, src.ptr); 16 | } 17 | 18 | -------------------------------------------------------------------------------- /ch13/13.01_-_Private_Constructor/PrivateConstructor.md: -------------------------------------------------------------------------------- 1 | In terms of inheritance, what is the effect of keeping a constructor private? 2 | 3 | If class A has a private constructor, it can only be called from A, A's inner classes, and any inner classes of a parent of A. 4 | What this means is that since a subclass calls its parent's constructor, A can only be inherited by its own inner classes or it's parent's inner classes. 5 | -------------------------------------------------------------------------------- /ch13/13.02_-_Return_From_Finally/ReturnFromFinally.md: -------------------------------------------------------------------------------- 1 | In Java, does the finally block get executed if we insert a return statement inside the try block of a try-catch-finally? 2 | 3 | The finally block will get executed regardless, unless the thread gets killed or the virtual machine exits. 4 | -------------------------------------------------------------------------------- /ch13/13.03_-_Final,_etc/Final,etc.md: -------------------------------------------------------------------------------- 1 | What is the difference between final, finally, and finalize? 2 | 3 | Final: Sets a variable, method, or class to immutable (unable to be changed). 4 | Finally: Used in a try/catch block to ensure something is always executed. 5 | Finalize: Called by the garbage collector once it is determined that no more references to this object exist. 6 | -------------------------------------------------------------------------------- /ch13/13.04_-_Generics_vs_Templates/GenericsVsTemplates.md: -------------------------------------------------------------------------------- 1 | Explain the difference between templates in C++ and generics in Java. 2 | 3 | Java generics are pretty much just syntactic sugar. Once compiling to byte code, something called 'type erasure' takes place. Any parameterized types are eliminated. 4 | 5 | For example, suppose you have the Java code below: 6 | Vector vector = new Vector(); 7 | vector.add(new String("hello")); 8 | String str = vector.get(0); 9 | 10 | During compilation, this code is re-written into: 11 | Vector vector = new Vector(); 12 | vector.add(new String("hello")); 13 | String str = (String) vector.get(0); 14 | 15 | However, in C++, templates are essentially a glorified macro set, with the compiler creating a new copy of the template code for each type. 16 | 17 | There are more differences: 18 | 19 | - C++ templates can use primitive types, like int. Java must used wrappers like Integer. 20 | - In C++, the type parameter can be instantiated, whereas Java does not support this. 21 | - In Java, all instances of a Class, regardless of their type parameters, are the same type. The type parameters are erased at runtime. 22 | -------------------------------------------------------------------------------- /ch13/13.05_-_TreeMap,HashMap,LinkedHashMap/Maps.txt: -------------------------------------------------------------------------------- 1 | TreeMap returns keys in sorted order, with O(log_n) lookup and insertion. Implemented by a Red-Black tree. 2 | HashMap returns keys in arbitrary order, with O(1) lookup and insertion. Implemented with an array of linked lists. 3 | LinkedHashMap returns keys in insertion order, with O(1) lookup and insertion. Implemented by doubly-linked buckets. 4 | -------------------------------------------------------------------------------- /ch13/13.06_-_Object_Reflection/ObjectReflection.md: -------------------------------------------------------------------------------- 1 | Explain what object reflection is in Java and why it is useful. 2 | 3 | Object Reflection is a feature in Java that allows you to get information about objects and classes at runtime. It is very useful for debugging. You can get information about the methods and fields present inside of a class/object, create new objects, and get/set object fields directly, regardless of what the access modifier is. 4 | -------------------------------------------------------------------------------- /ch13/13.07_-_Lambda_Expressions/LambdaExpressions.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.util.stream.*; 3 | 4 | class Country { 5 | String continent; 6 | int population; 7 | String getContinent() { 8 | return continent; 9 | } 10 | int getPopulation() { 11 | return population; 12 | } 13 | } 14 | public class LambdaExpressions { 15 | public static int getPopulation(List countries, String continent) { 16 | Stream sublist = countries 17 | .stream() 18 | .filter(country -> { return country.getContinent().equals(continent);}); 19 | 20 | Stream populations = sublist.map(c -> c.getPopulation()); 21 | 22 | int population = populations.reduce(0, (a, b) -> a + b); 23 | 24 | return population; 25 | } 26 | public static void main(String[] args) { 27 | Country a = new Country(); a.population = 55; a.continent = "A"; 28 | Country b = new Country(); b.population = 125; b.continent = "B"; 29 | Country c = new Country(); c.population = 2; c.continent = "A"; 30 | List list = new ArrayList(){{ 31 | add(a); 32 | add(b); 33 | add(c); 34 | }}; 35 | System.out.println(getPopulation(list, "A")); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ch13/13.08_-_Lambda_Random/LambdaRandom.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | import java.util.stream.*; 3 | 4 | public class LambdaRandom { 5 | public static List getRandomSubsetNoLambda(List list) { 6 | List subset = new ArrayList(); 7 | Random random = new Random(); 8 | for (int item : list) { 9 | if (random.nextBoolean()) { 10 | subset.add(item); 11 | } 12 | } 13 | return subset; 14 | } 15 | 16 | public static List getRandomSubset(List list) { 17 | Random random = new Random(); 18 | List subset = list 19 | .stream() 20 | .filter(k -> { return random.nextBoolean(); }) 21 | .collect(Collectors.toList()); 22 | return subset; 23 | } 24 | 25 | public static void main(String[] args) { 26 | List list = new ArrayList(){{ 27 | add(1); 28 | add(2); 29 | add(3); 30 | add(4); 31 | add(5); 32 | add(6); 33 | }}; 34 | List subset = getRandomSubset(list); 35 | System.out.println(subset); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ch14/14.01_-_Multiple_Apartments/multiple_apartments.sql: -------------------------------------------------------------------------------- 1 | SELECT TenantName 2 | FROM Tenants 3 | INNER JOIN (SELECT TenantID 4 | FROM AptTenants 5 | GROUP BY TenantID 6 | HAVING count(*) > 1) A 7 | ON Tenants.TenantID = A.TenantID 8 | -------------------------------------------------------------------------------- /ch14/14.05_-_Denormalization/Denormalization.md: -------------------------------------------------------------------------------- 1 | Denormalization is where you add redundant information to tables so you can speed up queries by reducing the need for joins. In a normalized database, you would split up information into separate tables and minimize redundant data. Ideally, you may want only one copy of each piece of data in the database. 2 | 3 | Cons of Denormalization 4 | * Updates and inserts require putting data into multiple tables and thus are more expensive + harder to write 5 | * Data may get inconistant if you're not adding/inserting/updating correctly. The same data could be in multiple tables with different values 6 | * Higher storage costs 7 | 8 | Pros of Denormalization 9 | * Faster Queries since you won't need to join tables 10 | * Queries can be more prone to errors 11 | -------------------------------------------------------------------------------- /ch15/15.01_-_Threads_vs._Processes/ThreadsVsProcesses.md: -------------------------------------------------------------------------------- 1 | Whats the difference between a thread and a process? 2 | 3 | Processes and threads are fundamentally different. A process can be thought of as an instance of a program in execution. That process may have multiple threads running under it. Communication between threads is much simpler than between processes, since the threads within a process share resources. There are various ways for one process to access another's resources: pipes, sockets, files, etc. 4 | -------------------------------------------------------------------------------- /ch15/15.02_-_Context_Switch/ContextSwitch.md: -------------------------------------------------------------------------------- 1 | How would you measure the time spent in a context switch? 2 | 3 | A context switch is the time spent switching between two processes. As two processes cannot run simultaneously on a single CPU core, one process must be put into a waiting/terminated state for another to run. In order to measure the time spent in a context switch, we need to record timestamps of the first and last instruction of the swapping processes. The context switch time is the difference in the timestamps. 4 | 5 | Note: There is a massive two page in depth overview of this problem and how exactly you would measure the timestamps in the book. 6 | -------------------------------------------------------------------------------- /ch16/16.01_-_NumberSwapper/NumberSwapper.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class NumberSwapper { 4 | public static void main(String[] args) { 5 | int x = 5; 6 | int y = 6; 7 | 8 | x = x ^ y; 9 | y = y ^ x; 10 | x = x ^ y; 11 | 12 | System.out.println("x: " + x); 13 | System.out.println("y: " + y); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ch16/16.02_-_Word_Frequencies/WordFrequencies.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class WordFrequencies { 4 | public static Map map; 5 | 6 | public static void setUpHashTable(String str) { 7 | map = new HashMap(); 8 | String[] words = str.replaceAll("[^A-Za-z0-9]", " ").split(" "); 9 | for (String word : words) { 10 | if (map.containsKey(word)) 11 | map.put(word, map.get(word) + 1); 12 | else 13 | map.put(word, 1); 14 | } 15 | } 16 | 17 | public static int frequencies(String given) { 18 | if (map.containsKey(given)) 19 | return map.get(given); 20 | else 21 | return 0; 22 | } 23 | public static void main(String[] args) { 24 | String str = "hello this is a test line supposedly representing a book. the book is very short."; 25 | setUpHashTable(str); 26 | System.out.println(frequencies("is")); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ch16/16.04_-_Tic_Tac_Win/TicTacWin.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class TicTacWin { 4 | public static boolean hasWinner(char a, char b, char c) { 5 | if (a == b && b == c && a != ' ') 6 | return true; 7 | return false; 8 | } 9 | 10 | public static char whoWon(char[][] board) { 11 | for (int i = 0; i < 3; i++) { 12 | // Check rows 13 | if (hasWinner(board[i][0], board[i][1], board[i][2])) { 14 | return board[i][0]; 15 | } 16 | 17 | // Check cols 18 | if (hasWinner(board[0][i], board[1][i], board[2][i])) { 19 | return board[0][i]; 20 | } 21 | } 22 | // Diagonals 23 | if (hasWinner(board[0][0], board[1][1], board[2][2])) 24 | return board[0][0]; 25 | 26 | if (hasWinner(board[0][2], board[1][1], board[2][0])) 27 | return board[0][2]; 28 | 29 | return '?'; 30 | } 31 | public static void main(String[] args) { 32 | System.out.println(whoWon( 33 | new char[][]{ 34 | {'X', 'O', 'X'}, 35 | {'X', 'X', 'O'}, 36 | {'X', 'O', 'O'} 37 | })); 38 | System.out.println(whoWon( 39 | new char[][]{ 40 | {'O', 'X', 'X'}, 41 | {'O', 'O', 'X'}, 42 | {'X', 'X', 'O'} 43 | })); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ch16/16.05_-_LRU_Cache/LRUCache.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class LRUCache { 4 | public Node head; 5 | public Node tail; 6 | public int capacity; 7 | public Map map = new HashMap(); 8 | 9 | public LRUCache(int capacity) { 10 | this.capacity = capacity; 11 | } 12 | 13 | public String get(int key) { 14 | if (map.containsKey(key)) { 15 | Node n = map.get(key); 16 | remove(n); 17 | setHead(n); 18 | return n.value; 19 | } 20 | return null; 21 | } 22 | 23 | public void set(int key, String value) { 24 | if (map.containsKey(key)) { 25 | Node old = map.get(key); 26 | old.value = value; 27 | remove(old); 28 | setHead(old); 29 | } else { 30 | Node node = new Node(key, value); 31 | if (map.size() >= capacity) { 32 | map.remove(tail.key); 33 | remove(tail); 34 | setHead(node); 35 | } else { 36 | setHead(node); 37 | } 38 | map.put(key, node); 39 | } 40 | } 41 | 42 | public void remove(Node node) { 43 | if (node == null) return; 44 | 45 | if (node.prev != null) node.prev.next = node.next; 46 | if (node.next != null) node.next.prev = node.prev; 47 | if (node == head) head = node.next; 48 | if (node == tail) tail = node.prev; 49 | } 50 | 51 | public void setHead(Node node) { 52 | if (head == null) { 53 | head = node; 54 | tail = node; 55 | } else { 56 | head.prev = node; 57 | node.next = head; 58 | head = node; 59 | } 60 | } 61 | 62 | public static class Node { 63 | public Node next; 64 | public Node prev; 65 | public int key; 66 | public String value; 67 | 68 | public Node(int k, String v) { 69 | this.key = k; 70 | this.value = v; 71 | } 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /ch16/16.07_-_Number_Max/NumberMax.java: -------------------------------------------------------------------------------- 1 | public class NumberMax { 2 | public static int max(int a, int b) { 3 | // if diff is negative, return b; 4 | int diff = a - b; 5 | 6 | // x = 1 if diff is negative (b > a) 7 | // x = 0 if diff is positive (a > b) 8 | int x = (diff >> 31) & 0x1; 9 | 10 | int max = a - x * diff; 11 | 12 | return max; 13 | } 14 | public static void main(String[] args) { 15 | System.out.println(max(28, 92)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ch16/16.24_-_Pairs_with_Sum/PairsWithSum.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class PairsWithSum { 4 | public static class Pair { 5 | public int p1; 6 | public int p2; 7 | public Pair(int p1, int p2) { 8 | this.p1 = p1; 9 | this.p2 = p2; 10 | } 11 | } 12 | public static List pairs(int[] nums, int sum) { 13 | List lst = new ArrayList(); 14 | Set set = new HashSet(); 15 | 16 | for (int i = 0; i < nums.length; i++) { 17 | if (set.contains(nums[i])) 18 | lst.add(new Pair(sum - nums[i], nums[i])); 19 | else 20 | set.add((sum - nums[i])); 21 | } 22 | return lst; 23 | } 24 | public static void main(String[] args) { 25 | List list = pairs(new int[]{1, 4, 2, 5, 6, 7, 0, 3}, 7); 26 | for (Pair pair : list) 27 | System.out.println(pair.p1 + " : " + pair.p2); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ch17/17.01_-_Add_Without_Plus/AddWithoutPlus.java: -------------------------------------------------------------------------------- 1 | public class AddWithoutPlus { 2 | public static int add(int a, int b) { 3 | if (b > a) { 4 | int temp = b; 5 | b = a; 6 | a = temp; 7 | } 8 | int carry = 0; 9 | while (b != 0) { 10 | carry = a & b; 11 | a = a ^ b; 12 | b = carry << 1; 13 | } 14 | return a; 15 | } 16 | 17 | public static int recursiveAdd(int a, int b) { 18 | if (b == 0) 19 | return a; 20 | else 21 | return recursiveAdd(a ^ b, (a & b) << 1); 22 | } 23 | 24 | public static void main(String[] args) { 25 | int a = 12; 26 | int b = 34; 27 | System.out.println(add(a, b)); 28 | System.out.println(recursiveAdd(b, a)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /ch17/17.10_-_Majority_Element/MajorityElement.java: -------------------------------------------------------------------------------- 1 | public class MajorityElement { 2 | public static int majority(int[] nums) { 3 | int count = 1; 4 | int majorityIndex = 0; 5 | for (int i = 1; i < nums.length; i++) { 6 | if (nums[i] == nums[majorityIndex]) 7 | count++; 8 | else 9 | count--; 10 | if (count == 0) { 11 | majorityIndex = i; 12 | count = 1; 13 | } 14 | } 15 | return nums[majorityIndex]; 16 | } 17 | public static void main(String[] args) { 18 | System.out.println(majority(new int[]{1, 2, 5, 5, 9, 5, 5, 3, 2})); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /count.sh: -------------------------------------------------------------------------------- 1 | totals=(9 8 6 12 8 10 9 14 8 11 6 11 8 7 7 26 26) 2 | chapters=(01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17) 3 | name=README.txt 4 | rm ${name} 5 | echo "Cracking the Coding Interview problems\n" >> ${name} 6 | for (( i=0; i<=16; i++ )) 7 | do 8 | #x=`echo */*/* | tr " " "\n" | grep -E "((ch${chapters[$i]}.*)(java|c|cpp|txt|md|sql)$)" | wc -l | bc` 9 | x=`echo */* | tr " " "\n" | grep -E "(ch${chapters[$i]}.*)" | wc -l | bc` 10 | echo "ch${chapters[$i]} - ${x} / ${totals[$i]}" >> ${name} 11 | done 12 | 13 | total=0 14 | for i in ${totals[@]}; do 15 | let total+=$i 16 | done 17 | 18 | echo "\nTotal" >> ${name} 19 | echo */* | tr ' ' '\n' | wc -l | bc | tr -d "\n" >> ${name} 20 | echo " / ${total} problems\n" >> ${name} 21 | 22 | echo "Feel free to submit your own solutions! All pull requests welcome!" >> ${name} 23 | 24 | cat ${name} 25 | --------------------------------------------------------------------------------