├── .classpath ├── .gitattributes ├── .gitignore ├── .project ├── Chp. 01 - Arrays and Strings ├── _1_1_Is_Unique │ ├── IsUnique.java │ └── Tester.java ├── _1_2_Check_Permutations │ ├── CheckPermutations.java │ └── Tester.java ├── _1_3_URLify │ ├── Tester.java │ └── URLify.java ├── _1_4_Palindrome_Permutation │ ├── PalindromePermutation.java │ └── Tester.java ├── _1_5_One_Away │ ├── OneAway.java │ └── Tester.java ├── _1_6_String_Compression │ ├── StringCompression.java │ └── Tester.java ├── _1_7_Rotate_Matrix │ ├── RotateMatrix.java │ └── Tester.java ├── _1_8_Zero_Matrix │ ├── Tester.java │ └── ZeroMatrix.java ├── _1_9_String_Rotation │ ├── StringRotation.java │ └── Tester.java ├── __Intro_ArrayList │ ├── IntroArrayList.java │ └── Tester.java └── __Intro_StringBuffer │ ├── IntroStringBuffer.java │ └── Tester.java ├── Chp. 02 - Linked Lists ├── _2_1_Remove_Dups │ ├── RemoveDups.java │ └── Tester.java ├── _2_2_Return_Kth_to_Last │ ├── ReturnKthToLast.java │ └── Tester.java ├── _2_3_Delete_Middle_Node │ ├── DeleteMiddleNode.java │ └── Tester.java ├── _2_4_Partition │ ├── Partition.java │ └── Tester.java ├── _2_5_Sum_Lists │ ├── SumLists.java │ └── Tester.java ├── _2_6_Palindrome │ ├── Palindrome.java │ └── Tester.java ├── _2_7_Intersection │ ├── Intersection.java │ └── Tester.java └── _2_8_Loop_Detection │ ├── LoopDetection.java │ └── Tester.java ├── Chp. 03 - Stacks and Queues ├── _3_1_Three_in_One │ ├── Tester.java │ └── ThreeInOne.java ├── _3_2_Stack_Min │ ├── StackMin.java │ └── Tester.java ├── _3_3_Stack_of_Plates │ ├── StackOfPlates.java │ └── Tester.java ├── _3_4_Queue_via_Stacks │ ├── QueueViaStacks.java │ └── Tester.java ├── _3_5_Sort_Stack │ ├── SortStack.java │ └── Tester.java ├── _3_6_Animal_Shelter │ ├── Animal.java │ ├── AnimalShelter.java │ ├── Cat.java │ ├── Dog.java │ └── Tester.java ├── __Intro_Queue │ ├── Queue.java │ └── Tester.java └── __Intro_Stack │ ├── Stack.java │ └── Tester.java ├── Chp. 04 - Trees and Graphs ├── _4_01_Route_Between_Nodes │ ├── RouteBetweenNodes.java │ └── Tester.java ├── _4_02_Minimal_Tree │ ├── MinimalTree.java │ └── Tester.java ├── _4_03_List_of_Depths │ ├── ListOfDepths.java │ └── Tester.java ├── _4_04_Check_Balanced │ ├── CheckBalanced.java │ └── Tester.java ├── _4_05_Validate_BST │ ├── Tester.java │ └── ValidateBST.java ├── _4_06_Successor │ ├── Successor.java │ └── Tester.java ├── _4_07_Build_Order │ ├── BuildOrder.java │ ├── Graph.java │ ├── Node.java │ ├── Tester.java │ └── Visited.java ├── _4_08_First_Common_Ancestor │ ├── FirstCommonAncestor.java │ └── Tester.java ├── _4_09_BST_Sequences │ ├── BSTSequences.java │ └── Tester.java ├── _4_10_Check_Subtree │ ├── CheckSubtree.java │ └── Tester.java ├── _4_11_Random_Node │ ├── BST.java │ ├── Node.java │ ├── RandomizedCollection.java │ └── Tester.java ├── _4_12_Paths_with_Sum │ ├── PathWithSums.java │ └── Tester.java ├── __Intro_BFS │ └── Tester.java ├── __Intro_DFS │ └── Tester.java ├── __Intro_InOrder_Traversal │ └── Tester.java ├── __Intro_LevelOrder_Traversal │ └── Tester.java ├── __Intro_PostOrder_Traversal │ └── Tester.java └── __Intro_PreOrder_Traversal │ └── Tester.java ├── Chp. 05 - Bit Manipulation ├── _5_1_Insertion │ ├── Insertion.java │ └── Tester.java ├── _5_2_Binary_to_String │ ├── BinaryToString.java │ └── Tester.java ├── _5_3_Flip_Bit_to_Win │ ├── FlipBitToWin.java │ └── Tester.java ├── _5_4_Next_Number │ ├── NextNumber.java │ └── Tester.java ├── _5_5_Debugger │ └── Debugger ├── _5_6_Conversion │ ├── Conversion.java │ └── Tester.java ├── _5_7_Pairwise_Swap │ ├── PairwiseSwap.java │ └── Tester.java └── _5_8_Draw_Line │ ├── DrawLine.java │ └── Tester.java ├── Chp. 06 - Math and Logic Puzzles ├── Intro_Notes └── __Intro_Prime │ ├── Prime.java │ └── Tester.java ├── Chp. 07 - Object-Oriented Design ├── _7_01_Deck_of_Cards │ ├── BlackjackCard.java │ ├── BlackjackHand.java │ ├── Card.java │ ├── Color.java │ ├── Deck.java │ ├── Hand.java │ ├── Rank.java │ └── Suit.java ├── _7_02_Call_Center │ └── CallCenter ├── _7_03_Jukebox │ └── Jukebox ├── _7_04_Parking_Lot │ └── ParkingLot ├── _7_05_Online_Book_Reader │ └── OnlineBookReader ├── _7_06_Jigsaw │ └── Jigsaw ├── _7_07_Chat_Server │ └── ChatServer ├── _7_08_Othello │ └── Othello ├── _7_09_Circular_Array │ └── CircularArray.java ├── _7_11_File_System │ └── FileSystem └── _7_12_Hash_Table │ ├── Cell.java │ ├── Hash.java │ └── Main.java ├── Chp. 08 - Recursion and Dynamic Programming ├── _8_01_Triple_Step │ ├── Tester.java │ └── TripleStep.java ├── _8_02_Robot_in_a_Grid │ ├── Point.java │ ├── RobotInAGrid.java │ └── Tester.java ├── _8_03_Magic_Index │ ├── MagicIndex.java │ └── Tester.java ├── _8_04_Power_Set │ ├── PowerSet.java │ └── Tester.java ├── _8_05_Recursive_Multiply │ ├── RecursiveMultiply.java │ └── Tester.java ├── _8_06_Towers_of_Hanoi │ ├── Tester.java │ ├── Tower.java │ └── TowersOfHanoi.java ├── _8_07_Permutations_without_Dups │ ├── PermutationsWithoutDups.java │ └── Tester.java ├── _8_08_Permutations_with_Dups │ ├── PermutationsWithDups.java │ └── Tester.java ├── _8_09_Parens │ ├── Parens.java │ └── Tester.java ├── _8_10_Paint_Fill │ ├── Color.java │ └── PaintFill.java ├── _8_11_Coins │ ├── Coins.java │ └── Tester.java ├── _8_12_Eight_Queens │ ├── EightQueens.java │ └── Tester.java ├── _8_13_Stack_of_Boxes │ ├── Box.java │ ├── StackOfBoxes.java │ └── Tester.java ├── _8_14_Boolean_Evaluation │ ├── BooleanEvaluation.java │ └── Tester.java └── __Intro_Fibonacci │ ├── Fibonacci.java │ └── Tester.java ├── Chp. 09 - System Design and Scalability ├── 9_1_Stock_Data ├── 9_2_Social_Network ├── 9_3_Web_Crawler ├── 9_4_Duplicate_URLs ├── 9_5_Cache ├── _Intro_4_ways_to_divide_data └── _Intro_Find_words_in_millions_of_documents ├── Chp. 10 - Sorting and Searching ├── _10_01_Sorted_Merge │ ├── SortedMerge.java │ └── Tester.java ├── _10_02_Group_Anagrams │ ├── GroupAnagrams.java │ └── Tester.java ├── _10_03_Search_in_Rotated_Array │ ├── SearchInRotatedArray.java │ └── Tester.java ├── _10_04_Sorted_Search_No_Size │ ├── Listy.java │ ├── SortedSearchNoSize.java │ └── Tester.java ├── _10_05_Sparse_Search │ ├── SparseSearch.java │ └── Tester.java ├── _10_06_Sort_Big_File │ └── SortBigFile ├── _10_07_Missing_Int │ ├── MissingInt.java │ ├── MyBitSet.java │ ├── Tester.java │ └── numbers ├── _10_08_Find_Duplicates │ ├── FindDuplicates.java │ └── Tester.java ├── _10_09_Sorted_Matrix_Search │ ├── SortedMatrixSearch.java │ └── Tester.java ├── _10_10_Rank_from_Stream │ ├── RankFromStream.java │ ├── RankNode.java │ └── Tester.java ├── _10_11_Peaks_and_Valleys │ ├── PeaksAndValleys.java │ └── Tester.java ├── __Intro_Binary_Search │ ├── BinarySearch.java │ └── Tester.java └── __Intro_Sorts │ ├── Sorts.java │ └── Tester.java ├── Chp. 11 - Testing ├── 11_2_Random_Crashes ├── 11_4_No_Test_Tools └── _General_Tips ├── Chp. 13 - Java ├── _13_1_Private_Constructor │ └── PrivateConstructor ├── _13_2_Return_From_Finally │ └── ReturnFromFinally └── _13_5_TreeMap_HashMap_LinkedHashMap │ └── _TreeMap_HashMap_LinkedHashMap ├── Chp. 15 - Threads and Locks ├── _15_1_Thread_vs_Process │ └── ThreadVsProcess ├── _15_2_Context_Switch │ └── ThreadVsProcess ├── _15_3_Dining_Philosophers │ ├── Chopstick.java │ ├── Philosopher.java │ └── Tester.java ├── _15_4_Deadlock_Free_Class │ └── DeadlockFreeClass ├── _15_5_Call_In_Order │ ├── CallInOrder.java │ ├── MyThread.java │ └── Tester.java ├── _15_6_Synchronized_Methods │ └── SynchronizedMethods └── __Intro_Examples │ ├── LockedATM.java │ ├── Main.java │ ├── MyClass.java │ ├── MyObject.java │ ├── RunnableThreadExample.java │ └── ThreadExample.java ├── Chp. 16 - More Problems (Moderate) ├── _16_01_Number_Swapper │ ├── NumberSwapper.java │ └── Tester.java ├── _16_02_Word_Frequencies │ └── WordFrequencies ├── _16_03_Intersection │ └── Tester.java ├── _16_04_Tic_Tac_Win │ ├── Tester.java │ └── TicTacWin.java ├── _16_05_Factorial_Zeros │ ├── FactorialZeros.java │ └── Tester.java ├── _16_06_Smallest_Difference │ ├── SmallestDifference.java │ └── Tester.java ├── _16_07_Number_Max │ ├── NumberMax.java │ └── Tester.java ├── _16_08_English_Int │ ├── EnglishInt.java │ └── Tester.java ├── _16_09_Operations │ ├── Operations.java │ └── Tester.java ├── _16_10_Living_People │ ├── LivingPeople.java │ ├── Person.java │ └── Tester.java ├── _16_11_Diving_Board │ ├── DivingBoard.java │ └── Tester.java ├── _16_12_XML_Encoding │ └── DeadlockFreeClass ├── _16_13_Bisect_Squares │ └── BisectSquares ├── _16_14_Best_Line │ ├── BestLine.java │ └── Tester.java ├── _16_15_Master_Mind │ ├── MasterMind.java │ ├── Result.java │ └── Tester.java ├── _16_16_Sub_Sort │ ├── SubSort.java │ └── Tester.java ├── _16_17_Contiguous_Sequence │ ├── ContiguousSequence.java │ └── Tester.java ├── _16_18_Pattern_Matching │ ├── PatternMatching.java │ └── Tester.java ├── _16_19_Pond_Sizes │ ├── PondSizes.java │ └── Tester.java ├── _16_20_T9__HashMap_Solution │ ├── T9.java │ └── Tester.java ├── _16_20_T9__Trie_Solution │ ├── T9.java │ ├── Tester.java │ ├── Trie.java │ └── TrieNode.java ├── _16_21_Sum_Swap │ ├── SumSwap.java │ └── Tester.java ├── _16_22_Langtons_Ant │ └── LangtonsAnt ├── _16_23_Rand7_from_Rand5 │ └── Rand7FromRand5.java ├── _16_24_Pairs_with_Sum │ ├── Pair.java │ ├── PairsWithSum.java │ └── Tester.java ├── _16_25_LRU_Cache │ ├── DoublyLinkedList.java │ ├── LRUCache.java │ ├── Node.java │ └── Tester.java └── _16_26_Calculator │ ├── Calculator.java │ └── Tester.java ├── Chp. 17 - More Problems (Hard) ├── _17_01_Add_Without_Plus │ ├── AddWithoutPlus.java │ └── Tester.java ├── _17_02_Shuffle │ └── Shuffle.java ├── _17_03_Random_Set │ └── RandomSet.java ├── _17_04_Missing_Number │ ├── MissingNumber.java │ └── Tester.java ├── _17_05_Letters_and_Numbers │ ├── LettersAndNumbers.java │ └── Tester.java ├── _17_06_Count_of_2s │ ├── CountOf2s.java │ └── Tester.java ├── _17_07_Baby_Names │ └── BabyNames ├── _17_08_Circus_Tower │ ├── CircusTower │ ├── CircusTower.java │ └── Tester.java ├── _17_09_Kth_Multiple │ ├── KthMultiple.java │ └── Tester.java ├── _17_10_Majority_Element │ ├── MajorityElement.java │ └── Tester.java ├── _17_11_Word_Distance │ ├── Pair.java │ ├── Tester.java │ └── WordDistance.java ├── _17_12_BiNode │ ├── BiNode.java │ ├── Converter.java │ ├── NodePair.java │ └── Tester.java ├── _17_13_ReSpace │ └── ReSpace ├── _17_14_Smallest_K │ ├── SmallestK.java │ └── Tester.java ├── _17_15_Longest_Word │ ├── LongestWord.java │ └── Tester.java ├── _17_16_The_Masseuse │ ├── Tester.java │ └── TheMasseuse.java ├── _17_17_Multi_Search │ └── MultiSearch ├── _17_18_Shortest_Supersequence │ ├── HeapNode.java │ ├── Range.java │ ├── ShortestSupersequence.java │ └── Tester.java ├── _17_19_Missing_Two │ └── MissingTwo ├── _17_20_Continuous_Median │ ├── ContinuousMedian.java │ └── Tester.java ├── _17_21_Volume_of_Histogram │ ├── Tester.java │ └── VolumeOfHistogram.java ├── _17_22_Word_Transformer │ ├── Tester.java │ └── WordTransformer.java ├── _17_23_Max_Black_Square │ ├── Cell.java │ ├── MaxBlackSquare.java │ ├── Subsquare.java │ └── Tester.java ├── _17_24_Max_Submatrix │ ├── MaxSubmatrix.java │ └── Tester.java ├── _17_25_Word_Rectangle │ └── WordRectangle └── _17_26_Sparse_Similarity │ └── SparseSimilarity ├── Common └── common │ ├── BitFunctions.java │ ├── Functions.java │ ├── GraphFunctions.java │ ├── GraphNode.java │ ├── Line.java │ ├── LineFunctions.java │ ├── ListFunctions.java │ ├── Node.java │ ├── Point.java │ ├── TreeFunctions.java │ └── TreeNode.java ├── Introduction └── introduction │ ├── ABCD.java │ ├── Pair.java │ └── Tester.java ├── README.md └── screenshots ├── instructions_1.png ├── instructions_2.png ├── instructions_3.png ├── instructions_4.png └── instructions_5.png /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Rodney: I changed this file below so that Github gets my .project and .classpath files 2 | 3 | .metadata 4 | bin/ 5 | tmp/ 6 | *.tmp 7 | *.bak 8 | *.swp 9 | *~.nib 10 | local.properties 11 | .settings/ 12 | .loadpath 13 | .recommenders 14 | 15 | # Eclipse Core 16 | # .project 17 | 18 | # External tool builders 19 | .externalToolBuilders/ 20 | 21 | # Locally stored "Eclipse launch configurations" 22 | *.launch 23 | 24 | # PyDev specific (Python IDE for Eclipse) 25 | *.pydevproject 26 | 27 | # CDT-specific (C/C++ Development Tooling) 28 | .cproject 29 | 30 | # JDT-specific (Eclipse Java Development Tools) 31 | # .classpath 32 | 33 | # Java annotation processor (APT) 34 | .factorypath 35 | 36 | # PDT-specific (PHP Development Tools) 37 | .buildpath 38 | 39 | # sbteclipse plugin 40 | .target 41 | 42 | # Tern plugin 43 | .tern-project 44 | 45 | # TeXlipse plugin 46 | .texlipse 47 | 48 | # STS (Spring Tool Suite) 49 | .springBeans 50 | 51 | # Code Recommenders 52 | .recommenders/ -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Cracking-the-Coding-Interview_solutions 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /Chp. 01 - Arrays and Strings/_1_1_Is_Unique/IsUnique.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _1_1_Is_Unique; 4 | 5 | import java.util.HashSet; 6 | 7 | // Should ask interviewer if String is ASCII or Unicode (We assume ASCII) 8 | 9 | public class IsUnique { 10 | private static final int NUM_ASCII_CHARS = 256; // number of ASCII characters 11 | 12 | public static boolean uniqueCharacters(String str) { 13 | if (str.length() > NUM_ASCII_CHARS) { 14 | return false; 15 | } 16 | HashSet mySet = new HashSet(NUM_ASCII_CHARS); 17 | for (int i = 0; i < str.length(); i++) { 18 | if (mySet.contains(str.charAt(i))) { 19 | return false; 20 | } else { 21 | mySet.add(str.charAt(i)); 22 | } 23 | } 24 | return true; 25 | } 26 | } 27 | 28 | // Time Complexity: O(1) 29 | // Space Complexity: O(1) 30 | // Checking for str.length() > 256 lowered our time/space complexity from O(n) to O(1) 31 | 32 | // Follow-up Question: What if we're not allowed to use additional data structures? 33 | // 34 | // Answer: Can do brute-force solution by comparing all pairs 35 | // Time Complexity: O(1) since String is max 256 characters. Without this bound it would be O(n^2) 36 | // Space Complexity: O(1) 37 | -------------------------------------------------------------------------------- /Chp. 01 - Arrays and Strings/_1_1_Is_Unique/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _1_1_Is_Unique; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 1.1: Unique characters?\n"); 8 | test("Benny"); 9 | test("Ben"); 10 | test("Alex"); 11 | } 12 | 13 | private static void test(String str) { 14 | System.out.format("%8s: %s%n", str, IsUnique.uniqueCharacters(str)); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Chp. 01 - Arrays and Strings/_1_2_Check_Permutations/CheckPermutations.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _1_2_Check_Permutations; 4 | 5 | import java.util.HashMap; 6 | 7 | // Should ask interviewer if String is ASCII or Unicode (We assume ASCII) 8 | 9 | // Algorithm 10 | // 11 | // Do a quick check on string lengths. If the lengths differ, the strings can't be anagrams 12 | // Save `String s` as `HashMap` of character counts 13 | // For `String t`, see if it can be made up of the characters of the previous `HashMap` 14 | 15 | public class CheckPermutations { 16 | 17 | private static final int NUM_ASCII_CHARS = 256; 18 | 19 | public static boolean isPermutation(String s, String t) { 20 | if (s.length() != t.length()) { 21 | return false; 22 | } 23 | HashMap map = new HashMap(NUM_ASCII_CHARS); 24 | for (int i = 0; i < s.length(); i++) { 25 | char ch = s.charAt(i); 26 | map.merge(ch, 1, Integer::sum); 27 | } 28 | for (int i = 0; i < t.length(); i++) { 29 | char ch = t.charAt(i); 30 | if (!map.containsKey(ch) || map.get(ch) == 0) { 31 | return false; 32 | } 33 | map.merge(ch, -1, Integer::sum); 34 | } 35 | return true; 36 | } 37 | } 38 | 39 | // Time Complexity: O(n) 40 | // Space Complexity: O(1) 41 | -------------------------------------------------------------------------------- /Chp. 01 - Arrays and Strings/_1_2_Check_Permutations/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _1_2_Check_Permutations; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 1.2: Check Permutations\n"); 8 | test("hello", "olhel"); 9 | test("james", "bean"); 10 | } 11 | 12 | private static void test(String s1, String s2) { 13 | System.out.format("%s, %s: %s\n", s1, s2, CheckPermutations.isPermutation(s1, s2)); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Chp. 01 - Arrays and Strings/_1_3_URLify/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _1_3_URLify; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 1.3: URLify\n"); 8 | URLifyHelper("Ben is smart ", 12); 9 | } 10 | 11 | private static void URLifyHelper(String str, int trueLength) { 12 | char[] sentence = str.toCharArray(); 13 | System.out.println(sentence); 14 | URLify.replaceWhitespace(sentence, trueLength); 15 | System.out.println(sentence); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chp. 01 - Arrays and Strings/_1_3_URLify/URLify.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _1_3_URLify; 4 | 5 | public class URLify { 6 | public static void replaceWhitespace(char[] sentence, int trueLength) { 7 | /* Count number of spaces */ 8 | int numSpaces = 0; 9 | for (int i = 0; i < trueLength; i++) { 10 | if (sentence[i] == ' ') { 11 | numSpaces++; 12 | } 13 | } 14 | /* Replace each space with %20 */ 15 | if (numSpaces > 0) { 16 | int j = trueLength - 1 + numSpaces * 2; // adds an additional 2 spots for each space. 17 | for (int i = trueLength - 1; i >= 0; i--) { 18 | if (sentence[i] == ' ') { 19 | sentence[j-2] = '%'; 20 | sentence[j-1] = '2'; 21 | sentence[j] = '0'; 22 | j = j - 3; 23 | } else { 24 | sentence[j] = sentence[i]; 25 | j--; 26 | } 27 | } 28 | } 29 | } 30 | } 31 | 32 | // Time Complexity: O(n) 33 | // Space Complexity: O(1) 34 | -------------------------------------------------------------------------------- /Chp. 01 - Arrays and Strings/_1_4_Palindrome_Permutation/PalindromePermutation.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _1_4_Palindrome_Permutation; 4 | 5 | import java.util.*; 6 | 7 | public class PalindromePermutation { 8 | 9 | private static final int NUM_LOWERCASE_LETTERS = 26; 10 | 11 | public static boolean palPerm(String str) { 12 | str = str.toLowerCase().replaceAll("\\s", ""); 13 | Map map = new HashMap(NUM_LOWERCASE_LETTERS); 14 | for (int i = 0; i < str.length(); i++) { 15 | Character ch = str.charAt(i); 16 | if (Character.isLetter(ch)) { 17 | map.merge(ch, 1, Integer::sum); 18 | } 19 | } 20 | 21 | // Odd length strings: Can have at most 1 character an odd # of times 22 | // Even length strings: Can have either 0,2,4,6... number of odd characters. 23 | // Anything above 1 means not a palindrome. 24 | int oddCount = 0; 25 | for (Integer value : map.values()) { 26 | if (value % 2 != 0) { 27 | oddCount++; 28 | } 29 | if (oddCount > 1) { 30 | return false; 31 | } 32 | } 33 | return true; 34 | } 35 | } 36 | 37 | // Time Complexity: O(n) 38 | // Space Complexity: O(1) 39 | -------------------------------------------------------------------------------- /Chp. 01 - Arrays and Strings/_1_4_Palindrome_Permutation/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _1_4_Palindrome_Permutation; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 1.4: Palindrome Permutation\n"); 8 | test("Tact Coa"); 9 | test("race the car"); 10 | } 11 | 12 | private static void test(String str) { 13 | System.out.println(str + ": " + PalindromePermutation.palPerm(str)); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Chp. 01 - Arrays and Strings/_1_5_One_Away/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _1_5_One_Away; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 1.5: One Away\n"); 8 | test("pale", "ple"); 9 | test("pales", "pale"); 10 | test("pale", "bale"); 11 | test("pale", "bake"); 12 | } 13 | 14 | private static void test(String s1, String s2) { 15 | System.out.format("%5s,%5s -- %s%n", s1, s2, OneAway.oneAway(s1, s2)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chp. 01 - Arrays and Strings/_1_6_String_Compression/StringCompression.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _1_6_String_Compression; 4 | 5 | // Time Complexity: O(n) 6 | // Space Complexity: O(n) 7 | 8 | public class StringCompression { 9 | public static String basicCompression(String str) { 10 | StringBuffer sb = new StringBuffer(); // StringBuffer has efficient "append" that String doesn't have 11 | int numSame = 1; 12 | for (int i = 1; i < str.length(); i++) { 13 | char prev = str.charAt(i-1); 14 | char curr = str.charAt(i); 15 | if (prev == curr) { 16 | numSame++; 17 | } else { 18 | sb.append(prev); 19 | sb.append(String.valueOf(numSame)); 20 | numSame = 1; 21 | } 22 | } 23 | 24 | // Accounts for last character 25 | sb.append(str.charAt(str.length() - 1)); 26 | sb.append(String.valueOf(numSame)); 27 | 28 | return sb.length() < str.length() ? sb.toString() : str; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Chp. 01 - Arrays and Strings/_1_6_String_Compression/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _1_6_String_Compression; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 1.6: String Compression\n"); 8 | test("aabcccccaaa"); 9 | test("abababa"); 10 | } 11 | 12 | private static void test(String original) { 13 | System.out.println(" Original string: " + original); 14 | String compressed = StringCompression.basicCompression(original); 15 | System.out.println("Compressed string: " + compressed + "\n"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chp. 01 - Arrays and Strings/_1_8_Zero_Matrix/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _1_8_Zero_Matrix; 4 | 5 | import common.Functions; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** Test 1.8: Zero Matrix\n"); 10 | int[][] matrix1 = {{ 1, 2, 3, 1 }, 11 | { 4, 5, 6, 0 }, 12 | { 0, 5, 3, 0 }}; 13 | 14 | int[][] matrix2 = {{ 1, 2, 3, 1 }, 15 | { 4, 5, 6, 0 }, 16 | { 0, 5, 3, 0 }}; 17 | 18 | testMatrix(matrix1); 19 | testMatrix(matrix2); 20 | } 21 | 22 | private static void testMatrix(int[][] matrix) { 23 | System.out.println("Original matrix"); 24 | Functions.printImage(matrix); // uses print function above in 1.6 25 | System.out.println("Zero out necessary rows/columns"); 26 | ZeroMatrix.solution1(matrix); 27 | Functions.printImage(matrix); 28 | System.out.println(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Chp. 01 - Arrays and Strings/_1_9_String_Rotation/StringRotation.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _1_9_String_Rotation; 4 | 5 | public class StringRotation { 6 | public static boolean isRotation(String s1, String s2) { 7 | if (s1.length() != s2.length()) { 8 | return false; 9 | } 10 | String doubledString = s1 + s1; 11 | return doubledString.contains(s2); 12 | } 13 | } 14 | 15 | // Time/Space Complexities are same as .contains() function 16 | // If .contains() is implemented using the "KMP algorithm" then we will have: 17 | // 18 | // Time Complexity: O(n) 19 | // Space Complexity: O(1) 20 | -------------------------------------------------------------------------------- /Chp. 01 - Arrays and Strings/_1_9_String_Rotation/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _1_9_String_Rotation; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 1.9: String Rotation\n"); 8 | test("waterbottle", "erbottlewat"); 9 | test("", "erbottlewat"); 10 | test("tooth", "candy"); 11 | } 12 | 13 | private static void test(String s1, String s2) { 14 | System.out.println(s1 + ", " + s2 + " --> " + StringRotation.isRotation(s1, s2)); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Chp. 01 - Arrays and Strings/__Intro_ArrayList/IntroArrayList.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package __Intro_ArrayList; 4 | 5 | import java.util.ArrayList; 6 | 7 | public class IntroArrayList { 8 | /* Merges 2 arrays into an ArrayList */ 9 | public static ArrayList merge(String[] words, String[] moreWords) { 10 | ArrayList result = new ArrayList(); 11 | for (String word : words) { 12 | result.add(word); 13 | } 14 | for (String word : moreWords) { 15 | result.add(word); 16 | } 17 | return result; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Chp. 01 - Arrays and Strings/__Intro_ArrayList/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package __Intro_ArrayList; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test ArrayList\n"); 8 | test(new String[]{ "Hi", "there" }, new String[]{ "Robert", "Jones" }); 9 | } 10 | 11 | private static void test(String[] strings1, String[] strings2) { 12 | System.out.println(IntroArrayList.merge(strings1, strings2)); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Chp. 01 - Arrays and Strings/__Intro_StringBuffer/IntroStringBuffer.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package __Intro_StringBuffer; 4 | 5 | public class IntroStringBuffer { 6 | /* 7 | * Joins an array of strings into 1 string. Uses StringBuffer for efficiency 8 | */ 9 | public static String joinWords(String[] strings) { 10 | StringBuffer sentence = new StringBuffer(); 11 | for (String string : strings) { 12 | sentence.append(string); 13 | } 14 | return sentence.toString(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Chp. 01 - Arrays and Strings/__Intro_StringBuffer/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package __Intro_StringBuffer; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | test(new String[]{ "Hi ", "there ", "Rob. ", "How ", "are ", "you?" }); 8 | } 9 | 10 | private static void test(String[] strings) { 11 | System.out.println(IntroStringBuffer.joinWords(strings)); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Chp. 02 - Linked Lists/_2_1_Remove_Dups/RemoveDups.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _2_1_Remove_Dups; 4 | 5 | import java.util.*; 6 | import common.Node; 7 | 8 | public class RemoveDups { 9 | static void removeDuplicates(Node head) { 10 | Set set = new HashSet(); 11 | set.add(head.data); 12 | Node n = head; 13 | while (n.next != null) { 14 | if (set.contains(n.next.data)) { 15 | n.next = n.next.next; 16 | } else { 17 | set.add(n.next.data); 18 | n = n.next; 19 | } 20 | } 21 | return; 22 | } 23 | } 24 | 25 | // Time Complexity: O(n) 26 | // Space Complexity: O(n) 27 | 28 | // Alternate solution: Brute-force compare all pairs (Advantage is low space complexity) 29 | // Use 1 pointer to walk list, and another pointer to check all remaining nodes each time 30 | // Time Complexity: O(n^2) 31 | // Space Complexity: O(1) 32 | -------------------------------------------------------------------------------- /Chp. 02 - Linked Lists/_2_1_Remove_Dups/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _2_1_Remove_Dups; 4 | 5 | import common.Node; 6 | import common.ListFunctions; 7 | 8 | public class Tester { 9 | public static void main(String[] args) { 10 | System.out.println("*** Test 2.1: Remove Dups\n"); 11 | test(new Node(new int[]{ 9, 9, 9, 9 })); 12 | test(new Node(new int[]{ 5, 7, 7, 3, 7, 6, 7, 5 })); 13 | } 14 | 15 | private static void test(Node head) { 16 | ListFunctions.printList(head); 17 | RemoveDups.removeDuplicates(head); 18 | ListFunctions.printList(head); 19 | System.out.println(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Chp. 02 - Linked Lists/_2_2_Return_Kth_to_Last/ReturnKthToLast.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _2_2_Return_Kth_to_Last; 4 | 5 | import common.Node; 6 | import common.ListFunctions; 7 | 8 | // Algorithm: Just calculate the size of the SLL, then walk "size - k" elements into list 9 | 10 | public class ReturnKthToLast { 11 | public static Node kthLast(Node n, int k) { 12 | int size = ListFunctions.calculateSize(n); 13 | if (k <= 0 || k > size) { 14 | return null; 15 | } 16 | for (int i = 0; i < size - k; i++) { 17 | n = n.next; 18 | } 19 | return n; 20 | } 21 | } 22 | 23 | // Time Complexity: O(n) 24 | // Space Complexity: O(1) 25 | -------------------------------------------------------------------------------- /Chp. 02 - Linked Lists/_2_2_Return_Kth_to_Last/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _2_2_Return_Kth_to_Last; 4 | 5 | import common.Node; 6 | import common.ListFunctions; 7 | 8 | public class Tester { 9 | public static void main(String[] args) { 10 | System.out.println("*** Test 2.2: Return Kth to Last\n"); 11 | System.out.println("we count starting from 1 (not 0), so last element is element #1\n"); 12 | test(new Node(new int[]{ 5, 6, 4, 9 }), 2); 13 | test(new Node(new int[]{ 6, 2, 1, 4 }), 5); 14 | } 15 | 16 | private static void test(Node head, int k) { 17 | ListFunctions.printList(head); 18 | Node m = ReturnKthToLast.kthLast(head, k); 19 | if (m != null) { 20 | System.out.format("Element %d from end = %d%n%n", k, m.data); 21 | } else { 22 | System.out.format("k = %d is outside of range%n", k); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Chp. 02 - Linked Lists/_2_3_Delete_Middle_Node/DeleteMiddleNode.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _2_3_Delete_Middle_Node; 4 | 5 | import common.Node; 6 | 7 | public class DeleteMiddleNode { 8 | public static boolean deleteMid(Node n) { 9 | if (n == null || n.next == null) { // this algorithm only works if we are deleting an element that's not the last element. 10 | return false; // Otherwise, we can maybe just mark that last element as a "Dummy", according to textbook. 11 | } 12 | n.data = n.next.data; 13 | n.next = n.next.next; 14 | return true; 15 | } 16 | } 17 | 18 | // Time Complexity: O(1) - simply move the data 19 | -------------------------------------------------------------------------------- /Chp. 02 - Linked Lists/_2_3_Delete_Middle_Node/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _2_3_Delete_Middle_Node; 4 | 5 | import common.Node; 6 | import common.ListFunctions; 7 | 8 | public class Tester { 9 | public static void main(String[] args) { 10 | System.out.println("*** Test 2.3: Delete Middle Node"); 11 | test(new Node(new int[]{ 6, 7, 8, 9 })); 12 | test(new Node(new int[]{ 6, 7, 8, 9, 10 })); 13 | } 14 | 15 | private static void test(Node head) { 16 | System.out.println(); 17 | ListFunctions.printList(head); 18 | DeleteMiddleNode.deleteMid(head.next.next); 19 | ListFunctions.printList(head); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Chp. 02 - Linked Lists/_2_4_Partition/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _2_4_Partition; 4 | 5 | import common.Node; 6 | import common.ListFunctions; 7 | 8 | public class Tester { 9 | public static void main(String[] args) { 10 | System.out.println("*** Test 2.4: Partition"); 11 | test(new Node(new int[]{ 6, 3, 4, 8, 2 }), 5); 12 | test(new Node(new int[]{ 4, 8, 6, 7, 9, 2, 1 }), 3); 13 | } 14 | 15 | private static void test(Node head, int partitionValue) { 16 | System.out.print("\nOriginal List: "); 17 | ListFunctions.printList(head); 18 | System.out.print("Partition value: " + partitionValue + "\n"); 19 | 20 | System.out.print("Solution 1: "); 21 | head = Partition.partition(head, partitionValue); 22 | ListFunctions.printList(head); 23 | 24 | System.out.print("Solution 2: "); 25 | head = Partition.partition2(head, partitionValue); 26 | ListFunctions.printList(head); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Chp. 02 - Linked Lists/_2_5_Sum_Lists/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _2_5_Sum_Lists; 4 | 5 | import common.Node; 6 | import common.ListFunctions; 7 | 8 | public class Tester { 9 | public static void main(String[] args) { 10 | System.out.println("*** Test 2.5: Sum Lists"); 11 | 12 | /* Part 1 - Reverse Order */ 13 | testReverse(new Node(new int[]{ 6, 3, 4, 8, 2 }), new Node(new int[]{ 7, 1, 3 })); 14 | testReverse(new Node(new int[]{ 9, 4 }), new Node(new int[]{ 7, 7 })); 15 | 16 | /* Part 2 - Forward Order */ 17 | testForward(new Node(new int[]{ 3, 3, 4 }), new Node(new int[]{ 7, 6, 8, 7 })); 18 | testForward(new Node(new int[]{ 3, 9 }), new Node(new int[]{ 7, 5 })); 19 | } 20 | 21 | private static void testReverse(Node num1_head, Node num2_head) { 22 | System.out.println("\nPart 1 - Reverse Order"); 23 | ListFunctions.printList(num1_head); 24 | ListFunctions.printList(num2_head); 25 | Node sum = SumLists.addReverseOrder(num1_head, num2_head); 26 | ListFunctions.printList(sum); 27 | } 28 | 29 | private static void testForward(Node num1_head, Node num2_head) { 30 | System.out.println("\nPart 2 - Forward Order"); 31 | ListFunctions.printList(num1_head); 32 | ListFunctions.printList(num2_head); 33 | Node sum = SumLists.addForwardOrder(num1_head, num2_head); 34 | ListFunctions.printList(sum); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Chp. 02 - Linked Lists/_2_6_Palindrome/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _2_6_Palindrome; 4 | 5 | import common.Node; 6 | import common.ListFunctions; 7 | 8 | public class Tester { 9 | public static void main(String[] args) { 10 | System.out.println("*** Test 2.6: Palindrome\n"); 11 | test(new Node(new int[]{ 1, 2, 3, 4 })); 12 | test(new Node(new int[]{ 1, 2, 3, 4, 3, 2, 1 })); 13 | test(new Node(new int[]{ 1, 2, 2, 1 })); 14 | test(new Node(new int[]{ 1, 2, 2, 1, 8, 2, 1 })); 15 | } 16 | 17 | private static void test(Node head) { 18 | ListFunctions.printList(head); 19 | System.out.println("Palindrome? " + Palindrome.palindrome(head) + "\n"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Chp. 02 - Linked Lists/_2_7_Intersection/Intersection.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _2_7_Intersection; 4 | 5 | import common.Node; 6 | 7 | // Let "tail" refer to the first null at the end of the list. 8 | // Create a pointer that iterates through a list. 9 | // When it's at the tail of the list, have it jump to the beginning of the other list. 10 | // Create 2 of these pointers, pointing to 2 different list heads. 11 | // The pointers will collide at the merge point after 1 or 2 passes. 12 | // If they don't collide after 2 passes, then they will both be null, and there is no merge point. 13 | 14 | public class Intersection { 15 | public static Integer findMergeNode(Node headA, Node headB) { 16 | if (headA == null || headB == null) { 17 | return null; 18 | } 19 | Node a = headA; 20 | Node b = headB; 21 | 22 | while (a != b) { 23 | a = (a == null) ? headB : a.next; 24 | b = (b == null) ? headA : b.next; 25 | } 26 | return a == null ? null: a.data; 27 | } 28 | } 29 | 30 | // Time Complexity: O(n) 31 | // Space Complexity: O(1) 32 | -------------------------------------------------------------------------------- /Chp. 02 - Linked Lists/_2_7_Intersection/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _2_7_Intersection; 4 | 5 | import common.Node; 6 | import common.ListFunctions; 7 | 8 | public class Tester { 9 | public static void main(String[] args) { 10 | System.out.println("*** Test 2.7: Intersection\n"); 11 | 12 | /* Test 1 */ 13 | Node head1 = new Node(new int[]{ 3, 1, 5, 9 }); 14 | Node head2 = new Node(new int[]{ 4, 6 }); 15 | Node rest = new Node(new int[]{ 7, 2, 1 }); 16 | head1.appendToTail(rest); 17 | head2.appendToTail(rest); 18 | test(head1, head2); 19 | 20 | /* Test 2 */ 21 | head1 = new Node(new int[]{ 3, 1, 5, 9, 7, 2, 1 }); 22 | head2 = new Node(new int[]{ 4, 6, }); 23 | test(head1, head2); 24 | } 25 | 26 | private static void test(Node head1, Node head2) { 27 | ListFunctions.printList(head1); 28 | ListFunctions.printList(head2); 29 | System.out.println("Intersection: " + Intersection.findMergeNode(head1, head2) + "\n"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Chp. 02 - Linked Lists/_2_8_Loop_Detection/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _2_8_Loop_Detection; 4 | 5 | import common.Node; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** Test 2.8: Loop Detection\n"); 10 | Node a1 = new Node(1); 11 | Node a2 = new Node(2); // will be beginning of loop. 12 | Node a3 = new Node(3); 13 | Node a4 = new Node(4); 14 | a1.next = a2; 15 | a2.next = a3; 16 | a3.next = a4; 17 | a4.next = a2; // a4 points to beginning of loop (a2). 18 | test(a1); 19 | } 20 | 21 | private static void test(Node head) { 22 | Node loopBeginning = LoopDetection.findBeginning(head); 23 | System.out.println("Loop Beginning Value (Should be 2): " + loopBeginning.data); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Chp. 03 - Stacks and Queues/_3_1_Three_in_One/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _3_1_Three_in_One; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.print("*** Test 3.1: Three in One\n"); 8 | ThreeInOne stacks = new ThreeInOne(); 9 | try { 10 | stacks.push(1, 0); 11 | stacks.push(2, 0); 12 | stacks.push(3, 0); 13 | stacks.push(4, 1); 14 | stacks.push(5, 1); 15 | stacks.push(6, 1); 16 | stacks.push(7, 2); 17 | stacks.push(8, 2); 18 | stacks.push(9, 2); 19 | } catch (Exception e) { 20 | System.out.println(e.getMessage()); 21 | } 22 | stacks.print(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Chp. 03 - Stacks and Queues/_3_2_Stack_Min/StackMin.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _3_2_Stack_Min; 4 | 5 | import java.util.Stack; 6 | 7 | public class StackMin { 8 | // Can alternatively use ArrayDeque (it's faster) 9 | Stack stack = new Stack(); 10 | Stack minStack = new Stack(); // keeps track of minimums 11 | 12 | // Always push onto stack. If it's a minimum, also push it onto minStack 13 | void push(int x) { 14 | stack.push(x); 15 | if (min() == null || x <= min()) { 16 | minStack.push(x); 17 | } 18 | } 19 | 20 | // Pop off stack. If we popped a minimum, we gotta remove it from minStack also 21 | Integer pop() { 22 | if (stack.isEmpty()) { 23 | return null; 24 | } 25 | int x = stack.pop(); 26 | if (x == minStack.peek()) { 27 | minStack.pop(); 28 | } 29 | return x; 30 | } 31 | 32 | // minStack gives us minimum in O(1) time 33 | Integer min() { 34 | if (minStack.isEmpty()) { 35 | return null; 36 | } else { 37 | return minStack.peek(); 38 | } 39 | } 40 | } 41 | 42 | // References 43 | // 44 | // int vs Integer comparison: https://stackoverflow.com/questions/18445158/int-vs-integer-comparison-java) 45 | // 46 | // In our case, we can safely use <= to compare an int to an Integer. 47 | // However, if we were comparing 2 Integers, we would have to use .intValue(), 48 | // .compareTo(Object other), or .equals(Object other). 49 | -------------------------------------------------------------------------------- /Chp. 03 - Stacks and Queues/_3_2_Stack_Min/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _3_2_Stack_Min; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 3.2: Stack Min\n"); 8 | System.out.println("Building stack: 8 4 6 3 3\n"); 9 | StackMin myStack = new StackMin(); 10 | myStack.push(8); 11 | System.out.println("(after 1st push) Min = " + myStack.min()); 12 | myStack.push(4); 13 | System.out.println("(after 2nd push) Min = " + myStack.min()); 14 | myStack.push(6); 15 | System.out.println("(after 3rd push) Min = " + myStack.min()); 16 | myStack.push(3); 17 | System.out.println("(after 4th push) Min = " + myStack.min()); 18 | myStack.push(3); 19 | System.out.println("(after 5th push) Min = " + myStack.min()); 20 | myStack.pop(); 21 | System.out.println("(after 1st pop) Min = " + myStack.min()); 22 | myStack.pop(); 23 | System.out.println("(after 2nd pop) Min = " + myStack.min()); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Chp. 03 - Stacks and Queues/_3_3_Stack_of_Plates/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _3_3_Stack_of_Plates; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 3.3: Stack of Plates\n"); 8 | StackOfPlates stack = new StackOfPlates(); 9 | for (int i = 1; i <= 5; i++) { 10 | System.out.println("Pushed " + i); 11 | stack.push(i); 12 | } 13 | for (int i = 1; i <= 5; i++) { 14 | System.out.println("Popped " + stack.pop()); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chp. 03 - Stacks and Queues/_3_4_Queue_via_Stacks/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _3_4_Queue_via_Stacks; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 3.4: Queue via Stacks\n"); 8 | System.out.println("elements we will be inserting: 1, 2, 3, 4, 5\n"); 9 | QueueViaStacks myQueue = new QueueViaStacks(); 10 | myQueue.add(1); 11 | myQueue.add(2); 12 | myQueue.add(3); 13 | myQueue.add(4); 14 | System.out.println("1st dequeued = " + myQueue.remove()); 15 | myQueue.add(5); 16 | System.out.println("2nd dequeued = " + myQueue.remove()); 17 | System.out.println("3rd dequeued = " + myQueue.remove()); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Chp. 03 - Stacks and Queues/_3_5_Sort_Stack/SortStack.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _3_5_Sort_Stack; 4 | 5 | import java.util.Stack; 6 | 7 | public class SortStack { 8 | public static Stack sort(Stack stack) { 9 | Stack helperStack = new Stack(); // can alternatively use ArrayDeque (it's faster) 10 | while (!stack.isEmpty()) { 11 | Integer curr = stack.pop(); // saving the top of the stack is one of the main tricks. 12 | while (!helperStack.isEmpty() && curr < helperStack.peek()) { 13 | stack.push(helperStack.pop()); 14 | } 15 | helperStack.push(curr); 16 | } 17 | return helperStack; 18 | } 19 | } 20 | 21 | // Time Complexity: O(n^2) 22 | // Space Complexity: O(n) 23 | -------------------------------------------------------------------------------- /Chp. 03 - Stacks and Queues/_3_5_Sort_Stack/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _3_5_Sort_Stack; 4 | 5 | import java.util.Stack; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** Test 3.6: Sort Stack\n"); 10 | Stack stackToSort = new Stack(); 11 | stackToSort.push(3); 12 | stackToSort.push(7); 13 | stackToSort.push(2); 14 | stackToSort.push(6); 15 | stackToSort.push(1); 16 | System.out.println("Original stack: " + stackToSort); 17 | Stack sortedStack = SortStack.sort(stackToSort); 18 | System.out.println("Sorted stack: " + sortedStack); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Chp. 03 - Stacks and Queues/_3_6_Animal_Shelter/Animal.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _3_6_Animal_Shelter; 4 | 5 | public abstract class Animal { 6 | String name; 7 | int barcode = 0; 8 | 9 | /* Constructor */ 10 | public Animal(String name) { 11 | this.name = name; 12 | } 13 | 14 | /* Constructor */ 15 | public Animal(String name, int barcode) { 16 | this.name = name; 17 | this.barcode = barcode; 18 | } 19 | 20 | public abstract void makeSound(); // abstract class. Must be implemented by subclass 21 | 22 | public boolean isOlderThan(Animal other) { 23 | return barcode < other.barcode; 24 | } 25 | 26 | @Override 27 | public String toString() { 28 | return this.name + " " + this.barcode; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Chp. 03 - Stacks and Queues/_3_6_Animal_Shelter/Cat.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _3_6_Animal_Shelter; 4 | 5 | public class Cat extends Animal { 6 | /* Constructor */ 7 | public Cat(String name) { 8 | super(name); 9 | } 10 | 11 | /* Constructor */ 12 | public Cat(String name, int barcode) { 13 | super(name, barcode); 14 | } 15 | 16 | /* Implements subclass's abstract class */ 17 | @Override 18 | public void makeSound() { 19 | System.out.println("meow"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Chp. 03 - Stacks and Queues/_3_6_Animal_Shelter/Dog.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _3_6_Animal_Shelter; 4 | 5 | public class Dog extends Animal { 6 | /* Constructor */ 7 | public Dog(String name) { 8 | super(name); 9 | } 10 | 11 | /* Constructor */ 12 | public Dog(String name, int barcode) { 13 | super(name, barcode); 14 | } 15 | 16 | /* Implements subclass's abstract class */ 17 | @Override 18 | public void makeSound() { 19 | System.out.println("woof"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Chp. 03 - Stacks and Queues/_3_6_Animal_Shelter/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _3_6_Animal_Shelter; 4 | 5 | // Skills Used: 6 | // 1) Inheritance: using "extends". Abstract class "Animal" with abstract method. 7 | // 2) Polymorphism: Typecasting (Dog) (Cat), instanceof 8 | 9 | public class Tester { 10 | public static void main(String[] args) { 11 | System.out.println("*** Test 3.6: Animal Shelter "); 12 | /* Create shelter */ 13 | AnimalShelter animalShelter = new AnimalShelter(); 14 | animalShelter.enqueue(new Cat("Suzy")); 15 | animalShelter.enqueue(new Dog("Mikey")); 16 | animalShelter.enqueue(new Cat("Lizzie")); 17 | animalShelter.enqueue(new Dog("Kevin")); 18 | 19 | animalShelter.printShelter(); 20 | 21 | /* Remove 2 oldest animals. Print Shelter */ 22 | System.out.print("\n-- removed 2 oldest animals. Now shelter contains: "); 23 | animalShelter.dequeueAny(); 24 | animalShelter.dequeueAny(); 25 | 26 | animalShelter.printShelter(); 27 | 28 | /* Remove cat. Remove dog */ 29 | System.out.println("\nDequeued cat is: " + animalShelter.dequeueCat()); 30 | System.out.println("Dequeued dog is: " + animalShelter.dequeueDog()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Chp. 03 - Stacks and Queues/__Intro_Queue/Queue.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package __Intro_Queue; 4 | 5 | import common.Node; 6 | 7 | public class Queue { 8 | private Node head = null; 9 | private Node tail = null; 10 | 11 | public void add(int data) { 12 | Node n = new Node(data); 13 | if (head == null) { 14 | head = n; 15 | tail = n; 16 | } else { 17 | tail.next = n; 18 | tail = n; 19 | } 20 | } 21 | 22 | public Node remove() { 23 | if (head == null) { 24 | return null; 25 | } 26 | Node front = head; 27 | head = head.next; 28 | if (head == null) { 29 | tail = null; 30 | } 31 | front.next = null; // rips the Node from the Queue 32 | return front; 33 | } 34 | 35 | public Node peek() { 36 | return head; 37 | } 38 | } 39 | 40 | // Time Complexity: O(1) for add(), remove(), peek(). 41 | // Space Complexity: O(1) for add(), remove(), peek(). O(1) to store each Node permanently. 42 | -------------------------------------------------------------------------------- /Chp. 03 - Stacks and Queues/__Intro_Queue/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package __Intro_Queue; 4 | 5 | import common.ListFunctions; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** Test Queue\n"); 10 | Queue q = new Queue(); 11 | q.add(1); 12 | q.add(2); 13 | q.add(3); 14 | System.out.print("Queue after 3 enqueues: "); 15 | ListFunctions.printList(q.peek()); 16 | q.remove(); 17 | System.out.print("Queue after dequeue: "); 18 | ListFunctions.printList(q.peek()); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Chp. 03 - Stacks and Queues/__Intro_Stack/Stack.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package __Intro_Stack; 4 | 5 | import common.Node; 6 | 7 | public class Stack { 8 | private Node top = null; 9 | 10 | public void push(int data) { 11 | Node n = new Node(data); 12 | n.next = top; 13 | top = n; 14 | } 15 | 16 | public Node pop() { 17 | if (top == null) { 18 | return null; 19 | } 20 | Node n = top; 21 | top = top.next; 22 | n.next = null; // rips off the node from the Stack 23 | return n; 24 | } 25 | 26 | public Node peek() { 27 | return top; 28 | } 29 | } 30 | 31 | // Time Complexity: O(1) for push(), pop(), peek(). 32 | // Space Complexity: O(1) for push(), pop(), peek(). O(1) to store each Node permanently. 33 | -------------------------------------------------------------------------------- /Chp. 03 - Stacks and Queues/__Intro_Stack/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package __Intro_Stack; 4 | 5 | import common.ListFunctions; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** Test Stack\n"); 10 | Stack s = new Stack(); 11 | s.push(1); 12 | s.push(2); 13 | s.push(3); 14 | System.out.println("(top of stack printed first)\n"); 15 | System.out.print("Stack after 3 pushes: "); 16 | ListFunctions.printList(s.peek()); 17 | s.pop(); 18 | System.out.print("Stack after pop : "); 19 | ListFunctions.printList(s.peek()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Chp. 04 - Trees and Graphs/_4_01_Route_Between_Nodes/RouteBetweenNodes.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _4_01_Route_Between_Nodes; 4 | 5 | import java.util.*; 6 | import common.GraphNode; 7 | 8 | // Algorithm: run BFS from start node and see if we arrive at end node 9 | 10 | public class RouteBetweenNodes { 11 | public static boolean routeExists(GraphNode start, GraphNode end) { 12 | if (start == end) { 13 | return true; 14 | } 15 | 16 | Deque deque = new ArrayDeque(); // use deque as a queue 17 | start.visit(); 18 | deque.add(start); 19 | 20 | while (!deque.isEmpty()) { 21 | GraphNode curr = deque.remove(); 22 | if (curr == end) { 23 | return true; 24 | } 25 | for (GraphNode neighbor : curr.getNeighbors()) { 26 | if (!neighbor.visited) { 27 | neighbor.visit(); 28 | deque.add(neighbor); 29 | } 30 | } 31 | } 32 | return false; 33 | } 34 | } 35 | 36 | // Improvement: If this was an undirected graph, we could do bi-directional BFS to improve runtime. 37 | -------------------------------------------------------------------------------- /Chp. 04 - Trees and Graphs/_4_01_Route_Between_Nodes/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _4_01_Route_Between_Nodes; 4 | 5 | import common.GraphNode; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** Test 4.1: Route Between Nodes\n"); 10 | GraphNode node1 = new GraphNode(1); 11 | GraphNode node2 = new GraphNode(2); 12 | GraphNode node3 = new GraphNode(3); 13 | node1.addNeighbor(node2); 14 | node2.addNeighbor(node3); 15 | System.out.println("Route exists? (should be true): " + RouteBetweenNodes.routeExists(node1, node3)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chp. 04 - Trees and Graphs/_4_02_Minimal_Tree/MinimalTree.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _4_02_Minimal_Tree; 4 | 5 | import common.TreeNode; 6 | 7 | public class MinimalTree { 8 | public static TreeNode createBST(int[] sortedArray) { 9 | if (sortedArray == null) { 10 | return null; 11 | } 12 | return createBST(sortedArray, 0, sortedArray.length - 1); 13 | } 14 | 15 | private static TreeNode createBST(int[] sortedArray, int startIndex, int endIndex) { 16 | if (startIndex > endIndex) { 17 | return null; 18 | } 19 | int mid = (startIndex + endIndex) / 2; 20 | TreeNode root = new TreeNode(sortedArray[mid]); 21 | root.left = createBST(sortedArray, startIndex, mid - 1); 22 | root.right = createBST(sortedArray, mid + 1, endIndex); 23 | return root; 24 | } 25 | } 26 | 27 | // Time Complexity: O(n) 28 | // Space Complexity: O(n) since we're creating a Binary Search Tree 29 | -------------------------------------------------------------------------------- /Chp. 04 - Trees and Graphs/_4_02_Minimal_Tree/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _4_02_Minimal_Tree; 4 | 5 | import common.TreeNode; 6 | import common.TreeFunctions; 7 | 8 | public class Tester { 9 | public static void main(String[] args) { 10 | System.out.println("*** Test 4.2: Minimal Tree\n"); 11 | int[] sortedArray = { 1, 2, 3, 4, 5, 6, 7 }; 12 | TreeNode BST = MinimalTree.createBST(sortedArray); 13 | System.out.print("In-Order print of tree: "); 14 | TreeFunctions.printInOrder(BST); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Chp. 04 - Trees and Graphs/_4_03_List_of_Depths/ListOfDepths.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _4_03_List_of_Depths; 4 | 5 | import java.util.*; 6 | import common.TreeNode; 7 | 8 | public class ListOfDepths { 9 | public static List> levelOrder(TreeNode root) { 10 | List> lists = new ArrayList(); 11 | if (root == null) { 12 | return lists; 13 | } 14 | ArrayDeque deque = new ArrayDeque(); // use deque as a queue 15 | deque.add(root); 16 | while (!deque.isEmpty()) { 17 | int numNodesInLevel = deque.size(); 18 | List level = new ArrayList(numNodesInLevel); 19 | for (int i = 0; i < numNodesInLevel; i++) { 20 | TreeNode n = deque.remove(); 21 | level.add(n.data); 22 | if (n.left != null) { 23 | deque.add(n.left); 24 | } 25 | if (n.right != null) { 26 | deque.add(n.right); 27 | } 28 | } 29 | lists.add(level); 30 | } 31 | return lists; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Chp. 04 - Trees and Graphs/_4_03_List_of_Depths/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _4_03_List_of_Depths; 4 | 5 | import java.util.*; 6 | import common.TreeNode; 7 | import common.TreeFunctions; 8 | 9 | public class Tester { 10 | public static void main(String[] args) { 11 | System.out.println("*** Test 4.3: List of Depths"); 12 | TreeNode tree = TreeFunctions.createBST(); 13 | List> lists = ListOfDepths.levelOrder(tree); 14 | for (int i = 0; i < lists.size(); i++) { 15 | List list = lists.get(i); 16 | System.out.format("\nLevel %d: ", i); 17 | for (Integer num : list) { 18 | System.out.print(num); 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Chp. 04 - Trees and Graphs/_4_04_Check_Balanced/CheckBalanced.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _4_04_Check_Balanced; 4 | 5 | import common.TreeNode; 6 | 7 | // Algorithm: If subtree at Node is imbalanced, return -1. Otherwise, return height of subtree. 8 | 9 | public class CheckBalanced { 10 | public static boolean isBalanced(TreeNode root) { 11 | return isBalancedHelper(root) != -1; 12 | } 13 | 14 | /* Returns -1 if unbalanced, otherwise returns height of tree from given node */ 15 | private static int isBalancedHelper(TreeNode root) { 16 | if (root == null) { 17 | return 0; 18 | } 19 | 20 | int leftHeight = isBalancedHelper(root.left); 21 | if (leftHeight == -1) { 22 | return -1; // left tree is unbalanced 23 | } 24 | 25 | int rightHeight = isBalancedHelper(root.right); 26 | if (rightHeight == -1) { 27 | return -1; // right tree is unbalanced 28 | } 29 | 30 | if (Math.abs(leftHeight - rightHeight) > 1) { 31 | return -1; // imbalance between the 2 subtrees 32 | } 33 | 34 | return 1 + Math.max(leftHeight, rightHeight); 35 | } 36 | } 37 | 38 | // Time Complexity: O(n) 39 | // Space Complexity: O(log n) if balanced tree. O(n) otherwise. 40 | -------------------------------------------------------------------------------- /Chp. 04 - Trees and Graphs/_4_04_Check_Balanced/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _4_04_Check_Balanced; 4 | 5 | import common.TreeNode; 6 | import common.TreeFunctions; 7 | 8 | public class Tester { 9 | public static void main(String[] args) { 10 | System.out.println("*** Test 4.4: Check Balanced\n"); 11 | TreeNode tree = TreeFunctions.createBST(); 12 | test(tree); 13 | } 14 | 15 | private static void test(TreeNode tree) { 16 | System.out.println("Tree balanced?: " + CheckBalanced.isBalanced(tree)); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chp. 04 - Trees and Graphs/_4_05_Validate_BST/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _4_05_Validate_BST; 4 | 5 | import common.TreeNode; 6 | import common.TreeFunctions; 7 | 8 | public class Tester { 9 | public static void main(String[] args) { 10 | System.out.println("*** Test 4.5: Validate BST\n"); 11 | TreeNode tree1 = TreeFunctions.createTree(); 12 | test(tree1); // should be false 13 | TreeNode tree2 = TreeFunctions.createBST(); 14 | test(tree2); // should be true 15 | } 16 | 17 | private static void test(TreeNode tree) { 18 | System.out.println("is BST?: " + ValidateBST.isBST(tree)); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Chp. 04 - Trees and Graphs/_4_05_Validate_BST/ValidateBST.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _4_05_Validate_BST; 4 | 5 | import common.TreeNode; 6 | 7 | public class ValidateBST { 8 | public static boolean isBST(TreeNode root) { 9 | return isBST(root, Integer.MIN_VALUE, Integer.MAX_VALUE); 10 | } 11 | 12 | private static boolean isBST(TreeNode node, int min, int max) { 13 | if (node == null) { 14 | return true; 15 | } 16 | if (node.data <= min || node.data > max) { // tricky off-by-one errors for duplicates. Tricky whether it's <, <=, >, >= 17 | return false; 18 | } 19 | return isBST(node.left, min, node.data) && isBST(node.right, node.data, max); 20 | } 21 | } 22 | 23 | // Time Complexity: O(n) since we visit every node 24 | // Space Complexity: O(log n) if tree is balanced, O(n) otherwise, since that's the depth of the recursion 25 | -------------------------------------------------------------------------------- /Chp. 04 - Trees and Graphs/_4_06_Successor/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _4_06_Successor; 4 | 5 | import common.TreeNode; 6 | import common.TreeFunctions; 7 | 8 | public class Tester { 9 | public static void main(String[] args) { 10 | System.out.println("*** Test 4.6: Successor\n"); 11 | TreeNode tree = TreeFunctions.createBST(); 12 | System.out.println("Should be 6: " + Successor.inOrderSucc(tree)); 13 | System.out.println("Should be 5: " + Successor.inOrderSucc(tree.left)); 14 | System.out.println("Should be null: " + Successor.inOrderSucc(tree.right.right)); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Chp. 04 - Trees and Graphs/_4_07_Build_Order/Graph.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _4_07_Build_Order; 4 | 5 | import java.util.*; 6 | 7 | public class Graph { 8 | List nodes = new ArrayList(); 9 | Map map = new HashMap(); 10 | 11 | public void addDirectedEdge(String s1, String s2) { 12 | Node source = map.get(s1); 13 | Node destination = map.get(s2); 14 | source.addDirectedNeighbor(destination); 15 | } 16 | 17 | public void addNode(String str) { 18 | Node node = new Node(str); 19 | nodes.add(node); 20 | map.put(str, node); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Chp. 04 - Trees and Graphs/_4_07_Build_Order/Node.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _4_07_Build_Order; 4 | 5 | import java.util.ArrayList; 6 | 7 | class Node { 8 | String data; 9 | Visited status; 10 | ArrayList neighbors; // could alternatively use a HashSet (if I give nodes unique IDs) 11 | 12 | public Node(String data) { 13 | this.data = data; 14 | status = Visited.NEW; 15 | neighbors = new ArrayList(); 16 | } 17 | 18 | public void addDirectedNeighbor(Node neighbor) { 19 | neighbors.add(neighbor); 20 | } 21 | 22 | @Override 23 | public String toString() { 24 | return String.valueOf(data); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Chp. 04 - Trees and Graphs/_4_07_Build_Order/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _4_07_Build_Order; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 4.7: Build Order\n"); 8 | 9 | String[] projects = {"a", "b", "c", "d", "e", "f"}; 10 | String[][] dependencies = { 11 | {"a", "d"}, 12 | {"f", "b"}, 13 | {"b", "d"}, 14 | {"f", "a"}, 15 | {"d", "c"} 16 | }; 17 | 18 | try { 19 | System.out.println(BuildOrder.topoSort(projects, dependencies)); 20 | } catch (Exception exc) { 21 | System.out.println(exc.getMessage()); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Chp. 04 - Trees and Graphs/_4_07_Build_Order/Visited.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _4_07_Build_Order; 4 | 5 | public enum Visited { 6 | NEW, ACTIVE, DONE 7 | } 8 | -------------------------------------------------------------------------------- /Chp. 04 - Trees and Graphs/_4_08_First_Common_Ancestor/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _4_08_First_Common_Ancestor; 4 | 5 | import common.TreeNode; 6 | import common.TreeFunctions; 7 | 8 | public class Tester { 9 | public static void main(String[] args) { 10 | TreeNode tree = TreeFunctions.createBST(); 11 | System.out.println("*** Test 4.8: First Common Ancestor\n"); 12 | System.out.println("Common ancestor (should be 5): " + FirstCommonAncestor.commonAnc(tree, tree.left, tree.right.right)); 13 | System.out.println("Common ancestor (should be 8): " + FirstCommonAncestor.commonAnc(tree, tree.right, tree.right.left)); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Chp. 04 - Trees and Graphs/_4_09_BST_Sequences/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _4_09_BST_Sequences; 4 | 5 | import java.util.*; 6 | 7 | import common.TreeNode; 8 | 9 | public class Tester { 10 | public static void main(String[] args) { 11 | System.out.println("*** Test 4.9: BST Sequences\n"); 12 | TreeNode root = new TreeNode(2); 13 | root.left = new TreeNode(1); 14 | root.right = new TreeNode(3); 15 | List> results = BSTSequences.allSequences(root); 16 | for (Deque result : results) { 17 | System.out.println(result); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Chp. 04 - Trees and Graphs/_4_10_Check_Subtree/CheckSubtree.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _4_10_Check_Subtree; 4 | 5 | import common.TreeNode; 6 | 7 | public class CheckSubtree { 8 | public static boolean containsTree(TreeNode t1, TreeNode t2) { 9 | StringBuffer sb1 = new StringBuffer(); 10 | StringBuffer sb2 = new StringBuffer(); 11 | 12 | getPreorder(t1, sb1); 13 | getPreorder(t2, sb2); 14 | 15 | return sb1.indexOf(sb2.toString()) != -1; 16 | } 17 | 18 | private static void getPreorder(TreeNode node, StringBuffer sb) { 19 | if (node == null) { 20 | sb.append("X"); // Add X representing null 21 | return; 22 | } 23 | sb.append("#" + node.data); // Add separator and root 24 | getPreorder(node.left, sb); // Add left 25 | getPreorder(node.right, sb); // Add right 26 | } 27 | } 28 | 29 | // Time Complexity: O(m + n) if we can assume .indexOf() uses KMP algorithm. 30 | // Space Complexity: O(m + n) 31 | -------------------------------------------------------------------------------- /Chp. 04 - Trees and Graphs/_4_10_Check_Subtree/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _4_10_Check_Subtree; 4 | 5 | import common.TreeNode; 6 | import common.TreeFunctions; 7 | 8 | public class Tester { 9 | public static void main(String[] args) { 10 | System.out.println("*** Test 4.10: subTree\n"); 11 | TreeNode tree1 = TreeFunctions.createTree(); 12 | TreeNode tree2 = TreeFunctions.createBST(); 13 | TreeNode tree3 = new TreeNode(5); 14 | System.out.println("Contains tree? (should be false): " + CheckSubtree.containsTree(tree1, tree2)); 15 | System.out.println("Contains tree? (should be false): " + CheckSubtree.containsTree(tree1, tree3)); 16 | System.out.println("Contains tree? (should be true ): " + CheckSubtree.containsTree(tree1, tree1)); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chp. 04 - Trees and Graphs/_4_11_Random_Node/Node.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _4_11_Random_Node; 4 | 5 | class Node { 6 | int value; 7 | Node left; 8 | Node right; 9 | 10 | Node(int value) { 11 | this.value = value; 12 | left = null; 13 | right = null; 14 | } 15 | 16 | @Override 17 | public boolean equals(Object other) { // must take an "Object" as a parameter, not a 18 | // "Node", so that it overrides the .equals method 19 | if (other == this) { 20 | return true; 21 | } else if (other == null || !(other instanceof Node)) { 22 | return false; 23 | } 24 | Node otherNode = (Node) other; 25 | return this.value == otherNode.value 26 | && this.left.equals(otherNode.left) 27 | && this.right.equals(otherNode.right); 28 | } 29 | 30 | @Override 31 | public int hashCode() { 32 | return value; // since only using 1 int, won't be multiplying by primes. 33 | } 34 | 35 | @Override 36 | public String toString() { 37 | return String.valueOf(value); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Chp. 04 - Trees and Graphs/_4_11_Random_Node/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _4_11_Random_Node; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 4.11: RandomNode\n"); 8 | BST bst = new BST(); 9 | int[] array = { 1, 0, 6, 2, 3, 9, 4, 5, 8, 7 }; 10 | for (int num : array) { 11 | bst.insert(num); 12 | } 13 | for (int i = 0; i < 20; i++) { 14 | System.out.print(bst.getRandomNode() + " "); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chp. 04 - Trees and Graphs/_4_12_Paths_with_Sum/PathWithSums.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _4_12_Paths_with_Sum; 4 | 5 | import common.TreeNode; 6 | import java.util.*; 7 | 8 | 9 | public class PathWithSums { 10 | public static int findSum(TreeNode node, int targetSum) { 11 | Map map = new HashMap(); 12 | map.put(0, 1); 13 | return findSum(node, targetSum, 0, map); 14 | } 15 | 16 | private static int findSum(TreeNode node, int targetSum, int runningSum, Map map) { 17 | if (node == null) { 18 | return 0; 19 | } 20 | 21 | runningSum += node.data; 22 | int totalPaths = map.getOrDefault(runningSum - targetSum, 0); 23 | 24 | map.merge(runningSum, 1, Integer::sum); 25 | totalPaths += findSum(node.left, targetSum, runningSum, map); 26 | totalPaths += findSum(node.right, targetSum, runningSum, map); 27 | map.merge(runningSum, -1, Integer::sum); 28 | if (map.get(runningSum) == 0) { // Remove when 0 to reduce space usage 29 | map.remove(runningSum); 30 | } 31 | 32 | return totalPaths; 33 | } 34 | } 35 | 36 | // Time Complexity: O(n) 37 | // Space Complexity: O(log n) on balanced tree. O(n) otherwise. 38 | -------------------------------------------------------------------------------- /Chp. 04 - Trees and Graphs/_4_12_Paths_with_Sum/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _4_12_Paths_with_Sum; 4 | 5 | import common.TreeNode; 6 | import common.TreeFunctions; 7 | 8 | public class Tester { 9 | public static void main(String[] args) { 10 | System.out.print("*** Test 4.12: Paths with Sum\n"); 11 | TreeNode tree = TreeFunctions.createBST(); 12 | int result = PathWithSums.findSum(tree, 6); 13 | System.out.println(result); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Chp. 04 - Trees and Graphs/__Intro_BFS/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package __Intro_BFS; 4 | 5 | import common.GraphNode; 6 | import common.GraphFunctions; 7 | 8 | public class Tester { 9 | public static void main(String[] args) { 10 | System.out.println("*** Test BFS\n"); 11 | GraphNode graphNode = GraphFunctions.createGraph(); 12 | GraphFunctions.BFS(graphNode, 6); // searches for value 6 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Chp. 04 - Trees and Graphs/__Intro_DFS/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package __Intro_DFS; 4 | 5 | import common.GraphNode; 6 | import common.GraphFunctions; 7 | 8 | public class Tester { 9 | public static void main(String[] args) { 10 | System.out.println("*** Test DFS\n"); 11 | GraphNode graphNode = GraphFunctions.createGraph(); 12 | GraphFunctions.DFS(graphNode, 6); // searches for value 6 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Chp. 04 - Trees and Graphs/__Intro_InOrder_Traversal/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package __Intro_InOrder_Traversal; 4 | 5 | import common.TreeNode; 6 | import common.TreeFunctions; 7 | 8 | public class Tester { 9 | public static void main(String[] args) { 10 | System.out.println("*** Test In-Order Traversal\n"); 11 | TreeNode tree = TreeFunctions.createBST(); 12 | TreeFunctions.printInOrder(tree); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Chp. 04 - Trees and Graphs/__Intro_LevelOrder_Traversal/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package __Intro_LevelOrder_Traversal; 4 | 5 | import common.TreeNode; 6 | import common.TreeFunctions; 7 | 8 | public class Tester { 9 | public static void main(String[] args) { 10 | System.out.println("*** Test Level-Order Traversal\n"); 11 | TreeNode tree = TreeFunctions.createBST(); 12 | TreeFunctions.printLevelOrder(tree); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Chp. 04 - Trees and Graphs/__Intro_PostOrder_Traversal/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package __Intro_PostOrder_Traversal; 4 | 5 | import common.TreeNode; 6 | import common.TreeFunctions; 7 | 8 | public class Tester { 9 | public static void main(String[] args) { 10 | System.out.println("*** Test Post-Order Traversal\n"); 11 | TreeNode tree = TreeFunctions.createBST(); 12 | TreeFunctions.printPostOrder(tree); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Chp. 04 - Trees and Graphs/__Intro_PreOrder_Traversal/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package __Intro_PreOrder_Traversal; 4 | 5 | import common.TreeNode; 6 | import common.TreeFunctions; 7 | 8 | public class Tester { 9 | public static void main(String[] args) { 10 | System.out.println("*** Test Pre-Order Traversal\n"); 11 | TreeNode tree = TreeFunctions.createBST(); 12 | TreeFunctions.printPreOrder(tree); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Chp. 05 - Bit Manipulation/_5_1_Insertion/Insertion.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _5_1_Insertion; 4 | 5 | import common.BitFunctions; 6 | 7 | public class Insertion { 8 | public static int insert_M_into_N(int N, int M, int i, int j) { 9 | /* Clear bits i to j in N */ 10 | for (int index = i; index <= j; index++) { 11 | N = BitFunctions.clearBit(N, index); 12 | } 13 | 14 | M <<= i; // shift M so that it lines up with bits i through j 15 | return M | N; // merge M and N 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chp. 05 - Bit Manipulation/_5_1_Insertion/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _5_1_Insertion; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 5.1: Insertion\n"); 8 | int result = Insertion.insert_M_into_N(0b10000000000, 0b10011, 2, 6); 9 | System.out.println(Integer.toBinaryString(result)); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Chp. 05 - Bit Manipulation/_5_2_Binary_to_String/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _5_2_Binary_to_String; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 5.2: Binary to String\n"); 8 | test(0.625); 9 | test(0.3); 10 | } 11 | 12 | private static void test(double decimal) { 13 | System.out.println("Decimal: " + decimal + " Binary: " + BinaryToString.printBinary(decimal)); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Chp. 05 - Bit Manipulation/_5_3_Flip_Bit_to_Win/FlipBitToWin.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _5_3_Flip_Bit_to_Win; 4 | 5 | public class FlipBitToWin { 6 | public static int flipBit(int n) { 7 | int numBits = Integer.BYTES * 8; 8 | if (n == -1) { // no 0s in bit representation of number 9 | return numBits; 10 | } 11 | 12 | int prevLength = 0; 13 | int currLength = 0; 14 | int maxLength = 1; 15 | 16 | /* set "currLength" as # of trailing 1s */ 17 | int i = 0; 18 | while (getBit(n, i)) { 19 | currLength++; 20 | i++; 21 | } 22 | 23 | /* Continue iterating through number */ 24 | for ( ; i < numBits; i++) { 25 | if (getBit(n, i)) { 26 | currLength++; 27 | } else { 28 | prevLength = currLength; 29 | currLength = 0; 30 | } 31 | maxLength = Math.max(maxLength, currLength + 1 + prevLength); 32 | } 33 | return maxLength; 34 | } 35 | 36 | private static boolean getBit(int num, int bit) { 37 | return (num & (1 << bit)) != 0; 38 | } 39 | } 40 | 41 | // Time Complexity: O(b) where b is number of bits in int. 42 | // Space Complexity: O(1) 43 | -------------------------------------------------------------------------------- /Chp. 05 - Bit Manipulation/_5_3_Flip_Bit_to_Win/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _5_3_Flip_Bit_to_Win; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 5.3: Flip Bit to Win\n"); 8 | test(1775); 9 | test(9); 10 | test(66); 11 | } 12 | 13 | private static void test(int num) { 14 | System.out.format("%12s - Longest (after flipping bit) = %d%n", 15 | Integer.toBinaryString(num), FlipBitToWin.flipBit(num)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chp. 05 - Bit Manipulation/_5_4_Next_Number/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _5_4_Next_Number; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 5.4: Next Number\n"); 8 | test(4); 9 | test(5); 10 | } 11 | 12 | private static void test(int original) { 13 | System.out.println("Original = " + original); 14 | System.out.println("Smaller = " + NextNumber.getPrev(original)); 15 | System.out.println("Larger = " + NextNumber.getNext(original) + "\n"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chp. 05 - Bit Manipulation/_5_5_Debugger/Debugger: -------------------------------------------------------------------------------- 1 | Assuming n is positive, the code is an efficient way to check to see if n is a power of 2 2 | 3 | -------------------------------------------------------------------------------- /Chp. 05 - Bit Manipulation/_5_6_Conversion/Conversion.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _5_6_Conversion; 4 | 5 | import common.BitFunctions; 6 | 7 | public class Conversion { 8 | public static int bitsRequired(int A, int B) { 9 | int xored = A ^ B; 10 | return BitFunctions.numOnes(xored); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Chp. 05 - Bit Manipulation/_5_6_Conversion/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _5_6_Conversion; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 5.5: Conversion\n"); 8 | test(31, 14); 9 | test(17, 15); 10 | } 11 | 12 | private static void test(int a, int b) { 13 | System.out.format("Bits required for converting %s to %2s is %d%n", Integer.toBinaryString(a), 14 | Integer.toBinaryString(b), Conversion.bitsRequired(a, b)); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Chp. 05 - Bit Manipulation/_5_7_Pairwise_Swap/PairwiseSwap.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _5_7_Pairwise_Swap; 4 | 5 | public class PairwiseSwap { 6 | public static int swapOddEven(int num) { 7 | int evenMask = 0xAAAAAAAA; // assumes 32-bit integer 8 | int oddMask = 0x55555555; // assumes 32-bit integer 9 | return ((num & evenMask) >> 1) | ((num & oddMask) << 1); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Chp. 05 - Bit Manipulation/_5_7_Pairwise_Swap/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _5_7_Pairwise_Swap; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | test(38); 8 | test(213309467); 9 | } 10 | 11 | private static void test(int num) { 12 | System.out.format("Original: %32s%n Swapped: %32s%n", Integer.toBinaryString(num), 13 | Integer.toBinaryString(PairwiseSwap.swapOddEven(num))); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Chp. 05 - Bit Manipulation/_5_8_Draw_Line/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _5_8_Draw_Line; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | // Code is same as book's code, so no testing is needed 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Chp. 06 - Math and Logic Puzzles/Intro_Notes: -------------------------------------------------------------------------------- 1 | github.com/RodneyShag 2 | 3 | P(A and B) = P(B|A) P(A) 4 | P(A or B) = P(A) + P(B) - P(A and B) 5 | 6 | Independence --> P(A and B) = P(A) P(B) 7 | Mutually Exclusive --> P(A and B) = 0, so P(A or B) = P(A) + P(B) 8 | 9 | Two events cannot be both independent and mutually exclusive (provided both have 10 | probabilities greater than 0). Why? Because mutual exclusivity means that if one 11 | happens then the other cannot. Independence, however, says that one event happening 12 | means absolutely nothing about the other event. Thus, as long as two events have 13 | non-zero probabilities, they will never be both mutually exclusive and independent. 14 | -------------------------------------------------------------------------------- /Chp. 06 - Math and Logic Puzzles/__Intro_Prime/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package __Intro_Prime; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test Prime\n"); 8 | test(11); 9 | test(12); 10 | test(13); 11 | testGeneratePrimes(50); 12 | } 13 | 14 | private static void test(int num) { 15 | System.out.println("Is " + num + " prime? " + Prime.isPrime(num)); 16 | } 17 | 18 | private static void testGeneratePrimes(int num) { 19 | boolean[] primes = Prime.generatePrimes(num); 20 | System.out.format("\nPrimes from 1-%d: ", num); 21 | for (int i = 0; i < primes.length; i++) { 22 | if (primes[i]) { 23 | System.out.print(i + " "); 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Chp. 07 - Object-Oriented Design/_7_01_Deck_of_Cards/BlackjackCard.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _7_01_Deck_of_Cards; 4 | 5 | public class BlackjackCard extends Card { 6 | public BlackjackCard(Rank rank, Suit suit, Color color) { 7 | super(rank, suit, color); 8 | } 9 | 10 | public boolean isFaceCard() { 11 | return rank == Rank.TEN || rank == Rank.JACK || rank == Rank.QUEEN || rank == Rank.KING; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Chp. 07 - Object-Oriented Design/_7_01_Deck_of_Cards/BlackjackHand.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _7_01_Deck_of_Cards; 4 | 5 | public class BlackjackHand extends Hand { // tricky Syntax 6 | public boolean isBusted() { 7 | return true; // unimplemented 8 | } 9 | 10 | public boolean isBlackjack() { 11 | return true; // unimplemented 12 | } 13 | // see book for more methods. 14 | } 15 | -------------------------------------------------------------------------------- /Chp. 07 - Object-Oriented Design/_7_01_Deck_of_Cards/Card.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _7_01_Deck_of_Cards; 4 | 5 | public class Card { 6 | Suit suit; 7 | Rank rank; 8 | Color color; 9 | 10 | public Card(Rank rank, Suit suit, Color color) { 11 | this.suit = suit; 12 | this.rank = rank; 13 | this.color = color; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Chp. 07 - Object-Oriented Design/_7_01_Deck_of_Cards/Color.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _7_01_Deck_of_Cards; 4 | 5 | public enum Color { 6 | RED, BLACK; 7 | } 8 | -------------------------------------------------------------------------------- /Chp. 07 - Object-Oriented Design/_7_01_Deck_of_Cards/Deck.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _7_01_Deck_of_Cards; 4 | 5 | import java.util.ArrayDeque; 6 | import java.util.LinkedList; 7 | 8 | public class Deck { 9 | 10 | private ArrayDeque deck; // can't use a fixed size array[] since we are using generics. 11 | 12 | public Deck() { 13 | deck = new ArrayDeque(); 14 | initializeCards(); 15 | } 16 | 17 | public void addCard(T card) { 18 | deck.add(card); 19 | } 20 | 21 | public T dealCard() { 22 | return deck.remove(); 23 | } 24 | 25 | public LinkedList dealHand(int numCards) { 26 | LinkedList cards = new LinkedList(); 27 | for (int i = 0; i < numCards; i++) { 28 | cards.add(deck.remove()); 29 | } 30 | return cards; 31 | } 32 | 33 | public void shuffle() { 34 | // unimplemented 35 | } 36 | 37 | public int cardsLeft() { 38 | return deck.size(); 39 | } 40 | 41 | private void initializeCards() { 42 | // Unimplemented. Would create 52 instances of cards here and add them to "deck" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Chp. 07 - Object-Oriented Design/_7_01_Deck_of_Cards/Hand.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _7_01_Deck_of_Cards; 4 | 5 | import java.util.ArrayList; 6 | 7 | public class Hand { 8 | ArrayList hand; 9 | 10 | public Hand() { 11 | hand = new ArrayList(); 12 | } 13 | // and more methods here. 14 | } 15 | -------------------------------------------------------------------------------- /Chp. 07 - Object-Oriented Design/_7_01_Deck_of_Cards/Rank.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _7_01_Deck_of_Cards; 4 | 5 | public enum Rank { 6 | TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, 7 | JACK, QUEEN, KING, ACE 8 | } 9 | -------------------------------------------------------------------------------- /Chp. 07 - Object-Oriented Design/_7_01_Deck_of_Cards/Suit.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _7_01_Deck_of_Cards; 4 | 5 | public enum Suit { 6 | SPADE, CLUB, DIAMOND, HEART 7 | } 8 | -------------------------------------------------------------------------------- /Chp. 07 - Object-Oriented Design/_7_02_Call_Center/CallCenter: -------------------------------------------------------------------------------- 1 | 7.2 - Call Center 2 | 3 | 1) Create as many classes as possible to show OOP Principles: 4 | abstract Employee class (with Respondent, Manager, Director as subclasses), Call, and CallCenter as classes. 5 | 2) Use 3 Queues. 1 for each Call "rank" 6 | -------------------------------------------------------------------------------- /Chp. 07 - Object-Oriented Design/_7_03_Jukebox/Jukebox: -------------------------------------------------------------------------------- 1 | 7.3 - Jukebox 2 | 3 | 1) Possible Classes: CD, Song, Playlist, Queue, User, Artist, PlayerControls, Display 4 | 2) Actions: Queue CD, Queue Song, Queue Artist, Play next song, Remove Song. 5 | -------------------------------------------------------------------------------- /Chp. 07 - Object-Oriented Design/_7_04_Parking_Lot/ParkingLot: -------------------------------------------------------------------------------- 1 | 7.4 - Parking Lot 2 | 3 | 1) Make abstract class Vehicle. Have Motorcycle, Car, Bus be subclasses of Vehicle. Also create ParkingSpot, ParkingLot classes. 4 | 2) ParkingLot has data: levels[], availableSpots, 5 | methods: parkVehicle(Vehicle v), removeVehicle(Vehicle v), availbleSpots() 6 | -------------------------------------------------------------------------------- /Chp. 07 - Object-Oriented Design/_7_05_Online_Book_Reader/OnlineBookReader: -------------------------------------------------------------------------------- 1 | 7.5 - Online Book Reader 2 | 3 | 1) The OnlineReaderSystem class can have classes: Library, User Manager, Display 4 | 2) Books: Hashed by ID: HashMap to hash ID to actual book. Can also hash the ID to the # of copies we have. 5 | 3) Users: Hashed by ID: HashMap usersByID. Have "add" and "remove" functions for the private HashMap. 6 | -------------------------------------------------------------------------------- /Chp. 07 - Object-Oriented Design/_7_06_Jigsaw/Jigsaw: -------------------------------------------------------------------------------- 1 | 7.6 - Jigsaw 2 | 3 | 1) 3 Classes - Puzzle, Piece (which has 4 Edges), Edge (which can be "inner", "outer", or "flat"). 4 | 2) Book's solution is overly complex. I would be able to solve this with my own algorithm: 5 | - Split Pieces into corner, edge, and center pieces. Then can simply loop through 2D array and brute-force pieces until it works. 6 | - Putting Edges into lists of "inner", "outer", or "flat" will enable us to only try pieces with proper edge configurations.. 7 | -------------------------------------------------------------------------------- /Chp. 07 - Object-Oriented Design/_7_07_Chat_Server/ChatServer: -------------------------------------------------------------------------------- 1 | 7.7 - Chat Server 2 | 3 | Class: Conversation (with subclasses GroupChat and PrivateChat). User. AddRequest. 4 | ----------------------------------- important lesson of when to use ArrayList vs. HashMap 5 | For fast lookup, book used: 6 | private HashMap usersByld; 7 | private HashMap usersByAccountName; 8 | private HashMap onlineUsers; 9 | 10 | Uses: HashMap privateChats, 11 | HashMap receivedAddRequests 12 | HashMap contacts 13 | ...I think using ArrayList instead of HashMap for these may have its own pros/cons. Maybe like this: 14 | ArrayList privateChats 15 | ArrayList receivedAddRequests 16 | ArrayList contacts 17 | "Tough problems to solve": Security, out-of-sync data / conflicting information. 18 | -------------------------------------------------------------------------------- /Chp. 07 - Object-Oriented Design/_7_08_Othello/Othello: -------------------------------------------------------------------------------- 1 | 7.8 - Othello 2 | 3 | Classes: Board, Player, Piece. I could have a separate "Game" class like the book, but a Game is basically just a Board. 4 | 5 | Fully functional Othello game: https://github.com/RodneyShag/Othello 6 | -------------------------------------------------------------------------------- /Chp. 07 - Object-Oriented Design/_7_09_Circular_Array/CircularArray.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _7_09_Circular_Array; 4 | 5 | public class CircularArray { 6 | private int head = 0; 7 | private T[] items; // I don't use an ArrayList since I want a fixed size array that doesn't grow 8 | 9 | public CircularArray(int size) { 10 | items = (T[]) new Object[size]; // since we cannot create an array of a generic type 11 | } 12 | 13 | public T get(int index) { 14 | if (index < 0 || index >= items.length) { 15 | throw new IndexOutOfBoundsException(); 16 | } 17 | return items[convert(index)]; 18 | } 19 | 20 | public void set(int index, T item) throws IndexOutOfBoundsException { 21 | if (index < 0 || index >= items.length) { 22 | throw new IndexOutOfBoundsException(); 23 | } 24 | items[convert(index)] = item; 25 | } 26 | 27 | private int convert(int index) { 28 | if (index < 0) { 29 | index += items.length; 30 | } 31 | return (head + index) % items.length; 32 | } 33 | 34 | public void rotate(int shiftRight) { 35 | head = (head + shiftRight) % items.length; 36 | } 37 | } 38 | 39 | // Part 2: Skip because 40 | // 1) I doubt we will have to do something this specific in an interview 41 | // 2) Spending time using and getting comfortable with iterators with .hasNext() and .next() 42 | // may be more useful than implementing them myself -------------------------------------------------------------------------------- /Chp. 07 - Object-Oriented Design/_7_11_File_System/FileSystem: -------------------------------------------------------------------------------- 1 | 7.11 - File System 2 | 3 | - Have abstract class "Entry", where "File" and "Directory" are subclasses. Entry will have useful fields like: 4 | - long created, lastUpdated, lastAccessed 5 | - String name 6 | - Directory parent 7 | - and methods like 8 | - getFullPath(); 9 | - have "Directory" have an ArrayList (alternatively have ArrayList and ArrayList) 10 | -------------------------------------------------------------------------------- /Chp. 07 - Object-Oriented Design/_7_12_Hash_Table/Cell.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _7_12_Hash_Table; 4 | 5 | public class Cell { // public variables for simplicity. 6 | K key; 7 | V value; 8 | 9 | Cell(K k, V v) { 10 | key = k; 11 | value = v; 12 | } 13 | 14 | public boolean equivalent(K k) { 15 | return key.equals(k); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chp. 07 - Object-Oriented Design/_7_12_Hash_Table/Main.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _7_12_Hash_Table; 4 | 5 | public class Main { 6 | public static void main(String[] args) { 7 | Hash map = new Hash(); 8 | map.put(2, "Bob"); 9 | System.out.print(map); 10 | System.out.println("Hash numBuckets = " + map.numBuckets + "\n"); 11 | 12 | map.put(3, "Jenny"); 13 | System.out.print(map); 14 | System.out.println("Hash numBuckets = " + map.numBuckets + "\n"); 15 | 16 | map.put(6, "Alex"); 17 | System.out.print(map); 18 | System.out.println("Hash numBuckets = " + map.numBuckets + "\n"); 19 | 20 | map.put(7, "Jenny"); 21 | System.out.print(map); 22 | System.out.println("Hash numBuckets = " + map.numBuckets + "\n"); 23 | 24 | map.put(10, "Cynthia"); 25 | System.out.print(map); 26 | System.out.println("Hash numBuckets = " + map.numBuckets + "\n"); 27 | 28 | System.out.println("** Sam should overwrite Alex **\n"); 29 | map.put(6, "Sam"); 30 | System.out.print(map); 31 | System.out.println("Hash numBuckets = " + map.numBuckets + "\n"); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Chp. 08 - Recursion and Dynamic Programming/_8_01_Triple_Step/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _8_01_Triple_Step; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 8.1: Triple Step\n"); 8 | test(0); System.out.println(); 9 | test(1); System.out.println(); 10 | test(2); System.out.println(); 11 | test(3); System.out.println(); 12 | test(5); System.out.println(); 13 | } 14 | 15 | private static void test(int steps) { 16 | System.out.format("(Recursive Solution) %d Step Staircase: %2d ways \n", steps, TripleStep.numPathsRecursive(steps)); 17 | System.out.format("(Iterative Solution) %d Step Staircase: %2d ways \n", steps, TripleStep.numPathsIterative(steps)); 18 | System.out.format("(Iterative Solution) %d Step Staircase: %2d ways \n", steps, TripleStep.numPathsIterativeNoArray(steps)); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Chp. 08 - Recursion and Dynamic Programming/_8_02_Robot_in_a_Grid/Point.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _8_02_Robot_in_a_Grid; 4 | 5 | public class Point { 6 | public int x; 7 | public int y; 8 | 9 | Point(int x, int y) { 10 | this.x = x; 11 | this.y = y; 12 | } 13 | 14 | // Good reads: 15 | // http://javarevisited.blogspot.com/2011/02/how-to-write-equals-method-in-java.html 16 | // http://javarevisited.blogspot.com/2011/10/override-hashcode-in-java-example.html 17 | 18 | @Override 19 | public boolean equals(Object other) { // must take an "Object" as a parameter, not a 20 | // "Point", so that it overrides the .equals method 21 | if (other == this) { 22 | return true; 23 | } else if (other == null || !(other instanceof Point)) { 24 | return false; 25 | } 26 | Point otherPoint = (Point) other; 27 | return this.x == otherPoint.x && this.y == otherPoint.y; 28 | } 29 | 30 | @Override 31 | public int hashCode() { 32 | return 13 * x + 7 * y; 33 | } 34 | 35 | @Override 36 | public String toString() { 37 | return "(" + x + "," + y + ")"; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Chp. 08 - Recursion and Dynamic Programming/_8_03_Magic_Index/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _8_03_Magic_Index; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 8.3: Magic Index\n"); 8 | 9 | int[] sortedArray = { -5, -3, -1, 3, 5 }; 10 | System.out.println("(Result should be 3) = " + MagicIndex.magicFast(sortedArray)); 11 | 12 | int[] sortedArray2 = { -10, -5, 2, 2, 2, 3, 4, 7, 9, 12, 13 }; 13 | System.out.println("(Result should be 2) = " + MagicIndex.magicFast2(sortedArray2)); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Chp. 08 - Recursion and Dynamic Programming/_8_04_Power_Set/PowerSet.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _8_04_Power_Set; 4 | 5 | import java.util.*; 6 | 7 | public class PowerSet { 8 | public static List> getSubsets(int[] array) { 9 | if (array == null || array.length == 0) { 10 | return new ArrayList(); 11 | } 12 | List> solutions = new ArrayList(); 13 | makeSubsets(array, 0, solutions, new ArrayList()); 14 | return solutions; 15 | } 16 | 17 | private static void makeSubsets(int[] array, int i, List> solutions, List list) { 18 | if (i == array.length) { 19 | solutions.add(new ArrayList(list)); 20 | return; 21 | } 22 | 23 | // don't use array[i] 24 | makeSubsets(array, i + 1, solutions, list); 25 | 26 | // use array[i] 27 | list.add(array[i]); 28 | makeSubsets(array, i + 1, solutions, list); 29 | list.remove(list.size() - 1); 30 | } 31 | } 32 | 33 | // Time Complexity: O(2^n). Impossible to do better 34 | -------------------------------------------------------------------------------- /Chp. 08 - Recursion and Dynamic Programming/_8_04_Power_Set/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _8_04_Power_Set; 4 | 5 | import java.util.*; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** Test 8.4: Power Set\n"); 10 | int[] array = new int[]{3,5,3}; 11 | test(array); 12 | } 13 | 14 | private static void test(int[] array) { 15 | List> subsets = PowerSet.getSubsets(array); 16 | System.out.println("Original array: " + Arrays.toString(array)); 17 | System.out.println("Subsets: " + subsets + "\n"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Chp. 08 - Recursion and Dynamic Programming/_8_05_Recursive_Multiply/RecursiveMultiply.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _8_05_Recursive_Multiply; 4 | 5 | public class RecursiveMultiply { 6 | public static int multiply(int a, int b) { 7 | if (a == 0 || b == 0) { 8 | return 0; 9 | } else if (a < b) { 10 | return multiplyHelper(a, b); 11 | } else { 12 | return multiplyHelper(b, a); 13 | } 14 | } 15 | 16 | private static int multiplyHelper(int smaller, int bigger) { 17 | if (smaller == 1) { 18 | return bigger; 19 | } 20 | 21 | int halfProd = multiplyHelper(smaller / 2, bigger); 22 | 23 | if (smaller % 2 == 0) { 24 | return halfProd + halfProd; 25 | } else { 26 | return halfProd + halfProd + bigger; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Chp. 08 - Recursion and Dynamic Programming/_8_05_Recursive_Multiply/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _8_05_Recursive_Multiply; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 8.5: Recursive Multiply\n"); 8 | test(4, 3); 9 | test(0, 3); 10 | } 11 | 12 | private static void test(int a, int b) { 13 | System.out.format("%d * %d = %d\n", a, b, RecursiveMultiply.multiply(a, b)); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Chp. 08 - Recursion and Dynamic Programming/_8_06_Towers_of_Hanoi/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _8_06_Towers_of_Hanoi; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 8.6: Towers of Hanoi\n"); 8 | int numTowers = 3; 9 | int numDisks = 4; // can make this bigger 10 | Tower[] towers = new Tower[numTowers]; 11 | for (int i = 0; i < numTowers; i++) { 12 | towers[i] = new Tower(i); // don't forget. We have to do this too! 13 | } 14 | for (int i = numDisks; i > 0; i--) { 15 | towers[0].push(i); 16 | } 17 | TowersOfHanoi.moveDisks(numDisks, towers[0], towers[2], towers[1]); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Chp. 08 - Recursion and Dynamic Programming/_8_06_Towers_of_Hanoi/Tower.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _8_06_Towers_of_Hanoi; 4 | 5 | import java.util.*; 6 | 7 | // It's just a stack, including 1) Error Checking 2) tower number 8 | class Tower { 9 | private Deque disks; // use deque as a stack 10 | public int towerNum; 11 | 12 | public Tower(int towerNum) { 13 | disks = new ArrayDeque(); 14 | this.towerNum = towerNum; 15 | } 16 | 17 | // Can only push a disk onto a stack if there isn't already a smaller disk on it 18 | public void push(int d) { 19 | if (!disks.isEmpty() && disks.peek() <= d) { 20 | System.out.println("Error Placing Disk " + d); 21 | } else { 22 | disks.push(d); 23 | } 24 | } 25 | 26 | // Can only pop from a non-empty stack 27 | public Integer pop() { 28 | if (disks.isEmpty()) { 29 | return null; 30 | } else { 31 | return disks.pop(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Chp. 08 - Recursion and Dynamic Programming/_8_06_Towers_of_Hanoi/TowersOfHanoi.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _8_06_Towers_of_Hanoi; 4 | 5 | public class TowersOfHanoi { 6 | public static void moveDisks(int n, Tower origin, Tower destination, Tower buffer) { 7 | if (n > 0) { 8 | moveDisks(n - 1, origin, buffer, destination); 9 | moveTop(origin, destination); 10 | moveDisks(n - 1, buffer, destination, origin); 11 | } 12 | } 13 | 14 | /* We teach it how to move 1 disk. Therefore it can recursively move n disks */ 15 | private static void moveTop(Tower origin, Tower destination) { 16 | Integer disk = origin.pop(); 17 | destination.push(disk); 18 | System.out.println("Move disk " + disk + " from Tower " + origin.towerNum + " to Tower " + destination.towerNum); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Chp. 08 - Recursion and Dynamic Programming/_8_07_Permutations_without_Dups/PermutationsWithoutDups.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _8_07_Permutations_without_Dups; 4 | 5 | import java.util.*; 6 | 7 | public class PermutationsWithoutDups { 8 | public static List> permute(int[] array) { 9 | if (array == null || array.length == 0) { 10 | return new ArrayList(); 11 | } 12 | List> solutions = new ArrayList(); 13 | permute(array, 0, new boolean[array.length], solutions, new ArrayList()); 14 | return solutions; 15 | } 16 | 17 | private static void permute(int[] array, int index, boolean[] used, List> solutions, List list) { 18 | if (index == array.length) { 19 | solutions.add(new ArrayList(list)); 20 | return; 21 | } 22 | for (int i = 0; i < array.length; i++) { 23 | if (used[i] == false) { 24 | list.add(array[i]); 25 | used[i] = true; 26 | permute(array, index + 1, used, solutions, list); 27 | used[i] = false; 28 | list.remove(list.size() - 1); 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Chp. 08 - Recursion and Dynamic Programming/_8_07_Permutations_without_Dups/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _8_07_Permutations_without_Dups; 4 | 5 | import java.util.*; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** Test 8.7: Permutations without Dups\n"); 10 | test(new int[]{1,2,3}); 11 | } 12 | 13 | private static void test(int[] array) { 14 | List> permutations = PermutationsWithoutDups.permute(array); 15 | System.out.println("Original array: " + Arrays.toString(array)); 16 | System.out.println("Permutations: " + permutations + "\n"); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chp. 08 - Recursion and Dynamic Programming/_8_08_Permutations_with_Dups/PermutationsWithDups.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _8_08_Permutations_with_Dups; 4 | 5 | import java.util.*; 6 | 7 | public class PermutationsWithDups { 8 | public static List> permute(int[] array) { 9 | if (array == null || array.length == 0) { 10 | return new ArrayList(); 11 | } 12 | Set> solutions = new HashSet(); 13 | permute(array, 0, new boolean[array.length], solutions, new ArrayList()); 14 | return new ArrayList(solutions); 15 | } 16 | 17 | private static void permute(int[] array, int index, boolean[] used, Set> solutions, List list) { 18 | if (index == array.length) { 19 | solutions.add(new ArrayList(list)); 20 | return; 21 | } 22 | for (int i = 0; i < array.length; i++) { 23 | if (used[i] == false) { 24 | list.add(array[i]); 25 | used[i] = true; 26 | permute(array, index + 1, used, solutions, list); 27 | used[i] = false; 28 | list.remove(list.size() - 1); 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Chp. 08 - Recursion and Dynamic Programming/_8_08_Permutations_with_Dups/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _8_08_Permutations_with_Dups; 4 | 5 | import java.util.*; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** Test 8.8: Permutations with Dups\n"); 10 | test(new int[]{1,2,3}); 11 | test(new int[]{1,1,4}); 12 | } 13 | 14 | private static void test(int[] array) { 15 | List> permutations = PermutationsWithDups.permute(array); 16 | System.out.println("Original array: " + Arrays.toString(array)); 17 | System.out.println("Permutations: " + permutations + "\n"); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Chp. 08 - Recursion and Dynamic Programming/_8_09_Parens/Parens.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _8_09_Parens; 4 | 5 | import java.util.*; 6 | 7 | public class Parens { 8 | public static List generateParentheses(int n) { 9 | List solutions = new ArrayList(); 10 | addParenthesis(new char[n * 2], 0, n, n, solutions); 11 | return solutions; 12 | } 13 | 14 | private static void addParenthesis(char[] expression, int index, int leftRem, int rightRem, List solutions) { 15 | if (leftRem == 0 && rightRem == 0) { 16 | solutions.add(new String(expression)); 17 | return; 18 | } 19 | if (leftRem > 0) { 20 | expression[index] = '('; 21 | addParenthesis(expression, index + 1, leftRem - 1, rightRem, solutions); 22 | } 23 | if (rightRem > 0 && rightRem > leftRem) { 24 | expression[index] = ')'; 25 | addParenthesis(expression, index + 1, leftRem, rightRem - 1, solutions); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Chp. 08 - Recursion and Dynamic Programming/_8_09_Parens/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _8_09_Parens; 4 | 5 | import java.util.*; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** Test 8.9: Parens\n"); 10 | test(2); 11 | test(3); 12 | } 13 | 14 | private static void test(int n) { 15 | System.out.println("n = " + n); 16 | List list = Parens.generateParentheses(n); 17 | for (String str : list) { 18 | System.out.println(str); 19 | } 20 | System.out.println("Number of solutions: " + list.size() + "\n"); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Chp. 08 - Recursion and Dynamic Programming/_8_10_Paint_Fill/Color.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _8_10_Paint_Fill; 4 | 5 | public enum Color { 6 | BLACK, WHITE, RED, YELLOW, GREEN 7 | } 8 | -------------------------------------------------------------------------------- /Chp. 08 - Recursion and Dynamic Programming/_8_10_Paint_Fill/PaintFill.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _8_10_Paint_Fill; 4 | 5 | /* Same as book's code */ 6 | public class PaintFill { 7 | public static boolean paintFill(Color[][] screen, int x, int y, Color newColor) { 8 | if (screen == null || newColor == null || screen[y][x] == newColor) { 9 | return false; 10 | } 11 | return paintFillRecursive(screen, x, y, newColor, screen[y][x]); 12 | } 13 | 14 | private static boolean paintFillRecursive(Color[][] screen, int x, int y, Color newColor, Color oldColor) { 15 | if (x < 0 || x >= screen[0].length || y < 0 || y >= screen.length) { 16 | return false; 17 | } 18 | 19 | if (screen[y][x] == oldColor) { 20 | screen[y][x] = newColor; 21 | paintFillRecursive(screen, x - 1, y, newColor, oldColor); 22 | paintFillRecursive(screen, x + 1, y, newColor, oldColor); 23 | paintFillRecursive(screen, x, y - 1, newColor, oldColor); 24 | paintFillRecursive(screen, x, y + 1, newColor, oldColor); 25 | } 26 | return true; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Chp. 08 - Recursion and Dynamic Programming/_8_11_Coins/Coins.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _8_11_Coins; 4 | 5 | // Video explanation: https://www.youtube.com/watch?time_continue=350&v=jaNZ83Q3QGc 6 | 7 | public class Coins { 8 | public static long makeChange(int amount) { 9 | int[] coins = new int[]{1, 5, 10, 25}; 10 | return makeChange(amount, coins); 11 | } 12 | 13 | public static long makeChange(int amount, int[] coins) { 14 | long[] dp = new long[amount + 1]; 15 | dp[0] = 1; 16 | for (int coin : coins) { 17 | for (int i = coin; i <= amount; i++) { 18 | dp[i] += dp[i-coin]; 19 | } 20 | } 21 | return dp[amount]; 22 | } 23 | } 24 | 25 | // Time Complexity: O(amount * coins) 26 | // Space Complexity: O(amount) 27 | -------------------------------------------------------------------------------- /Chp. 08 - Recursion and Dynamic Programming/_8_11_Coins/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _8_11_Coins; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 8.11: Coins\n"); 8 | test(100); 9 | test(5); 10 | } 11 | 12 | private static void test(int n) { 13 | System.out.format("# of ways to make %3d cents (Using Quarters, Dimes, Nickels, Pennies) = %d\n", n, Coins.makeChange(n)); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Chp. 08 - Recursion and Dynamic Programming/_8_12_Eight_Queens/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _8_12_Eight_Queens; 4 | 5 | import java.util.*; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** Test 8.12: Eight Queens\n"); 10 | List> solution = EightQueens.solveNQueens(8); 11 | for (List board : solution) { 12 | printBoard(board); 13 | } 14 | } 15 | 16 | private static void printBoard(List board) { 17 | for (String str : board) { 18 | System.out.println(str); 19 | } 20 | System.out.println(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Chp. 08 - Recursion and Dynamic Programming/_8_13_Stack_of_Boxes/Box.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _8_13_Stack_of_Boxes; 4 | 5 | public class Box { 6 | int width; 7 | int height; 8 | int depth; 9 | 10 | Box(int w, int h, int d) { 11 | width = w; 12 | height = h; 13 | depth = d; 14 | } 15 | 16 | public boolean canBeAbove(Box other) { 17 | return (other == null) || (width < other.width && height < other.height && depth < other.depth); 18 | } 19 | 20 | @Override 21 | public String toString() { 22 | return "Box (" + width + "," + height + "," + depth + ")"; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Chp. 08 - Recursion and Dynamic Programming/_8_13_Stack_of_Boxes/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _8_13_Stack_of_Boxes; 4 | 5 | import java.util.*; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** Test 8.13: Stack of Boxes\n"); 10 | List boxes = new LinkedList(); 11 | boxes.add(new Box(3, 4, 1)); 12 | boxes.add(new Box(8, 6, 2)); 13 | boxes.add(new Box(4, 8, 3)); 14 | test(boxes); 15 | } 16 | 17 | private static void test(List boxes) { 18 | System.out.println("Original boxes: " + boxes + "\n"); 19 | int height = StackOfBoxes.findMaxHeight(boxes); 20 | System.out.println("Height of tallest stack: " + height); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Chp. 08 - Recursion and Dynamic Programming/_8_14_Boolean_Evaluation/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _8_14_Boolean_Evaluation; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 8.14: Boolean Evaluation\n"); 8 | test("1^0|0|1", false); 9 | } 10 | 11 | private static void test(String str, boolean bool) { 12 | System.out.format("# of ways to parenthesize %s to be %s = %d\n", str, bool, BooleanEvaluation.f(str, bool)); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Chp. 08 - Recursion and Dynamic Programming/__Intro_Fibonacci/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package __Intro_Fibonacci; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test Fibonacci"); 8 | for (int i = 0; i < 16; i++) { 9 | System.out.print(Fibonacci.fibRecursive(i) + " "); 10 | } 11 | 12 | System.out.println(); 13 | for (int i = 0; i < 16; i++) { 14 | System.out.print(Fibonacci.fibIterative(i) + " "); 15 | } 16 | 17 | System.out.println(); 18 | for (int i = 0; i < 16; i++) { 19 | System.out.print(Fibonacci.fibIterativeNoArray(i) + " "); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Chp. 09 - System Design and Scalability/9_1_Stock_Data: -------------------------------------------------------------------------------- 1 | github.com/RodneyShag 2 | 3 | 9.1 - Stock Data 4 | 5 | Storing data formats: text files, SQL Database, or XML (or nowadays JSON) 6 | -------------------------------------------------------------------------------- /Chp. 09 - System Design and Scalability/9_2_Social_Network: -------------------------------------------------------------------------------- 1 | github.com/RodneyShag 2 | 3 | 9.2 - Social Network 4 | 5 | - Use BFS to find (shortest) path between 2 people. 6 | - To Handle the Millions of Users (which won't fit on one machine) 7 | - Server Should have: 8 | - HashMap machines (which maps machine's ID to the actual machine) 9 | - HashMap personToMachineMap (which maps person's ID to machine's ID) 10 | - Machine should have: 11 | - HashMap persons (which maps person's ID to Person) 12 | - Optimization: Reduce Machine Jumps - Look up 5 things at once instead of 1 by 1 (see book for details) 13 | -------------------------------------------------------------------------------- /Chp. 09 - System Design and Scalability/9_3_Web_Crawler: -------------------------------------------------------------------------------- 1 | github.com/RodneyShag 2 | 3 | 9.3 - Web Crawler 4 | 5 | - Simple Answer: Use HashMap/HashSet to mark pages as visited. 6 | - To solve problem where some URLs are different but content is same/similar: 7 | - Create a "signature" for each page so we can assess degree of similarity. 8 | Then, If a page has a high degree of similarity to other pages, deprioritize crawling its children. 9 | -------------------------------------------------------------------------------- /Chp. 09 - System Design and Scalability/9_4_Duplicate_URLs: -------------------------------------------------------------------------------- 1 | github.com/RodneyShag 2 | 3 | 9.4 - Duplicate URLs 4 | 5 | - Simple Answer: Use HashMap to detect duplicates 6 | - 10 billion URLS at 100 characters each at 4 bytes each = 4 terabytes of information. Can't save this all in 1 file. 7 | - Create 4000 1GB files called .txt where is hash(url) % 4000. 8 | - (Although mostly uniformly distributed, some files may be bigger or smaller 9 | than 1GB since it's very unlikely we can create a perfect hash function) 10 | - Now all URLs with same hash value are in same file 11 | - (this ensures that 2 of the same key are not in different files, so our next step will successfully remove all duplicates) 12 | - Do a 2nd pass (through each of the 4000 files) and create a HashMap to detect duplicates 13 | - This 2nd pass can be done in parallel on 4000 Machines (Pro: Faster, Con: if 1 machine crashes it affects our final result) 14 | -------------------------------------------------------------------------------- /Chp. 09 - System Design and Scalability/9_5_Cache: -------------------------------------------------------------------------------- 1 | github.com/RodneyShag 2 | 3 | 9.5 - Cache 4 | 5 | - We basically design an LRU cache 6 | - Main idea: Use linked list to keep track of popular pages. Use a HashMap (in parallel w/ the LinkedList) 7 | for fast access to LinkedList nodes (key = the url string, value = node in LinkedList) 8 | - "A linked list would allow easy purging of old data, by moving "fresh" items to the front. We could implement it to remove the 9 | last element of the linked list when the list exceeds a certain size." 10 | - Options for storing the cache 11 | 0) Each machine has it's own cache of just it's searches (lame) 12 | 1) Each machine has it's own cache of ALL machine's searches 13 | - Pro: Efficient Lookup 14 | - Con: takes up a ton of memory. Updating cache means updating it on every machine) 15 | 2) Cache is shared across machines (by hashing keys, which are queries) 16 | 3) Rodney method: Each machine has most popular searches cached. Less popular searches are shared among machines 17 | -------------------------------------------------------------------------------- /Chp. 09 - System Design and Scalability/_Intro_4_ways_to_divide_data: -------------------------------------------------------------------------------- 1 | github.com/RodneyShag 2 | 3 | 4 ways to divide data (Read book's explanation for great tips) 4 | - by order of appearance (Benefit: won't ever need more machines than necessary) 5 | - by hashing it mod number of machines (Benefit: Every machine knows exactly where data is) 6 | - by using what the actual values represent. Can group similar things together, like all people in Mexico. 7 | - arbitrarily (Benefit: better load balancing) 8 | -------------------------------------------------------------------------------- /Chp. 09 - System Design and Scalability/_Intro_Find_words_in_millions_of_documents: -------------------------------------------------------------------------------- 1 | github.com/RodneyShag 2 | 3 | - preprocess the data with a HashMap> 4 | - Somehow divide the HashMap across machines. Can do it alphabetically by keywords. 5 | -------------------------------------------------------------------------------- /Chp. 10 - Sorting and Searching/_10_01_Sorted_Merge/SortedMerge.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _10_01_Sorted_Merge; 4 | 5 | // Same concept as "merge" from MergeSort. 6 | // Additional Trick: copy to end of array since that's where our empty buffer is. 7 | 8 | public class SortedMerge { 9 | public static void merge(int[] a, int[] b, int lastA, int lastB) { // lastA is index of last element in array. Same with lastB 10 | int curr = lastA + lastB + 1; 11 | while (lastA >= 0 && lastB >= 0) { 12 | if (a[lastA] > b[lastB]) { 13 | a[curr--] = a[lastA--]; 14 | } else { 15 | a[curr--] = b[lastB--]; 16 | } 17 | } 18 | 19 | // Copy Remaining Elements. No need to copy lastA elements since they're already in correct spot 20 | while (lastB >= 0) { 21 | a[curr--] = b[lastB--]; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Chp. 10 - Sorting and Searching/_10_01_Sorted_Merge/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _10_01_Sorted_Merge; 4 | 5 | import java.util.Arrays; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** 10.1: Sorted Merge"); 10 | test(new int[]{ 3, 6, 8, 9, 0, 0, 0, 0 }, new int[]{ 1, 2, 4, 7 }, 3, 3); 11 | } 12 | 13 | private static void test(int[] arrayA, int[] arrayB, int lastA, int lastB) { 14 | System.out.println("Original arrays: " + Arrays.toString(arrayA) + " " + Arrays.toString(arrayB)); 15 | SortedMerge.merge(arrayA, arrayB, lastA, lastB); 16 | System.out.println("Merged: " + Arrays.toString(arrayA)); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chp. 10 - Sorting and Searching/_10_02_Group_Anagrams/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _10_02_Group_Anagrams; 4 | 5 | import java.util.Arrays; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** 10.2: Group Anagrams"); 10 | String[] array1 = {"hello", "hi", "ih", "obb", "bob", "helol", "olleh", "god", "loleh", "lolhe", "asd", "nwr", "gsegae", "fesf"}; 11 | String[] array2 = array1.clone(); 12 | String[] array3 = array1.clone(); 13 | 14 | System.out.println("\nInput: " + Arrays.toString(array1) + "\n"); 15 | test(array2); 16 | test2(array3); 17 | } 18 | 19 | private static void test(String[] array) { 20 | GroupAnagrams.groupAnagrams(array); 21 | System.out.println(Arrays.toString(array)); 22 | } 23 | 24 | private static void test2(String[] array) { 25 | GroupAnagrams.groupAnagrams2(array); 26 | System.out.println(Arrays.toString(array)); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Chp. 10 - Sorting and Searching/_10_03_Search_in_Rotated_Array/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _10_03_Search_in_Rotated_Array; 4 | 5 | import java.util.Arrays; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** 10.3: Search in Rotated Array"); 10 | int[] rotatedArray = { 15, 16, 19, 20, 25, 1, 3, 4, 5, 7, 10, 14 }; 11 | System.out.println("Rotated Array: " + Arrays.toString(rotatedArray)); 12 | for (int num : rotatedArray) { 13 | test(rotatedArray, num); 14 | } 15 | } 16 | 17 | private static void test(int[] rotatedArray, int num) { 18 | System.out.format("%n%2d is at index: %2d", num, SearchInRotatedArray.search(rotatedArray, num)); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Chp. 10 - Sorting and Searching/_10_04_Sorted_Search_No_Size/Listy.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _10_04_Sorted_Search_No_Size; 4 | 5 | public class Listy { 6 | private int[] array; 7 | 8 | public Listy(int[] arr) { 9 | array = arr; 10 | } 11 | 12 | public int elementAt(int index) { 13 | if (index >= array.length) { 14 | return -1; 15 | } 16 | return array[index]; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chp. 10 - Sorting and Searching/_10_04_Sorted_Search_No_Size/SortedSearchNoSize.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _10_04_Sorted_Search_No_Size; 4 | 5 | public class SortedSearchNoSize { 6 | public static int search(Listy list, int value) { 7 | int index = 1; 8 | while (list.elementAt(index) != -1 && list.elementAt(index) < value) { 9 | index *= 2; 10 | } 11 | return binarySearch(list, value, index / 2, index); 12 | } 13 | 14 | public static int binarySearch(Listy listy, int value, int start, int end) { 15 | while (start <= end) { 16 | int mid = (start + end) / 2; 17 | int midValue = listy.elementAt(mid); 18 | if (midValue == -1 || midValue > value) { 19 | end = mid - 1; 20 | } else if (midValue < value) { 21 | start = mid + 1; 22 | } else { 23 | return mid; 24 | } 25 | } 26 | return -1; 27 | } 28 | } 29 | 30 | // Time Complexity: O(log n) 31 | // Space Complexity: O(1) 32 | -------------------------------------------------------------------------------- /Chp. 10 - Sorting and Searching/_10_04_Sorted_Search_No_Size/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _10_04_Sorted_Search_No_Size; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** 10.4: Sorted Search, No Size\n"); 8 | test(new int[]{ 1, 2, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 16, 18 }); 9 | } 10 | 11 | private static void test(int[] array) { 12 | Listy list = new Listy(array); 13 | for (int num : array) { 14 | System.out.format("%2d is at index %2d\n", num, SortedSearchNoSize.search(list, num)); 15 | } 16 | System.out.println(SortedSearchNoSize.search(list, 91291873)); // Should print -1 if not in array 17 | System.out.println(SortedSearchNoSize.search(list, 3) + "\n"); // Should print -1 if not in array 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Chp. 10 - Sorting and Searching/_10_05_Sparse_Search/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _10_05_Sparse_Search; 4 | 5 | import java.util.Arrays; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** 10.5: Sparse Search\n"); 10 | String[] words = { "at", "", "", "", "ball", "", "", "car", "", "", "dad", "", "" }; 11 | System.out.println("Array: " + Arrays.toString(words)); 12 | test(words, "at"); 13 | test(words, "ball"); 14 | test(words, "car"); 15 | test(words, "dad"); 16 | test(words, "food"); 17 | } 18 | 19 | private static void test(String[] words, String word) { 20 | System.out.format("\n%5s is at index: %d", word, SparseSearch.find(words, word)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Chp. 10 - Sorting and Searching/_10_06_Sort_Big_File/SortBigFile: -------------------------------------------------------------------------------- 1 | Solution: External Sort 2 | 3 | We will assume that 20 gigabytes of data is too big to bring into memory. 4 | 5 | Let's assume we have "x" megabytes of memory (where x < 20 gigabytes) 6 | 7 | We'll divide the 20 gigabyte file into chunks of "x" megabytes each. 8 | 9 | Next, we sort each chunk separately and save it back to the file system. 10 | 11 | Finally, merge the chunks together into a fully sorted file. 12 | -------------------------------------------------------------------------------- /Chp. 10 - Sorting and Searching/_10_07_Missing_Int/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _10_07_Missing_Int; 4 | 5 | import java.util.Arrays; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** Test 10.3: Missing Int"); 10 | test(new int[]{ 22, 25, 0, 1, 2, 3, 4, 5, 6, 7, 8, 200, 201, 202 }); 11 | test(new int[]{ 5, 7, 0, 1, 2 }); 12 | } 13 | 14 | private static void test(int[] input) { 15 | System.out.println("\ninput: " + Arrays.toString(input)); 16 | MissingInt.findNumber(input); 17 | MissingInt.findNumber2(input); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Chp. 10 - Sorting and Searching/_10_07_Missing_Int/numbers: -------------------------------------------------------------------------------- 1 | 22 2 | 25 3 | 0 4 | 1 5 | 2 6 | 3 7 | 4 8 | 5 9 | 6 10 | 7 11 | 8 12 | 9 13 | 10 14 | 11 15 | 12 16 | 13 17 | 14 18 | 15 19 | 16 20 | 17 21 | 18 22 | 19 23 | 200 24 | 201 25 | 202 26 | 203 27 | 204 28 | 205 29 | 206 -------------------------------------------------------------------------------- /Chp. 10 - Sorting and Searching/_10_08_Find_Duplicates/FindDuplicates.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _10_08_Find_Duplicates; 4 | 5 | import java.util.BitSet; 6 | 7 | // - 4 KB = 4096 Bytes = (4096 * 8) Bits > 32000, so 4 KB bit vector should be enough to hold 32,000 bits. 8 | // - Using BitSet instead of HashMap since we have limited memory. 9 | 10 | public class FindDuplicates { 11 | public static void checkDuplicates(int[] array) { 12 | BitSet bitset = new BitSet(32000); 13 | for (int i = 0; i < array.length; i++) { 14 | int num = array[i]; 15 | if (bitset.get(num)) { 16 | System.out.print(num + " "); 17 | } else { 18 | bitset.set(num); 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Chp. 10 - Sorting and Searching/_10_08_Find_Duplicates/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _10_08_Find_Duplicates; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 10.4: Find Duplicates"); 8 | FindDuplicates.checkDuplicates(new int[] { 3, 4, 4, 4, 1, 6, 1 }); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Chp. 10 - Sorting and Searching/_10_09_Sorted_Matrix_Search/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _10_09_Sorted_Matrix_Search; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** 10.9: Sorted Matrix Search"); 8 | int[][] sortedMatrix = {{ 1, 6, 8, 9 }, 9 | { 3, 8, 9, 11 }, 10 | { 6, 9, 11, 15 }, 11 | { 7, 14, 17, 22 }}; 12 | test(sortedMatrix, 6); 13 | test(sortedMatrix, 64); 14 | } 15 | 16 | private static void test(int[][] sortedMatrix, int num) { 17 | System.out.format("\n%2d exists: %s", num, SortedMatrixSearch.findElement(sortedMatrix, num)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Chp. 10 - Sorting and Searching/_10_10_Rank_from_Stream/RankNode.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _10_10_Rank_from_Stream; 4 | 5 | public class RankNode { 6 | int data; 7 | RankNode left; 8 | RankNode right; 9 | int leftSize; // each RankNode will keep track of the number of RankNodes in its left subtree 10 | 11 | public RankNode(int data) { 12 | this.data = data; 13 | left = null; 14 | right = null; 15 | leftSize = 0; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chp. 10 - Sorting and Searching/_10_10_Rank_from_Stream/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _10_10_Rank_from_Stream; 4 | 5 | import java.util.Arrays; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** 10.10: Rank from Stream"); 10 | int[] array = { 5, 1, 4, 4, 5, 9, 7, 13, 3 }; 11 | System.out.println(Arrays.toString(array)); 12 | trackNums(array); // must call "trackNums" on array before calling "test" function 13 | test(array, 1); 14 | test(array, 3); 15 | test(array, 4); 16 | } 17 | 18 | private static void trackNums(int[] array) { 19 | for (int n : array) { 20 | RankFromStream.track(n); 21 | } 22 | } 23 | 24 | private static void test(int[] array, int num) { 25 | System.out.format("\nRank of %d = %d", num, RankFromStream.getRankOfNumber(num)); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Chp. 10 - Sorting and Searching/_10_11_Peaks_and_Valleys/PeaksAndValleys.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _10_11_Peaks_and_Valleys; 4 | 5 | // Algorithm: Look at groups of 3 and put the "valleys" in the right place. 6 | // This will also make the "peaks" fall in the right place. 7 | 8 | public class PeaksAndValleys { 9 | public static void sortValleyPeak(int[] array) { 10 | for (int i = 1; i < array.length; i += 2) { 11 | if (array[i - 1] < array[i]) { 12 | swap(array, i - 1, i); 13 | } 14 | if (i + 1 < array.length && array[i + 1] < array[i]) { 15 | swap(array, i + 1, i); 16 | } 17 | } 18 | } 19 | 20 | private static void swap(int[] array, int left, int right) { 21 | int temp = array[left]; 22 | array[left] = array[right]; 23 | array[right] = temp; 24 | } 25 | } 26 | 27 | // Time Complexity: O(n) 28 | // Space Complexity: O(1) 29 | -------------------------------------------------------------------------------- /Chp. 10 - Sorting and Searching/_10_11_Peaks_and_Valleys/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _10_11_Peaks_and_Valleys; 4 | 5 | import java.util.Arrays; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** 10.11: Peaks and Valleys"); 10 | test(new int[]{ 5, 3, 1, 2, 3 }); 11 | test(new int[]{ 1, 2, 3, 4, 5 }); 12 | } 13 | 14 | private static void test(int[] array) { 15 | System.out.println("\nOriginal: " + Arrays.toString(array)); 16 | PeaksAndValleys.sortValleyPeak(array); 17 | System.out.println("Altered: " + Arrays.toString(array)); 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Chp. 10 - Sorting and Searching/__Intro_Binary_Search/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package __Intro_Binary_Search; 4 | 5 | import java.util.Arrays; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** Test Binary Search"); 10 | test(new int[]{ -3, -1, 0, 2, 9, 22, 23, 25, 53 }, -1); 11 | test(new int[]{ -5, -4, 0, 1, 2 }, 2); 12 | 13 | } 14 | 15 | private static void test(int[] sortedArray, int value) { 16 | System.out.println("\nOriginal array: " + Arrays.toString(sortedArray)); 17 | System.out.println(value + " is at index " + BinarySearch.Iterative(sortedArray, value)); 18 | System.out.println(value + " is at index " + BinarySearch.Recursive(sortedArray, value)); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Chp. 11 - Testing/11_2_Random_Crashes: -------------------------------------------------------------------------------- 1 | github.com/RodneyShag 2 | 3 | The cause could be: 4 | - Random Variable (user input, random generated number, time of day) 5 | - Uninitialized Variable (in some languages this means it's a different value each time) 6 | - Memory Leak 7 | - External Dependencies (another application, machine, resource) 8 | -------------------------------------------------------------------------------- /Chp. 11 - Testing/11_4_No_Test_Tools: -------------------------------------------------------------------------------- 1 | github.com/RodneyShag 2 | 3 | To do load testing, we can create thousands of virtual users to test 4 | - response time 5 | - resource utilization 6 | - max load system can bear 7 | -------------------------------------------------------------------------------- /Chp. 11 - Testing/_General_Tips: -------------------------------------------------------------------------------- 1 | github.com/RodneyShag 2 | 3 | Main thing to remember is to ask WHO/WHAT/WHEN/WHERE/WHY/HOW 4 | 5 | ******************** 6 | *** General Tips *** 7 | ******************** 8 | 9 | - PRIORITIZE test cases (security or payment systems would be high priority) 10 | - Test in Organized Manner. 11 | - For Camera, categorize as: 12 | - Take Photos 13 | - Image Management 14 | - Settings 15 | 16 | 17 | **************************************************** 18 | *** Testing real-world object (like a paperclip) *** 19 | **************************************************** 20 | 21 | Test: 22 | - who, what, when, where, why, how 23 | - Bounds of use, Stress/Failure Conditions (max papers can hold without bending damage, temperatures it should work at) 24 | 25 | 26 | ************************** 27 | *** Testing a function *** 28 | ************************** 29 | 30 | Test: 31 | - Normal Input 32 | - Extremes 33 | - Null & Illegal Input 34 | - Strange Input (Like a sorted array or reverse-order array) 35 | - Make sure no side effects: If a function takes an array as an argument, and that array is not supposed to be altered, 36 | then that can be tested 37 | - use assertEquals(__, ___), assertTrue(__), assertFalse(__), assertNull(__), assertNotNull(__), assertNotEquals(__,__) 38 | -------------------------------------------------------------------------------- /Chp. 13 - Java/_13_1_Private_Constructor/PrivateConstructor: -------------------------------------------------------------------------------- 1 | github.com/RodneyShag 2 | 3 | If a class, A, has a private constructor, this prevents other classes from inheriting from A. 4 | 5 | Exceptions: 6 | - If A has an inner class, that class has access to A's private constructor, so it can inherit from A 7 | - If A is an inner class of another class, Q, then Q's other inner classes can inherit from A 8 | -------------------------------------------------------------------------------- /Chp. 13 - Java/_13_2_Return_From_Finally/ReturnFromFinally: -------------------------------------------------------------------------------- 1 | github.com/RodneyShag 2 | 3 | Yes. The "finally" block (still) gets executed when the "try" block exits. 4 | -------------------------------------------------------------------------------- /Chp. 13 - Java/_13_5_TreeMap_HashMap_LinkedHashMap/_TreeMap_HashMap_LinkedHashMap: -------------------------------------------------------------------------------- 1 | github.com/RodneyShag 2 | 3 | HashMap 4 | 5 | O(1) add and remove. 6 | Iterating over it will return elements in an arbitrary order 7 | 8 | TreeMap 9 | 10 | O(log n) add and remove 11 | Iterating over it will return elements in sorted order 12 | 13 | LinkedHashMap 14 | 15 | O(1) add and remove 16 | Iterating over it will return elements in the same order they were inserted 17 | 18 | StackOverflow Answer: https://stackoverflow.com/a/17708526 19 | -------------------------------------------------------------------------------- /Chp. 15 - Threads and Locks/_15_1_Thread_vs_Process/ThreadVsProcess: -------------------------------------------------------------------------------- 1 | From "Cracking the Coding Interview" book solutions: 2 | 3 | Processes and threads are related to each other but are fundamentally different. 4 | 5 | A process can be thought of as an instance of a program in execution. A process is an independent entity to 6 | which system resources (e.g., CPU time and memory) are allocated. Each process is executed in a separate 7 | address space, and one process cannot access the variables and data structures of another process. If a 8 | process wishes to access another process' resources, inter-process communications have to be used. These 9 | include pipes, files, sockets, and other forms. 10 | 11 | A thread exists within a process and shares the process' resources (including its heap space). Multiple 12 | threads within the same process will share the same heap space. This is very different from processes, which 13 | cannot directly access the memory of another process. Each thread still has its own registers and its own 14 | stack, but other threads can read and write the heap memory. 15 | A thread is a particular execution path of a process. When one thread modifies a process resource, the 16 | change is immediately visible to sibling threads. 17 | -------------------------------------------------------------------------------- /Chp. 15 - Threads and Locks/_15_2_Context_Switch/ThreadVsProcess: -------------------------------------------------------------------------------- 1 | Skip: Bad Question -------------------------------------------------------------------------------- /Chp. 15 - Threads and Locks/_15_3_Dining_Philosophers/Chopstick.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _15_3_Dining_Philosophers; 4 | 5 | import java.util.concurrent.locks.Lock; 6 | import java.util.concurrent.locks.ReentrantLock; 7 | 8 | /* Code from online solutions */ 9 | public class Chopstick { 10 | private Lock lock; 11 | 12 | public Chopstick() { 13 | lock = new ReentrantLock(); 14 | } 15 | 16 | public boolean pickUp() { 17 | return lock.tryLock(); // important that we do .tryLock() instead of 18 | // .lock() 19 | } 20 | 21 | public void putDown() { 22 | lock.unlock(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Chp. 15 - Threads and Locks/_15_3_Dining_Philosophers/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _15_3_Dining_Philosophers; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | int numPhilosophers = 3; 8 | 9 | Chopstick[] chopsticks = new Chopstick[numPhilosophers + 1]; 10 | for (int i = 0; i < numPhilosophers + 1; i++) { 11 | chopsticks[i] = new Chopstick(); 12 | } 13 | 14 | Philosopher[] philosophers = new Philosopher[numPhilosophers]; 15 | for (int i = 0; i < numPhilosophers; i++) { 16 | Chopstick left = chopsticks[leftOf(i)]; 17 | Chopstick right = chopsticks[rightOf(i, numPhilosophers)]; 18 | philosophers[i] = new Philosopher(i, left, right); 19 | } 20 | 21 | for (int i = 0; i < numPhilosophers; i++) { 22 | philosophers[i].start(); // I believe this will call the Philosopher's overwritten run() method 23 | } 24 | } 25 | 26 | private static int leftOf(int i) { 27 | return i; 28 | } 29 | 30 | private static int rightOf(int i, int numPhilosophers) { 31 | return (i + 1) % numPhilosophers; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Chp. 15 - Threads and Locks/_15_4_Deadlock_Free_Class/DeadlockFreeClass: -------------------------------------------------------------------------------- 1 | Implement a directed graph and use DFS/BFS to detect a cycle. 2 | 3 | A deadlock can occur if and only if we find a cycle. 4 | -------------------------------------------------------------------------------- /Chp. 15 - Threads and Locks/_15_5_Call_In_Order/MyThread.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _15_5_Call_In_Order; 4 | 5 | /* Code from online solutions */ 6 | public class MyThread extends Thread { 7 | private String method; 8 | private CallInOrder foo; 9 | 10 | public MyThread(CallInOrder foo, String method) { 11 | this.method = method; 12 | this.foo = foo; 13 | } 14 | 15 | @Override 16 | public void run() { 17 | if (method == "first") { 18 | foo.first(); 19 | } else if (method == "second") { 20 | foo.second(); 21 | } else if (method == "third") { 22 | foo.third(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Chp. 15 - Threads and Locks/_15_5_Call_In_Order/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _15_5_Call_In_Order; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | CallInOrder callInOrder = new CallInOrder(); 8 | 9 | MyThread thread1 = new MyThread(callInOrder, "first"); 10 | MyThread thread2 = new MyThread(callInOrder, "second"); 11 | MyThread thread3 = new MyThread(callInOrder, "third"); 12 | 13 | thread3.start(); 14 | thread2.start(); 15 | thread1.start(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chp. 15 - Threads and Locks/_15_6_Synchronized_Methods/SynchronizedMethods: -------------------------------------------------------------------------------- 1 | From "Cracking the Coding Interview" book solutions: 2 | 3 | By applying the word synchronized to a method, we ensure that two threads cannot execute 4 | synchronized methods on the same object instance at the same time. 5 | 6 | So, the answer to the first part really depends. If the two threads have the same instance of the object, then 7 | no, they cannot simultaneously execute method A. However, if they have different instances of the object, 8 | then they can. 9 | 10 | Conceptually, you can see this by considering locks. A synchronized method applies a "lock" on all 11 | synchronized methods in that instance of the object. This blocks other threads from executing synchronized 12 | methods within that instance. 13 | 14 | In the second part, we're asked if threadl can execute synchronized method A while thread2 is 15 | executing non-synchronized method B. Since B is not synchronized, there is nothing to block threadl 16 | from executing A while thread2 is executing B. This is true regardless of whether threadl and thread2 17 | have the same instance of the object. 18 | 19 | Ultimately, the key concept to remember is that only one synchronized method can be in execution per 20 | instance of that object. Other threads can execute non-synchronized methods on that instance, or they can 21 | execute any method on a different instance of the object. 22 | -------------------------------------------------------------------------------- /Chp. 15 - Threads and Locks/__Intro_Examples/LockedATM.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package __Intro_Examples; 4 | 5 | import java.util.concurrent.locks.Lock; 6 | import java.util.concurrent.locks.ReentrantLock; 7 | 8 | /* Code from online examples */ 9 | public class LockedATM { 10 | private Lock lock; 11 | private int balance = 100; 12 | 13 | public LockedATM() { 14 | lock = new ReentrantLock(); 15 | } 16 | 17 | public int withdraw(int value) { 18 | lock.lock(); 19 | int temp = balance; 20 | try { 21 | Thread.sleep(100); 22 | temp = temp - value; 23 | Thread.sleep(100); 24 | balance = temp; 25 | } catch (InterruptedException e) { } 26 | lock.unlock(); 27 | return temp; 28 | } 29 | 30 | public int deposit(int value) { 31 | lock.lock(); 32 | int temp = balance; 33 | try { 34 | Thread.sleep(100); 35 | temp = temp + value; 36 | Thread.sleep(100); 37 | balance = temp; 38 | } catch (InterruptedException e) { } 39 | lock.unlock(); 40 | return temp; 41 | } 42 | 43 | public int getBalance() { 44 | return balance; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Chp. 15 - Threads and Locks/__Intro_Examples/MyClass.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package __Intro_Examples; 4 | 5 | /* Code from online examples */ 6 | public class MyClass extends Thread { 7 | private String name; 8 | private MyObject myObj; 9 | 10 | public MyClass(MyObject obj, String n) { 11 | name = n; 12 | myObj = obj; 13 | } 14 | 15 | @Override 16 | public void run() { 17 | myObj.foo(name); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Chp. 15 - Threads and Locks/__Intro_Examples/MyObject.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package __Intro_Examples; 4 | 5 | /* Code from online examples */ 6 | public class MyObject { 7 | public synchronized void foo(String name) { 8 | try { 9 | System.out.println("Thread " + name + ".foo(): starting"); 10 | Thread.sleep(3000); 11 | System.out.println("Thread " + name + ".fooQ: ending"); 12 | } catch (InterruptedException exc) { 13 | System.out.println("Thread " + name + ": interrupted."); 14 | } 15 | } 16 | // Further Reading: p.166 in PDF about synchronized STATIC methods 17 | } 18 | -------------------------------------------------------------------------------- /Chp. 15 - Threads and Locks/__Intro_Examples/RunnableThreadExample.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package __Intro_Examples; 4 | 5 | /* Code from online examples */ 6 | public class RunnableThreadExample implements Runnable { 7 | public int count = 0; 8 | 9 | public void run() { 10 | System.out.println("RunnableThread starting."); 11 | try { 12 | while (count < 5) { 13 | Thread.sleep(500); 14 | count++; 15 | } 16 | } catch (InterruptedException exc) { 17 | System.out.println("RunnableThread interrupted."); 18 | } 19 | System.out.println("RunnableThread terminating."); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Chp. 15 - Threads and Locks/__Intro_Examples/ThreadExample.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package __Intro_Examples; 4 | 5 | /* Code from online examples */ 6 | public class ThreadExample extends Thread { 7 | int count = 0; 8 | 9 | @Override 10 | public void run() { 11 | System.out.println("Thread starting."); 12 | try { 13 | while (count < 5) { 14 | Thread.sleep(500); 15 | System.out.println("In Thread, count is " + count); 16 | count++; 17 | } 18 | } catch (InterruptedException exc) { 19 | System.out.println("Thread interrupted."); 20 | } 21 | System.out.println("Thread terminating."); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_01_Number_Swapper/NumberSwapper.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_01_Number_Swapper; 4 | 5 | public class NumberSwapper { 6 | public static void swap1(int a, int b) { 7 | a = a - b; 8 | b = b + a; 9 | a = b - a; 10 | System.out.println("Swapped (Solution 1): a = " + a + " b = " + b); 11 | } 12 | 13 | public static void swap2(int a, int b) { 14 | a = a ^ b; 15 | b = a ^ b; 16 | a = a ^ b; 17 | System.out.println("Swapped (Solution 2): a = " + a + " b = " + b); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_01_Number_Swapper/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_01_Number_Swapper; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 16.1: Number Swapper"); 8 | test(2, 4); 9 | test(3, 5); 10 | } 11 | 12 | private static void test(int a, int b) { 13 | System.out.println("\nOriginal: a = " + a + " b = " + b); 14 | NumberSwapper.swap1(a, b); 15 | NumberSwapper.swap2(a, b); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_02_Word_Frequencies/WordFrequencies: -------------------------------------------------------------------------------- 1 | Simply save document as a HashMap 2 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_04_Tic_Tac_Win/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_04_Tic_Tac_Win; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 16.4: Tic Tac Win\n"); 8 | char[][] board = {{'x', 'o', 'x'}, 9 | {' ', ' ', ' '}, 10 | {' ', ' ', ' '}}; 11 | test(board); // converted to "int" value should be 23 for the above board 12 | } 13 | 14 | private static void test(char[][] board) { 15 | int intValue = TicTacWin.convertBoardToInt(board); 16 | System.out.println("Board int value: " + intValue); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_05_Factorial_Zeros/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_05_Factorial_Zeros; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 16.5: Factorial Zeros"); 8 | test(8); 9 | test(9); 10 | test(10); 11 | test(20); 12 | } 13 | 14 | private static void test(int n) { 15 | System.out.format("\n%2d! = %20d # Trailing 0s = %d", n, calculateFactorial(n), FactorialZeros.numTrailingZeros(n)); 16 | } 17 | 18 | private static long calculateFactorial(long num) { 19 | if (num > 20) { 20 | return -1; // since result may cause overflow 21 | } 22 | long result = 1; 23 | while (num > 1) { 24 | result *= num; 25 | num--; 26 | } 27 | return result; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_06_Smallest_Difference/SmallestDifference.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_06_Smallest_Difference; 4 | 5 | import java.util.Arrays; 6 | 7 | // Kind of like a "closest 2 sum" problem. 8 | 9 | public class SmallestDifference { 10 | public static int smallestDifference(int[] array1, int[] array2) { 11 | Arrays.sort(array1); 12 | Arrays.sort(array2); 13 | int minDifference = Integer.MAX_VALUE; 14 | int i = 0; 15 | int j = 0; 16 | while (i < array1.length && j < array2.length) { 17 | int difference = Math.abs(array1[i] - array2[j]); 18 | minDifference = Math.min(minDifference, difference); 19 | if (array1[i] == array2[j]) { 20 | return 0; 21 | } 22 | if (array1[i] < array2[j]) { 23 | i++; 24 | } else { 25 | j++; 26 | } 27 | } 28 | return minDifference; 29 | } 30 | } 31 | 32 | // Time Complexity: O(a log a + b log b) where a, b are lengths of the 2 arrays 33 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_06_Smallest_Difference/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_06_Smallest_Difference; 4 | 5 | import java.util.Arrays; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** Test 16.6: Smallest Difference"); 10 | test(new int[]{ 1, 3, 15, 11, 2 }, new int[]{ 23, 127, 235, 19, 8 }); 11 | } 12 | 13 | private static void test(int[] array1, int[] array2) { 14 | System.out.println("\nArray 1: " + Arrays.toString(array1)); 15 | System.out.println("Array 2: " + Arrays.toString(array2)); 16 | int difference = SmallestDifference.smallestDifference(array1, array2); 17 | System.out.println("Smallest difference = " + difference); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_07_Number_Max/NumberMax.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_07_Number_Max; 4 | 5 | /* Finds max of 2 numbers without using if-else, comparison operators */ 6 | public class NumberMax { 7 | private static int flip(int bit) { 8 | return 1 ^ bit; 9 | } 10 | 11 | /* Returns 0 if a is negative, 1 if positive */ 12 | public static int sign(int a) { 13 | return flip(a >>> 31); // >>> is unsigned right shift 14 | } 15 | 16 | /* Overflow of "a-b" will cause incorrect results */ 17 | public static int max(int a, int b) { 18 | int k = sign(a - b); 19 | return k*a + flip(k)*b; // cool trick 20 | } 21 | 22 | /* This version solves overflow problem. From website solutions */ 23 | public static int max2(int a, int b) { 24 | int difSigns = sign(a) ^ sign(b); 25 | int k = difSigns * sign(a) + flip(difSigns) * sign(a-b); // if a,b have different signs, we simply set k = sign(a) 26 | return k*a + flip(k)*b; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_07_Number_Max/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_07_Number_Max; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 16.7: Number Max\n"); 8 | System.out.print("0 means negative, 1 means positive"); 9 | 10 | testSign(-61); 11 | testSign(-252); 12 | testSign(61); 13 | testSign(252); 14 | System.out.println(); 15 | 16 | testMax(-3, -5); 17 | testMax(0, 8); 18 | testMax(-3, 5); 19 | } 20 | 21 | private static void testSign(int n) { 22 | System.out.format("\n%4d (Sign): %d", n, NumberMax.sign(n)); 23 | } 24 | 25 | private static void testMax(int a, int b) { 26 | System.out.format("\nmax(%2d, %2d): %2d", a, b, NumberMax.max(a, b)); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_08_English_Int/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_08_English_Int; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 16.8: English Int"); 8 | for (int i = 0; i < 23; i++) { 9 | test(i); 10 | } 11 | test(0); 12 | test(1000); 13 | test(-2998); 14 | test(253513); 15 | test(1000010); 16 | test(10090034); 17 | } 18 | 19 | private static void test(int n) { 20 | System.out.format("\n%d: %s", n, EnglishInt.numToString(n)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_09_Operations/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_09_Operations; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 16.9: Operations\n"); 8 | 9 | testSubtract(4, 7); 10 | System.out.println(); 11 | 12 | testMultiply( 2, 3); 13 | testMultiply(-2, 3); 14 | testMultiply( 2, -3); 15 | testMultiply(-2, -3); 16 | System.out.println(); 17 | 18 | testDivide( 7, 2); 19 | testDivide(-7, 2); 20 | testDivide( 7, -2); 21 | testDivide(-7, -2); 22 | } 23 | 24 | private static void testSubtract(int a, int b) { 25 | int result = Operations.subtract(a, b); 26 | System.out.format("%2d - %2d = %2d%n", a, b, result); 27 | } 28 | 29 | private static void testMultiply(int a, int b) { 30 | int result = Operations.multiply(a, b); 31 | System.out.format("%2d * %2d = %2d%n", a, b, result); 32 | } 33 | 34 | private static void testDivide(int a, int b) { 35 | try { 36 | int result = Operations.divide(a, b); 37 | System.out.format("%2d / %2d = %2d%n", a, b, result); 38 | } catch (Exception e) { 39 | System.out.println(e.getMessage()); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_10_Living_People/LivingPeople.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_10_Living_People; 4 | 5 | public class LivingPeople { 6 | public static int maxAlive(Person[] people, int min, int max) { 7 | int[] populationDeltas = getDeltas(people, min, max); 8 | int maxAliveYear = findMaxAliveYear(populationDeltas); 9 | return maxAliveYear + min; 10 | } 11 | 12 | private static int[] getDeltas(Person[] people, int min, int max) { 13 | int[] deltas = new int[max - min + 2]; 14 | for (Person person : people) { 15 | deltas[person.birth - min]++; 16 | deltas[person.death + 1 - min]--; // We consider him/her alive on death year 17 | } 18 | return deltas; 19 | } 20 | 21 | private static int findMaxAliveYear(int[] deltas) { 22 | int alive = 0; 23 | int maxAlive = 0; 24 | int maxYear = 0; 25 | for (int i = 0; i < deltas.length; i++) { 26 | alive += deltas[i]; 27 | if (alive > maxAlive) { 28 | maxAlive = alive; 29 | maxYear = i; 30 | } 31 | } 32 | return maxYear; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_10_Living_People/Person.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_10_Living_People; 4 | 5 | public class Person { 6 | int birth; 7 | int death; 8 | 9 | Person(int birth, int death) { 10 | this.birth = birth; 11 | this.death = death; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_10_Living_People/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_10_Living_People; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 16.10: Living People\n"); 8 | Person[] people = new Person[4]; 9 | people[0] = new Person(1943, 1988); 10 | people[1] = new Person(1923, 1999); 11 | people[2] = new Person(1903, 1958); 12 | people[3] = new Person(1920, 1979); 13 | test(people, 1900, 2017); 14 | } 15 | 16 | private static void test(Person[] people, int startDate, int endDate) { 17 | int max = LivingPeople.maxAlive(people, startDate, endDate); 18 | System.out.println("Max alive year: " + max); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_11_Diving_Board/DivingBoard.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_11_Diving_Board; 4 | 5 | import java.util.*; 6 | 7 | public class DivingBoard { 8 | public static List allLengths(int k, int shorter, int longer) { 9 | List lengths = new ArrayList(); 10 | for (int numShorter = 0; numShorter <= k; numShorter++) { 11 | int numLonger = k - numShorter; 12 | int length = numShorter * shorter + numLonger * longer; 13 | lengths.add(length); 14 | } 15 | return lengths; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_11_Diving_Board/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_11_Diving_Board; 4 | 5 | import java.util.*; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** Test 16.11: Diving Board"); 10 | test(12, 1, 3); 11 | test(5, 2, 6); 12 | } 13 | 14 | private static void test(int k, int shortLength, int longLength) { 15 | System.out.println("\n k = " + k); 16 | System.out.println("shortLength = " + shortLength); 17 | System.out.println(" longLength = " + longLength); 18 | List lengths = DivingBoard.allLengths(k, shortLength, longLength); 19 | System.out.println("Possible lengths: " + lengths); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_12_XML_Encoding/DeadlockFreeClass: -------------------------------------------------------------------------------- 1 | Skip. Bad, outdated problem. -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_13_Bisect_Squares/BisectSquares: -------------------------------------------------------------------------------- 1 | Skip: no new concepts in this problem. 2 | 3 | Only trick is that the line goes through the center of the 2 squares. 4 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_14_Best_Line/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_14_Best_Line; 4 | 5 | import common.Point; 6 | import common.Line; 7 | 8 | public class Tester { 9 | public static void main(String[] args) { 10 | System.out.println("*** Test 16.9: Best Line\n"); 11 | Point[] points = new Point[4]; 12 | points[0] = new Point(1, 3); 13 | points[1] = new Point(2, 4); 14 | points[2] = new Point(3, 5); 15 | points[3] = new Point(13, 7); 16 | 17 | Line bestLine = BestLine.findBestLine(points); 18 | System.out.println("\nbestLine: " + bestLine); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_15_Master_Mind/Result.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_15_Master_Mind; 4 | 5 | public class Result { 6 | int directHits = 0; 7 | int pseudoHits = 0; 8 | 9 | @Override 10 | public String toString() { 11 | return ("(Direct Hits, Pseudo Hits) = (" + directHits + "," + pseudoHits + ")"); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_15_Master_Mind/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_15_Master_Mind; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 16.15: Master Mind"); 8 | test("RGBY", "GGRR"); 9 | test("RRRG", "GGRR"); 10 | test("YYBY", "BBBB"); 11 | } 12 | 13 | private static void test(String s1, String s2) { 14 | System.out.format("\nSolution = %s\nGuess = %s\n%s\n", s1, s2, MasterMind.estimate(s1, s2)); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_16_Sub_Sort/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_16_Sub_Sort; 4 | 5 | import java.util.Arrays; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** Test 16.16: Sub Sort"); 10 | test(new int[]{ 1, 2, 4, 7, 10, 11, 7, 12, 6, 7, 16, 18, 19 }); 11 | test(new int[]{ 1, 2, 4, 7, 10, 11, 12, 13, 16, 16, 18, 19 }); 12 | test(new int[]{ 4, 6, 5, 2, 9, 8, 7, 10 }); 13 | } 14 | 15 | private static void test(int[] array) { 16 | System.out.println("\nOriginal array: " + Arrays.toString(array)); 17 | SubSort.minMax(array); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_17_Contiguous_Sequence/ContiguousSequence.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_17_Contiguous_Sequence; 4 | 5 | public class ContiguousSequence { 6 | public static int maxSum(int[] array) { 7 | int runningSum = 0; 8 | int maxSum = 0; 9 | for (int i = 0; i < array.length; i++) { 10 | runningSum += array[i]; 11 | if (runningSum < 0) { 12 | runningSum = 0; 13 | } 14 | maxSum = Math.max(maxSum, runningSum); 15 | } 16 | return maxSum; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_17_Contiguous_Sequence/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_17_Contiguous_Sequence; 4 | 5 | import java.util.Arrays; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** Test 16.18: Contiguous Sequence"); 10 | test(new int[]{ 2, -8, 3, -2, 4, -10 }); 11 | test(new int[]{ -6, -8, -3, -2, -4, -10 }); 12 | } 13 | 14 | private static void test(int[] array) { 15 | System.out.println("\nOriginal array: " + Arrays.toString(array)); 16 | System.out.println("Max Subsequence = " + ContiguousSequence.maxSum(array)); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_18_Pattern_Matching/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_18_Pattern_Matching; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 16.18: Pattern Matching"); 8 | test("catcatgocatgo", "aabab"); 9 | test("catcatgocatgo", "bab"); 10 | test("foodfoodfood", "a"); 11 | test("foodfoodfood", "aa"); 12 | test("foodfoodfood", "aaa"); 13 | } 14 | 15 | private static void test(String value, String pattern) { 16 | System.out.println("\nvalue = " + value); 17 | System.out.println("pattern = " + pattern); 18 | System.out.println("Matches?: " + PatternMatching.matches(value, pattern)); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_19_Pond_Sizes/PondSizes.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_19_Pond_Sizes; 4 | 5 | import java.util.*; 6 | 7 | public class PondSizes { 8 | 9 | public static List findPonds(int[][] grid) { 10 | List pondSizes = new ArrayList(); 11 | int rows = grid.length; 12 | int cols = grid[0].length; 13 | for (int row = 0; row < rows; row++) { 14 | for (int col = 0; col < cols; col++) { 15 | if (grid[row][col] == 0) { 16 | int pondSize = findPondSize(grid, row, col, rows, cols); 17 | pondSizes.add(pondSize); 18 | } 19 | } 20 | } 21 | return pondSizes; 22 | } 23 | 24 | private static int findPondSize(int[][] grid, int row, int col, int rows, int cols) { 25 | if (row < 0 || row >= rows || col < 0 || col >= cols || grid[row][col] != 0) { 26 | return 0; 27 | } 28 | 29 | grid[row][col] = -1; // marks as visited 30 | int pondSize = 1; // 1 accounts for our size 31 | for (int r = row - 1; r <= row + 1; r++) { 32 | for (int c = col - 1; c <= col + 1; c++) { 33 | pondSize += findPondSize(grid, r, c, rows, cols); 34 | } 35 | } 36 | return pondSize; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_19_Pond_Sizes/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_19_Pond_Sizes; 4 | 5 | import java.util.*; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** Test 16.19: Pond Sizes\n"); 10 | int[][] grid = {{0, 2, 1, 0}, 11 | {0, 2, 0, 1}, 12 | {1, 1, 0, 1}, 13 | {0, 1, 0, 1}}; 14 | test(grid); 15 | } 16 | 17 | private static void test(int[][] grid) { 18 | List pondSizes = PondSizes.findPonds(grid); 19 | System.out.println(pondSizes); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_20_T9__HashMap_Solution/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_20_T9__HashMap_Solution; 4 | 5 | import java.util.*; 6 | 7 | public class Tester { 8 | private static String[] words = {"tree", "used", "ace", "bee", "bed", "tape", 9 | "mouse", "pan", "ran", "ninja", "ninjas"}; 10 | 11 | public static void main(String[] args) { 12 | System.out.println("*** Test 16.20: T9 - HashMap Solution\n"); 13 | T9 t9 = new T9(); 14 | Map> map = t9.buildMap(words); 15 | System.out.println("Matching words: "); 16 | for (String word : map.get("8733")) { 17 | System.out.println(word); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_20_T9__Trie_Solution/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_20_T9__Trie_Solution; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class Tester { 9 | private static String[] words = {"tree", "used", "ace", "bee", "bed", "tape", 10 | "mouse", "pan", "ran", "ninja", "ninjas"}; 11 | 12 | public static void main(String[] args) { 13 | System.out.println("*** Test 16.20: T9 - Trie Solution\n"); 14 | Trie trie = new Trie(words); 15 | List results = new ArrayList(); 16 | T9.getValidWords(new StringBuffer(), "8733", trie, trie.root, results); 17 | System.out.println("Matching words: " + results); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_20_T9__Trie_Solution/Trie.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_20_T9__Trie_Solution; 4 | 5 | class Trie { 6 | TrieNode root = new TrieNode(); 7 | 8 | Trie() {} // default constructor 9 | 10 | Trie(String[] words) { 11 | for (String word : words) { 12 | add(word); 13 | } 14 | } 15 | 16 | public void add(String str) { 17 | TrieNode curr = root; 18 | for (int i = 0; i < str.length(); i++) { 19 | Character ch = str.charAt(i); 20 | curr.putChildIfAbsent(ch); 21 | curr = curr.getChild(ch); 22 | curr.size++; 23 | } 24 | } 25 | 26 | public boolean find(String str) { 27 | TrieNode curr = root; 28 | for (int i = 0; i < str.length(); i++) { 29 | Character ch = str.charAt(i); 30 | curr = curr.getChild(ch); 31 | if (curr == null) { 32 | return false; 33 | } 34 | } 35 | return true; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_20_T9__Trie_Solution/TrieNode.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_20_T9__Trie_Solution; 4 | 5 | import java.util.HashMap; 6 | 7 | class TrieNode { 8 | private HashMap children = new HashMap(); 9 | public int size; 10 | 11 | public void putChildIfAbsent(char ch) { 12 | children.putIfAbsent(ch, new TrieNode()); 13 | } 14 | 15 | public TrieNode getChild(char ch) { 16 | return children.get(ch); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_21_Sum_Swap/SumSwap.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_21_Sum_Swap; 4 | 5 | import java.util.*; 6 | 7 | public class SumSwap { 8 | public static void toSwap(int[] arrayA, int[] arrayB) { 9 | int sum1 = Arrays.stream(arrayA).reduce(0, Integer::sum); 10 | int sum2 = Arrays.stream(arrayB).reduce(0, Integer::sum); 11 | if ((sum2 - sum1) % 2 != 0) { 12 | System.out.println("wont work"); 13 | return; 14 | } 15 | int difference = (sum2 - sum1) / 2; 16 | Set set = buildSet(arrayB); 17 | for (int numA : arrayA) { 18 | int neededNumB = numA + difference; 19 | if (set.contains(neededNumB)) { 20 | System.out.println("swap value " + numA + " from A\nwith value " + neededNumB + " from B"); 21 | return; 22 | } 23 | } 24 | System.out.println("no solution"); 25 | } 26 | 27 | private static Set buildSet(int[] array) { 28 | Set set = new HashSet(); 29 | for (int num : array) { 30 | set.add(num); 31 | } 32 | return set; 33 | } 34 | } 35 | 36 | // Time complexity: O(a + b) where a, b are size of arrays 37 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_21_Sum_Swap/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_21_Sum_Swap; 4 | 5 | import java.util.Arrays; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** Test 16.21: Sum Swap\n"); 10 | test(new int[]{ 4, 1, 2, 1, 1, 2 }, new int[]{ 3, 6, 3, 3 }); 11 | } 12 | 13 | private static void test(int[] arrayA, int[] arrayB) { 14 | System.out.println("arrayA: " + Arrays.toString(arrayA)); 15 | System.out.println("arrayB: " + Arrays.toString(arrayB)); 16 | SumSwap.toSwap(arrayA, arrayB); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_22_Langtons_Ant/LangtonsAnt: -------------------------------------------------------------------------------- 1 | Ant starts at Position(0,0). 2 | 3 | Instead of a 2-D array, use a HashSet to keep track of White squares. 4 | 5 | If a Position is not in the HashSet, it is a black square. 6 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_23_Rand7_from_Rand5/Rand7FromRand5.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_23_Rand7_from_Rand5; 4 | 5 | public class Rand7FromRand5 { 6 | public static int rand7() { 7 | while (true) { 8 | int num = 5 * rand5() + rand5(); // generates random number between 0 and 24. EVENLY DISTRIBUTED 9 | if (num < 21) { // discard values 21-24 since they unfairly weight towards 0-3 when doing %7 10 | return num % 7; 11 | } 12 | } 13 | } 14 | 15 | /* returns an "int": 0, 1, 2, 3, or 4 */ 16 | private static int rand5() { 17 | return (int) (Math.random() * 5); // casting to "int" always truncates 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_24_Pairs_with_Sum/Pair.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_24_Pairs_with_Sum; 4 | 5 | class Pair { // always places smaller value in "a" 6 | int a; 7 | int b; 8 | 9 | Pair(int a, int b) { 10 | this.a = Math.min(a, b); 11 | this.b = Math.max(a, b); 12 | } 13 | 14 | @Override 15 | public boolean equals(Object obj) { 16 | if (obj == this) { 17 | return true; 18 | } else if (obj == null || !(obj instanceof Pair)) { 19 | return false; 20 | } 21 | Pair otherPair = (Pair) obj; 22 | return a == otherPair.a && b == otherPair.b; 23 | } 24 | 25 | @Override 26 | public int hashCode() { 27 | return 2 * a + 3 * b; 28 | } 29 | 30 | @Override 31 | public String toString() { 32 | return "(" + a + "," + b + ")"; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_24_Pairs_with_Sum/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_24_Pairs_with_Sum; 4 | 5 | import java.util.Arrays; 6 | import java.util.HashSet; 7 | 8 | public class Tester { 9 | public static void main(String[] args) { 10 | System.out.print("*** Test 16.24: Pairs with Sum"); 11 | 12 | /* 2-sum: No duplicates in array */ 13 | testNoDuplicates(new int[]{ 2, 3, 7, 6, 9, 8, 1, 4, 5 }, 7); 14 | 15 | /* 2-sum: Duplicates in array */ 16 | testWithDuplicates(new int[]{ 5, 2, 7, 3, 1, 5, 7, 7 }, 12); 17 | } 18 | 19 | private static void testNoDuplicates(int[] array, int value) { 20 | System.out.println("\n\narray (no duplicates): " + Arrays.toString(array)); 21 | System.out.print("pairs: "); 22 | PairsWithSum.twoSum_NoDuplicatesExist(array, value); 23 | } 24 | 25 | private static void testWithDuplicates(int[] array, int value) { 26 | System.out.println("\n\narray (with duplicates): " + Arrays.toString(array)); 27 | 28 | /* Print all pairs summing to "value" */ 29 | System.out.print("all pairs: "); 30 | PairsWithSum.twoSum_PrintDuplicates(array, value); 31 | 32 | /* Print unique pairs summing to "value" */ 33 | System.out.print("\nunique pairs: "); 34 | HashSet pairs = PairsWithSum.twoSum_DontPrintDuplicates(array, value); 35 | for (Pair pair : pairs) { 36 | System.out.print(pair); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_25_LRU_Cache/DoublyLinkedList.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_25_LRU_Cache; 4 | 5 | public class DoublyLinkedList { 6 | private Node head = new Node(0, "dummy"); 7 | private Node tail = new Node(0, "dummy"); 8 | 9 | public DoublyLinkedList() { 10 | head.next = tail; 11 | tail.prev = head; 12 | } 13 | 14 | public void addFirst(Node n) { 15 | if (n == null) { 16 | return; 17 | } 18 | n.prev = head; 19 | n.next = head.next; 20 | head.next.prev = n; 21 | head.next = n; 22 | } 23 | 24 | public void remove(Node n) { // Assumes 'n' is in this list 25 | if (n == null || n.prev == null || n.next == null) { 26 | return; 27 | } 28 | n.prev.next = n.next; 29 | n.next.prev = n.prev; 30 | } 31 | 32 | public Node getFirst() { 33 | if (head.next == tail) { 34 | return null; // list has 0 Nodes 35 | } 36 | return head.next; 37 | } 38 | 39 | public Node getLast() { 40 | if (head.next == tail) { 41 | return null; // list has 0 Nodes 42 | } 43 | return tail.prev; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_25_LRU_Cache/Node.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_25_LRU_Cache; 4 | 5 | public class Node { // public variables for simplicity 6 | int key; 7 | String value; 8 | Node next; 9 | Node prev; 10 | 11 | public Node(int k, String v) { 12 | key = k; 13 | value = v; 14 | next = null; 15 | prev = null; 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | return value; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_25_LRU_Cache/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_25_LRU_Cache; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 16.25: LRU Cache\n"); 8 | 9 | // Create LRU Cache 10 | LRUCache cache = new LRUCache(7); 11 | for (int i = 20; i >= 1; i--) { 12 | cache.put(i, "Node " + i + " value"); 13 | } 14 | 15 | // Access Item 4, and print cache items 16 | cache.remove(1); 17 | cache.get(4); // should move it to head of cache 18 | Node n = cache.getItems().getFirst(); 19 | while (n != null) { 20 | System.out.println(n); 21 | n = n.next; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Chp. 16 - More Problems (Moderate)/_16_26_Calculator/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _16_26_Calculator; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 16.26: Calculator\n"); 8 | test("2-6-7*8/2+5"); 9 | } 10 | 11 | private static void test(String expression) { 12 | System.out.println(expression + " = " + Calculator.evaluate(expression)); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_01_Add_Without_Plus/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _17_01_Add_Without_Plus; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 17.1: Add Without Plus\n"); 8 | test(17, 34); 9 | test(-17, 34); 10 | test(17, -34); 11 | test(-17, -34); 12 | System.out.println(); 13 | test_2(17, 34); 14 | test_2(-17, 34); 15 | test_2(17, -34); 16 | test_2(-17, -34); 17 | System.out.println(); 18 | test(9, 65); 19 | test(-9, 65); 20 | test(9, -65); 21 | test(-9, -65); 22 | System.out.println(); 23 | test_2(9, 65); 24 | test_2(-9, 65); 25 | test_2(9, -65); 26 | test_2(-9, -65); 27 | } 28 | 29 | private static void test(int a, int b) { 30 | System.out.format("%3d + %3d = %3d\n", a, b, AddWithoutPlus.add(a, b)); 31 | } 32 | 33 | private static void test_2(int a, int b) { 34 | System.out.format("%3d + %3d = %3d\n", a, b, AddWithoutPlus.add_version2(a, b)); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_02_Shuffle/Shuffle.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _17_02_Shuffle; 4 | 5 | public class Shuffle { 6 | public void shuffle(int[] cards) { 7 | for (int i = 1; i < cards.length; i++) { 8 | int rand = (int) (Math.random() * (i + 1)); // random integer between 0 and i inclusive 9 | swap(cards, i, rand); 10 | } 11 | } 12 | 13 | private void swap(int[] cards, int i, int j) { 14 | int temp = cards[i]; 15 | cards[i] = cards[j]; 16 | cards[j] = temp; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_04_Missing_Number/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _17_04_Missing_Number; 4 | 5 | import java.util.ArrayList; 6 | import java.util.BitSet; 7 | 8 | public class Tester { 9 | public static void main(String[] args) { 10 | System.out.println("*** Test 17.4: Missing Number"); 11 | ArrayList array = new ArrayList(); 12 | // Testing note: I have to test this with all (except one) of the 3-digit binary numbers, since I set BitInteger.INTEGER_SIZE to 3 13 | 14 | for (int i = 0; i < 8; i++) { 15 | if (i != 2) { // will have numbers 0-7, but skips 2 16 | array.add(BitSet.valueOf(new long[] { i })); 17 | } 18 | } 19 | 20 | int missing = MissingNumber.findMissing(array); 21 | System.out.println("Missing # should be 2 (since array has 0 to 7, without 2) = " + missing); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_05_Letters_and_Numbers/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _17_05_Letters_and_Numbers; 4 | 5 | import java.util.Arrays; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** Test 17.5: Letters and Numbers\n"); 10 | test("aaaa11a11aa1aa1aaaaa"); 11 | test("a11a1"); 12 | } 13 | 14 | private static void test(String str) { 15 | System.out.print(str + " - "); 16 | char[] array = str.toCharArray(); 17 | char[] result = LettersAndNumbers.maxSubarray(array); 18 | if (result != null) { 19 | System.out.println(Arrays.toString(result)); 20 | } else { 21 | System.out.println("null result"); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_06_Count_of_2s/CountOf2s.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _17_06_Count_of_2s; 4 | 5 | /* Brute force solution. Book's other solution is too complicated for an interview */ 6 | public class CountOf2s { 7 | 8 | public static int count2s(int num) { 9 | int count = 0; 10 | for (int i = 2; i <= num; i++) { 11 | count += numberOf2s(i); 12 | } 13 | return count; 14 | } 15 | 16 | /* Counts number of 2s in a single number */ 17 | private static int numberOf2s(int num) { 18 | int count = 0; 19 | while (num > 0) { 20 | if (num % 10 == 2) { 21 | count++; 22 | } 23 | num /= 10; 24 | } 25 | return count; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_06_Count_of_2s/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _17_06_Count_of_2s; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 17.6: Count of 2s\n"); 8 | test(5); 9 | test(99); 10 | } 11 | 12 | private static void test(int n) { 13 | System.out.format("(from 1 to %2d): %2d\n", n, CountOf2s.count2s(n)); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_07_Baby_Names/BabyNames: -------------------------------------------------------------------------------- 1 | This question fundamentally boils down to creating Equivalence Classes. 2 | Disjoint sets are 1 way to do this but are overly complicated here. 3 | 4 | Solution 1: 5 | 6 | - Have each of the "n" name points to a set with 1 element. So we have "n" sets. 7 | - For every pair of elements that's equivalent, merge the 2 sets 8 | - Doing this in code is tricky. We have 2 options (I prefer option #2) 9 | 1) Somehow use a Multi-key HashMap where multiple keys map to same value 10 | 2) Basically use a standard HashMap as a multi-key hashmap. We would use 11 | HashMap>, and it's okay that 2 keys point 12 | to the same ArrayList. Make sure it's the SAME ArrayList though and 13 | not a copy of it. 14 | - Runtime would be O(n log n) since it's kind of like the tree for mergesort 15 | 16 | 17 | Solution 2 (preferred): 18 | 19 | - Represent this as a Graph. Names are Nodes. Pairs of names are Edges. 20 | - Generating the desired output is simply doing a BFS or DFS on each connected 21 | component, while summing the values at each node. 22 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_08_Circus_Tower/CircusTower: -------------------------------------------------------------------------------- 1 | This problem is a simplified version of problem 8.3: "Stack of Boxes". Do that problem instead. 2 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_08_Circus_Tower/CircusTower.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _17_08_Circus_Tower; 4 | 5 | import java.util.*; 6 | 7 | public class CircusTower { 8 | public static int findMax(int[][] persons) { 9 | if (persons == null || persons.length == 0 || persons[0].length != 2) { 10 | return 0; 11 | } 12 | Arrays.sort(persons, (a, b) -> { 13 | if (a[0] != b[0]) { 14 | return a[0] - b[0]; 15 | } else { 16 | return b[1] - a[1]; 17 | } 18 | }); 19 | 20 | int[] sortedArray = new int[persons.length]; 21 | int size = 0; 22 | for (int[] person : persons) { 23 | int num = person[1]; 24 | int start = 0; 25 | int end = size; // 1 element past end of our sortedArray 26 | while (start != end) { 27 | int mid = (start + end) / 2; 28 | if (sortedArray[mid] < num) { 29 | start = mid + 1; 30 | } else { 31 | end = mid; 32 | } 33 | } 34 | sortedArray[start] = num; 35 | if (start == size) { 36 | size++; 37 | } 38 | } 39 | return size; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_08_Circus_Tower/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _17_08_Circus_Tower; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 8.13: Stack of Boxes\n"); 8 | int result = CircusTower.findMax(new int[][]{{2, 3}, {3, 3}, {4,3}, {5, 5}}); 9 | System.out.println(result); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_09_Kth_Multiple/KthMultiple.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _17_09_Kth_Multiple; 4 | 5 | // Different than book's solution. Algorithm is Method 2 from: https://www.geeksforgeeks.org/ugly-numbers/ 6 | 7 | public class KthMultiple { 8 | public static int getKthMagicNumber(int k) { 9 | if (k < 0) { 10 | return -1; 11 | } 12 | 13 | int[] magic = new int[k]; 14 | magic[0] = 1; 15 | 16 | int i3 = 0; 17 | int i5 = 0; 18 | int i7 = 0; 19 | 20 | for (int i = 1; i < k; i++) { 21 | magic[i] = Math.min(magic[i3] * 3, Math.min(magic[i5] * 5, magic[i7] * 7)); 22 | if (magic[i] == magic[i3] * 3) { 23 | i3++; 24 | } 25 | if (magic[i] == magic[i5] * 5) { 26 | i5++; 27 | } 28 | if (magic[i] == magic[i7] * 7) { 29 | i7++; 30 | } 31 | } 32 | return magic[k-1]; 33 | } 34 | } 35 | 36 | // Time Complexity: O(n) 37 | // Space Complexity: O(n) 38 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_09_Kth_Multiple/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _17_09_Kth_Multiple; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 17.9: Kth Multiple\n"); 8 | System.out.print("Magic numbers:"); 9 | for (int i = 1; i <= 10; i++) { 10 | System.out.print(" " + KthMultiple.getKthMagicNumber(i)); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_10_Majority_Element/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _17_10_Majority_Element; 4 | 5 | import java.util.Arrays; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** Test 17.10: Majority Element"); 10 | test(new int[]{ 1, 2, 5, 9, 5, 9, 5, 5, 5 }); 11 | test(new int[]{ 3, 1, 7, 1, 1, 7, 7, 3, 7, 7, 7 }); 12 | test(new int[]{ 1, 2, 2, 3 }); 13 | } 14 | 15 | private static void test(int[] array) { 16 | System.out.print("\n" + Arrays.toString(array) + "\nmajority element = "); 17 | System.out.println(MajorityElement.majorityElement(array)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_11_Word_Distance/Pair.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _17_11_Word_Distance; 4 | 5 | public class Pair { 6 | public Integer num; 7 | public boolean fromListA; 8 | 9 | public Pair(Integer n, boolean bool) { 10 | num = n; 11 | fromListA = bool; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_11_Word_Distance/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _17_11_Word_Distance; 4 | 5 | import java.util.Arrays; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** Test 17.11: Word Distance\n"); 10 | String[] file = { "hey", "there", "hi", "food", "there", "now", "hope", "hi", "food", "now", "gone", "hey" }; 11 | System.out.println(Arrays.toString(file)); 12 | WordDistance.preProcess(file); 13 | test(file, "there", "food"); 14 | test(file, "now", "hi"); 15 | test(file, "gone", "hi"); 16 | } 17 | 18 | private static void test(String[] file, String s1, String s2) { 19 | System.out.format("\n(Solution 1) (%s, %s) Distance = %d", s1, s2, WordDistance.shortest(file, s1, s2)); 20 | System.out.format("\n(Solution 2) (%s, %s) Distance = %d\n", s1, s2, WordDistance.shortest2(s1, s2)); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_12_BiNode/BiNode.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _17_12_BiNode; 4 | 5 | public class BiNode { 6 | public BiNode left, right; 7 | public int data; 8 | 9 | public BiNode(int d) { 10 | left = null; 11 | right = null; 12 | data = d; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_12_BiNode/NodePair.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _17_12_BiNode; 4 | 5 | class NodePair { 6 | BiNode head; 7 | BiNode tail; 8 | 9 | public NodePair(BiNode h, BiNode t) { 10 | head = h; 11 | tail = t; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_13_ReSpace/ReSpace: -------------------------------------------------------------------------------- 1 | Skip: Great problem, but way too difficult to be asked on an interview 2 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_14_Smallest_K/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _17_14_Smallest_K; 4 | 5 | import java.util.Arrays; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** Test 17.14: Smallest K\n"); 10 | int[] array = { 52, 10, 39, 26, 42, 31, 26, 0, 6, 19, 61, 33, 14, 26, 22, 25 }; 11 | System.out.println(Arrays.toString(array)); 12 | test(array, 3); 13 | test(array, 9); 14 | test(array, 12); 15 | } 16 | 17 | private static void test(int[] array, int k) { 18 | System.out.format("\n%2d Smallest: ", k); 19 | SmallestK.findNthSmallestNums(array, k); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_15_Longest_Word/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _17_15_Longest_Word; 4 | 5 | import java.util.Arrays; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** Test 17.15: Longest Word"); 10 | test(new String[]{ "cat", "banana", "dog", "nana", "walk", "walker", "dogwalker", "spectaculous" }); 11 | test(new String[]{ "cat", "banana", "dog", "nana", "walk", "nanadogwalkercat", "walker", "dogwalker" }); 12 | } 13 | 14 | private static void test(String[] array) { 15 | System.out.println("\n" + Arrays.toString(array)); 16 | System.out.println("Solution: " + LongestWord.longestWord(array)); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_16_The_Masseuse/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _17_16_The_Masseuse; 4 | 5 | import java.util.Arrays; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** Test 17.16: The Masseuse\n"); 10 | test(new int[]{ 30, 15, 60, 75, 45, 15, 15, 45 }); 11 | } 12 | 13 | private static void test(int[] array) { 14 | System.out.println(Arrays.toString(array)); 15 | System.out.println("Solution 1: " + TheMasseuse.maxMinutes1(array)); 16 | System.out.println("Solution 2: " + TheMasseuse.maxMinutes2(array)); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_17_Multi_Search/MultiSearch: -------------------------------------------------------------------------------- 1 | This problem requires knowledge of suffix trees. 2 | 3 | First master Tries, then try this problem. 4 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_18_Shortest_Supersequence/HeapNode.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _17_18_Shortest_Supersequence; 4 | 5 | public class HeapNode { 6 | int value; // same as the value that's the key in our HashMap 7 | int index; // index in array it came from 8 | 9 | HeapNode(int listID, int pos) { 10 | this.value = listID; 11 | this.index = pos; 12 | } 13 | 14 | @Override 15 | public String toString() { 16 | return "" + index; 17 | } 18 | } -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_18_Shortest_Supersequence/Range.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _17_18_Shortest_Supersequence; 4 | 5 | public class Range { 6 | Integer min; 7 | Integer max; 8 | 9 | Range(int min, int max) { 10 | this.min = min; 11 | this.max = max; 12 | } 13 | 14 | Range(Range other) { 15 | min = other.min; 16 | max = other.max; 17 | } 18 | 19 | void setRange(Range other) { 20 | min = other.min; 21 | max = other.max; 22 | } 23 | 24 | boolean isShorterThan(Range other) { 25 | return size() < other.size(); 26 | } 27 | 28 | int size() { 29 | return max - min + 1; 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return "[" + min + "," + max + "]"; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_18_Shortest_Supersequence/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _17_18_Shortest_Supersequence; 4 | 5 | import java.util.Arrays; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** Test 17.18: Shortest Supersequence \n"); 10 | int[] arrayA = new int[]{ 1, 5, 9 }; 11 | int[] arrayB = new int[]{ 7, 5, 9, 9, 2, 1, 3, 5, 7, 9, 1, 1, 5, 8, 8, 9, 7 }; 12 | test(arrayA, arrayB); 13 | } 14 | 15 | private static void test(int[] arrayA, int[] arrayB) { 16 | System.out.println(Arrays.toString(arrayA)); 17 | System.out.println(Arrays.toString(arrayB)); 18 | Range range = ShortestSupersequence.shortest(arrayA, arrayB); 19 | System.out.println("Range: " + range); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_19_Missing_Two/MissingTwo: -------------------------------------------------------------------------------- 1 | Let's label the 2 missing numbers as "a" and "b". 2 | 3 | Formula 1: Sum of 1 to n is (n)(n+1)/2 4 | Formula 2: Sum of squares of 1 to n is 1^2 + 2^2 + .... n^2 5 | 6 | We can calculate "ActualValue" by using the 2 formulas above, giving us: 7 | 8 | ActualValue + a + b = (n)(n+1)/2 9 | ActualValue + a^2 + b^2 = 1^2 + 2^2 + .... n^2 10 | 11 | Since ActualValue and "n" are both known, this gives us 2 formulas with 2 unknowns: a, b 12 | 13 | We can solve these 2 equations for "a" and "b" (giving us the 2 missing numbers) 14 | 15 | Note: We dont use 1*2*...*n as a formula since that will likely cause integer overflow 16 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_20_Continuous_Median/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _17_20_Continuous_Median; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 17.20: Continuous Median\n"); 8 | for (int i = 0; i < 5; i++) { 9 | ContinuousMedian.addNum(i); 10 | System.out.println("Add " + i + " to data structure. Median = " + ContinuousMedian.getMedian()); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_21_Volume_of_Histogram/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _17_21_Volume_of_Histogram; 4 | 5 | import java.util.Arrays; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** Test 17.21: Volume of Histogram\n"); 10 | int[] histogram = { 0, 0, 4, 0, 0, 6, 0, 0, 3, 0, 5, 0, 1, 0, 0, 0 }; 11 | test(histogram); 12 | } 13 | 14 | private static void test(int[] histogram) { 15 | System.out.println(Arrays.toString(histogram)); 16 | int result = VolumeOfHistogram.computeHistogramVolume(histogram); 17 | System.out.println("volume of histogram = " + result); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_21_Volume_of_Histogram/VolumeOfHistogram.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _17_21_Volume_of_Histogram; 4 | 5 | // Main idea: For each index, 2 walls (the tallest wall anywhere to the left, and to the right), together 6 | // determine the amount of water the index will hold. We can calculate this iteratively. 7 | 8 | public class VolumeOfHistogram { 9 | public static int computeHistogramVolume(int[] height) { 10 | if (height == null || height.length <= 1) { 11 | return 0; 12 | } 13 | int size = height.length; 14 | 15 | // Calculate left maxes 16 | int[] leftMax = new int[size]; 17 | leftMax[0] = height[0]; 18 | for (int i = 1; i < size; i++) { 19 | leftMax[i] = Math.max(leftMax[i - 1], height[i]); 20 | } 21 | 22 | // Calculate right maxes 23 | int[] rightMax = new int[size]; 24 | rightMax[size - 1] = height[size - 1]; 25 | for (int i = size - 2; i >= 0; i--) { 26 | rightMax[i] = Math.max(rightMax[i + 1], height[i]); 27 | } 28 | 29 | // Calculate amount of water that can be stored above each spot on histogram 30 | int water = 0; 31 | for (int i = 1; i < size - 1; i++) { 32 | water += Math.min(leftMax[i], rightMax[i]) - height[i]; 33 | } 34 | return water; 35 | } 36 | } 37 | 38 | // Time Complexity: O(n) 39 | // Space Complexity: O(n) 40 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_22_Word_Transformer/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _17_22_Word_Transformer; 4 | 5 | import java.util.ArrayDeque; 6 | 7 | public class Tester { 8 | public static void main(String[] args) { 9 | System.out.println("*** Test 17.22: Word Transformer\n"); 10 | WordTransformer.setUpDict(); 11 | test("Damp", "Like"); 12 | } 13 | 14 | private static void test(String s1, String s2) { 15 | ArrayDeque solution = WordTransformer.convert(s1, s2); 16 | System.out.println(solution); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_23_Max_Black_Square/Cell.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _17_23_Max_Black_Square; 4 | 5 | public class Cell { // public variables for simplicity 6 | int blacksRight = 0; // including itself 7 | int blacksDown = 0; // including itself 8 | 9 | public Cell(int right, int down) { 10 | blacksRight = right; 11 | blacksDown = down; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_23_Max_Black_Square/Subsquare.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _17_23_Max_Black_Square; 4 | 5 | public class Subsquare { 6 | int row; 7 | int col; 8 | int length; 9 | 10 | public Subsquare(int r, int c, int l) { 11 | row = r; 12 | col = c; 13 | length = l; 14 | } 15 | 16 | @Override 17 | public String toString() { 18 | return "row = " + row + " col = " + col + " length = " + length; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_23_Max_Black_Square/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _17_23_Max_Black_Square; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 17.23: Max Black Square\n"); 8 | int[][] matrix = {{1,0,1,1,1}, 9 | {1,1,1,0,1}, 10 | {1,1,1,1,1}, 11 | {1,1,1,1,0}, 12 | {1,0,1,0,1}}; 13 | test(matrix); 14 | } 15 | 16 | private static void test(int[][] matrix) { 17 | System.out.println(MaxBlackSquare.findLargestSubsquare(matrix)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_24_Max_Submatrix/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package _17_24_Max_Submatrix; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test 17.24: Max Submatrix\n"); 8 | int[][] matrix = {{ 1,-2, 3, 1}, 9 | { 1, 5,-4, 1}, 10 | { 1, 1, 0, 2}, 11 | {-1, 1, 1,-8}, 12 | {-8,-9, 9,-3}}; 13 | test(matrix); 14 | } 15 | 16 | private static void test(int[][] matrix) { 17 | System.out.println("(Solution 1): " + MaxSubmatrix.findLargestSubmatrix(matrix)); 18 | System.out.println("(Solution 2): " + MaxSubmatrix.findLargestSubmatrix2(matrix)); 19 | System.out.println("(Solution 3): " + MaxSubmatrix.findLargestSubmatrix3(matrix)); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_25_Word_Rectangle/WordRectangle: -------------------------------------------------------------------------------- 1 | Skip. Way too difficult to be asked on an interview. -------------------------------------------------------------------------------- /Chp. 17 - More Problems (Hard)/_17_26_Sparse_Similarity/SparseSimilarity: -------------------------------------------------------------------------------- 1 | Skip. Too long and complicated for an interview. -------------------------------------------------------------------------------- /Common/common/BitFunctions.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package common; 4 | 5 | public class BitFunctions { 6 | public static boolean getBit(int num, int bit) { 7 | return (num & (1 << bit)) != 0; 8 | } 9 | 10 | public static int setBit(int num, int bit) { 11 | return num | (1 << bit); 12 | } 13 | 14 | public static int clearBit(int num, int bit) { 15 | int mask = ~(1 << bit); 16 | return num & mask; 17 | } 18 | 19 | public static int clearBitsMSBthroughI(int num, int bit) { 20 | int mask = (1 << bit) - 1; // subtracting 1 is the main trick. 21 | return num & mask; 22 | } 23 | 24 | public static int clearBitsIthrough0(int num, int bit) { 25 | int mask = ~((1 << (bit + 1)) - 1); 26 | return num & mask; 27 | } 28 | 29 | /* Used in Question 5.5 */ 30 | public static int numOnes(int num) { 31 | int count = 0; 32 | for (int i = 0; i < Integer.SIZE; i++) { 33 | if ((num & 1) == 1) { 34 | count++; 35 | } 36 | num >>= 1; 37 | } 38 | return count; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Common/common/Functions.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package common; 4 | 5 | public class Functions { 6 | public static void printImage(int[][] image) { 7 | int rows = image.length; 8 | int cols = image[0].length; 9 | for (int row = 0; row < rows; row++) { 10 | for (int col = 0; col < cols; col++) { 11 | System.out.printf("%2d ", image[row][col]); 12 | } 13 | System.out.println(); 14 | } 15 | System.out.println(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Common/common/GraphNode.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package common; 4 | 5 | import java.util.ArrayList; 6 | 7 | // - Here, our graph is implemented somewhat like a Graph "Adjacency List" like in CS 225. 8 | // - Edges are not directly stored. Instead, a node's neighbors are saved in an ArrayList 9 | 10 | public class GraphNode { 11 | public int data; 12 | public boolean visited; // needed for BFS, DFS 13 | private ArrayList neighbors; // can alternatively use a HashSet (and give nodes unique IDs) 14 | 15 | /* Constructor */ 16 | public GraphNode(int data) { 17 | this.data = data; 18 | visited = false; 19 | neighbors = new ArrayList(); 20 | } 21 | 22 | public void visit() { 23 | visited = true; 24 | } 25 | 26 | public ArrayList getNeighbors() { 27 | return neighbors; 28 | } 29 | 30 | public void addNeighbor(GraphNode neighbor) { 31 | neighbors.add(neighbor); 32 | neighbor.neighbors.add(this); 33 | } 34 | 35 | public void addDirectedNeighbor(GraphNode neighbor) { 36 | neighbors.add(neighbor); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Common/common/Node.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package common; 4 | 5 | /* Implementation of SINGLY-linked list */ 6 | /* In interview, ask if it's DOUBLY or SINGLY linked */ 7 | public class Node { 8 | /* Data */ 9 | public Node next = null; 10 | public int data = 0; 11 | 12 | /* Constructor */ 13 | public Node(int d) { 14 | data = d; 15 | } 16 | 17 | /* Constructor - Converts array to singly linked list (added for testing) */ 18 | public Node(int[] array) { 19 | data = array[0]; 20 | Node curr = this; 21 | for (int i = 1; i < array.length; i++) { 22 | curr.next = new Node(array[i]); 23 | curr = curr.next; 24 | } 25 | } 26 | 27 | /* Creates a Node and appends it to tail of linked list */ 28 | public void appendToTail(int d) { 29 | Node n = this; // slick move 30 | while (n.next != null) { 31 | n = n.next; 32 | } 33 | n.next = new Node(d); 34 | } 35 | 36 | public void appendToTail(Node nodeToPut) { 37 | Node n = this; // slick move 38 | while (n.next != null) { 39 | n = n.next; 40 | } 41 | n.next = nodeToPut; 42 | } 43 | 44 | // More functions written in ListFunctions.java 45 | } 46 | -------------------------------------------------------------------------------- /Common/common/Point.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package common; 4 | 5 | public class Point { 6 | double x; 7 | double y; 8 | 9 | public Point(double x, double y) { 10 | this.x = x; 11 | this.y = y; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Common/common/TreeNode.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package common; 4 | 5 | // This represents a binary Tree. If we wanted an n-ary tree, 6 | // we would use an array of TreeNodes as children 7 | 8 | public class TreeNode { 9 | public TreeNode left = null; 10 | public TreeNode right = null; 11 | public TreeNode parent = null; // Needed for problem 4.6 12 | public int data; 13 | 14 | public TreeNode(int data) { 15 | this.data = data; 16 | } 17 | 18 | /* Useful for Problem 4.6 */ 19 | public void addLeftChild(int data) { 20 | TreeNode node = new TreeNode(data); 21 | left = node; 22 | node.parent = this; 23 | } 24 | 25 | /* Useful for Problem 4.6 */ 26 | public void addRightChild(int data) { 27 | TreeNode node = new TreeNode(data); 28 | right = node; 29 | node.parent = this; 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return String.valueOf(data) + " "; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Introduction/introduction/ABCD.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package introduction; 4 | 5 | import java.util.ArrayList; 6 | import java.util.HashMap; 7 | 8 | /* Prints pairs where a^3 + b^3 = c^3 + d^3 */ 9 | 10 | public class ABCD { 11 | public static void printPairs() { 12 | /* Put Pairs in HashMap */ 13 | HashMap> map = new HashMap(); 14 | for (int i = 0; i < 100; i++) { 15 | for (int j = 0; j < 100; j++) { 16 | int result = i*i*i + j*j*j; 17 | map.putIfAbsent(result, new ArrayList()); 18 | ArrayList list = map.get(result); 19 | list.add(new Pair(i, j)); 20 | } 21 | } 22 | 23 | /* Print pairs of Pairs */ 24 | for (Integer num : map.keySet()) { 25 | ArrayList pairs = map.get(num); 26 | for (int i = 0; i < pairs.size(); i++) { 27 | for (int j = 0; j < pairs.size(); j++) { 28 | Pair pair1 = pairs.get(i); 29 | Pair pair2 = pairs.get(j); 30 | System.out.println(pair1 + " " + pair2); 31 | } 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Introduction/introduction/Pair.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package introduction; 4 | 5 | public class Pair { 6 | int a; 7 | int b; 8 | 9 | Pair(int a, int b) { 10 | this.a = a; 11 | this.b = b; 12 | } 13 | 14 | @Override 15 | public String toString() { 16 | return "(" + a + "," + b + ")"; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Introduction/introduction/Tester.java: -------------------------------------------------------------------------------- 1 | // github.com/RodneyShag 2 | 3 | package introduction; 4 | 5 | public class Tester { 6 | public static void main(String[] args) { 7 | System.out.println("*** Test print pairs\n"); 8 | ABCD.printPairs(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /screenshots/instructions_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RodneyShag/Cracking-the-Coding-Interview_solutions/1c3e6c954ab20d2b5254e1dc9179cc5bf35193ee/screenshots/instructions_1.png -------------------------------------------------------------------------------- /screenshots/instructions_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RodneyShag/Cracking-the-Coding-Interview_solutions/1c3e6c954ab20d2b5254e1dc9179cc5bf35193ee/screenshots/instructions_2.png -------------------------------------------------------------------------------- /screenshots/instructions_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RodneyShag/Cracking-the-Coding-Interview_solutions/1c3e6c954ab20d2b5254e1dc9179cc5bf35193ee/screenshots/instructions_3.png -------------------------------------------------------------------------------- /screenshots/instructions_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RodneyShag/Cracking-the-Coding-Interview_solutions/1c3e6c954ab20d2b5254e1dc9179cc5bf35193ee/screenshots/instructions_4.png -------------------------------------------------------------------------------- /screenshots/instructions_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RodneyShag/Cracking-the-Coding-Interview_solutions/1c3e6c954ab20d2b5254e1dc9179cc5bf35193ee/screenshots/instructions_5.png --------------------------------------------------------------------------------