From b8908be72993c6ed0887a1e0c6f92265d344c0da Mon Sep 17 00:00:00 2001 From: Kevin Naughton Jr Date: Tue, 20 Mar 2018 14:37:10 -0400 Subject: [PATCH 1/2] reformatting files --- company/amazon/ThreeSum.java | 52 +++++++++ .../Chapter1ArraysAndStrings/DeleteDups.java | 18 +++ .../Chapter1ArraysAndStrings/IsRotation.java | 17 +++ .../IsUniqueChars.java | 15 +++ .../Chapter1ArraysAndStrings/NthToLast.java | 27 +++++ .../Chapter1ArraysAndStrings/Permutation.java | 25 +++++ .../ReplaceSpaces.java | 30 +++++ .../Chapter2LinkedLists/DeleteDups.java | 18 +++ .../Chapter2LinkedLists/DeleteNode.java | 14 +++ .../Chapter2LinkedLists/FindBeginning.java | 36 ++++++ .../Chapter2LinkedLists/IsPalindrome.java | 38 +++++++ .../Chapter2LinkedLists/NthToLast.java | 0 .../Chapter2LinkedLists/Partition.java | 28 +++++ .../BinaryTreeIsBalanced.java | 26 +++++ .../Chapter3StacksAndQueues/MyQueue.java | 40 +++++++ .../QueueUsingTwoStacks.java | 5 + .../Chapter3StacksAndQueues/SetOfStacks.java | 44 ++++++++ .../Chapter3StacksAndQueues/SortStack.java | 18 +++ .../Chapter3StacksAndQueues/StackWithMin.java | 26 +++++ .../Chapter3StacksAndQueues/ThreeStacks.java | 44 ++++++++ .../TowersOfHanoi.java | 59 ++++++++++ .../BinaryTreeIsBalanced.java | 26 +++++ .../CreateBinarySearchTree.java | 19 ++++ .../CreateLinkedListForEachLevel.java | 29 +++++ .../Chapter4TreesAndGraphs/FindPath.java | 40 +++++++ .../Chapter4TreesAndGraphs/IsSubtree.java | 37 +++++++ .../Chapter4TreesAndGraphs/PrintPaths.java | 53 +++++++++ .../ValidBinarySearchTree.java | 21 ++++ .../BinaryRepresentation.java | 31 ++++++ .../FindMissingInteger.java | 37 +++++++ .../Chapter5BitManipulation/InsertMIntoN.java | 33 ++++++ .../Chapter5BitManipulation/SwapBits.java | 8 ++ .../Operations.java | 66 +++++++++++ .../WouldIntersect.java | 20 ++++ .../AllPermutations.java | 31 ++++++ .../AllSubsets.java | 24 ++++ .../EightQueens.java | 48 ++++++++ .../MagicIndex.java | 24 ++++ .../RepresentingNCents.java | 26 +++++ .../StackBoxes.java | 35 ++++++ .../Staircase.java | 22 ++++ .../CrackingTheCodingInterview.iml | 12 ++ .../closestBinarySearchTreeValue.java | 30 +++++ leetcode/binary-search/firstBadVersion.java | 29 +++++ .../guessNumberHigherOrLower.java | 46 ++++++++ leetcode/binary-search/pow(x,n).java | 30 +++++ leetcode/binary-search/sqrt(x).java | 28 +++++ leetcode/bit-manipulation/binaryWatch.java | 45 ++++++++ leetcode/bit-manipulation/countingBits.java | 23 ++++ .../bit-manipulation/hammingDistance.java | 29 +++++ .../maximumProductOfWordLengths.java | 61 ++++++++++ leetcode/bit-manipulation/numberOf1Bits.java | 25 +++++ .../bit-manipulation/sumOfTwoIntegers.java | 25 +++++ .../bit-manipulation/utf-8Validation.java | 63 +++++++++++ .../binaryTreeLevelOrderTraversal.java | 81 ++++++++++++++ leetcode/breadth-first-search/cloneGraph.java | 54 +++++++++ .../pacificAtlanticWaterFlow.java | 100 +++++++++++++++++ .../removeInvalidParentheses.java | 41 +++++++ .../shortestDistanceFromAllBuildings.java | 104 ++++++++++++++++++ .../breadth-first-search/symmetricTree.java | 46 ++++++++ .../breadth-first-search/wallsAndGates.java | 60 ++++++++++ .../balancedBinaryTree.java | 42 +++++++ .../battleshipsInABoard.java | 61 ++++++++++ .../convertSortedArrayToBinarySearchTree.java | 43 ++++++++ .../maximumDepthOfABinaryTree.java | 24 ++++ .../depth-first-search/numberOfIslands.java | 71 ++++++++++++ ...populatingNextRightPointersInEachNode.java | 81 ++++++++++++++ leetcode/depth-first-search/sameTree.java | 30 +++++ .../expressionAddOperators.java | 58 ++++++++++ .../kthLargestElementInAnArray.java | 19 ++++ leetcode/dynamic-programming/bombEnemy.java | 87 +++++++++++++++ .../dynamic-programming/climbingStairs.java | 26 +++++ .../dynamic-programming/combinationSumIV.java | 50 +++++++++ .../dynamic-programming/countingBits.java | 29 +++++ .../dynamic-programming/editDistance.java | 59 ++++++++++ leetcode/dynamic-programming/houseRobber.java | 33 ++++++ leetcode/dynamic-programming/paintFence.java | 35 ++++++ .../dynamic-programming/paintHouseII.java | 65 +++++++++++ .../regularExpressionMatching.java | 79 +++++++++++++ .../sentenceScreenFitting.java | 88 +++++++++++++++ .../uniqueBinarySearchTrees.java | 34 ++++++ leetcode/dynamic-programming/wordBreak.java | 34 ++++++ leetcode/linked-list/README.md | 1 + leetcode/linked-list/addTwoNumbers.java | 62 +++++++++++ .../linked-list/deleteNodeInALinkedList.java | 22 ++++ leetcode/linked-list/mergeKSortedLists.java | 46 ++++++++ .../linked-list/palindromeLinkedList.java | 45 ++++++++ leetcode/linked-list/plusOneLinkedList.java | 59 ++++++++++ leetcode/linked-list/reverseLinkedList.java | 32 ++++++ leetcode/two-pointers/3Sum.java | 73 ++++++++++++ leetcode/two-pointers/3SumSmaller.java | 62 +++++++++++ leetcode/two-pointers/mergeSortedArray.java | 28 +++++ .../two-pointers/minimumSizeSubarraySum.java | 34 ++++++ leetcode/two-pointers/moveZeros.java | 36 ++++++ .../removeDuplicatesFromSortedArray.java | 33 ++++++ leetcode/two-pointers/reverseString.java | 26 +++++ leetcode/two-pointers/sortColors.java | 42 +++++++ 97 files changed, 3791 insertions(+) create mode 100644 company/amazon/ThreeSum.java create mode 100644 cracking-the-coding-interview/Chapter1ArraysAndStrings/DeleteDups.java create mode 100644 cracking-the-coding-interview/Chapter1ArraysAndStrings/IsRotation.java create mode 100644 cracking-the-coding-interview/Chapter1ArraysAndStrings/IsUniqueChars.java create mode 100644 cracking-the-coding-interview/Chapter1ArraysAndStrings/NthToLast.java create mode 100644 cracking-the-coding-interview/Chapter1ArraysAndStrings/Permutation.java create mode 100644 cracking-the-coding-interview/Chapter1ArraysAndStrings/ReplaceSpaces.java create mode 100644 cracking-the-coding-interview/Chapter2LinkedLists/DeleteDups.java create mode 100644 cracking-the-coding-interview/Chapter2LinkedLists/DeleteNode.java create mode 100644 cracking-the-coding-interview/Chapter2LinkedLists/FindBeginning.java create mode 100644 cracking-the-coding-interview/Chapter2LinkedLists/IsPalindrome.java create mode 100644 cracking-the-coding-interview/Chapter2LinkedLists/NthToLast.java create mode 100644 cracking-the-coding-interview/Chapter2LinkedLists/Partition.java create mode 100644 cracking-the-coding-interview/Chapter3StacksAndQueues/BinaryTreeIsBalanced.java create mode 100644 cracking-the-coding-interview/Chapter3StacksAndQueues/MyQueue.java create mode 100644 cracking-the-coding-interview/Chapter3StacksAndQueues/QueueUsingTwoStacks.java create mode 100644 cracking-the-coding-interview/Chapter3StacksAndQueues/SetOfStacks.java create mode 100644 cracking-the-coding-interview/Chapter3StacksAndQueues/SortStack.java create mode 100644 cracking-the-coding-interview/Chapter3StacksAndQueues/StackWithMin.java create mode 100644 cracking-the-coding-interview/Chapter3StacksAndQueues/ThreeStacks.java create mode 100644 cracking-the-coding-interview/Chapter3StacksAndQueues/TowersOfHanoi.java create mode 100644 cracking-the-coding-interview/Chapter4TreesAndGraphs/BinaryTreeIsBalanced.java create mode 100644 cracking-the-coding-interview/Chapter4TreesAndGraphs/CreateBinarySearchTree.java create mode 100644 cracking-the-coding-interview/Chapter4TreesAndGraphs/CreateLinkedListForEachLevel.java create mode 100644 cracking-the-coding-interview/Chapter4TreesAndGraphs/FindPath.java create mode 100644 cracking-the-coding-interview/Chapter4TreesAndGraphs/IsSubtree.java create mode 100644 cracking-the-coding-interview/Chapter4TreesAndGraphs/PrintPaths.java create mode 100644 cracking-the-coding-interview/Chapter4TreesAndGraphs/ValidBinarySearchTree.java create mode 100644 cracking-the-coding-interview/Chapter5BitManipulation/BinaryRepresentation.java create mode 100644 cracking-the-coding-interview/Chapter5BitManipulation/FindMissingInteger.java create mode 100644 cracking-the-coding-interview/Chapter5BitManipulation/InsertMIntoN.java create mode 100644 cracking-the-coding-interview/Chapter5BitManipulation/SwapBits.java create mode 100644 cracking-the-coding-interview/Chapter7MathematicsAndProbability/Operations.java create mode 100644 cracking-the-coding-interview/Chapter7MathematicsAndProbability/WouldIntersect.java create mode 100644 cracking-the-coding-interview/Chapter9RecursionAndDynamicProgramming/AllPermutations.java create mode 100644 cracking-the-coding-interview/Chapter9RecursionAndDynamicProgramming/AllSubsets.java create mode 100644 cracking-the-coding-interview/Chapter9RecursionAndDynamicProgramming/EightQueens.java create mode 100644 cracking-the-coding-interview/Chapter9RecursionAndDynamicProgramming/MagicIndex.java create mode 100644 cracking-the-coding-interview/Chapter9RecursionAndDynamicProgramming/RepresentingNCents.java create mode 100644 cracking-the-coding-interview/Chapter9RecursionAndDynamicProgramming/StackBoxes.java create mode 100644 cracking-the-coding-interview/Chapter9RecursionAndDynamicProgramming/Staircase.java create mode 100644 cracking-the-coding-interview/CrackingTheCodingInterview.iml create mode 100644 leetcode/binary-search/closestBinarySearchTreeValue.java create mode 100644 leetcode/binary-search/firstBadVersion.java create mode 100644 leetcode/binary-search/guessNumberHigherOrLower.java create mode 100644 leetcode/binary-search/pow(x,n).java create mode 100644 leetcode/binary-search/sqrt(x).java create mode 100644 leetcode/bit-manipulation/binaryWatch.java create mode 100644 leetcode/bit-manipulation/countingBits.java create mode 100644 leetcode/bit-manipulation/hammingDistance.java create mode 100644 leetcode/bit-manipulation/maximumProductOfWordLengths.java create mode 100644 leetcode/bit-manipulation/numberOf1Bits.java create mode 100644 leetcode/bit-manipulation/sumOfTwoIntegers.java create mode 100644 leetcode/bit-manipulation/utf-8Validation.java create mode 100644 leetcode/breadth-first-search/binaryTreeLevelOrderTraversal.java create mode 100644 leetcode/breadth-first-search/cloneGraph.java create mode 100644 leetcode/breadth-first-search/pacificAtlanticWaterFlow.java create mode 100644 leetcode/breadth-first-search/removeInvalidParentheses.java create mode 100644 leetcode/breadth-first-search/shortestDistanceFromAllBuildings.java create mode 100644 leetcode/breadth-first-search/symmetricTree.java create mode 100644 leetcode/breadth-first-search/wallsAndGates.java create mode 100644 leetcode/depth-first-search/balancedBinaryTree.java create mode 100644 leetcode/depth-first-search/battleshipsInABoard.java create mode 100644 leetcode/depth-first-search/convertSortedArrayToBinarySearchTree.java create mode 100644 leetcode/depth-first-search/maximumDepthOfABinaryTree.java create mode 100644 leetcode/depth-first-search/numberOfIslands.java create mode 100644 leetcode/depth-first-search/populatingNextRightPointersInEachNode.java create mode 100644 leetcode/depth-first-search/sameTree.java create mode 100644 leetcode/divide-and-conquer/expressionAddOperators.java create mode 100644 leetcode/divide-and-conquer/kthLargestElementInAnArray.java create mode 100644 leetcode/dynamic-programming/bombEnemy.java create mode 100644 leetcode/dynamic-programming/climbingStairs.java create mode 100644 leetcode/dynamic-programming/combinationSumIV.java create mode 100644 leetcode/dynamic-programming/countingBits.java create mode 100644 leetcode/dynamic-programming/editDistance.java create mode 100644 leetcode/dynamic-programming/houseRobber.java create mode 100644 leetcode/dynamic-programming/paintFence.java create mode 100644 leetcode/dynamic-programming/paintHouseII.java create mode 100644 leetcode/dynamic-programming/regularExpressionMatching.java create mode 100644 leetcode/dynamic-programming/sentenceScreenFitting.java create mode 100644 leetcode/dynamic-programming/uniqueBinarySearchTrees.java create mode 100644 leetcode/dynamic-programming/wordBreak.java create mode 100644 leetcode/linked-list/README.md create mode 100644 leetcode/linked-list/addTwoNumbers.java create mode 100644 leetcode/linked-list/deleteNodeInALinkedList.java create mode 100644 leetcode/linked-list/mergeKSortedLists.java create mode 100644 leetcode/linked-list/palindromeLinkedList.java create mode 100644 leetcode/linked-list/plusOneLinkedList.java create mode 100644 leetcode/linked-list/reverseLinkedList.java create mode 100644 leetcode/two-pointers/3Sum.java create mode 100644 leetcode/two-pointers/3SumSmaller.java create mode 100644 leetcode/two-pointers/mergeSortedArray.java create mode 100644 leetcode/two-pointers/minimumSizeSubarraySum.java create mode 100644 leetcode/two-pointers/moveZeros.java create mode 100644 leetcode/two-pointers/removeDuplicatesFromSortedArray.java create mode 100644 leetcode/two-pointers/reverseString.java create mode 100644 leetcode/two-pointers/sortColors.java diff --git a/company/amazon/ThreeSum.java b/company/amazon/ThreeSum.java new file mode 100644 index 00000000..40e7eedc --- /dev/null +++ b/company/amazon/ThreeSum.java @@ -0,0 +1,52 @@ +// Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero. + +// Note: The solution set must not contain duplicate triplets. + +// For example, given array S = [-1, 0, 1, 2, -1, -4], + +// A solution set is: +// [ +// [-1, 0, 1], +// [-1, -1, 2] +// ] + +public class ThreeSum { + public List> threeSum(int[] nums) { + List> result = new ArrayList<>(); + Arrays.sort(nums); + for(int i = 0; i < nums.length - 2; i++) { + if(i > 0 && nums[i] == nums[i - 1]) { + continue; + } + + int j = i + 1; + int k = nums.length - 1; + int target = -nums[i]; + + while(j < k) { + if(nums[j] + nums[k] == target) { + ArrayList temp = new ArrayList(); + temp.add(nums[i]); + temp.add(nums[j]); + temp.add(nums[k]); + + result.add(temp); + + j++; + k--; + + while(j < k && nums[j] == nums[j - 1]) j++; + while(j < k && nums[k] == nums[k + 1]) k--; + } + else if(nums[j] + nums[k] > target) { + k--; + } + else { + j++; + } + } + } + + return result; + } +} diff --git a/cracking-the-coding-interview/Chapter1ArraysAndStrings/DeleteDups.java b/cracking-the-coding-interview/Chapter1ArraysAndStrings/DeleteDups.java new file mode 100644 index 00000000..46e04a43 --- /dev/null +++ b/cracking-the-coding-interview/Chapter1ArraysAndStrings/DeleteDups.java @@ -0,0 +1,18 @@ +//Write code to remove duplicates from an unsorted linked list + +public class RemoveDups { + void deleteDups(LinkedListNode n) { + HashSet set = new HashSet(); + LinkedListNode previous = null; + while(n != null) { + if(set.contains(n.data)) { + previous.next = n.next; + } + else { + set.add(n.data); + previous = n; + } + n = n.next; + } + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter1ArraysAndStrings/IsRotation.java b/cracking-the-coding-interview/Chapter1ArraysAndStrings/IsRotation.java new file mode 100644 index 00000000..9e84ab6a --- /dev/null +++ b/cracking-the-coding-interview/Chapter1ArraysAndStrings/IsRotation.java @@ -0,0 +1,17 @@ +// Assume you have a method isSubstring which checks if one word is a isSubstring of another. +// Given two strings, s1 and s2, write code to check if s2 is a rotation of s1 using only +// one call to isSubstring(e.g., "waterbottle" is a rotation of "erbottlewat"). + +public class IsRotation { + public boolean isRotation(String s1, String s2) { + int len = s1.length(); + /*check that s1 and s2 are equal length and not empty */ + if(len == s2.length() && len > 0) { + /* concatenate s1 and s1 within new buffer */ + String s1s1 = s1 + s1; + return isSubstring(s1s1, s2); + } + + return false; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter1ArraysAndStrings/IsUniqueChars.java b/cracking-the-coding-interview/Chapter1ArraysAndStrings/IsUniqueChars.java new file mode 100644 index 00000000..bd1e043a --- /dev/null +++ b/cracking-the-coding-interview/Chapter1ArraysAndStrings/IsUniqueChars.java @@ -0,0 +1,15 @@ +//Implement an algorithm to determine if a string has all unique characters. What if you cannot use additional data structures? + +public class isUniqueChars { + public boolean isUniqueChars(String str) { + int checker = 0; + for(int i = 0; i < str.length(); i++) { + int val = str.charAt(i) - 'a'; + if((checker & (1 << val)) > 0) { + return false; + } + checker |= (1 << val)); + } + return true; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter1ArraysAndStrings/NthToLast.java b/cracking-the-coding-interview/Chapter1ArraysAndStrings/NthToLast.java new file mode 100644 index 00000000..b5ed5bac --- /dev/null +++ b/cracking-the-coding-interview/Chapter1ArraysAndStrings/NthToLast.java @@ -0,0 +1,27 @@ +//Implement an algorithm to find the kth to last element of a single linked list + +public class NthToLast { + LinkedListNode nthToLast(LinkedListNode head, int k) { + if(k <= 0) return null; + + LinkedListNode p1 = head; + LinkedListNode p2 = head; + + //move p2 forward k nodes into the list + for(int i = 0; i < k - 1; i++) { + if(p2 == null) return null; //error check + p2 = p2.next; + } + + if(p2 == null) return null; + + /* now, move p1 and p2 at the same speed. When p2 hits the end, + * p1 will be at the right element */ + while(p2.next != null) { + p1 = p1.next; + p2 = p2.next; + } + + return p1; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter1ArraysAndStrings/Permutation.java b/cracking-the-coding-interview/Chapter1ArraysAndStrings/Permutation.java new file mode 100644 index 00000000..babdd096 --- /dev/null +++ b/cracking-the-coding-interview/Chapter1ArraysAndStrings/Permutation.java @@ -0,0 +1,25 @@ +// Given two strings, write a method to decide if one is a permutation of the other + +public class Permutation { + public boolean permutation(String s, String t) { + if(s.length() != t.length()) { + return false; + } + + int[] letters = new int[256]; + + char[] s_array = s.toCharArray(); + for(char c : s_array) { + letters[c]++; + } + + for(int i = 0; i < t.length(); i++) { + int c = (int)t.charAt(i); + if(--letters[c] < 0) { + return false; + } + } + + return true; + } +} diff --git a/cracking-the-coding-interview/Chapter1ArraysAndStrings/ReplaceSpaces.java b/cracking-the-coding-interview/Chapter1ArraysAndStrings/ReplaceSpaces.java new file mode 100644 index 00000000..4dddcab7 --- /dev/null +++ b/cracking-the-coding-interview/Chapter1ArraysAndStrings/ReplaceSpaces.java @@ -0,0 +1,30 @@ +// Write a method to replace all spaces in a string with '%20.' You may assum ethat the string +// has sufficient space at th eend of the string to hold the additional characters, and that you +// are given the "true" length of the string. (Note: if implementing in Java, please use a characters +// array so that you can perform this operation in place) + +public class ReplaceSpaces { + public void replaceSpaces(char[] str, int length) { + int spaceCount = 0, newLength; i; + for(int i = 0; i < length; i++) { + if(str[i] == ' ') { + spaceCount++; + } + } + + newLength = length + spaceCount * 2; + str[newLength] = '\0'; + for(int i = length - 1; i >= 0; i--) { + if(str[i] == ' ') { + str[newLength - 1] = '0'; + str[newLength - 2] = '2'; + str[newLength - 3] = '%'; + newLength = newLength - 3; + } + else { + str[newLength - 1] = str[i]; + newLength = newLength - 1; + } + } + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter2LinkedLists/DeleteDups.java b/cracking-the-coding-interview/Chapter2LinkedLists/DeleteDups.java new file mode 100644 index 00000000..46e04a43 --- /dev/null +++ b/cracking-the-coding-interview/Chapter2LinkedLists/DeleteDups.java @@ -0,0 +1,18 @@ +//Write code to remove duplicates from an unsorted linked list + +public class RemoveDups { + void deleteDups(LinkedListNode n) { + HashSet set = new HashSet(); + LinkedListNode previous = null; + while(n != null) { + if(set.contains(n.data)) { + previous.next = n.next; + } + else { + set.add(n.data); + previous = n; + } + n = n.next; + } + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter2LinkedLists/DeleteNode.java b/cracking-the-coding-interview/Chapter2LinkedLists/DeleteNode.java new file mode 100644 index 00000000..c65db93c --- /dev/null +++ b/cracking-the-coding-interview/Chapter2LinkedLists/DeleteNode.java @@ -0,0 +1,14 @@ +//Implement an algorithm to delete a node in the middle of a singly linked list, give only access to that node + +public class DeleteNode { + public static boolean deleteNode(LinkedListNode n) { + if(n == null || n.next == null) { + return false; + } + + LinkedListNode next = n.next; + n.data = next.data; + n.next = next.next; + return true; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter2LinkedLists/FindBeginning.java b/cracking-the-coding-interview/Chapter2LinkedLists/FindBeginning.java new file mode 100644 index 00000000..be958bb8 --- /dev/null +++ b/cracking-the-coding-interview/Chapter2LinkedLists/FindBeginning.java @@ -0,0 +1,36 @@ +//Given a circular linked list, implement an algorithm which returns +//the node at the beginning of the loop + +public class FindBeginning { + LinkedListNode findBeginning(LinkedListNode head) { + LinkedListNode slow = head; + LinkedListNode fast = head; + + /* find meeting point. This will be LOOP_SIZE - k + * steps int othe linked list */ + while(fast != null && fast.next != null) { + slow = slow.next; + fast = fast.next.next; + if(fast == slow) { + break; + } + } + + /* error checking - no meeting point, and therefore no loop */ + if(fast == null || fast.next == null) { + return null; + } + + /* move slow to head. Keep fast at meeting point. Each are k + * steps from the loop start. If they move at the same pace, + * they must meet at the loop start */ + slow = head; + while(slow != fast) { + slow = slow.next; + fast = fast.next; + } + + /* both now point to the start of the loop */ + return fast; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter2LinkedLists/IsPalindrome.java b/cracking-the-coding-interview/Chapter2LinkedLists/IsPalindrome.java new file mode 100644 index 00000000..7eecc465 --- /dev/null +++ b/cracking-the-coding-interview/Chapter2LinkedLists/IsPalindrome.java @@ -0,0 +1,38 @@ +//Implement a function to check if a linked list is a palindrome +//don't forget import statements! + +public class IsPalindrome { + boolean isPalindrome(LinkedListNode head) { + LinkedListNode fast = head; + LinkedListNode slow = head; + + Stack stack = new Stack(); + + /* push elements from first half of linked list onto stack. + * When fast runner (which is moving at 2x speed) reaches the + * end of the linked list, then we know we're at the middle */ + while(fast != null && fast.next != null) { + stack.push(slow.data); + slow = slow.next; + fast = fast.next.next; + } + + /*has odd number of elements, so skip the middle element */ + if(fast != null) { + slow = slow.next; + } + + while(slow != null) { + int top = stack.pop().intValue(); + + /* if values are different, then it's not a palindrome */ + if(top != slow.data) { + return false; + } + + slow = slow.next; + } + + return true; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter2LinkedLists/NthToLast.java b/cracking-the-coding-interview/Chapter2LinkedLists/NthToLast.java new file mode 100644 index 00000000..e69de29b diff --git a/cracking-the-coding-interview/Chapter2LinkedLists/Partition.java b/cracking-the-coding-interview/Chapter2LinkedLists/Partition.java new file mode 100644 index 00000000..aa692dd1 --- /dev/null +++ b/cracking-the-coding-interview/Chapter2LinkedLists/Partition.java @@ -0,0 +1,28 @@ +//Write code to partition a linked list around a value x, such that +//all nodes less than x come before all nodes greater than or equal to x. + +public class Partition { + LinkedListNode partition(LinkedListNode node, int x) { + LinkedListNode head = node; + LinkedListNode tail = node; + + while(node != null) { + LinkedListNode next = node.next; + if(node.data < x) { + /* insert node at head */ + node.next = head; + head = node; + } + else { + /* insert node at tail */ + tail.next = node; + tail = node; + } + node = next; + } + tail.next = null; + + //the head has changed, so we need to return it to the user + return head; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter3StacksAndQueues/BinaryTreeIsBalanced.java b/cracking-the-coding-interview/Chapter3StacksAndQueues/BinaryTreeIsBalanced.java new file mode 100644 index 00000000..44ced48e --- /dev/null +++ b/cracking-the-coding-interview/Chapter3StacksAndQueues/BinaryTreeIsBalanced.java @@ -0,0 +1,26 @@ +/* implement a function to check if a binary tree is balanced. For the purpose of this + * question, a balanced tree is defined to be a tree such that the heights of the two + * subtrees of any node never differ by more than one */ + +public class BinaryTreeIsBalanaced { + public static int getHeight(TreeNode root) { + if(root == null) { + return 0; //base case + } + return Math.max(getHeight(root.left), getHeight(root.right)) + 1; + } + + public static boolean isBalanced(TreeNode root) { + if(root == null) { //base case + return true; + } + + int heightDiff = getHeight(root.left) - getHeight(root.right); + if(Math.abs(heightDiff) > 1) { + return false; + } + else { //recurse + return isBalanced(root.left) && isBalanced(root.right); + } + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter3StacksAndQueues/MyQueue.java b/cracking-the-coding-interview/Chapter3StacksAndQueues/MyQueue.java new file mode 100644 index 00000000..4fd0ccbd --- /dev/null +++ b/cracking-the-coding-interview/Chapter3StacksAndQueues/MyQueue.java @@ -0,0 +1,40 @@ +/* implement a MyQueue class which implements a queue using two stacks */ + +public class MyQueue { + Stack stackNewest, stackOldest; + + public MyQueue() { + stackNewest = new Stack(); + stackOldest = new Stack(); + } + + public int size() { + return stackNewest.size() + stackOldest.size(); + } + + public void add(T value) { + /* push onto stackNewest, which always has the newest + * elements on top */ + stackNewest.push(value); + } + + /* Move elements from stackNewest into stackOldest. This + * is usually done so that we can do operations on stackOldest */ + private void shiftStacks() { + if(stackOldest.isEmpty()) { + while(!stackNewest.isEmpty()) { + stackOldest.push(stackNewest.pop()); + } + } + } + + public T peek() { + shiftStacks(); //ensure stackOldest has the current elements + return stackOldest.peek(); //retrieve the oldest item + } + + public T remove() { + shiftStacks(); //ensure stackOldest has the current elements + return stackOldest.pop(); + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter3StacksAndQueues/QueueUsingTwoStacks.java b/cracking-the-coding-interview/Chapter3StacksAndQueues/QueueUsingTwoStacks.java new file mode 100644 index 00000000..5024fb8e --- /dev/null +++ b/cracking-the-coding-interview/Chapter3StacksAndQueues/QueueUsingTwoStacks.java @@ -0,0 +1,5 @@ +/* implement a MyQueue class which implements a queue using two stacks */ + +public class QueueUsingTwoStacks { + +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter3StacksAndQueues/SetOfStacks.java b/cracking-the-coding-interview/Chapter3StacksAndQueues/SetOfStacks.java new file mode 100644 index 00000000..a00d0dc3 --- /dev/null +++ b/cracking-the-coding-interview/Chapter3StacksAndQueues/SetOfStacks.java @@ -0,0 +1,44 @@ +/* imagine a (literal) stack of plates. If the stack gets too high, it might topple. + * Therefore, in real life, we would likely start a new stack when the previous stack + * exceeds some threshold. Implement a data structure SetOfStacks that mimics this. + * SetOfStacks should be composed of several stacks and should create a new stack once + * the previous one exceeds capacity. SetOfStacks.push() and SetOfStacks.pop() should + * behave identically to a single stack (that is, pop() should return the same values as + * it would if there were just a single stack) */ + +//in this problem, we've been told what our data structure should look like: +public class SetOfStacks { + ArrayList stacks = new ArrayList(); + //public void push(int v) {...} + //public int pop() {...} + + public void push(int v) { + Stack last = getLastStack(); + if(last != null && !last.isFull()) { //add to the last stack + last.push(v); + } + else { //must create new stack + Stack stack = new Stack(capacity); + stack.push(v); + stacks.add(stack); + } + } + + public void pop() { + Stack last = getLastStack(); + int v = last.pop(); + if(last.size == 0) { + stacks.remove(stacks.size() - 1); + } + return v; + } + + public Stack getLastStack() { + if(stacks.size() == 0) { + return null; + } + return stacks.get(stacks.size() - 1); + } +} + + diff --git a/cracking-the-coding-interview/Chapter3StacksAndQueues/SortStack.java b/cracking-the-coding-interview/Chapter3StacksAndQueues/SortStack.java new file mode 100644 index 00000000..0f07d890 --- /dev/null +++ b/cracking-the-coding-interview/Chapter3StacksAndQueues/SortStack.java @@ -0,0 +1,18 @@ +/* write a program to sort a stack in ascending order (with biggest items on top). + * you may use at most one additional stack to hold items, but you may not copy the + * elements into any other data strcuture (such as an array). The stack supports the + * folowing operations: push, pop, peek, and isEmpty */ + +public class SortStack { + public static Stack sort(Stack s) { + Stack r = new Stack(); + while(!s.isEmpty()) { + int tmp = s.pop(); //step 1 + while(!r.isEmpty() && r.peek() > tmp) { //step 2 + s.push(r.pop()); + } + r.push(tmp) //step 3 + } + return r; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter3StacksAndQueues/StackWithMin.java b/cracking-the-coding-interview/Chapter3StacksAndQueues/StackWithMin.java new file mode 100644 index 00000000..6d640293 --- /dev/null +++ b/cracking-the-coding-interview/Chapter3StacksAndQueues/StackWithMin.java @@ -0,0 +1,26 @@ +//How would you design a stack which, in addition to push and pop, also has a function min which returns the minimum element? Push, pop, and min should all operate in O(1) time + +public class StackWithMin extends Stack { + public void push(int value) { + int newMin = Math.min(value, min()); + super.push(new NodeWithMin(value, newMin)); + } + + public int min() { + if(this.isEmpty()) { + return Integer.MAX_VALUE; //error value + } + else { + return peek().min; + } + } +} + +class NodeWithMin { + public int value; + public int min; + public NodeWithMin(int v, int min) { + this.value = v; + this.min = min; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter3StacksAndQueues/ThreeStacks.java b/cracking-the-coding-interview/Chapter3StacksAndQueues/ThreeStacks.java new file mode 100644 index 00000000..90722307 --- /dev/null +++ b/cracking-the-coding-interview/Chapter3StacksAndQueues/ThreeStacks.java @@ -0,0 +1,44 @@ +//Describe how you could use a single array to implement three stacks + +public class ThreeStacks { + int stackSize = 100; + int[] buffer = new int[stackSize * 3]; + int[] stackPointer = {-1, -1, -1}; //pointers to track top element + + void push(int stackNum, int value) throws Exception { + /* check if we have space */ + if(stackPointer[stackNum] + 1 >= stackSize) { //last element + throw new FullStackException(); + } + /* increment stack pointer and then update top value */ + stackPointer[stackNum]++; + buffer[absTopOfStack(stackNum)] = value; + } + + int pop(int stackNum) throws Exception { + if(isEmpty(stackNum)) { + throw new EmptyStackException(); + } + int value = buffer[absTopOfStack(stackNum)]; //get top + buffer[absTopOfStack(stackNum)] = 0; //clear index + stackPointer[stackNum]--; //decrement pointer + return value; + } + + int peek(int stackNum) { + if(isEmpty(stackNum)) { + throw new EmptyStackException(); + } + int index = absTopOfStack(stackNum); + return buffer[index]; + } + + boolean isEmpty(int stackNum) { + return stackPointer[stackNum] == -1; + } + + /* returns index of top of stack "stackNum", in absolute terms */ + int absTopOfStack(int stasckNum) { + return stackNum * stackSize + stackPointer[stackNum]; + } +} diff --git a/cracking-the-coding-interview/Chapter3StacksAndQueues/TowersOfHanoi.java b/cracking-the-coding-interview/Chapter3StacksAndQueues/TowersOfHanoi.java new file mode 100644 index 00000000..6a03ba51 --- /dev/null +++ b/cracking-the-coding-interview/Chapter3StacksAndQueues/TowersOfHanoi.java @@ -0,0 +1,59 @@ +/* in the classic problem of the Towers of Hanoi, you have 3 towers and N disks of + * different sizes which can slide onto any tower. The puzzle starts with disks sorted + * in ascending order of size from top to bottom (i.e. each disk sits on top of an even + * larger one). You have the following constraints: + * (1) Only one disk can be moved at a time + * (2) A disk is slid off the top of one tower onto the next rod + * (3) A disk can only be placed on top of a larger disk + * Write a program to move the disks from the first tower to the last tower using Stacks */ + +public class TowersOfHanoi { + public static void main(String args[]) { + int n = 3; + Tower[] towers = new Tower[n]; + for(int i = 0; i < 3; i++) { + towers[i] = new Tower(i); + } + + for(int i = n - 1; i >= 0; i--) { + towers[0].add(i); + } + towers[0].moveDisks(n, towers[2], towers[1]); + } +} + +public class Tower { + private Stack disks; + private int index; + public Tower(int i) { + disks = new Stack(); + index = i; + } + + public int index() { + return index; + } + + public void add(int d) { + if(!disks.isEmpty() && disks.peek() <= d) { + System.out.println("Error placing disk " + d); + } + else { + disks.push(d): + } + } + + public void moveTopTo(Tower t) { + int top = disks.pop(); + t.add(top); + System.out.println("Move disk " + top + " from " + index() + " to " + t.index()); + } + + public void moveDisks(int n, Tower destination, Tower buffer) { + if(n > 0) { + moveDisks(n - 1, buffer, destination); + moveTopTo(destination); + buffer.moveDisks(n - 1, destination, this); + } + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter4TreesAndGraphs/BinaryTreeIsBalanced.java b/cracking-the-coding-interview/Chapter4TreesAndGraphs/BinaryTreeIsBalanced.java new file mode 100644 index 00000000..44ced48e --- /dev/null +++ b/cracking-the-coding-interview/Chapter4TreesAndGraphs/BinaryTreeIsBalanced.java @@ -0,0 +1,26 @@ +/* implement a function to check if a binary tree is balanced. For the purpose of this + * question, a balanced tree is defined to be a tree such that the heights of the two + * subtrees of any node never differ by more than one */ + +public class BinaryTreeIsBalanaced { + public static int getHeight(TreeNode root) { + if(root == null) { + return 0; //base case + } + return Math.max(getHeight(root.left), getHeight(root.right)) + 1; + } + + public static boolean isBalanced(TreeNode root) { + if(root == null) { //base case + return true; + } + + int heightDiff = getHeight(root.left) - getHeight(root.right); + if(Math.abs(heightDiff) > 1) { + return false; + } + else { //recurse + return isBalanced(root.left) && isBalanced(root.right); + } + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter4TreesAndGraphs/CreateBinarySearchTree.java b/cracking-the-coding-interview/Chapter4TreesAndGraphs/CreateBinarySearchTree.java new file mode 100644 index 00000000..80323199 --- /dev/null +++ b/cracking-the-coding-interview/Chapter4TreesAndGraphs/CreateBinarySearchTree.java @@ -0,0 +1,19 @@ +/* given a sorted (increasing order) array with unique integer elements, write an algorithm + * to create a binary search tree with minimal height */ + +public class CreateBinarySearchTree { + TreeNode createMinimalBST(int arr[], int start, int end) { + if(end < start) { + return null; + } + int mid = (start + end) / 2; + TreeNode n = new TreeNode(arr[mid]); + n.left = createMinimalBST(arr, start, mid - 1); + n.right = createMinimalBST(arr, mid + 1, end); + return n; + } + + TreeNode createMinimalBST(int array[]) { + return createMinimalBST(array, 0, array.length - 1); + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter4TreesAndGraphs/CreateLinkedListForEachLevel.java b/cracking-the-coding-interview/Chapter4TreesAndGraphs/CreateLinkedListForEachLevel.java new file mode 100644 index 00000000..fdf77e81 --- /dev/null +++ b/cracking-the-coding-interview/Chapter4TreesAndGraphs/CreateLinkedListForEachLevel.java @@ -0,0 +1,29 @@ +/* given a binary tree, design an algorithm which creates a linked list of all the nodes + * at each depth (e.g., if you have a tree with depth D, you'll have D linked lists) */ + +public class CreateLinkedListForEachLevel { + ArrayList> createLinkedList(TreeNode root) { + ArrayList> result = new ArrayList>(); + /* "visit" the root */ + LinkedList current = new LinkedList(); + if(root != null) { + current.add(root); + } + + while(current.size() > 0) { + result.add(current); //add previous level + LinkedList parents = current; //go to next level + current = new LinkedList(); + for(TreeNode parent : parents) { + /* visit the children */ + if(parent.left != null) { + current.add(parrent.left); + } + if(parent.right != null) { + current.add(parent.right); + } + } + } + return result; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter4TreesAndGraphs/FindPath.java b/cracking-the-coding-interview/Chapter4TreesAndGraphs/FindPath.java new file mode 100644 index 00000000..0b6b420e --- /dev/null +++ b/cracking-the-coding-interview/Chapter4TreesAndGraphs/FindPath.java @@ -0,0 +1,40 @@ +/* give a directed graph, design an algorithm to find out whether there is a route between two nodes */ + +public class FindPath { + public enum State { + Unvisited, Visited, Visiting; + } + + public static boolean search(Graph g, Node start, Node end) { + if(start == end) return true; + + //operates as Queue + LinkedList q = new LinkedList(); + + for(Node u : g.getNodes()) { + u.state = State.Unvisited; + } + + start.state = State.Visiting; + q.add(start); + Node u; + while(!q.isEmpty()) { + u = q.removeFirst(); //i.e., dequeue() + if(u != null) { + for(Node v : u.getAdjacent()) { + if(v.state == State.Unvisited) { + if(v == end) { + return true; + } + else { + v.state = State.Visiting; + q.add(v); + } + } + } + } + u.state = State.Visited; + } + return false; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter4TreesAndGraphs/IsSubtree.java b/cracking-the-coding-interview/Chapter4TreesAndGraphs/IsSubtree.java new file mode 100644 index 00000000..2ddacd50 --- /dev/null +++ b/cracking-the-coding-interview/Chapter4TreesAndGraphs/IsSubtree.java @@ -0,0 +1,37 @@ +/* you have two very large binary trees: T1, with millions of nodes, and T2, with hundreds + * of nodes. Create an algorithm to decide if T2 is a subtree of T1. + * A tree T2 is a subtree of T1 if there exists a node n in T1 such that the subtree of n + * is identical to T2. That is, if you cut off the tree at node n, the two trees would be identical */ + +public class IsSubtree { + boolean containsTree(TreeNode t1, TreeNode t2) { + if(t2 == null) { //the empty tree is always a subtree + return true; + } + return subTree(t1, t2); + } + + boolean subTree(TreeNode r1, TreeNode r2) { + if(r1 == null) { + return false; //big tree empty & subtree still not found + } + if(r1.data == r2.data) { + if(matchTree(r1, r2)) return true; + } + return (subTree(r1.left, r2) || subTree(r1.right, r2)); + } + + boolean matchTree(TreeNode r1, TreeNode r2) { + if(r2 == null && r1 == null) //if both are empty + return true; //nothing left in the subtree + + //if one, but not both, are empty + if(r1 == null || r2 == null) { + return false; + } + + if(r1.data != r2.data) + return false; //data doesn't match + return (matchTree(r1.left, r2.left) && matchTree(r1.right, r2.right)); + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter4TreesAndGraphs/PrintPaths.java b/cracking-the-coding-interview/Chapter4TreesAndGraphs/PrintPaths.java new file mode 100644 index 00000000..588e368f --- /dev/null +++ b/cracking-the-coding-interview/Chapter4TreesAndGraphs/PrintPaths.java @@ -0,0 +1,53 @@ +/* you are given a binary tree in which each ndoe contains an integer value (which might be positive + * or negative). Design an algorithm to print all paths which sum to a given value. The path does not need + * to start or end at the root or a leaf, but it must go in a straight line */ + +public class PrintPaths { + void findSum(TreeNode node, int sum, int[] path, int level) { + if(node == null) { + return; + } + + /* insert current node into path */ + path[level] = node.data; + + /* look for paths with a sum that ends at this node */ + int t = 0; + for(int i = level; i >= 0; i--) { + t += path[i]; + if(t == sum) { + print(path, i, level); + } + } + + /* search nodes beneath this one */ + findSum(node.left, sum, path, level + 1); + findSum(node.right, sum, path, level + 1); + + /* remove current node from path. Not strictly necessary, since + * we would ignore this value, but it's good practice */ + path[level] = Integer.MIN_VALUE; + } + + void findSum(TreeNode node, int sum) { + int depth = depth(node); + int[] path = new int[depth]; + findSum(node, sum, path, 0); + } + + void print(int[] path, int start, int end) { + for(int i = start; i <= end; i++) { + System.out.print(path[i] + " "); + } + System.out.println(); + } + + int depth(TreeNode node) { + if(node == null) { + return 0; + } + else { + return 1 + Math.max(depth(node.left), depth(node.right)); + } + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter4TreesAndGraphs/ValidBinarySearchTree.java b/cracking-the-coding-interview/Chapter4TreesAndGraphs/ValidBinarySearchTree.java new file mode 100644 index 00000000..ea22e050 --- /dev/null +++ b/cracking-the-coding-interview/Chapter4TreesAndGraphs/ValidBinarySearchTree.java @@ -0,0 +1,21 @@ +/* implement a function to check if a binary tree is a binary search tree */ + +public class ValidBinarySearchTree { + boolean checkBST(TreeNode n) { + return checkBST(n, null, null); + } + + boolean checkBST(TreeNode n, Integer min, Integer max) { + if(n == null) { + return true; + } + if((min != null && n.data <= min) || (max != null && n.data > max)) { + return false; + } + + if(!checkBST(n.left, min, n.data) || !checkBST(n.right, n.data, max)) { + return false; + } + return true; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter5BitManipulation/BinaryRepresentation.java b/cracking-the-coding-interview/Chapter5BitManipulation/BinaryRepresentation.java new file mode 100644 index 00000000..773a1e03 --- /dev/null +++ b/cracking-the-coding-interview/Chapter5BitManipulation/BinaryRepresentation.java @@ -0,0 +1,31 @@ +/* given a real number between 0 and 1 (e.g., 0.72) that is passed in as a double, print + * the binary representation. If the number cannot be represented accurately in binary + * with at most 32 characters, print "ERROR" */ + +public class BinaryRepresentation { + public static String printBinary(double num) { + if(num >= 1 || num <= 0) { + return "ERROR"; + } + + StrinBuilder binary = new StringBuilder(); + binary.append("."); + while(num > 0) { + /* setting a limit on length: 32 characters */ + if(binary.length() >= 32) { + return "ERROR"; + } + + double r = num * 2; + if(r >= 1) { + binary.append(1); + num = r - 1; + } + else { + binary.append(0); + num = r; + } + } + return binary.toString(); + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter5BitManipulation/FindMissingInteger.java b/cracking-the-coding-interview/Chapter5BitManipulation/FindMissingInteger.java new file mode 100644 index 00000000..0dde8fec --- /dev/null +++ b/cracking-the-coding-interview/Chapter5BitManipulation/FindMissingInteger.java @@ -0,0 +1,37 @@ +/* An array A contains all the integers from 0 through n, except for one number which is + * missing. In this problem, we cannot access an entire integer in A with a single operation. + * The elements of A are represented in binary, and the only operation we can use to acces them + * is "fetch the jth bit of A[i]," which takes constant time. Write code to find the missing + * integer. Can you do it in O(n) time? */ + +public class FindMissingInteger { + public int findMissing(ArrayList array) { + /* start from the least significant bit, and work our way up */ + return findMissing(array, 0); + } + + public int findMissing(ArrayList input, int column) { + if(column >= BigInteger.INTEGER_SIZE) { //we're done! + return 0; + } + ArrayList oneBits = new ArrayList(input.size() / 2); + ArrayList zeroBits = new ArrayList(input.size() / 2); + + for(BigInteger t : input) { + if(t.fetch(column) == 0) { + zeroBits.add(t); + } + else { + oneBits.add(t); + } + } + if(zeroBits.size() <= oneBits.size()) { + int v = findMissing(zeroBits, column + 1); + return (v << 1) | 0; + } + else { + int v = findMissing(oneBits, column + 1); + return (v << 1) | 1; + } + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter5BitManipulation/InsertMIntoN.java b/cracking-the-coding-interview/Chapter5BitManipulation/InsertMIntoN.java new file mode 100644 index 00000000..9700739c --- /dev/null +++ b/cracking-the-coding-interview/Chapter5BitManipulation/InsertMIntoN.java @@ -0,0 +1,33 @@ +/* you are given two 32-bit numbers, N and M, are two bit positions, i and j. Write + * a method to insert M into N such that M starts at bit j and ends at bit i. You can + * assume that the bits j through i have enough space to fit all of M. That is, if M = 10011, + * you can assume that there are at least 5 bits between j and i. You would not, for example, + * have j = 3 and i = 2, because M could not fully bit between bit 3 and bit 2. + EXAMPLE: + Input: N = 10000000000, m = 10011, i = 2, j = 6 + Output: N = 10001001100 */ + + public class InsertMIntoN { + int updateBits(int n, int m, int i, int j) { + /* create a mask to clear bits i through j in n + * EXAMPLE: i = 2, j = 4. Result should be 11100011. + * For simplicity, we'll just use 8 bits for the example. + */ + int allones = ~0; //wil equal sequence of all 1s + + //1s before position j, then 0s. Left = 11100000 + int left = allOnes << (j + 1); + + //1s after position i. Right = 00000011 + int right = ((1 << i) - 1); + + //all 1s, except for 0s between i and j. Mask = 11100011 + int mask = left | right; + + /* clear bits j through i then put m in there */ + int n_cleared = n & mask; //clear bits j through i + int m_shifted = m << i; //move m into correct position + + return n_cleared | m_shifted; //OR them, and we're done! + } + } \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter5BitManipulation/SwapBits.java b/cracking-the-coding-interview/Chapter5BitManipulation/SwapBits.java new file mode 100644 index 00000000..6458e864 --- /dev/null +++ b/cracking-the-coding-interview/Chapter5BitManipulation/SwapBits.java @@ -0,0 +1,8 @@ +/* write a program to swap odd and even bits in an integer with as few instructions as + * possible (e.g., bit 0 and bit 1 are swapped, bit 2 and bit 3 are swapped, and so on) */ + +public class SwapBits { + public int swapOddEvenBits(int x) { + return ( ((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1) ); + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter7MathematicsAndProbability/Operations.java b/cracking-the-coding-interview/Chapter7MathematicsAndProbability/Operations.java new file mode 100644 index 00000000..b4e0c9c4 --- /dev/null +++ b/cracking-the-coding-interview/Chapter7MathematicsAndProbability/Operations.java @@ -0,0 +1,66 @@ +/* write methods to implement the multiply, subtract, and divide operations for integers. Use only the add operator */ + +public class Operations { + /* flip a positive sign to negative or negative sign to positive */ + public static int negate(int a) { + int neg = 0; + int d = a < 0 ? 1 : -1; + while(a != 0) { + neg += d; + a += d; + } + return neg; + } + + /* subtract two numbers by negating b and adding them */ + public static int minus(int a, int b) { + return a + negate(b); + } + + /* multiply a by b by adding a to itself b times */ + public static int multiply(int a, int b) { + if(a < b) { + return multiply(b, a); //algorithm is faster is b < a + } + int sum = 0; + for(int i = abs(b); i > 0; i--) { + sum += a; + } + if(b < 0) { + sum = negate(sum); + } + return sum; + } + + /* return absolute value */ + public static int abs(int a) { + if(a < 0) { + return negate(a); + } + else { + return a; + } + } + + public int divide(int a, int b) throws ArithmeticException { + if(b == 0) { + throw new java.lang.ArithmeticException("ERROR"); + } + int absa = abs(a); + int absb = abs(b); + + int product = 0; + int x = 0; + while(product + absb <= absa) { //don't go past a + product += absb; + x++; + } + + if((a < 0 && b < 0) || (a > 0 && b > 0)) { + return x; + } + else { + return negate(x); + } + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter7MathematicsAndProbability/WouldIntersect.java b/cracking-the-coding-interview/Chapter7MathematicsAndProbability/WouldIntersect.java new file mode 100644 index 00000000..cfd67026 --- /dev/null +++ b/cracking-the-coding-interview/Chapter7MathematicsAndProbability/WouldIntersect.java @@ -0,0 +1,20 @@ +/* give two lines on a Cartesian plane, determine whether the two lines would intersect */ + +public class WouldIntersect { + //placeholder for class name +} + +class Line { + static double epsilon = 0.000001; + public double slope; + public double yintercept; + + public Line(double s, double y) { + this.slope = s; + this.yintercept = y; + } + + public boolean Intersect(Line line2) { + return Math.abs(this.slope - line2.slope) > epsilon || Math.abs(this.yintercept - line2.yintercept) < epsilon; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter9RecursionAndDynamicProgramming/AllPermutations.java b/cracking-the-coding-interview/Chapter9RecursionAndDynamicProgramming/AllPermutations.java new file mode 100644 index 00000000..ddd18d66 --- /dev/null +++ b/cracking-the-coding-interview/Chapter9RecursionAndDynamicProgramming/AllPermutations.java @@ -0,0 +1,31 @@ +/* write a method to compute all permutations of a string of unique characters */ + +public class AllPermutations { + public static ArrayList getPerms(String str) { + if(str == null) { + return null; + } + ArrayList permutations = new ArrayList(); + if(str.length() == 0) { //base case + permutations.add(""); + return permutations; + } + + char first = str.charAt(0); //get the first character + String remainder = str.substring(1); //remove the 1st character + ArrayList words = getPerms(remainder); + for(String word : words) { + for(int j = 0; j <= word.length(); j++) { + String s = insertCharAt(word, first, j); + permutations.add(s); + } + } + return permutations; + } + + public static String insertCharAt(String word, char c, int i) { + String start = word.substring(0, i); + String end = word.substring(i); + return start + c + end; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter9RecursionAndDynamicProgramming/AllSubsets.java b/cracking-the-coding-interview/Chapter9RecursionAndDynamicProgramming/AllSubsets.java new file mode 100644 index 00000000..ce10e221 --- /dev/null +++ b/cracking-the-coding-interview/Chapter9RecursionAndDynamicProgramming/AllSubsets.java @@ -0,0 +1,24 @@ +/* write a method to return all subsets of a set */ + +public class AllSubsets { + ArrayList> getSubsets(ArrayList set, int index) { + ArrayList> allsubsets; + if(set.size() == index) { //base case - add empty set + allsubsets = new ArrayList>(); + allsubsets.add(new ArrayList()); //empty set + } + else { + allsubsets = getSubsets(set, index + 1); + int item = set.get(index); + ArrayList> moresubsets = new ArrayList>(); + for(ArrayList subset : allsubsets) { + ArrayList newsubset = new ArrayList(); + newsubset.addAll(subset); + newsubset.add(item); + moresubsets.add(newsubset); + } + allsubsets.addAll(moresubsets); + } + return allsubsets; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter9RecursionAndDynamicProgramming/EightQueens.java b/cracking-the-coding-interview/Chapter9RecursionAndDynamicProgramming/EightQueens.java new file mode 100644 index 00000000..90ea7fe1 --- /dev/null +++ b/cracking-the-coding-interview/Chapter9RecursionAndDynamicProgramming/EightQueens.java @@ -0,0 +1,48 @@ +/* write an algorithm to print all ways of arranging eight queens on an 8x8 chess board so that none of them + * share the same row, column or diagonal. In this case, "diagonal" means all diagonals, not just the two + * that bisect the board */ + +public class EightQueens { + public static final int GRID_SIZE = 8; + + void placeQueens(int row, Integer[] columns, ArrayList results) { + if(row == GRID_SIZE) { //found valid placement + results.add(columns.clone()); + } + else { + for(int col = 0; col < GRID_SIZE; col++) { + if(checkValid(columns, row, col)) { + columns[row] = col; //place queen + placeQueens(row + 1, columns, results); + } + } + } + } + + /* check if (row1, column1) is a valid spot for a queen by checking if there + * is a queen in the same column or diagonal. We don't need to check it for + * queens in the same row because the calling placeQueen only attempts to + * place one queen at a time. We know thi srow is empty */ + boolean checkValid(Integer[] columns, int row1, int column1) { + for(int row2 = 0; row2 < row1; row2++) { + int column2 = columns[row2]; + /* check if (row2, column2) invalides (row1, column1) as a queen spot */ + + /* check if rows have a queen in the same column */ + if(column1 == column2) { + return false; + } + + /* check diagonals: if the distance between the columns equals the distance + * between the rows, then they're in the same diagonal */ + int columnDistance = Math.abs(column2 - column1); + + /* row1 > row2, so no need for abs */ + int rowDistance = row1 - row2; + if(columnDistance == rowDistance) { + return false; + } + } + return true; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter9RecursionAndDynamicProgramming/MagicIndex.java b/cracking-the-coding-interview/Chapter9RecursionAndDynamicProgramming/MagicIndex.java new file mode 100644 index 00000000..c2d74c13 --- /dev/null +++ b/cracking-the-coding-interview/Chapter9RecursionAndDynamicProgramming/MagicIndex.java @@ -0,0 +1,24 @@ +/* a magic index is an array A[1...n - 1] is defined to be an index such that A[i] = i. Given a sorted + * array of distinct integers, write a method to find a magic index, if one exists, in array A */ + + public class MagicIndex { + public static int magicFast(int[] array, int start, int end) { + if(end < start || start < 0 || end >= array.length) { + return -1; + } + int mid = (start + end) / 2; + if(array[mid] == mid) { + return mid; + } + else if(array[mid] > mid) { + return magicFast(array, start, mid - 1); + } + else { + return magicFast(array, mid + 1, end); + } + } + + public static int magicFast(int[] array) { + return magicFast(array, 0, array.length - 1); + } + } \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter9RecursionAndDynamicProgramming/RepresentingNCents.java b/cracking-the-coding-interview/Chapter9RecursionAndDynamicProgramming/RepresentingNCents.java new file mode 100644 index 00000000..7ccb7439 --- /dev/null +++ b/cracking-the-coding-interview/Chapter9RecursionAndDynamicProgramming/RepresentingNCents.java @@ -0,0 +1,26 @@ +/* given an infinite number of quars (25 cents), dimes (10 cents), nickels (5 cents), and pennies (1 cent), + * write code to calculate the number of ways of representing n cents */ + + public class RepresentingNCents { + int makeChange(int n) { + int[] denoms = {25, 10, 5, 1}; + int[][] map = new int[n + 1][denoms.length]; //precomputed vals + return makeChange(n, denoms, 0, map); + } + + int makeChange(int amount, int[] denoms, int index, int[][] map) { + if(map[amount][index] > 0) { //retrieve value + return map[amount][index]; + } + if(index >= denoms.length - 1) return 1; //one denom remaining + int denomAmount = denoms[index]; + int ways = 0; + for(int i = 0; i * denomAmount <= amount; i++) { + //go to next denom, assuming i coints of denomAmount + int amountRemaining = amount - i * denomAmount; + ways += makeChange(amountRemaining, denoms, index + 1, map); + } + map[amount][index] = ways; + return ways; + } + } \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter9RecursionAndDynamicProgramming/StackBoxes.java b/cracking-the-coding-interview/Chapter9RecursionAndDynamicProgramming/StackBoxes.java new file mode 100644 index 00000000..d595cde5 --- /dev/null +++ b/cracking-the-coding-interview/Chapter9RecursionAndDynamicProgramming/StackBoxes.java @@ -0,0 +1,35 @@ +/* you have a stack of n boxes, with widths wi, heights hi, and depths di. The boxes cannot be rotated + * and can only be stacked on top of one another if each box in the stack is strictly larger than the + * the box above it in width, height, and depth. Implement a method to build the tallest stack possible, + * where the height of a stack is the sum of the heights of each box */ + +public class StackBoxes { + public ArrayList createStackDP(Box[] boxes, Box bottom, HashMap> stack_map) { + if(bottom != null && stack_map.containsKey(bottom)) { + return (ArrayList) stack_map.get(bottom).clone(); + } + + int max_height = 0; + ArrayList max_stack = null; + for(int i = 0; i < boxes.length; i++) { + if(boxes[i].canBeAbove(bottom)) { + ArrayList new_stack = createStackDP(boxes, boxes[i], stack_map); + int new_height = stackHeight(new_stack); + if(new_height > max_height) { + max_stack = new_stack; + max_height = new_height; + } + } + } + + if(max_stack == null) { + max_stack = new ArrayList(); + } + if(bottom != null) { + max_stack.add(0, bottom); + } + stack_map.put(bottom, max_stack); + + return max_stack; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/Chapter9RecursionAndDynamicProgramming/Staircase.java b/cracking-the-coding-interview/Chapter9RecursionAndDynamicProgramming/Staircase.java new file mode 100644 index 00000000..31d8cf5e --- /dev/null +++ b/cracking-the-coding-interview/Chapter9RecursionAndDynamicProgramming/Staircase.java @@ -0,0 +1,22 @@ +/* a child is running up a staircase with n steps, and can hop either 1 step, 2 steps, or 3 steps + * at a time. Implement a method to count how many possible ways the child can run up the stairs */ + + public class Staircase { + public static int countWaysDP(int n, int[] map) { + if(n < 0) { + return 0; + } + else if(n == 0) { + return 1; + } + else if(map[n] > -1) { + return map[n]; + } + else { + map[n] = countWaysDP(n - 1, map) + + countWaysDP(n - 2, map) + + countWaysDP(n - 3, map); + return map[n]; + } + } + } \ No newline at end of file diff --git a/cracking-the-coding-interview/CrackingTheCodingInterview.iml b/cracking-the-coding-interview/CrackingTheCodingInterview.iml new file mode 100644 index 00000000..76e7abb4 --- /dev/null +++ b/cracking-the-coding-interview/CrackingTheCodingInterview.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/leetcode/binary-search/closestBinarySearchTreeValue.java b/leetcode/binary-search/closestBinarySearchTreeValue.java new file mode 100644 index 00000000..9aad641d --- /dev/null +++ b/leetcode/binary-search/closestBinarySearchTreeValue.java @@ -0,0 +1,30 @@ +// Given a non-empty binary search tree and a target value, find the value in the BST that is closest to the target. + +// Note: + // Given target value is a floating point. + // You are guaranteed to have only one unique value in the BST that is closest to the target. + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode(int x) { val = x; } + * } + */ +public class Solution { + public int closestValue(TreeNode root, double target) { + + int value = root.val; + TreeNode child = root.val < target ? root.right : root.left; + + if(child == null) return value; + + int childValue = closestValue(child, target); + + return Math.abs(value - target) < Math.abs(childValue - target) ? value : childValue; + + } + +} \ No newline at end of file diff --git a/leetcode/binary-search/firstBadVersion.java b/leetcode/binary-search/firstBadVersion.java new file mode 100644 index 00000000..f8090b83 --- /dev/null +++ b/leetcode/binary-search/firstBadVersion.java @@ -0,0 +1,29 @@ +// You are a product manager and currently leading a team to develop a new product. Unfortunately, the latest version of your product fails the quality check. Since each version is developed based on the previous version, all the versions after a bad version are also bad. + +// Suppose you have n versions [1, 2, ..., n] and you want to find out the first bad one, which causes all the following ones to be bad. + +// You are given an API bool isBadVersion(version) which will return whether version is bad. Implement a function to find the first bad version. You should minimize the number of calls to the API. + +/* The isBadVersion API is defined in the parent class VersionControl. + boolean isBadVersion(int version); */ + +public class Solution extends VersionControl { + + public int firstBadVersion(int n) { + + int start = 1; + int end = n; + + while(start < end) { + + int mid = start + (end - start) / 2; + if(!isBadVersion(mid)) start = mid + 1; + else end = mid; + + } + + return start; + + } + +} \ No newline at end of file diff --git a/leetcode/binary-search/guessNumberHigherOrLower.java b/leetcode/binary-search/guessNumberHigherOrLower.java new file mode 100644 index 00000000..c1a8be88 --- /dev/null +++ b/leetcode/binary-search/guessNumberHigherOrLower.java @@ -0,0 +1,46 @@ +// We are playing the Guess Game. The game is as follows: + +// I pick a number from 1 to n. You have to guess which number I picked. + +// Every time you guess wrong, I'll tell you whether the number is higher or lower. + +// You call a pre-defined API guess(int num) which returns 3 possible results (-1, 1, or 0): + +// -1 : My number is lower +// 1 : My number is higher +// 0 : Congrats! You got it! +// Example: +// n = 10, I pick 6. + +// Return 6. + +/* The guess API is defined in the parent class GuessGame. + @param num, your guess + @return -1 if my number is lower, 1 if my number is higher, otherwise return 0 + int guess(int num); */ + +public class Solution extends GuessGame { + + public int guessNumber(int n) { + + return binarySearch(1, n); + + } + + private int binarySearch(int start, int end) { + + if(start > end) return -1; + + if(guess(start) == 0) return start; + if(guess(end) == 0) return end; + + int mid = start + (end - start) / 2; + + if(guess(mid) == 0) return mid; + + else if(guess(mid) == 1) return binarySearch(mid + 1, end); + else return binarySearch(start, mid - 1); + + } + +} \ No newline at end of file diff --git a/leetcode/binary-search/pow(x,n).java b/leetcode/binary-search/pow(x,n).java new file mode 100644 index 00000000..07cc9545 --- /dev/null +++ b/leetcode/binary-search/pow(x,n).java @@ -0,0 +1,30 @@ +// Implement pow(x, n). + +public class Solution { + + public double myPow(double x, int n) { + + if(n == 0) { + + return 1; + + } + + if(Double.isInfinite(x)) { + + return 0; + + } + + if(n < 0) { + + n = -n; + x = 1 / x; + + } + + return n % 2 == 0 ? myPow(x * x, n / 2) : x * myPow(x * x, n / 2); + + } + +} \ No newline at end of file diff --git a/leetcode/binary-search/sqrt(x).java b/leetcode/binary-search/sqrt(x).java new file mode 100644 index 00000000..13318f31 --- /dev/null +++ b/leetcode/binary-search/sqrt(x).java @@ -0,0 +1,28 @@ +// Implement int sqrt(int x). + +// Compute and return the square root of x. + +public class Solution { + + public int mySqrt(int x) { + + if(x == 0) return 0; + + int left = 1; + int right = x; + + while(left <= right) { + + int mid = left + (right - left) / 2; + + if(mid == x / mid) return mid; + else if(mid > x / mid) right = mid - 1; + else if(mid < x / mid) left = mid + 1; + + } + + return right; + + } + +} \ No newline at end of file diff --git a/leetcode/bit-manipulation/binaryWatch.java b/leetcode/bit-manipulation/binaryWatch.java new file mode 100644 index 00000000..f4106b5b --- /dev/null +++ b/leetcode/bit-manipulation/binaryWatch.java @@ -0,0 +1,45 @@ +// A binary watch has 4 LEDs on the top which represent the hours (0-11), and the 6 LEDs on the bottom represent the minutes (0-59). + +// Each LED represents a zero or one, with the least significant bit on the right. + +// For example, the above binary watch reads "3:25". + +// Given a non-negative integer n which represents the number of LEDs that are currently on, return all possible times the watch could represent. + +// Example: + +// Input: n = 1 +// Return: ["1:00", "2:00", "4:00", "8:00", "0:01", "0:02", "0:04", "0:08", "0:16", "0:32"] +// Note: +// The order of output does not matter. +// The hour must not contain a leading zero, for example "01:00" is not valid, it should be "1:00". +// The minute must be consist of two digits and may contain a leading zero, for example "10:2" is not valid, it should be "10:02". + +public class Solution { + + public List readBinaryWatch(int num) { + + ArrayList allTimes = new ArrayList(); + + //iterate through all possible time combinations + for(int i = 0; i < 12; i++) { + + for(int j = 0; j < 60; j++) { + + //if the current number and n have the same number of bits the time is possible + if(Integer.bitCount(i * 64 + j) == num) { + + //add the current time to all times arraylist + allTimes.add(String.format("%d:%02d", i, j)); + + } + + } + + } + + return allTimes; + + } + +} \ No newline at end of file diff --git a/leetcode/bit-manipulation/countingBits.java b/leetcode/bit-manipulation/countingBits.java new file mode 100644 index 00000000..261f1f06 --- /dev/null +++ b/leetcode/bit-manipulation/countingBits.java @@ -0,0 +1,23 @@ +// Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate the number of 1's in their binary representation and return them as an array. + +// Example: +// For num = 5 you should return [0,1,1,2,1,2]. + +public class Solution { + public int[] countBits(int num) { + + int[] bits = new int[num + 1]; + + bits[0] = 0; + + for(int i = 1; i <= num; i++) { + + bits[i] = bits[i >> 1] + (i & 1); + + } + + return bits; + + } + +} \ No newline at end of file diff --git a/leetcode/bit-manipulation/hammingDistance.java b/leetcode/bit-manipulation/hammingDistance.java new file mode 100644 index 00000000..12b27879 --- /dev/null +++ b/leetcode/bit-manipulation/hammingDistance.java @@ -0,0 +1,29 @@ +// The Hamming distance between two integers is the number of positions at which the corresponding bits are different. + +// Given two integers x and y, calculate the Hamming distance. + +// Note: +// 0 ≤ x, y < 2^31. + +// Example: + +// Input: x = 1, y = 4 + +// Output: 2 + +// Explanation: +// 1 (0 0 0 1) +// 4 (0 1 0 0) +// ↑ ↑ + +// The above arrows point to positions where the corresponding bits are different. + +public class Solution { + + public int hammingDistance(int x, int y) { + + return Integer.bitCount(x ^ y); + + } + +} \ No newline at end of file diff --git a/leetcode/bit-manipulation/maximumProductOfWordLengths.java b/leetcode/bit-manipulation/maximumProductOfWordLengths.java new file mode 100644 index 00000000..8a5d387b --- /dev/null +++ b/leetcode/bit-manipulation/maximumProductOfWordLengths.java @@ -0,0 +1,61 @@ +// Given a string array words, find the maximum value of length(word[i]) * length(word[j]) where the two words do not share common letters. You may assume that each word will contain only lower case letters. If no such two words exist, return 0. + +// Example 1: +// Given ["abcw", "baz", "foo", "bar", "xtfn", "abcdef"] +// Return 16 +// The two words can be "abcw", "xtfn". + +// Example 2: +// Given ["a", "ab", "abc", "d", "cd", "bcd", "abcd"] +// Return 4 +// The two words can be "ab", "cd". + +// Example 3: +// Given ["a", "aa", "aaa", "aaaa"] +// Return 0 +// No such pair of words. + +public class Solution { + + public int maxProduct(String[] words) { + + if(words.length == 0 || words == null) return 0; + + int length = words.length; + int[] value = new int[length]; + int max = 0; + + for(int i = 0; i < length; i++) { + + String temp = words[i]; + + value[i] = 0; + + for(int j = 0; j < temp.length(); j++) { + + value[i] |= 1 << (temp.charAt(j) - 'a'); + + } + + } + + + for(int i = 0; i < length; i++) { + + for(int j = 1; j < length; j++) { + + if((value[i] & value[j]) == 0 && (words[i].length() * words[j].length()) > max) { + + max = words[i].length() * words[j].length(); + + } + + } + + } + + return max; + + } + +} \ No newline at end of file diff --git a/leetcode/bit-manipulation/numberOf1Bits.java b/leetcode/bit-manipulation/numberOf1Bits.java new file mode 100644 index 00000000..1327edeb --- /dev/null +++ b/leetcode/bit-manipulation/numberOf1Bits.java @@ -0,0 +1,25 @@ +// Write a function that takes an unsigned integer and returns the number of ’1' bits it has (also known as the Hamming weight). + +// For example, the 32-bit integer ’11' has binary representation 00000000000000000000000000001011, so the function should return 3. + +public class Solution { + + // you need to treat n as an unsigned value + public int hammingWeight(int n) { + + if(n == 0) return 0; + + int count = 0; + + while(n != 0) { + + count += (n) & 1; + n >>>= 1; + + } + + return count; + + } + +} \ No newline at end of file diff --git a/leetcode/bit-manipulation/sumOfTwoIntegers.java b/leetcode/bit-manipulation/sumOfTwoIntegers.java new file mode 100644 index 00000000..80d034a6 --- /dev/null +++ b/leetcode/bit-manipulation/sumOfTwoIntegers.java @@ -0,0 +1,25 @@ +// Calculate the sum of two integers a and b, but you are not allowed to use the operator + and -. + +// Example: +// Given a = 1 and b = 2, return 3. + +public class Solution { + + public int getSum(int a, int b) { + + if(a == 0) return b; + if(b == 0) return a; + + while(b != 0) { + + int carry = a & b; + a = a ^ b; + b = carry << 1; + + } + + return a; + + } + +} \ No newline at end of file diff --git a/leetcode/bit-manipulation/utf-8Validation.java b/leetcode/bit-manipulation/utf-8Validation.java new file mode 100644 index 00000000..eb30560c --- /dev/null +++ b/leetcode/bit-manipulation/utf-8Validation.java @@ -0,0 +1,63 @@ +// A character in UTF8 can be from 1 to 4 bytes long, subjected to the following rules: + +// For 1-byte character, the first bit is a 0, followed by its unicode code. +// For n-bytes character, the first n-bits are all one's, the n+1 bit is 0, followed by n-1 bytes with most significant 2 bits being 10. +// This is how the UTF-8 encoding would work: + +// Char. number range | UTF-8 octet sequence +// (hexadecimal) | (binary) +// --------------------+--------------------------------------------- +// 0000 0000-0000 007F | 0xxxxxxx +// 0000 0080-0000 07FF | 110xxxxx 10xxxxxx +// 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx +// 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx +// Given an array of integers representing the data, return whether it is a valid utf-8 encoding. + +// Note: +// The input is an array of integers. Only the least significant 8 bits of each integer is used to store the data. This means each integer represents only 1 byte of data. + +// Example 1: + +// data = [197, 130, 1], which represents the octet sequence: 11000101 10000010 00000001. + +// Return true. +// It is a valid utf-8 encoding for a 2-bytes character followed by a 1-byte character. +// Example 2: + +// data = [235, 140, 4], which represented the octet sequence: 11101011 10001100 00000100. + +// Return false. +// The first 3 bits are all one's and the 4th bit is 0 means it is a 3-bytes character. +// The next byte is a continuation byte which starts with 10 and that's correct. +// But the second continuation byte does not start with 10, so it is invalid. + +public class Solution { + + public boolean validUtf8(int[] data) { + + int count = 0; + for(int i : data) { + + if(count == 0) { + + if((i >> 5) == 0b110) count = 1; + else if((i >> 4) == 0b1110) count = 2; + else if((i >> 3) == 0b11110) count = 3; + else if((i >> 7) == 0b1) return false; + + } + + else { + + if((i >> 6) != 0b10) return false; + count--; + + } + + } + + return count == 0; + + } + +} \ No newline at end of file diff --git a/leetcode/breadth-first-search/binaryTreeLevelOrderTraversal.java b/leetcode/breadth-first-search/binaryTreeLevelOrderTraversal.java new file mode 100644 index 00000000..248c7b93 --- /dev/null +++ b/leetcode/breadth-first-search/binaryTreeLevelOrderTraversal.java @@ -0,0 +1,81 @@ +// Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level). + +// For example: +// Given binary tree [3,9,20,null,null,15,7], +// 3 +// / \ +// 9 20 +// / \ +// 15 7 +// return its level order traversal as: +// [ +// [3], +// [9,20], +// [15,7] +// ] + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode(int x) { val = x; } + * } + */ +public class Solution { + + public List> levelOrder(TreeNode root) { + + List> result = new ArrayList>(); + + if(root == null) return result; + + Queue queue = new LinkedList(); + + queue.add(root); + + List tempList = new ArrayList(); + tempList.add(root.val); + result.add(tempList); + + while(!queue.isEmpty()) { + + Queue currentLevel = new LinkedList(); + + List list = new ArrayList(); + + while(!queue.isEmpty()) { + + TreeNode current = queue.remove(); + + if(current.left != null) { + + currentLevel.add(current.left); + list.add(current.left.val); + + } + + if(current.right != null) { + + currentLevel.add(current.right); + list.add(current.right.val); + + } + + } + + if(list.size() > 0) { + + result.add(list); + + } + queue = currentLevel; + + } + + return result; + + } + +} \ No newline at end of file diff --git a/leetcode/breadth-first-search/cloneGraph.java b/leetcode/breadth-first-search/cloneGraph.java new file mode 100644 index 00000000..e0e953bf --- /dev/null +++ b/leetcode/breadth-first-search/cloneGraph.java @@ -0,0 +1,54 @@ +// Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. + +// OJ's undirected graph serialization: +// Nodes are labeled uniquely. + +// We use # as a separator for each node, and , as a separator for node label and each neighbor of the node. +// As an example, consider the serialized graph {0,1,2#1,2#2,2}. + +// The graph has a total of three nodes, and therefore contains three parts as separated by #. + +// First node is labeled as 0. Connect node 0 to both nodes 1 and 2. +// Second node is labeled as 1. Connect node 1 to node 2. +// Third node is labeled as 2. Connect node 2 to node 2 (itself), thus forming a self-cycle. +// Visually, the graph looks like the following: + +// 1 +// / \ +// / \ +// 0 --- 2 +// / \ +// \_/ + +/** + * Definition for undirected graph. + * class UndirectedGraphNode { + * int label; + * List neighbors; + * UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList(); } + * }; + */ +public class Solution { + + public HashMap map = new HashMap(); + + public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) { + + if(node == null) return null; + + if(map.containsKey(node.label)) return map.get(node.label); + + UndirectedGraphNode newNode = new UndirectedGraphNode(node.label); + map.put(newNode.label, newNode); + + for(UndirectedGraphNode neighbor : node.neighbors) { + + newNode.neighbors.add(cloneGraph(neighbor)); + + } + + return newNode; + + } + +} \ No newline at end of file diff --git a/leetcode/breadth-first-search/pacificAtlanticWaterFlow.java b/leetcode/breadth-first-search/pacificAtlanticWaterFlow.java new file mode 100644 index 00000000..c9964fa9 --- /dev/null +++ b/leetcode/breadth-first-search/pacificAtlanticWaterFlow.java @@ -0,0 +1,100 @@ +// Given an m x n matrix of non-negative integers representing the height of each unit cell in a continent, the "Pacific ocean" touches the left and top edges of the matrix and the "Atlantic ocean" touches the right and bottom edges. + +// Water can only flow in four directions (up, down, left, or right) from a cell to another one with height equal or lower. + +// Find the list of grid coordinates where water can flow to both the Pacific and Atlantic ocean. + +// Note: + // The order of returned grid coordinates does not matter. + // Both m and n are less than 150. + +// Example: + +// Given the following 5x5 matrix: + +// Pacific ~ ~ ~ ~ ~ +// ~ 1 2 2 3 (5) * +// ~ 3 2 3 (4) (4) * +// ~ 2 4 (5) 3 1 * +// ~ (6) (7) 1 4 5 * +// ~ (5) 1 1 2 4 * +// * * * * * Atlantic + +// Return: + +// [[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]] (positions with parentheses in above matrix). + +public class Solution { + + public List pacificAtlantic(int[][] matrix) { + + List result = new LinkedList<>(); + + //error checking + if(matrix == null || matrix.length == 0 || matrix[0].length == 0) { + + return result; + + } + + int n = matrix.length; + int m = matrix[0].length; + + boolean[][] pacific = new boolean[n][m]; + boolean[][] atlantic = new boolean[n][m]; + + for(int i = 0; i < n; i++) { + + dfs(matrix, pacific, Integer.MIN_VALUE, i, 0); + dfs(matrix, atlantic, Integer.MIN_VALUE, i, m - 1); + + } + + for(int i = 0; i < m; i++) { + + dfs(matrix, pacific, Integer.MIN_VALUE, 0, i); + dfs(matrix, atlantic, Integer.MIN_VALUE, n - 1, i); + + } + + for(int i = 0; i < n; i++) { + + for(int j = 0; j < m; j++) { + + if(pacific[i][j] && atlantic[i][j]) { + + result.add(new int[] {i, j}); + + } + + } + + } + + return result; + + } + + + public void dfs(int[][] matrix, boolean[][] visited, int height, int x, int y) { + + int n = matrix.length; + int m = matrix[0].length; + + if(x < 0 || x >= n || y < 0 || y >= m || visited[x][y] || matrix[x][y] < height) { + + return; + + } + + + visited[x][y] = true; + + dfs(matrix, visited, matrix[x][y], x + 1, y); + dfs(matrix, visited, matrix[x][y], x - 1, y); + dfs(matrix, visited, matrix[x][y], x, y + 1); + dfs(matrix, visited, matrix[x][y], x, y - 1); + + } + +} \ No newline at end of file diff --git a/leetcode/breadth-first-search/removeInvalidParentheses.java b/leetcode/breadth-first-search/removeInvalidParentheses.java new file mode 100644 index 00000000..8d8a55c8 --- /dev/null +++ b/leetcode/breadth-first-search/removeInvalidParentheses.java @@ -0,0 +1,41 @@ +// Remove the minimum number of invalid parentheses in order to make the input string valid. Return all possible results. + +// Note: The input string may contain letters other than the parentheses ( and ). + +// Examples: +// "()())()" -> ["()()()", "(())()"] +// "(a)())()" -> ["(a)()()", "(a())()"] +// ")(" -> [""] + +public class Solution { + + public List removeInvalidParentheses(String s) { + List result = new ArrayList<>(); + remove(s, result, 0, 0, new char[]{'(', ')'}); + return result; + } + + public void remove(String s, List result, int last_i, int last_j, char[] par) { + + for (int stack = 0, i = last_i; i < s.length(); i++) { + + if (s.charAt(i) == par[0]) stack++; + if (s.charAt(i) == par[1]) stack--; + if (stack >= 0) continue; + + for (int j = last_j; j <= i; j++) + if (s.charAt(j) == par[1] && (j == last_j || s.charAt(j - 1) != par[1])) + remove(s.substring(0, j) + s.substring(j + 1, s.length()), result, i, j, par); + return; + } + + String reversed = new StringBuilder(s).reverse().toString(); + + if (par[0] == '(') // finished left to right + remove(reversed, result, 0, 0, new char[]{')', '('}); + + else // finished right to left + result.add(reversed); + } + +} \ No newline at end of file diff --git a/leetcode/breadth-first-search/shortestDistanceFromAllBuildings.java b/leetcode/breadth-first-search/shortestDistanceFromAllBuildings.java new file mode 100644 index 00000000..1b4c7a0a --- /dev/null +++ b/leetcode/breadth-first-search/shortestDistanceFromAllBuildings.java @@ -0,0 +1,104 @@ +// You want to build a house on an empty land which reaches all buildings in the shortest amount of distance. You can only move up, down, left and right. You are given a 2D grid of values 0, 1 or 2, where: + +// Each 0 marks an empty land which you can pass by freely. +// Each 1 marks a building which you cannot pass through. +// Each 2 marks an obstacle which you cannot pass through. +// For example, given three buildings at (0,0), (0,4), (2,2), and an obstacle at (0,2): + +// 1 - 0 - 2 - 0 - 1 +// | | | | | +// 0 - 0 - 0 - 0 - 0 +// | | | | | +// 0 - 0 - 1 - 0 - 0 +// The point (1,2) is an ideal empty land to build a house, as the total travel distance of 3+3+1=7 is minimal. So return 7. + +// Note: +// There will be at least one building. If it is not possible to build such house according to the above rules, return -1. + +public class Solution { + + public int shortestDistance(int[][] grid) { + + if(grid == null || grid.length == 0 || grid[0].length == 0) return -1; + + final int[] shift = {0, 1, 0, -1, 0}; + + int rows = grid.length; + int columns = grid[0].length; + + int[][] distance = new int[rows][columns]; + int[][] reach = new int[rows][columns]; + + int numberOfBuildings = 0; + + for(int i = 0; i < rows; i++) { + + for(int j = 0; j < columns; j++) { + + if(grid[i][j] == 1) { + + numberOfBuildings++; + Queue queue = new LinkedList(); + queue.offer(new int[] {i, j}); + + boolean[][] visited = new boolean[rows][columns]; + + int relativeDistance = 1; + + while(!queue.isEmpty()) { + + int qSize = queue.size(); + + for(int q = 0; q < qSize; q++) { + + int[] current = queue.poll(); + + for(int k = 0; k < 4; k++) { + + int nextRow = current[0] + shift[k]; + int nextColumn = current[1] + shift[k + 1]; + + if(nextRow >= 0 && nextRow < rows && nextColumn >= 0 && nextColumn < columns && grid[nextRow][nextColumn] == 0 && !visited[nextRow][nextColumn]) { + + distance[nextRow][nextColumn] += relativeDistance; + reach[nextRow][nextColumn]++; + + visited[nextRow][nextColumn] = true; + queue.offer(new int[] {nextRow, nextColumn}); + + } + + } + + } + + relativeDistance++; + + } + + } + } + + } + + int shortest = Integer.MAX_VALUE; + + for(int i = 0; i < rows; i++) { + + for(int j = 0; j < columns; j++) { + + if(grid[i][j] == 0 && reach[i][j] == numberOfBuildings) { + + shortest = Math.min(shortest, distance[i][j]); + + } + + } + + } + + return shortest == Integer.MAX_VALUE ? -1 : shortest; + + } + +} \ No newline at end of file diff --git a/leetcode/breadth-first-search/symmetricTree.java b/leetcode/breadth-first-search/symmetricTree.java new file mode 100644 index 00000000..7a550f40 --- /dev/null +++ b/leetcode/breadth-first-search/symmetricTree.java @@ -0,0 +1,46 @@ +// Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). + +// For example, this binary tree [1,2,2,3,4,4,3] is symmetric: + +// 1 +// / \ +// 2 2 +// / \ / \ +// 3 4 4 3 +// But the following [1,2,2,null,3,null,3] is not: +// 1 +// / \ +// 2 2 +// \ \ +// 3 3 + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode(int x) { val = x; } + * } + */ +public class Solution { + + public boolean isSymmetric(TreeNode root) { + + if(root == null) return true; + + return helper(root.left, root.right); + + } + + public boolean helper(TreeNode left, TreeNode right) { + + if(left == null && right == null) return true; + + if(left == null || right == null || left.val != right.val) return false; + + return helper(left.right, right.left) && helper(left.left, right.right); + + } + +} \ No newline at end of file diff --git a/leetcode/breadth-first-search/wallsAndGates.java b/leetcode/breadth-first-search/wallsAndGates.java new file mode 100644 index 00000000..cf23da68 --- /dev/null +++ b/leetcode/breadth-first-search/wallsAndGates.java @@ -0,0 +1,60 @@ +// You are given a m x n 2D grid initialized with these three possible values. + +// -1 - A wall or an obstacle. +// 0 - A gate. +// INF - Infinity means an empty room. We use the value 231 - 1 = 2147483647 to represent INF as you may assume that the distance to a gate is less than 2147483647. +// Fill each empty room with the distance to its nearest gate. If it is impossible to reach a gate, it should be filled with INF. + +// For example, given the 2D grid: +// INF -1 0 INF +// INF INF INF -1 +// INF -1 INF -1 +// 0 -1 INF INF +// After running your function, the 2D grid should be: +// 3 -1 0 1 +// 2 2 1 -1 +// 1 -1 2 -1 +// 0 -1 3 4 + +public class Solution { + + public void wallsAndGates(int[][] rooms) { + + //iterate through the matrix calling dfs on all indices that contain a zero + for(int i = 0; i < rooms.length; i++) { + + for(int j = 0; j < rooms[0].length; j++) { + + if(rooms[i][j] == 0) { + + dfs(rooms, i, j, 0); + + } + + } + } + + } + + void dfs(int[][] rooms, int i, int j, int distance) { + + //if you have gone out of the bounds of the array or you have run into a wall/obstacle, return + // room[i][j] < distance also ensure that we do not overwrite any previously determined distance if it is shorter than our current distance + if(i < 0 || i >= rooms.length || j < 0 || j >= rooms[0].length || rooms[i][j] < distance) { + + return; + + } + + //set current index's distance to distance + rooms[i][j] = distance; + + //recurse on all adjacent neighbors of rooms[i][j] + dfs(rooms, i + 1, j, distance + 1); + dfs(rooms, i - 1, j, distance + 1); + dfs(rooms, i, j + 1, distance + 1); + dfs(rooms, i, j - 1, distance + 1); + + } + +} \ No newline at end of file diff --git a/leetcode/depth-first-search/balancedBinaryTree.java b/leetcode/depth-first-search/balancedBinaryTree.java new file mode 100644 index 00000000..dceeb106 --- /dev/null +++ b/leetcode/depth-first-search/balancedBinaryTree.java @@ -0,0 +1,42 @@ +// Given a binary tree, determine if it is height-balanced. + +// For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1. + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode(int x) { val = x; } + * } + */ +public class Solution { + + boolean balanced = true; + + public boolean isBalanced(TreeNode root) { + + height(root); + return balanced; + + } + + private int height(TreeNode root) { + + if(root == null) return 0; + + int leftHeight = height(root.left); + int rightHeight = height(root.right); + + if(Math.abs(leftHeight - rightHeight) > 1) { + + balanced = false; + + } + + return 1 + Math.max(leftHeight, rightHeight); + + } + +} \ No newline at end of file diff --git a/leetcode/depth-first-search/battleshipsInABoard.java b/leetcode/depth-first-search/battleshipsInABoard.java new file mode 100644 index 00000000..9230b3b6 --- /dev/null +++ b/leetcode/depth-first-search/battleshipsInABoard.java @@ -0,0 +1,61 @@ +// Given an 2D board, count how many battleships are in it. The battleships are represented with 'X's, empty slots are represented with '.'s. You may assume the following rules: + +// You receive a valid board, made of only battleships or empty slots. +// Battleships can only be placed horizontally or vertically. In other words, they can only be made of the shape 1xN (1 row, N columns) or Nx1 (N rows, 1 column), where N can be of any size. +// At least one horizontal or vertical cell separates between two battleships - there are no adjacent battleships. + +// Example: +// X..X +// ...X +// ...X +// In the above board there are 2 battleships. + +// Invalid Example: +// ...X +// XXXX +// ...X +// This is an invalid board that you will not receive - as battleships will always have a cell separating between them. + +// Follow up: +// Could you do it in one-pass, using only O(1) extra memory and without modifying the value of the board? + +public class Solution { + + public int countBattleships(char[][] board) { + + int ships = 0; + + for(int i = 0; i < board.length; i++) { + + for(int j = 0; j < board[0].length; j++) { + + if(board[i][j] == 'X') { + + ships++; + sink(board, i, j, 1); + + } + + } + + } + + return ships; + + } + + public void sink(char[][] board, int i, int j, int numberOfShips) { + + if(i < 0 || i >= board.length || j < 0 || j >= board[0].length || board[i][j] == '.') { + + return; + + } + + board[i][j] = '.'; + sink(board, i + 1, j, numberOfShips + 1); + sink(board, i, j + 1, numberOfShips + 1); + + } + +} \ No newline at end of file diff --git a/leetcode/depth-first-search/convertSortedArrayToBinarySearchTree.java b/leetcode/depth-first-search/convertSortedArrayToBinarySearchTree.java new file mode 100644 index 00000000..a9ca0e0d --- /dev/null +++ b/leetcode/depth-first-search/convertSortedArrayToBinarySearchTree.java @@ -0,0 +1,43 @@ +// Given an array where elements are sorted in ascending order, convert it to a height balanced BST. + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode(int x) { val = x; } + * } + */ +public class Solution { + + public TreeNode sortedArrayToBST(int[] nums) { + + if(nums.length == 0) return null; + + TreeNode root = helper(nums, 0, nums.length - 1); + + return root; + + } + + private TreeNode helper(int[] nums, int start, int end) { + + if(start <= end) { + + int mid = (start + end) / 2; + + TreeNode current = new TreeNode(nums[mid]); + + current.left = helper(nums, start, mid - 1); + current.right = helper(nums, mid + 1, end); + + return current; + + } + + return null; + + } + +} \ No newline at end of file diff --git a/leetcode/depth-first-search/maximumDepthOfABinaryTree.java b/leetcode/depth-first-search/maximumDepthOfABinaryTree.java new file mode 100644 index 00000000..097f3e36 --- /dev/null +++ b/leetcode/depth-first-search/maximumDepthOfABinaryTree.java @@ -0,0 +1,24 @@ +// Given a binary tree, find its maximum depth. + +// The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode(int x) { val = x; } + * } + */ +public class Solution { + + public int maxDepth(TreeNode root) { + + if(root == null) return 0; + + return 1 + Math.max(maxDepth(root.left), maxDepth(root.right)); + + } + +} \ No newline at end of file diff --git a/leetcode/depth-first-search/numberOfIslands.java b/leetcode/depth-first-search/numberOfIslands.java new file mode 100644 index 00000000..7857aa8d --- /dev/null +++ b/leetcode/depth-first-search/numberOfIslands.java @@ -0,0 +1,71 @@ +// Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water. + +// Example 1: + +// 11110 +// 11010 +// 11000 +// 00000 +// Answer: 1 + +// Example 2: + +// 11000 +// 11000 +// 00100 +// 00011 +// Answer: 3 + +public class Solution { + + char[][] gridCopy; + + public int numIslands(char[][] grid) { + + //set grid copy to the current grid + gridCopy = grid; + + //initialize number of islands to zero + int numberOfIslands = 0; + + //iterate through every index of the grid + for(int i = 0; i < grid.length; i++) { + + for(int j = 0; j < grid[0].length; j++) { + + //attempt to "sink" the current index of the grid + numberOfIslands += sink(gridCopy, i, j); + + } + + } + + //return the total number of islands + return numberOfIslands; + + } + + int sink(char[][] grid, int i, int j) { + + //check the bounds of i and j and if the current index is an island or not (1 or 0) + if(i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == '0') { + + return 0; + + } + + //set current index to 0 + grid[i][j] = '0'; + + // sink all neighbors of current index + sink(grid, i + 1, j); + sink(grid, i - 1, j); + sink(grid, i, j + 1); + sink(grid, i, j - 1); + + //increment number of islands + return 1; + + } + +} \ No newline at end of file diff --git a/leetcode/depth-first-search/populatingNextRightPointersInEachNode.java b/leetcode/depth-first-search/populatingNextRightPointersInEachNode.java new file mode 100644 index 00000000..e4c956da --- /dev/null +++ b/leetcode/depth-first-search/populatingNextRightPointersInEachNode.java @@ -0,0 +1,81 @@ +// Given a binary tree + +// struct TreeLinkNode { +// TreeLinkNode *left; +// TreeLinkNode *right; +// TreeLinkNode *next; +// } +// Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL. + +// Initially, all next pointers are set to NULL. + +// Note: + +// You may only use constant extra space. +// You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children). +// For example, +// Given the following perfect binary tree, +// 1 +// / \ +// 2 3 +// / \ / \ +// 4 5 6 7 +// After calling your function, the tree should look like: +// 1 -> NULL +// / \ +// 2 -> 3 -> NULL +// / \ / \ +// 4->5->6->7 -> NULL + +/** + * Definition for binary tree with next pointer. + * public class TreeLinkNode { + * int val; + * TreeLinkNode left, right, next; + * TreeLinkNode(int x) { val = x; } + * } + */ +public class Solution { + + public void connect(TreeLinkNode root) { + + if(root == null) return; + + Queue queue = new LinkedList(); + + queue.add(root); + + while(!queue.isEmpty()) { + + Queue currentLevel = new LinkedList(); + + TreeLinkNode temp = null; + + while(!queue.isEmpty()) { + + TreeLinkNode current = queue.remove(); + current.next = temp; + temp = current; + + + if(current.right != null) { + + currentLevel.add(current.right); + + } + + if(current.left!= null) { + + currentLevel.add(current.left); + } + + + } + + queue = currentLevel; + + } + + } + +} \ No newline at end of file diff --git a/leetcode/depth-first-search/sameTree.java b/leetcode/depth-first-search/sameTree.java new file mode 100644 index 00000000..aa8244a5 --- /dev/null +++ b/leetcode/depth-first-search/sameTree.java @@ -0,0 +1,30 @@ +// Given two binary trees, write a function to check if they are equal or not. + +// Two binary trees are considered equal if they are structurally identical and the nodes have the same value. + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode(int x) { val = x; } + * } + */ +public class Solution { + + public boolean isSameTree(TreeNode p, TreeNode q) { + + if(p == null && q == null) return true; + + if(p == null && q != null || q == null && p != null) return false; + + if(p.val != q.val) return false; + + return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); + + + + } + +} \ No newline at end of file diff --git a/leetcode/divide-and-conquer/expressionAddOperators.java b/leetcode/divide-and-conquer/expressionAddOperators.java new file mode 100644 index 00000000..1a7865eb --- /dev/null +++ b/leetcode/divide-and-conquer/expressionAddOperators.java @@ -0,0 +1,58 @@ +// Given a string that contains only digits 0-9 and a target value, return all possibilities to add binary operators (not unary) +, -, or * between the digits so they evaluate to the target value. + +// Examples: +// "123", 6 -> ["1+2+3", "1*2*3"] +// "232", 8 -> ["2*3+2", "2+3*2"] +// "105", 5 -> ["1*0+5","10-5"] +// "00", 0 -> ["0+0", "0-0", "0*0"] +// "3456237490", 9191 -> [] + +public class Solution { + + public List addOperators(String num, int target) { + + List result = new ArrayList(); + if(num == null || num.length() == 0) return result; + helper(result, "", num, target, 0, 0, 0); + return result; + + } + + public void helper(List result, String path, String num, int target, int pos, long eval, long multed) { + + if(pos == num.length()) { + + if(eval == target) { + + result.add(path); + + } + + return; + + } + + for(int i = pos; i < num.length(); i++) { + + if(i != pos && num.charAt(pos) == '0') break; + long cur = Long.parseLong(num.substring(pos, i + 1)); + if(pos == 0) { + + helper(result, path + cur, num, target, i + 1, cur, cur); + + } + + else { + + helper(result, path + "+" + cur, num, target, i + 1, eval + cur, cur); + helper(result, path + "-" + cur, num, target, i + 1, eval - cur, -cur); + helper(result, path + "*" + cur, num, target, i + 1, eval - multed + multed * cur, multed * cur); + + + } + + } + + } + +} \ No newline at end of file diff --git a/leetcode/divide-and-conquer/kthLargestElementInAnArray.java b/leetcode/divide-and-conquer/kthLargestElementInAnArray.java new file mode 100644 index 00000000..de934f69 --- /dev/null +++ b/leetcode/divide-and-conquer/kthLargestElementInAnArray.java @@ -0,0 +1,19 @@ +// Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element. + +// For example, +// Given [3,2,1,5,6,4] and k = 2, return 5. + +// Note: +// You may assume k is always valid, 1 ≤ k ≤ array's length. + +public class Solution { + + public int findKthLargest(int[] nums, int k) { + + int length = nums.length; + Arrays.sort(nums); + return nums[length - k]; + + } + +} \ No newline at end of file diff --git a/leetcode/dynamic-programming/bombEnemy.java b/leetcode/dynamic-programming/bombEnemy.java new file mode 100644 index 00000000..26dc39c8 --- /dev/null +++ b/leetcode/dynamic-programming/bombEnemy.java @@ -0,0 +1,87 @@ +// Given a 2D grid, each cell is either a wall 'W', an enemy 'E' or empty '0' (the number zero), return the maximum enemies you can kill using one bomb. +// The bomb kills all the enemies in the same row and column from the planted point until it hits the wall since the wall is too strong to be destroyed. +// Note that you can only put the bomb at an empty cell. + +// Example: +// For the given grid + +// 0 E 0 0 +// E 0 W E +// 0 E 0 0 + +// return 3. (Placing a bomb at (1,1) kills 3 enemies) + + public class Solution { + + public int maxKilledEnemies(char[][] grid) { + + if(grid == null || grid.length == 0 || grid[0].length == 0) return 0; + + int max = 0; + int row = 0; + int[] col = new int[grid[0].length]; + + for(int i = 0; i max) ? row + col[j] : max; + + } + + } + + } + + return max; + + } + + //calculate killed enemies for row i from column j + private int killedEnemiesRow(char[][] grid, int i, int j) { + + int num = 0; + + while(j <= grid[0].length-1 && grid[i][j] != 'W') { + + if(grid[i][j] == 'E') num++; + j++; + + } + + return num; + + } + + //calculate killed enemies for column j from row i + private int killedEnemiesCol(char[][] grid, int i, int j) { + + int num = 0; + + while(i <= grid.length -1 && grid[i][j] != 'W'){ + + if(grid[i][j] == 'E') num++; + i++; + + } + + return num; + + } + +} \ No newline at end of file diff --git a/leetcode/dynamic-programming/climbingStairs.java b/leetcode/dynamic-programming/climbingStairs.java new file mode 100644 index 00000000..a585a3d2 --- /dev/null +++ b/leetcode/dynamic-programming/climbingStairs.java @@ -0,0 +1,26 @@ +// You are climbing a stair case. It takes n steps to reach to the top. + +// Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top? + +// Note: Given n will be a positive integer. + +public class Solution { + + public int climbStairs(int n) { + + int[] dp = new int[n + 1]; + + dp[0] = 1; + dp[1] = 1; + + for(int i = 2; i < dp.length; i++) { + + dp[i] = dp[i - 1] + dp[i - 2]; + + } + + return dp[dp.length - 1]; + + } + +} \ No newline at end of file diff --git a/leetcode/dynamic-programming/combinationSumIV.java b/leetcode/dynamic-programming/combinationSumIV.java new file mode 100644 index 00000000..2fe98be4 --- /dev/null +++ b/leetcode/dynamic-programming/combinationSumIV.java @@ -0,0 +1,50 @@ +// Given an integer array with all positive numbers and no duplicates, find the number of possible combinations that add up to a positive integer target. + +// Example: + +// nums = [1, 2, 3] +// target = 4 + +// The possible combination ways are: +// (1, 1, 1, 1) +// (1, 1, 2) +// (1, 2, 1) +// (1, 3) +// (2, 1, 1) +// (2, 2) +// (3, 1) + +// Note that different sequences are counted as different combinations. + +// Therefore the output is 7. + +// Follow up: + // What if negative numbers are allowed in the given array? + // How does it change the problem? + // What limitation we need to add to the question to allow negative numbers? + +public class Solution { + + public int combinationSum4(int[] nums, int target) { + + int[] dp = new int[target + 1]; + dp[0] = 1; + + for(int i = 1; i < dp.length; i++) { + for(int j = 0; j < nums.length; j++) { + + if(i - nums[j] >= 0) { + + dp[i] += dp[i - nums[j]]; + + } + + } + + } + + return dp[target]; + + } + +} \ No newline at end of file diff --git a/leetcode/dynamic-programming/countingBits.java b/leetcode/dynamic-programming/countingBits.java new file mode 100644 index 00000000..9ac99061 --- /dev/null +++ b/leetcode/dynamic-programming/countingBits.java @@ -0,0 +1,29 @@ +// Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate the number of 1's in their binary representation and return them as an array. + +// Example: +// For num = 5 you should return [0,1,1,2,1,2]. + +// Follow up: + // It is very easy to come up with a solution with run time O(n*sizeof(integer)). But can you do it in linear time O(n) /possibly in a single pass? + // Space complexity should be O(n). + // Can you do it like a boss? Do it without using any builtin function like __builtin_popcount in c++ or in any other language. + +public class Solution { + + public int[] countBits(int num) { + + int[] bits = new int[num + 1]; + + bits[0] = 0; + + for(int i = 1; i <= num; i++) { + + bits[i] = bits[i >> 1] + (i & 1); + + } + + return bits; + + } + +} \ No newline at end of file diff --git a/leetcode/dynamic-programming/editDistance.java b/leetcode/dynamic-programming/editDistance.java new file mode 100644 index 00000000..c5e8ef68 --- /dev/null +++ b/leetcode/dynamic-programming/editDistance.java @@ -0,0 +1,59 @@ +// Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.) + +// You have the following 3 operations permitted on a word: + +// a) Insert a character +// b) Delete a character +// c) Replace a character + +public class Solution { + + public int minDistance(String word1, String word2) { + + int m = word1.length(); + int n = word2.length(); + + int[][] dp = new int[m + 1][n + 1]; + + for(int i = 0; i <= m; i++) { + + dp[i][0] = i; + + } + + for(int i = 0; i <= n; i++) { + + dp[0][i] = i; + + } + + for(int i = 0; i < m; i++) { + + for(int j = 0; j < n; j++) { + + if(word1.charAt(i) == word2.charAt(j)) { + + dp[i + 1][j + 1] = dp[i][j]; + + } + + else { + + int a = dp[i][j]; + int b = dp[i][j + 1]; + int c = dp[i + 1][j]; + + dp[i + 1][j + 1] = Math.min(a, Math.min(b, c)); + dp[i + 1][j + 1]++; + + } + + } + + } + + return dp[m][n]; + + } + +} \ No newline at end of file diff --git a/leetcode/dynamic-programming/houseRobber.java b/leetcode/dynamic-programming/houseRobber.java new file mode 100644 index 00000000..d4d45ca6 --- /dev/null +++ b/leetcode/dynamic-programming/houseRobber.java @@ -0,0 +1,33 @@ +// You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night. + +// Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police. + +public class Solution { + + public int rob(int[] nums) { + + if(nums.length == 0) return 0; + if(nums.length == 1) return nums[0]; + + int[] dp = new int[nums.length]; + + dp[0] = nums[0]; + dp[1] = nums[0] > nums[1] ? nums[0] : nums[1]; + + for(int i = 2; i < nums.length; i++) { + + dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]); + + } + + for(int i = 0; i < dp.length; i++) { + + System.out.print(dp[i] + " "); + + } + + return dp[dp.length - 1]; + + } + +} \ No newline at end of file diff --git a/leetcode/dynamic-programming/paintFence.java b/leetcode/dynamic-programming/paintFence.java new file mode 100644 index 00000000..15ea5f33 --- /dev/null +++ b/leetcode/dynamic-programming/paintFence.java @@ -0,0 +1,35 @@ +// There is a fence with n posts, each post can be painted with one of the k colors. + +// You have to paint all the posts such that no more than two adjacent fence posts have the same color. + +// Return the total number of ways you can paint the fence. + +// Note: +// n and k are non-negative integers. + +public class Solution { + + public int numWays(int n, int k) { + + if(n <= 0) { + + return 0; + + } + + int sameColorCounts = 0; + int differentColorCounts = k; + + for(int i = 2; i <= n; i++) { + + int temp = differentColorCounts; + differentColorCounts = (sameColorCounts + differentColorCounts) * (k - 1); + sameColorCounts = temp; + + } + + return sameColorCounts + differentColorCounts; + + } + +} \ No newline at end of file diff --git a/leetcode/dynamic-programming/paintHouseII.java b/leetcode/dynamic-programming/paintHouseII.java new file mode 100644 index 00000000..f0acbfb5 --- /dev/null +++ b/leetcode/dynamic-programming/paintHouseII.java @@ -0,0 +1,65 @@ + // There are a row of n houses, each house can be painted with one of the k colors. The cost of painting each house with a certain color is different. You have to paint all the houses such that no two adjacent houses have the same color. + +// The cost of painting each house with a certain color is represented by a n x k cost matrix. For example, costs[0][0] is the cost of painting house 0 with color 0; costs[1][2] is the cost of painting house 1 with color 2, and so on... Find the minimum cost to paint all houses. + +// Note: +// All costs are positive integers. + +// Follow up: +// Could you solve it in O(nk) runtime? + +public class Solution { + + public int minCostII(int[][] costs) { + + if(costs == null|| costs.length == 0) return 0; + + int m = costs.length; + int n = costs[0].length; + + int min1 = -1; + int min2 = -1; + + for(int i = 0; i < m; i++) { + + int last1 = min1; + int last2 = min2; + min1 = -1; + min2 = -1; + + for(int j = 0; j < n; j++) { + + if(j != last1) { + + costs[i][j] += last1 < 0 ? 0 : costs[i - 1][last1]; + + } + + else { + + costs[i][j] += last2 < 0 ? 0 : costs[i - 1][last2]; + + } + + if(min1 < 0 || costs[i][j] < costs[i][min1]) { + + min2 = min1; + min1 = j; + + } + + else if(min2 < 0 || costs[i][j] < costs[i][min2]) { + + min2 = j; + + } + + } + + } + + return costs[m - 1][min1]; + + } + +} \ No newline at end of file diff --git a/leetcode/dynamic-programming/regularExpressionMatching.java b/leetcode/dynamic-programming/regularExpressionMatching.java new file mode 100644 index 00000000..2144a618 --- /dev/null +++ b/leetcode/dynamic-programming/regularExpressionMatching.java @@ -0,0 +1,79 @@ +// Implement regular expression matching with support for '.' and '*'. + +// '.' Matches any single character. +// '*' Matches zero or more of the preceding element. + +// The matching should cover the entire input string (not partial). + +// The function prototype should be: +// bool isMatch(const char *s, const char *p) + +// Some examples: +// isMatch("aa","a") → false +// isMatch("aa","aa") → true +// isMatch("aaa","aa") → false +// isMatch("aa", "a*") → true +// isMatch("aa", ".*") → true +// isMatch("ab", ".*") → true +// isMatch("aab", "c*a*b") → true + +public class Solution { + + public boolean isMatch(String s, String p) { + + if(s == null || p == null) return false; + + boolean[][] dp = new boolean[s.length() + 1][p.length() + 1]; + dp[0][0] = true; + + for(int i = 0; i < p.length(); i++) { + + if(p.charAt(i) == '*' && dp[0][i - 1]) { + + dp[0][i + 1] = true; + + } + + } + + for(int i = 0; i < s.length(); i++) { + + for(int j = 0; j < p.length(); j++) { + + if(p.charAt(j) == '.') { + + dp[i + 1][j + 1] = dp[i][j]; + + } + + if(p.charAt(j) == s.charAt(i)) { + + dp[i + 1][j + 1] = dp[i][j]; + + } + + if(p.charAt(j) == '*') { + + if(p.charAt(j - 1) != s.charAt(i) && p.charAt(j - 1) != '.') { + + dp[i + 1][j + 1] = dp[i + 1][j - 1]; + + } + + else { + + dp[i + 1][j + 1] = (dp[i + 1][j] || dp[i][j + 1] || dp[i + 1][j - 1]); + + } + + } + + } + + } + + return dp[s.length()][p.length()]; + + } + +} \ No newline at end of file diff --git a/leetcode/dynamic-programming/sentenceScreenFitting.java b/leetcode/dynamic-programming/sentenceScreenFitting.java new file mode 100644 index 00000000..5c589f45 --- /dev/null +++ b/leetcode/dynamic-programming/sentenceScreenFitting.java @@ -0,0 +1,88 @@ +// Given a rows x cols screen and a sentence represented by a list of non-empty words, find how many times the given sentence can be fitted on the screen. + +// Note: + // A word cannot be split into two lines. + // The order of words in the sentence must remain unchanged. + // Two consecutive words in a line must be separated by a single space. + // Total words in the sentence won't exceed 100. + // Length of each word is greater than 0 and won't exceed 10. + // 1 ≤ rows, cols ≤ 20,000. + +// Example 1: + +// Input: +// rows = 2, cols = 8, sentence = ["hello", "world"] + +// Output: +// 1 + +// Explanation: +// hello--- +// world--- + +// The character '-' signifies an empty space on the screen. +// Example 2: + +// Input: +// rows = 3, cols = 6, sentence = ["a", "bcd", "e"] + +// Output: +// 2 + +// Explanation: +// a-bcd- +// e-a--- +// bcd-e- + +// The character '-' signifies an empty space on the screen. +// Example 3: + +// Input: +// rows = 4, cols = 5, sentence = ["I", "had", "apple", "pie"] + +// Output: +// 1 + +// Explanation: +// I-had +// apple +// pie-I +// had-- + +// The character '-' signifies an empty space on the screen. + +public class Solution { + + public int wordsTyping(String[] sentence, int rows, int cols) { + + String s = String.join(" ", sentence) + " "; + int start = 0; + int l = s.length(); + + for(int i = 0; i < rows; i++) { + + start += cols; + + if(s.charAt(start % l) == ' ') { + + start++; + + } + + else { + + while(start > 0 && s.charAt((start - 1) % l) != ' ') { + + start--; + + } + + } + + } + + return start / s.length(); + + } + +} \ No newline at end of file diff --git a/leetcode/dynamic-programming/uniqueBinarySearchTrees.java b/leetcode/dynamic-programming/uniqueBinarySearchTrees.java new file mode 100644 index 00000000..ef6909cf --- /dev/null +++ b/leetcode/dynamic-programming/uniqueBinarySearchTrees.java @@ -0,0 +1,34 @@ +// Given n, how many structurally unique BST's (binary search trees) that store values 1...n? + +// For example, +// Given n = 3, there are a total of 5 unique BST's. + +// 1 3 3 2 1 +// \ / / / \ \ +// 3 2 1 1 3 2 +// / / \ \ +// 2 1 2 3 + +public class Solution { + + public int numTrees(int n) { + + int[] dp = new int[n + 1]; + + dp[0] = 1; + dp[1] = 1; + + for(int i = 2; i <= n; i++) { + for(int j = 1; j <= i; j++) { + + dp[i] += dp[i - j] * dp[j - 1]; + + } + + } + + return dp[n]; + + } + +} \ No newline at end of file diff --git a/leetcode/dynamic-programming/wordBreak.java b/leetcode/dynamic-programming/wordBreak.java new file mode 100644 index 00000000..5549eeb0 --- /dev/null +++ b/leetcode/dynamic-programming/wordBreak.java @@ -0,0 +1,34 @@ +// Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine if s can be segmented into a space-separated sequence of one or more dictionary words. You may assume the dictionary does not contain duplicate words. + +// For example, given +// s = "leetcode", +// dict = ["leet", "code"]. + +// Return true because "leetcode" can be segmented as "leet code". + +public class Solution { + + public boolean wordBreak(String s, Set wordDict) { + + boolean[] dp = new boolean[s.length() + 1]; + + dp[0] = true; + + for(int i = 1; i <= s.length(); i++) { + for(int j = 0; j < i; j++) { + + if(dp[j] && wordDict.contains(s.substring(j, i))) { + + dp[i] = true; + break; + + } + + } + + } + + return dp[s.length()]; + + } +} \ No newline at end of file diff --git a/leetcode/linked-list/README.md b/leetcode/linked-list/README.md new file mode 100644 index 00000000..17a3e3d1 --- /dev/null +++ b/leetcode/linked-list/README.md @@ -0,0 +1 @@ +List of interview questions pertaining to Linked Lists diff --git a/leetcode/linked-list/addTwoNumbers.java b/leetcode/linked-list/addTwoNumbers.java new file mode 100644 index 00000000..779e7b52 --- /dev/null +++ b/leetcode/linked-list/addTwoNumbers.java @@ -0,0 +1,62 @@ +// You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list. + +// You may assume the two numbers do not contain any leading zero, except the number 0 itself. + +// Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) +// Output: 7 -> 0 -> 8 + +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode(int x) { val = x; } + * } + */ +public class Solution { + + public ListNode addTwoNumbers(ListNode l1, ListNode l2) { + + ListNode current1 = l1; + ListNode current2 = l2; + + ListNode head = new ListNode(0); + ListNode currentHead = head; + + int sum = 0; + + while(current1 != null || current2 != null) { + + sum /= 10; + + if(current1 != null) { + + sum += current1.val; + current1 = current1.next; + + } + + if(current2 != null) { + + sum += current2.val; + current2 = current2.next; + + } + + currentHead.next = new ListNode(sum % 10); + currentHead = currentHead.next; + + } + + + if(sum / 10 == 1) { + + currentHead.next = new ListNode(1); + + } + + return head.next; + + } + +} \ No newline at end of file diff --git a/leetcode/linked-list/deleteNodeInALinkedList.java b/leetcode/linked-list/deleteNodeInALinkedList.java new file mode 100644 index 00000000..5d3ab5f2 --- /dev/null +++ b/leetcode/linked-list/deleteNodeInALinkedList.java @@ -0,0 +1,22 @@ +// Write a function to delete a node (except the tail) in a singly linked list, given only access to that node. + +// Supposed the linked list is 1 -> 2 -> 3 -> 4 and you are given the third node with value 3, the linked list should become 1 -> 2 -> 4 after calling your function. + +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode(int x) { val = x; } + * } + */ +public class Solution { + + public void deleteNode(ListNode node) { + + node.val = node.next.val; + node.next = node.next.next; + + } + +} \ No newline at end of file diff --git a/leetcode/linked-list/mergeKSortedLists.java b/leetcode/linked-list/mergeKSortedLists.java new file mode 100644 index 00000000..a01aaa32 --- /dev/null +++ b/leetcode/linked-list/mergeKSortedLists.java @@ -0,0 +1,46 @@ +// Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. + +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode(int x) { val = x; } + * } + */ +public class Solution { + + public ListNode mergeKLists(ListNode[] lists) { + + if (lists==null||lists.length==0) return null; + + PriorityQueue queue= new PriorityQueue(lists.length,new Comparator(){ + @Override + public int compare(ListNode o1,ListNode o2){ + if (o1.val stack = new Stack(); + + ListNode fast = head; + ListNode slow = head; + + while(fast != null && fast.next != null) { + + stack.push(slow.val); + fast = fast.next.next; + slow = slow.next; + + } + + if(fast != null) { + + slow = slow.next; + + } + + while(slow != null) { + + if(stack.pop() != slow.val) return false; + slow = slow.next; + + } + + return true; + + } + +} \ No newline at end of file diff --git a/leetcode/linked-list/plusOneLinkedList.java b/leetcode/linked-list/plusOneLinkedList.java new file mode 100644 index 00000000..bd06f11e --- /dev/null +++ b/leetcode/linked-list/plusOneLinkedList.java @@ -0,0 +1,59 @@ +// Given a non-negative integer represented as non-empty a singly linked list of digits, plus one to the integer. + +// You may assume the integer do not contain any leading zero, except the number 0 itself. + +// The digits are stored such that the most significant digit is at the head of the list. + +// Example: +// Input: +// 1->2->3 + +// Output: +// 1->2->4 + +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode(int x) { val = x; } + * } + */ +public class Solution { + + public ListNode plusOne(ListNode head) { + + if(plusOneRecursive(head) == 0) { + + return head; + + } + + else { + + ListNode newHead = new ListNode(1); + + newHead.next = head; + + return newHead; + + } + + } + + private int plusOneRecursive(ListNode head) { + + if(head == null) return 1; + + int carry = plusOneRecursive(head.next); + + if(carry == 0) return 0; + + int value = head.val + 1; + head.val = value % 10; + return value/10; + + + } + +} \ No newline at end of file diff --git a/leetcode/linked-list/reverseLinkedList.java b/leetcode/linked-list/reverseLinkedList.java new file mode 100644 index 00000000..f8fae627 --- /dev/null +++ b/leetcode/linked-list/reverseLinkedList.java @@ -0,0 +1,32 @@ +// Reverse a singly linked list. + +/** + * Definition for singly-linked list. + * public class ListNode { + * int val; + * ListNode next; + * ListNode(int x) { val = x; } + * } + */ +public class Solution { + + public ListNode reverseList(ListNode head) { + + if(head == null) return head; + + ListNode newHead = null; + + while(head != null) { + + ListNode next = head.next; + head.next = newHead; + newHead = head; + head = next; + + } + + return newHead; + + } + +} \ No newline at end of file diff --git a/leetcode/two-pointers/3Sum.java b/leetcode/two-pointers/3Sum.java new file mode 100644 index 00000000..e0e992a5 --- /dev/null +++ b/leetcode/two-pointers/3Sum.java @@ -0,0 +1,73 @@ +// Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero. + +// Note: The solution set must not contain duplicate triplets. + +// For example, given array S = [-1, 0, 1, 2, -1, -4], + +// A solution set is: +// [ +// [-1, 0, 1], +// [-1, -1, 2] +// ] + +public class Solution { + + public List> threeSum(int[] nums) { + + List> result = new ArrayList<>(); + + Arrays.sort(nums); + + for(int i = 0; i < nums.length - 2; i++) { + + if(i > 0 && nums[i] == nums[i - 1]) { + + continue; + + } + + int j = i + 1; + int k = nums.length - 1; + int target = -nums[i]; + + while(j < k) { + + if(nums[j] + nums[k] == target) { + + ArrayList temp = new ArrayList(); + + temp.add(nums[i]); + temp.add(nums[j]); + temp.add(nums[k]); + + result.add(temp); + + j++; + k--; + + while(j < k && nums[j] == nums[j - 1]) j++; + while(j < k && nums[k] == nums[k + 1]) k--; + + } + + else if(nums[j] + nums[k] > target) { + + k--; + + } + + else { + + j++; + + } + + } + + } + + return result; + + } + +} \ No newline at end of file diff --git a/leetcode/two-pointers/3SumSmaller.java b/leetcode/two-pointers/3SumSmaller.java new file mode 100644 index 00000000..9c9a5f2d --- /dev/null +++ b/leetcode/two-pointers/3SumSmaller.java @@ -0,0 +1,62 @@ +// Given an array of n integers nums and a target, find the number of index triplets i, j, k with 0 <= i < j < k < n that satisfy the condition nums[i] + nums[j] + nums[k] < target. + +// For example, given nums = [-2, 0, 1, 3], and target = 2. + +// Return 2. Because there are two triplets which sums are less than 2: + +// [-2, 0, 1] +// [-2, 0, 3] + +// Follow up: + // Could you solve it in O(n2) runtime? + +public class Solution { + + public int threeSumSmaller(int[] nums, int target) { + + //initialize total count to zero + int count = 0; + + //sort the array + Arrays.sort(nums); + + //loop through entire array + for(int i = 0; i < nums.length - 2; i++) { + + //set left to i + 1 + int left = i + 1; + + //set right to end of array + int right = nums.length - 1; + + //while left index < right index + while(left < right) { + + //if the 3 indices add to less than the target increment count + if(nums[i] + nums[left] + nums[right] < target) { + + //increment the count by the distance between left and right because the array is sorted + count += right - left; + + //decrement right pointer + left++; + + } + + //if they sum to a value greater than target... + else { + + //increment left pointer + right--; + + } + + } + + } + + return count; + + } + +} \ No newline at end of file diff --git a/leetcode/two-pointers/mergeSortedArray.java b/leetcode/two-pointers/mergeSortedArray.java new file mode 100644 index 00000000..169f33bc --- /dev/null +++ b/leetcode/two-pointers/mergeSortedArray.java @@ -0,0 +1,28 @@ +// Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. + +// Note: +// You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2. The number of elements initialized in nums1 and nums2 are m and n respectively. + +public class Solution { + + public void merge(int[] A, int m, int[] B, int n) { + + int i = m - 1; + int j = n - 1; + int k = m + n - 1; + + while(i >= 0 && j >= 0) { + + A[k--] = A[i] > B[j] ? A[i--] : B[j--]; + + } + + while(j >= 0) { + + A[k--] = B[j--]; + + } + + } + +} \ No newline at end of file diff --git a/leetcode/two-pointers/minimumSizeSubarraySum.java b/leetcode/two-pointers/minimumSizeSubarraySum.java new file mode 100644 index 00000000..c376ae95 --- /dev/null +++ b/leetcode/two-pointers/minimumSizeSubarraySum.java @@ -0,0 +1,34 @@ +// Given an array of n positive integers and a positive integer s, find the minimal length of a contiguous subarray of which the sum ≥ s. If there isn't one, return 0 instead. + +// For example, given the array [2,3,1,2,4,3] and s = 7, +// the subarray [4,3] has the minimal length under the problem constraint. + +public class Solution { + + public int minSubArrayLen(int s, int[] nums) { + + if(nums == null || nums.length == 0) return 0; + + int i = 0; + int j = 0; + int result = Integer.MAX_VALUE; + int total = 0; + + while(i < nums.length) { + + total += nums[i++]; + + while(total >= s) { + + result = Math.min(result, i - j); + total -= nums[j++]; + + } + + } + + return result == Integer.MAX_VALUE ? 0 : result; + + } + +} \ No newline at end of file diff --git a/leetcode/two-pointers/moveZeros.java b/leetcode/two-pointers/moveZeros.java new file mode 100644 index 00000000..ea9a46b4 --- /dev/null +++ b/leetcode/two-pointers/moveZeros.java @@ -0,0 +1,36 @@ +// Given an array nums, write a function to move all 0's to the end of it while maintaining the relative order of the non-zero elements. + +// For example, given nums = [0, 1, 0, 3, 12], after calling your function, nums should be [1, 3, 12, 0, 0]. + +// Note: + // You must do this in-place without making a copy of the array. + // Minimize the total number of operations. + +public class Solution { + + public void moveZeroes(int[] nums) { + + if(nums == null || nums.length == 0) return; + + int index = 0; + for(int num : nums) { + + if(num != 0) { + + nums[index] = num; + index++; + + } + + } + + while(index < nums.length) { + + nums[index] = 0; + index++; + + } + + } + +} \ No newline at end of file diff --git a/leetcode/two-pointers/removeDuplicatesFromSortedArray.java b/leetcode/two-pointers/removeDuplicatesFromSortedArray.java new file mode 100644 index 00000000..8a304a5c --- /dev/null +++ b/leetcode/two-pointers/removeDuplicatesFromSortedArray.java @@ -0,0 +1,33 @@ +// Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length. + +// Do not allocate extra space for another array, you must do this in place with constant memory. + +// For example, +// Given input array nums = [1,1,2], + +// Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. It doesn't matter what you leave beyond the new length. + +public class Solution { + + public int removeDuplicates(int[] nums) { + + if(nums.length == 0 || nums == null) return 0; + if(nums.length < 2) return nums.length; + + int index = 1; + + for(int i = 1; i < nums.length; i++) { + + if(nums[i] != nums[i - 1]) { + + nums[index++] = nums[i]; + + } + + } + + return index; + + } + +} \ No newline at end of file diff --git a/leetcode/two-pointers/reverseString.java b/leetcode/two-pointers/reverseString.java new file mode 100644 index 00000000..200716bd --- /dev/null +++ b/leetcode/two-pointers/reverseString.java @@ -0,0 +1,26 @@ +// Write a function that takes a string as input and returns the string reversed. + +// Example: +// Given s = "hello", return "olleh". + +public class Solution { + + public String reverseString(String s) { + + if(s == null || s.length() == 1 || s.length() == 0) return s; + + char[] word = s.toCharArray(); + + for(int i = 0, j = s.length() - 1; i < j; i++, j--) { + + char temp = word[i]; + word[i] = word[j]; + word[j] = temp; + + } + + return new String(word); + + } + +} \ No newline at end of file diff --git a/leetcode/two-pointers/sortColors.java b/leetcode/two-pointers/sortColors.java new file mode 100644 index 00000000..2c9bd5fa --- /dev/null +++ b/leetcode/two-pointers/sortColors.java @@ -0,0 +1,42 @@ +// Given an array with n objects colored red, white or blue, sort them so that objects of the same color are adjacent, with the colors in the order red, white and blue. + +// Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively. + +// Note: + // You are not suppose to use the library's sort function for this problem. + +public class Solution { + + public void sortColors(int[] nums) { + + int wall = 0; + + for(int i = 0; i < nums.length; i++) { + + if(nums[i] < 1) { + + int temp = nums[i]; + nums[i] = nums[wall]; + nums[wall] = temp; + wall++; + + } + + } + + for(int i = 0; i < nums.length; i++) { + + if(nums[i] == 1) { + + int temp = nums[i]; + nums[i] = nums[wall]; + nums[wall] = temp; + wall++; + + } + + } + + } + +} \ No newline at end of file From 1e2db0b6944e6a0a852b113d48a41fb41e899cee Mon Sep 17 00:00:00 2001 From: Kevin Naughton Jr Date: Wed, 21 Mar 2018 01:26:46 -0400 Subject: [PATCH 2/2] finish reformatting files --- company/facebook/PowerOfXToTheN.java | 20 +++ company/facebook/SquareRootX.java | 28 +++++ company/google/LoggerRateLimit.java | 60 +++++++++ company/google/PowerOfXToTheN.java | 20 +++ company/google/Utf8Validation.java | 59 +++++++++ company/linkedin/PowerOfXToTheN.java | 20 +++ company/uber/PadlindromePermutation.java | 23 ++++ .../BinaryRepresentation.java | 31 +++++ .../FindMissingInteger.java | 37 ++++++ .../InsertMIntoN.java | 33 +++++ .../SwapBits.java | 8 ++ .../BinaryTreeIsBalanced.java | 26 ++++ .../CreateBinarySearchTree.java | 19 +++ .../CreateLinkedListForEachLevel.java | 29 +++++ .../FindPath.java | 40 ++++++ .../IsSubtree.java | 37 ++++++ .../PrintPaths.java | 53 ++++++++ .../ValidBinarySearchTree.java | 21 ++++ .../AllPermutations.java | 31 +++++ .../AllSubsets.java | 24 ++++ .../EightQueens.java | 48 ++++++++ .../MagicIndex.java | 24 ++++ .../RepresentingNCents.java | 26 ++++ .../StackBoxes.java | 35 ++++++ .../Staircase.java | 22 ++++ .../DeleteDups.java | 18 +++ .../IsRotation.java | 17 +++ .../IsUniqueChars.java | 15 +++ .../NthToLast.java | 27 ++++ .../Permutation.java | 25 ++++ .../ReplaceSpaces.java | 30 +++++ .../Operations.java | 66 ++++++++++ .../WouldIntersect.java | 20 +++ .../BinaryTreeIsBalanced.java | 26 ++++ .../MyQueue.java | 40 ++++++ .../QueueUsingTwoStacks.java | 5 + .../SetOfStacks.java | 44 +++++++ .../SortStack.java | 18 +++ .../StackWithMin.java | 26 ++++ .../ThreeStacks.java | 44 +++++++ .../TowersOfHanoi.java | 59 +++++++++ .../chapter-two-linked-lists/DeleteDups.java | 18 +++ .../chapter-two-linked-lists/DeleteNode.java | 14 +++ .../FindBeginning.java | 36 ++++++ .../IsPalindrome.java | 38 ++++++ .../chapter-two-linked-lists/NthToLast.java | 0 .../chapter-two-linked-lists/Partition.java | 28 +++++ leetcode/binary-search/PowerOfXToTheN.java | 20 +++ leetcode/binary-search/SquareRootX.java | 28 +++++ .../bit-manipulation/NumberOfOneBits.java | 21 ++++ leetcode/bit-manipulation/Utf8Validation.java | 60 +++++++++ ...inarySearchTreeVerticalOrderTraversal.java | 115 ++++++++++++++++++ 52 files changed, 1632 insertions(+) create mode 100644 company/facebook/PowerOfXToTheN.java create mode 100644 company/facebook/SquareRootX.java create mode 100644 company/google/LoggerRateLimit.java create mode 100644 company/google/PowerOfXToTheN.java create mode 100644 company/google/Utf8Validation.java create mode 100644 company/linkedin/PowerOfXToTheN.java create mode 100644 company/uber/PadlindromePermutation.java create mode 100644 cracking-the-coding-interview/chapter-five-bit-manipulation/BinaryRepresentation.java create mode 100644 cracking-the-coding-interview/chapter-five-bit-manipulation/FindMissingInteger.java create mode 100644 cracking-the-coding-interview/chapter-five-bit-manipulation/InsertMIntoN.java create mode 100644 cracking-the-coding-interview/chapter-five-bit-manipulation/SwapBits.java create mode 100644 cracking-the-coding-interview/chapter-four-trees-and-graphs/BinaryTreeIsBalanced.java create mode 100644 cracking-the-coding-interview/chapter-four-trees-and-graphs/CreateBinarySearchTree.java create mode 100644 cracking-the-coding-interview/chapter-four-trees-and-graphs/CreateLinkedListForEachLevel.java create mode 100644 cracking-the-coding-interview/chapter-four-trees-and-graphs/FindPath.java create mode 100644 cracking-the-coding-interview/chapter-four-trees-and-graphs/IsSubtree.java create mode 100644 cracking-the-coding-interview/chapter-four-trees-and-graphs/PrintPaths.java create mode 100644 cracking-the-coding-interview/chapter-four-trees-and-graphs/ValidBinarySearchTree.java create mode 100644 cracking-the-coding-interview/chapter-nine-recursion-and-dynamic-programming/AllPermutations.java create mode 100644 cracking-the-coding-interview/chapter-nine-recursion-and-dynamic-programming/AllSubsets.java create mode 100644 cracking-the-coding-interview/chapter-nine-recursion-and-dynamic-programming/EightQueens.java create mode 100644 cracking-the-coding-interview/chapter-nine-recursion-and-dynamic-programming/MagicIndex.java create mode 100644 cracking-the-coding-interview/chapter-nine-recursion-and-dynamic-programming/RepresentingNCents.java create mode 100644 cracking-the-coding-interview/chapter-nine-recursion-and-dynamic-programming/StackBoxes.java create mode 100644 cracking-the-coding-interview/chapter-nine-recursion-and-dynamic-programming/Staircase.java create mode 100644 cracking-the-coding-interview/chapter-one-arrays-and-strings/DeleteDups.java create mode 100644 cracking-the-coding-interview/chapter-one-arrays-and-strings/IsRotation.java create mode 100644 cracking-the-coding-interview/chapter-one-arrays-and-strings/IsUniqueChars.java create mode 100644 cracking-the-coding-interview/chapter-one-arrays-and-strings/NthToLast.java create mode 100644 cracking-the-coding-interview/chapter-one-arrays-and-strings/Permutation.java create mode 100644 cracking-the-coding-interview/chapter-one-arrays-and-strings/ReplaceSpaces.java create mode 100644 cracking-the-coding-interview/chapter-seven-mathematics-and-probability/Operations.java create mode 100644 cracking-the-coding-interview/chapter-seven-mathematics-and-probability/WouldIntersect.java create mode 100644 cracking-the-coding-interview/chapter-three-stacks-and-queues/BinaryTreeIsBalanced.java create mode 100644 cracking-the-coding-interview/chapter-three-stacks-and-queues/MyQueue.java create mode 100644 cracking-the-coding-interview/chapter-three-stacks-and-queues/QueueUsingTwoStacks.java create mode 100644 cracking-the-coding-interview/chapter-three-stacks-and-queues/SetOfStacks.java create mode 100644 cracking-the-coding-interview/chapter-three-stacks-and-queues/SortStack.java create mode 100644 cracking-the-coding-interview/chapter-three-stacks-and-queues/StackWithMin.java create mode 100644 cracking-the-coding-interview/chapter-three-stacks-and-queues/ThreeStacks.java create mode 100644 cracking-the-coding-interview/chapter-three-stacks-and-queues/TowersOfHanoi.java create mode 100644 cracking-the-coding-interview/chapter-two-linked-lists/DeleteDups.java create mode 100644 cracking-the-coding-interview/chapter-two-linked-lists/DeleteNode.java create mode 100644 cracking-the-coding-interview/chapter-two-linked-lists/FindBeginning.java create mode 100644 cracking-the-coding-interview/chapter-two-linked-lists/IsPalindrome.java create mode 100644 cracking-the-coding-interview/chapter-two-linked-lists/NthToLast.java create mode 100644 cracking-the-coding-interview/chapter-two-linked-lists/Partition.java create mode 100644 leetcode/binary-search/PowerOfXToTheN.java create mode 100644 leetcode/binary-search/SquareRootX.java create mode 100644 leetcode/bit-manipulation/NumberOfOneBits.java create mode 100644 leetcode/bit-manipulation/Utf8Validation.java create mode 100644 leetcode/hashtable/BinarySearchTreeVerticalOrderTraversal.java diff --git a/company/facebook/PowerOfXToTheN.java b/company/facebook/PowerOfXToTheN.java new file mode 100644 index 00000000..26cf76dc --- /dev/null +++ b/company/facebook/PowerOfXToTheN.java @@ -0,0 +1,20 @@ +// Implement pow(x, n). + +public class PowerOfXToTheN { + public double myPow(double x, int n) { + if(n == 0) { + return 1; + } + + if(Double.isInfinite(x)) { + return 0; + } + + if(n < 0) { + n = -n; + x = 1 / x; + } + + return n % 2 == 0 ? myPow(x * x, n / 2) : x * myPow(x * x, n / 2); + } +} diff --git a/company/facebook/SquareRootX.java b/company/facebook/SquareRootX.java new file mode 100644 index 00000000..1243ffc9 --- /dev/null +++ b/company/facebook/SquareRootX.java @@ -0,0 +1,28 @@ +// Implement int sqrt(int x). + +// Compute and return the square root of x. + +public class SquareRootX { + public int mySqrt(int x) { + if(x == 0) { + return 0; + } + + int left = 1; + int right = x; + + while(left <= right) { + int mid = left + (right - left) / 2; + + if(mid == x / mid) { + return mid; + } else if(mid > x / mid) { + right = mid - 1; + } else if(mid < x / mid) { + left = mid + 1; + } + } + + return right; + } +} diff --git a/company/google/LoggerRateLimit.java b/company/google/LoggerRateLimit.java new file mode 100644 index 00000000..01bc2d06 --- /dev/null +++ b/company/google/LoggerRateLimit.java @@ -0,0 +1,60 @@ +// Design a logger system that receive stream of messages along with its timestamps, each message should be printed if and only if it is not printed in the last 10 seconds. + +// Given a message and a timestamp (in seconds granularity), return true if the message should be printed in the given timestamp, otherwise returns false. + +// It is possible that several messages arrive roughly at the same time. + +// Example: + +// Logger logger = new Logger(); + +// // logging string "foo" at timestamp 1 +// logger.shouldPrintMessage(1, "foo"); returns true; + +// // logging string "bar" at timestamp 2 +// logger.shouldPrintMessage(2,"bar"); returns true; + +// // logging string "foo" at timestamp 3 +// logger.shouldPrintMessage(3,"foo"); returns false; + +// // logging string "bar" at timestamp 8 +// logger.shouldPrintMessage(8,"bar"); returns false; + +// // logging string "foo" at timestamp 10 +// logger.shouldPrintMessage(10,"foo"); returns false; + +// // logging string "foo" at timestamp 11 +// logger.shouldPrintMessage(11,"foo"); returns true; + +public class LoggerRateLimit { + HashMap messages; + + /** Initialize your data structure here. */ + public Logger() { + this.messages = new HashMap(); + } + + /** Returns true if the message should be printed in the given timestamp, otherwise returns false. + If this method returns false, the message will not be printed. + The timestamp is in seconds granularity. */ + public boolean shouldPrintMessage(int timestamp, String message) { + if(messages.containsKey(message)) { + if(timestamp - messages.get(message) >= 10) { + messages.put(message, timestamp); + + return true; + } else { + return false; + } + } else { + messages.put(message, timestamp); + return true; + } + } +} + +/** + * Your Logger object will be instantiated and called as such: + * Logger obj = new Logger(); + * boolean param_1 = obj.shouldPrintMessage(timestamp,message); + */ diff --git a/company/google/PowerOfXToTheN.java b/company/google/PowerOfXToTheN.java new file mode 100644 index 00000000..26cf76dc --- /dev/null +++ b/company/google/PowerOfXToTheN.java @@ -0,0 +1,20 @@ +// Implement pow(x, n). + +public class PowerOfXToTheN { + public double myPow(double x, int n) { + if(n == 0) { + return 1; + } + + if(Double.isInfinite(x)) { + return 0; + } + + if(n < 0) { + n = -n; + x = 1 / x; + } + + return n % 2 == 0 ? myPow(x * x, n / 2) : x * myPow(x * x, n / 2); + } +} diff --git a/company/google/Utf8Validation.java b/company/google/Utf8Validation.java new file mode 100644 index 00000000..36137f7b --- /dev/null +++ b/company/google/Utf8Validation.java @@ -0,0 +1,59 @@ +// A character in UTF8 can be from 1 to 4 bytes long, subjected to the following rules: + +// For 1-byte character, the first bit is a 0, followed by its unicode code. +// For n-bytes character, the first n-bits are all one's, the n+1 bit is 0, followed by n-1 bytes with most significant 2 bits being 10. +// This is how the UTF-8 encoding would work: + +// Char. number range | UTF-8 octet sequence +// (hexadecimal) | (binary) +// --------------------+--------------------------------------------- +// 0000 0000-0000 007F | 0xxxxxxx +// 0000 0080-0000 07FF | 110xxxxx 10xxxxxx +// 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx +// 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx +// Given an array of integers representing the data, return whether it is a valid utf-8 encoding. + +// Note: +// The input is an array of integers. Only the least significant 8 bits of each integer is used to store the data. This means each integer represents only 1 byte of data. + +// Example 1: + +// data = [197, 130, 1], which represents the octet sequence: 11000101 10000010 00000001. + +// Return true. +// It is a valid utf-8 encoding for a 2-bytes character followed by a 1-byte character. +// Example 2: + +// data = [235, 140, 4], which represented the octet sequence: 11101011 10001100 00000100. + +// Return false. +// The first 3 bits are all one's and the 4th bit is 0 means it is a 3-bytes character. +// The next byte is a continuation byte which starts with 10 and that's correct. +// But the second continuation byte does not start with 10, so it is invalid. + +public class Utf8Validation { + public boolean validUtf8(int[] data) { + int count = 0; + for(int i : data) { + if(count == 0) { + if((i >> 5) == 0b110) { + count = 1; + } else if((i >> 4) == 0b1110) { + count = 2; + } else if((i >> 3) == 0b11110) { + count = 3; + } else if((i >> 7) == 0b1) { + return false; + } + } else { + if((i >> 6) != 0b10) { + return false; + } + + count--; + } + } + + return count == 0; + } +} diff --git a/company/linkedin/PowerOfXToTheN.java b/company/linkedin/PowerOfXToTheN.java new file mode 100644 index 00000000..26cf76dc --- /dev/null +++ b/company/linkedin/PowerOfXToTheN.java @@ -0,0 +1,20 @@ +// Implement pow(x, n). + +public class PowerOfXToTheN { + public double myPow(double x, int n) { + if(n == 0) { + return 1; + } + + if(Double.isInfinite(x)) { + return 0; + } + + if(n < 0) { + n = -n; + x = 1 / x; + } + + return n % 2 == 0 ? myPow(x * x, n / 2) : x * myPow(x * x, n / 2); + } +} diff --git a/company/uber/PadlindromePermutation.java b/company/uber/PadlindromePermutation.java new file mode 100644 index 00000000..7b9125da --- /dev/null +++ b/company/uber/PadlindromePermutation.java @@ -0,0 +1,23 @@ +public class PalindromePermutation { + public boolean canPermutePalindrome(String s) { + char[] characters = new char[256]; + + for(int i = 0; i < s.length(); i++) { + characters[s.charAt(i)]++; + } + + int oddCount = 0; + + for(int i = 0; i < characters.length; i++) { + if(!(characters[i] % 2 == 0)) { + oddCount++; + + if(oddCount > 1) { + return false; + } + } + } + + return true; + } +} diff --git a/cracking-the-coding-interview/chapter-five-bit-manipulation/BinaryRepresentation.java b/cracking-the-coding-interview/chapter-five-bit-manipulation/BinaryRepresentation.java new file mode 100644 index 00000000..773a1e03 --- /dev/null +++ b/cracking-the-coding-interview/chapter-five-bit-manipulation/BinaryRepresentation.java @@ -0,0 +1,31 @@ +/* given a real number between 0 and 1 (e.g., 0.72) that is passed in as a double, print + * the binary representation. If the number cannot be represented accurately in binary + * with at most 32 characters, print "ERROR" */ + +public class BinaryRepresentation { + public static String printBinary(double num) { + if(num >= 1 || num <= 0) { + return "ERROR"; + } + + StrinBuilder binary = new StringBuilder(); + binary.append("."); + while(num > 0) { + /* setting a limit on length: 32 characters */ + if(binary.length() >= 32) { + return "ERROR"; + } + + double r = num * 2; + if(r >= 1) { + binary.append(1); + num = r - 1; + } + else { + binary.append(0); + num = r; + } + } + return binary.toString(); + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-five-bit-manipulation/FindMissingInteger.java b/cracking-the-coding-interview/chapter-five-bit-manipulation/FindMissingInteger.java new file mode 100644 index 00000000..0dde8fec --- /dev/null +++ b/cracking-the-coding-interview/chapter-five-bit-manipulation/FindMissingInteger.java @@ -0,0 +1,37 @@ +/* An array A contains all the integers from 0 through n, except for one number which is + * missing. In this problem, we cannot access an entire integer in A with a single operation. + * The elements of A are represented in binary, and the only operation we can use to acces them + * is "fetch the jth bit of A[i]," which takes constant time. Write code to find the missing + * integer. Can you do it in O(n) time? */ + +public class FindMissingInteger { + public int findMissing(ArrayList array) { + /* start from the least significant bit, and work our way up */ + return findMissing(array, 0); + } + + public int findMissing(ArrayList input, int column) { + if(column >= BigInteger.INTEGER_SIZE) { //we're done! + return 0; + } + ArrayList oneBits = new ArrayList(input.size() / 2); + ArrayList zeroBits = new ArrayList(input.size() / 2); + + for(BigInteger t : input) { + if(t.fetch(column) == 0) { + zeroBits.add(t); + } + else { + oneBits.add(t); + } + } + if(zeroBits.size() <= oneBits.size()) { + int v = findMissing(zeroBits, column + 1); + return (v << 1) | 0; + } + else { + int v = findMissing(oneBits, column + 1); + return (v << 1) | 1; + } + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-five-bit-manipulation/InsertMIntoN.java b/cracking-the-coding-interview/chapter-five-bit-manipulation/InsertMIntoN.java new file mode 100644 index 00000000..9700739c --- /dev/null +++ b/cracking-the-coding-interview/chapter-five-bit-manipulation/InsertMIntoN.java @@ -0,0 +1,33 @@ +/* you are given two 32-bit numbers, N and M, are two bit positions, i and j. Write + * a method to insert M into N such that M starts at bit j and ends at bit i. You can + * assume that the bits j through i have enough space to fit all of M. That is, if M = 10011, + * you can assume that there are at least 5 bits between j and i. You would not, for example, + * have j = 3 and i = 2, because M could not fully bit between bit 3 and bit 2. + EXAMPLE: + Input: N = 10000000000, m = 10011, i = 2, j = 6 + Output: N = 10001001100 */ + + public class InsertMIntoN { + int updateBits(int n, int m, int i, int j) { + /* create a mask to clear bits i through j in n + * EXAMPLE: i = 2, j = 4. Result should be 11100011. + * For simplicity, we'll just use 8 bits for the example. + */ + int allones = ~0; //wil equal sequence of all 1s + + //1s before position j, then 0s. Left = 11100000 + int left = allOnes << (j + 1); + + //1s after position i. Right = 00000011 + int right = ((1 << i) - 1); + + //all 1s, except for 0s between i and j. Mask = 11100011 + int mask = left | right; + + /* clear bits j through i then put m in there */ + int n_cleared = n & mask; //clear bits j through i + int m_shifted = m << i; //move m into correct position + + return n_cleared | m_shifted; //OR them, and we're done! + } + } \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-five-bit-manipulation/SwapBits.java b/cracking-the-coding-interview/chapter-five-bit-manipulation/SwapBits.java new file mode 100644 index 00000000..6458e864 --- /dev/null +++ b/cracking-the-coding-interview/chapter-five-bit-manipulation/SwapBits.java @@ -0,0 +1,8 @@ +/* write a program to swap odd and even bits in an integer with as few instructions as + * possible (e.g., bit 0 and bit 1 are swapped, bit 2 and bit 3 are swapped, and so on) */ + +public class SwapBits { + public int swapOddEvenBits(int x) { + return ( ((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1) ); + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-four-trees-and-graphs/BinaryTreeIsBalanced.java b/cracking-the-coding-interview/chapter-four-trees-and-graphs/BinaryTreeIsBalanced.java new file mode 100644 index 00000000..44ced48e --- /dev/null +++ b/cracking-the-coding-interview/chapter-four-trees-and-graphs/BinaryTreeIsBalanced.java @@ -0,0 +1,26 @@ +/* implement a function to check if a binary tree is balanced. For the purpose of this + * question, a balanced tree is defined to be a tree such that the heights of the two + * subtrees of any node never differ by more than one */ + +public class BinaryTreeIsBalanaced { + public static int getHeight(TreeNode root) { + if(root == null) { + return 0; //base case + } + return Math.max(getHeight(root.left), getHeight(root.right)) + 1; + } + + public static boolean isBalanced(TreeNode root) { + if(root == null) { //base case + return true; + } + + int heightDiff = getHeight(root.left) - getHeight(root.right); + if(Math.abs(heightDiff) > 1) { + return false; + } + else { //recurse + return isBalanced(root.left) && isBalanced(root.right); + } + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-four-trees-and-graphs/CreateBinarySearchTree.java b/cracking-the-coding-interview/chapter-four-trees-and-graphs/CreateBinarySearchTree.java new file mode 100644 index 00000000..80323199 --- /dev/null +++ b/cracking-the-coding-interview/chapter-four-trees-and-graphs/CreateBinarySearchTree.java @@ -0,0 +1,19 @@ +/* given a sorted (increasing order) array with unique integer elements, write an algorithm + * to create a binary search tree with minimal height */ + +public class CreateBinarySearchTree { + TreeNode createMinimalBST(int arr[], int start, int end) { + if(end < start) { + return null; + } + int mid = (start + end) / 2; + TreeNode n = new TreeNode(arr[mid]); + n.left = createMinimalBST(arr, start, mid - 1); + n.right = createMinimalBST(arr, mid + 1, end); + return n; + } + + TreeNode createMinimalBST(int array[]) { + return createMinimalBST(array, 0, array.length - 1); + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-four-trees-and-graphs/CreateLinkedListForEachLevel.java b/cracking-the-coding-interview/chapter-four-trees-and-graphs/CreateLinkedListForEachLevel.java new file mode 100644 index 00000000..fdf77e81 --- /dev/null +++ b/cracking-the-coding-interview/chapter-four-trees-and-graphs/CreateLinkedListForEachLevel.java @@ -0,0 +1,29 @@ +/* given a binary tree, design an algorithm which creates a linked list of all the nodes + * at each depth (e.g., if you have a tree with depth D, you'll have D linked lists) */ + +public class CreateLinkedListForEachLevel { + ArrayList> createLinkedList(TreeNode root) { + ArrayList> result = new ArrayList>(); + /* "visit" the root */ + LinkedList current = new LinkedList(); + if(root != null) { + current.add(root); + } + + while(current.size() > 0) { + result.add(current); //add previous level + LinkedList parents = current; //go to next level + current = new LinkedList(); + for(TreeNode parent : parents) { + /* visit the children */ + if(parent.left != null) { + current.add(parrent.left); + } + if(parent.right != null) { + current.add(parent.right); + } + } + } + return result; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-four-trees-and-graphs/FindPath.java b/cracking-the-coding-interview/chapter-four-trees-and-graphs/FindPath.java new file mode 100644 index 00000000..0b6b420e --- /dev/null +++ b/cracking-the-coding-interview/chapter-four-trees-and-graphs/FindPath.java @@ -0,0 +1,40 @@ +/* give a directed graph, design an algorithm to find out whether there is a route between two nodes */ + +public class FindPath { + public enum State { + Unvisited, Visited, Visiting; + } + + public static boolean search(Graph g, Node start, Node end) { + if(start == end) return true; + + //operates as Queue + LinkedList q = new LinkedList(); + + for(Node u : g.getNodes()) { + u.state = State.Unvisited; + } + + start.state = State.Visiting; + q.add(start); + Node u; + while(!q.isEmpty()) { + u = q.removeFirst(); //i.e., dequeue() + if(u != null) { + for(Node v : u.getAdjacent()) { + if(v.state == State.Unvisited) { + if(v == end) { + return true; + } + else { + v.state = State.Visiting; + q.add(v); + } + } + } + } + u.state = State.Visited; + } + return false; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-four-trees-and-graphs/IsSubtree.java b/cracking-the-coding-interview/chapter-four-trees-and-graphs/IsSubtree.java new file mode 100644 index 00000000..2ddacd50 --- /dev/null +++ b/cracking-the-coding-interview/chapter-four-trees-and-graphs/IsSubtree.java @@ -0,0 +1,37 @@ +/* you have two very large binary trees: T1, with millions of nodes, and T2, with hundreds + * of nodes. Create an algorithm to decide if T2 is a subtree of T1. + * A tree T2 is a subtree of T1 if there exists a node n in T1 such that the subtree of n + * is identical to T2. That is, if you cut off the tree at node n, the two trees would be identical */ + +public class IsSubtree { + boolean containsTree(TreeNode t1, TreeNode t2) { + if(t2 == null) { //the empty tree is always a subtree + return true; + } + return subTree(t1, t2); + } + + boolean subTree(TreeNode r1, TreeNode r2) { + if(r1 == null) { + return false; //big tree empty & subtree still not found + } + if(r1.data == r2.data) { + if(matchTree(r1, r2)) return true; + } + return (subTree(r1.left, r2) || subTree(r1.right, r2)); + } + + boolean matchTree(TreeNode r1, TreeNode r2) { + if(r2 == null && r1 == null) //if both are empty + return true; //nothing left in the subtree + + //if one, but not both, are empty + if(r1 == null || r2 == null) { + return false; + } + + if(r1.data != r2.data) + return false; //data doesn't match + return (matchTree(r1.left, r2.left) && matchTree(r1.right, r2.right)); + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-four-trees-and-graphs/PrintPaths.java b/cracking-the-coding-interview/chapter-four-trees-and-graphs/PrintPaths.java new file mode 100644 index 00000000..588e368f --- /dev/null +++ b/cracking-the-coding-interview/chapter-four-trees-and-graphs/PrintPaths.java @@ -0,0 +1,53 @@ +/* you are given a binary tree in which each ndoe contains an integer value (which might be positive + * or negative). Design an algorithm to print all paths which sum to a given value. The path does not need + * to start or end at the root or a leaf, but it must go in a straight line */ + +public class PrintPaths { + void findSum(TreeNode node, int sum, int[] path, int level) { + if(node == null) { + return; + } + + /* insert current node into path */ + path[level] = node.data; + + /* look for paths with a sum that ends at this node */ + int t = 0; + for(int i = level; i >= 0; i--) { + t += path[i]; + if(t == sum) { + print(path, i, level); + } + } + + /* search nodes beneath this one */ + findSum(node.left, sum, path, level + 1); + findSum(node.right, sum, path, level + 1); + + /* remove current node from path. Not strictly necessary, since + * we would ignore this value, but it's good practice */ + path[level] = Integer.MIN_VALUE; + } + + void findSum(TreeNode node, int sum) { + int depth = depth(node); + int[] path = new int[depth]; + findSum(node, sum, path, 0); + } + + void print(int[] path, int start, int end) { + for(int i = start; i <= end; i++) { + System.out.print(path[i] + " "); + } + System.out.println(); + } + + int depth(TreeNode node) { + if(node == null) { + return 0; + } + else { + return 1 + Math.max(depth(node.left), depth(node.right)); + } + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-four-trees-and-graphs/ValidBinarySearchTree.java b/cracking-the-coding-interview/chapter-four-trees-and-graphs/ValidBinarySearchTree.java new file mode 100644 index 00000000..ea22e050 --- /dev/null +++ b/cracking-the-coding-interview/chapter-four-trees-and-graphs/ValidBinarySearchTree.java @@ -0,0 +1,21 @@ +/* implement a function to check if a binary tree is a binary search tree */ + +public class ValidBinarySearchTree { + boolean checkBST(TreeNode n) { + return checkBST(n, null, null); + } + + boolean checkBST(TreeNode n, Integer min, Integer max) { + if(n == null) { + return true; + } + if((min != null && n.data <= min) || (max != null && n.data > max)) { + return false; + } + + if(!checkBST(n.left, min, n.data) || !checkBST(n.right, n.data, max)) { + return false; + } + return true; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-nine-recursion-and-dynamic-programming/AllPermutations.java b/cracking-the-coding-interview/chapter-nine-recursion-and-dynamic-programming/AllPermutations.java new file mode 100644 index 00000000..ddd18d66 --- /dev/null +++ b/cracking-the-coding-interview/chapter-nine-recursion-and-dynamic-programming/AllPermutations.java @@ -0,0 +1,31 @@ +/* write a method to compute all permutations of a string of unique characters */ + +public class AllPermutations { + public static ArrayList getPerms(String str) { + if(str == null) { + return null; + } + ArrayList permutations = new ArrayList(); + if(str.length() == 0) { //base case + permutations.add(""); + return permutations; + } + + char first = str.charAt(0); //get the first character + String remainder = str.substring(1); //remove the 1st character + ArrayList words = getPerms(remainder); + for(String word : words) { + for(int j = 0; j <= word.length(); j++) { + String s = insertCharAt(word, first, j); + permutations.add(s); + } + } + return permutations; + } + + public static String insertCharAt(String word, char c, int i) { + String start = word.substring(0, i); + String end = word.substring(i); + return start + c + end; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-nine-recursion-and-dynamic-programming/AllSubsets.java b/cracking-the-coding-interview/chapter-nine-recursion-and-dynamic-programming/AllSubsets.java new file mode 100644 index 00000000..ce10e221 --- /dev/null +++ b/cracking-the-coding-interview/chapter-nine-recursion-and-dynamic-programming/AllSubsets.java @@ -0,0 +1,24 @@ +/* write a method to return all subsets of a set */ + +public class AllSubsets { + ArrayList> getSubsets(ArrayList set, int index) { + ArrayList> allsubsets; + if(set.size() == index) { //base case - add empty set + allsubsets = new ArrayList>(); + allsubsets.add(new ArrayList()); //empty set + } + else { + allsubsets = getSubsets(set, index + 1); + int item = set.get(index); + ArrayList> moresubsets = new ArrayList>(); + for(ArrayList subset : allsubsets) { + ArrayList newsubset = new ArrayList(); + newsubset.addAll(subset); + newsubset.add(item); + moresubsets.add(newsubset); + } + allsubsets.addAll(moresubsets); + } + return allsubsets; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-nine-recursion-and-dynamic-programming/EightQueens.java b/cracking-the-coding-interview/chapter-nine-recursion-and-dynamic-programming/EightQueens.java new file mode 100644 index 00000000..90ea7fe1 --- /dev/null +++ b/cracking-the-coding-interview/chapter-nine-recursion-and-dynamic-programming/EightQueens.java @@ -0,0 +1,48 @@ +/* write an algorithm to print all ways of arranging eight queens on an 8x8 chess board so that none of them + * share the same row, column or diagonal. In this case, "diagonal" means all diagonals, not just the two + * that bisect the board */ + +public class EightQueens { + public static final int GRID_SIZE = 8; + + void placeQueens(int row, Integer[] columns, ArrayList results) { + if(row == GRID_SIZE) { //found valid placement + results.add(columns.clone()); + } + else { + for(int col = 0; col < GRID_SIZE; col++) { + if(checkValid(columns, row, col)) { + columns[row] = col; //place queen + placeQueens(row + 1, columns, results); + } + } + } + } + + /* check if (row1, column1) is a valid spot for a queen by checking if there + * is a queen in the same column or diagonal. We don't need to check it for + * queens in the same row because the calling placeQueen only attempts to + * place one queen at a time. We know thi srow is empty */ + boolean checkValid(Integer[] columns, int row1, int column1) { + for(int row2 = 0; row2 < row1; row2++) { + int column2 = columns[row2]; + /* check if (row2, column2) invalides (row1, column1) as a queen spot */ + + /* check if rows have a queen in the same column */ + if(column1 == column2) { + return false; + } + + /* check diagonals: if the distance between the columns equals the distance + * between the rows, then they're in the same diagonal */ + int columnDistance = Math.abs(column2 - column1); + + /* row1 > row2, so no need for abs */ + int rowDistance = row1 - row2; + if(columnDistance == rowDistance) { + return false; + } + } + return true; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-nine-recursion-and-dynamic-programming/MagicIndex.java b/cracking-the-coding-interview/chapter-nine-recursion-and-dynamic-programming/MagicIndex.java new file mode 100644 index 00000000..c2d74c13 --- /dev/null +++ b/cracking-the-coding-interview/chapter-nine-recursion-and-dynamic-programming/MagicIndex.java @@ -0,0 +1,24 @@ +/* a magic index is an array A[1...n - 1] is defined to be an index such that A[i] = i. Given a sorted + * array of distinct integers, write a method to find a magic index, if one exists, in array A */ + + public class MagicIndex { + public static int magicFast(int[] array, int start, int end) { + if(end < start || start < 0 || end >= array.length) { + return -1; + } + int mid = (start + end) / 2; + if(array[mid] == mid) { + return mid; + } + else if(array[mid] > mid) { + return magicFast(array, start, mid - 1); + } + else { + return magicFast(array, mid + 1, end); + } + } + + public static int magicFast(int[] array) { + return magicFast(array, 0, array.length - 1); + } + } \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-nine-recursion-and-dynamic-programming/RepresentingNCents.java b/cracking-the-coding-interview/chapter-nine-recursion-and-dynamic-programming/RepresentingNCents.java new file mode 100644 index 00000000..7ccb7439 --- /dev/null +++ b/cracking-the-coding-interview/chapter-nine-recursion-and-dynamic-programming/RepresentingNCents.java @@ -0,0 +1,26 @@ +/* given an infinite number of quars (25 cents), dimes (10 cents), nickels (5 cents), and pennies (1 cent), + * write code to calculate the number of ways of representing n cents */ + + public class RepresentingNCents { + int makeChange(int n) { + int[] denoms = {25, 10, 5, 1}; + int[][] map = new int[n + 1][denoms.length]; //precomputed vals + return makeChange(n, denoms, 0, map); + } + + int makeChange(int amount, int[] denoms, int index, int[][] map) { + if(map[amount][index] > 0) { //retrieve value + return map[amount][index]; + } + if(index >= denoms.length - 1) return 1; //one denom remaining + int denomAmount = denoms[index]; + int ways = 0; + for(int i = 0; i * denomAmount <= amount; i++) { + //go to next denom, assuming i coints of denomAmount + int amountRemaining = amount - i * denomAmount; + ways += makeChange(amountRemaining, denoms, index + 1, map); + } + map[amount][index] = ways; + return ways; + } + } \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-nine-recursion-and-dynamic-programming/StackBoxes.java b/cracking-the-coding-interview/chapter-nine-recursion-and-dynamic-programming/StackBoxes.java new file mode 100644 index 00000000..d595cde5 --- /dev/null +++ b/cracking-the-coding-interview/chapter-nine-recursion-and-dynamic-programming/StackBoxes.java @@ -0,0 +1,35 @@ +/* you have a stack of n boxes, with widths wi, heights hi, and depths di. The boxes cannot be rotated + * and can only be stacked on top of one another if each box in the stack is strictly larger than the + * the box above it in width, height, and depth. Implement a method to build the tallest stack possible, + * where the height of a stack is the sum of the heights of each box */ + +public class StackBoxes { + public ArrayList createStackDP(Box[] boxes, Box bottom, HashMap> stack_map) { + if(bottom != null && stack_map.containsKey(bottom)) { + return (ArrayList) stack_map.get(bottom).clone(); + } + + int max_height = 0; + ArrayList max_stack = null; + for(int i = 0; i < boxes.length; i++) { + if(boxes[i].canBeAbove(bottom)) { + ArrayList new_stack = createStackDP(boxes, boxes[i], stack_map); + int new_height = stackHeight(new_stack); + if(new_height > max_height) { + max_stack = new_stack; + max_height = new_height; + } + } + } + + if(max_stack == null) { + max_stack = new ArrayList(); + } + if(bottom != null) { + max_stack.add(0, bottom); + } + stack_map.put(bottom, max_stack); + + return max_stack; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-nine-recursion-and-dynamic-programming/Staircase.java b/cracking-the-coding-interview/chapter-nine-recursion-and-dynamic-programming/Staircase.java new file mode 100644 index 00000000..31d8cf5e --- /dev/null +++ b/cracking-the-coding-interview/chapter-nine-recursion-and-dynamic-programming/Staircase.java @@ -0,0 +1,22 @@ +/* a child is running up a staircase with n steps, and can hop either 1 step, 2 steps, or 3 steps + * at a time. Implement a method to count how many possible ways the child can run up the stairs */ + + public class Staircase { + public static int countWaysDP(int n, int[] map) { + if(n < 0) { + return 0; + } + else if(n == 0) { + return 1; + } + else if(map[n] > -1) { + return map[n]; + } + else { + map[n] = countWaysDP(n - 1, map) + + countWaysDP(n - 2, map) + + countWaysDP(n - 3, map); + return map[n]; + } + } + } \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-one-arrays-and-strings/DeleteDups.java b/cracking-the-coding-interview/chapter-one-arrays-and-strings/DeleteDups.java new file mode 100644 index 00000000..46e04a43 --- /dev/null +++ b/cracking-the-coding-interview/chapter-one-arrays-and-strings/DeleteDups.java @@ -0,0 +1,18 @@ +//Write code to remove duplicates from an unsorted linked list + +public class RemoveDups { + void deleteDups(LinkedListNode n) { + HashSet set = new HashSet(); + LinkedListNode previous = null; + while(n != null) { + if(set.contains(n.data)) { + previous.next = n.next; + } + else { + set.add(n.data); + previous = n; + } + n = n.next; + } + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-one-arrays-and-strings/IsRotation.java b/cracking-the-coding-interview/chapter-one-arrays-and-strings/IsRotation.java new file mode 100644 index 00000000..9e84ab6a --- /dev/null +++ b/cracking-the-coding-interview/chapter-one-arrays-and-strings/IsRotation.java @@ -0,0 +1,17 @@ +// Assume you have a method isSubstring which checks if one word is a isSubstring of another. +// Given two strings, s1 and s2, write code to check if s2 is a rotation of s1 using only +// one call to isSubstring(e.g., "waterbottle" is a rotation of "erbottlewat"). + +public class IsRotation { + public boolean isRotation(String s1, String s2) { + int len = s1.length(); + /*check that s1 and s2 are equal length and not empty */ + if(len == s2.length() && len > 0) { + /* concatenate s1 and s1 within new buffer */ + String s1s1 = s1 + s1; + return isSubstring(s1s1, s2); + } + + return false; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-one-arrays-and-strings/IsUniqueChars.java b/cracking-the-coding-interview/chapter-one-arrays-and-strings/IsUniqueChars.java new file mode 100644 index 00000000..bd1e043a --- /dev/null +++ b/cracking-the-coding-interview/chapter-one-arrays-and-strings/IsUniqueChars.java @@ -0,0 +1,15 @@ +//Implement an algorithm to determine if a string has all unique characters. What if you cannot use additional data structures? + +public class isUniqueChars { + public boolean isUniqueChars(String str) { + int checker = 0; + for(int i = 0; i < str.length(); i++) { + int val = str.charAt(i) - 'a'; + if((checker & (1 << val)) > 0) { + return false; + } + checker |= (1 << val)); + } + return true; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-one-arrays-and-strings/NthToLast.java b/cracking-the-coding-interview/chapter-one-arrays-and-strings/NthToLast.java new file mode 100644 index 00000000..b5ed5bac --- /dev/null +++ b/cracking-the-coding-interview/chapter-one-arrays-and-strings/NthToLast.java @@ -0,0 +1,27 @@ +//Implement an algorithm to find the kth to last element of a single linked list + +public class NthToLast { + LinkedListNode nthToLast(LinkedListNode head, int k) { + if(k <= 0) return null; + + LinkedListNode p1 = head; + LinkedListNode p2 = head; + + //move p2 forward k nodes into the list + for(int i = 0; i < k - 1; i++) { + if(p2 == null) return null; //error check + p2 = p2.next; + } + + if(p2 == null) return null; + + /* now, move p1 and p2 at the same speed. When p2 hits the end, + * p1 will be at the right element */ + while(p2.next != null) { + p1 = p1.next; + p2 = p2.next; + } + + return p1; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-one-arrays-and-strings/Permutation.java b/cracking-the-coding-interview/chapter-one-arrays-and-strings/Permutation.java new file mode 100644 index 00000000..babdd096 --- /dev/null +++ b/cracking-the-coding-interview/chapter-one-arrays-and-strings/Permutation.java @@ -0,0 +1,25 @@ +// Given two strings, write a method to decide if one is a permutation of the other + +public class Permutation { + public boolean permutation(String s, String t) { + if(s.length() != t.length()) { + return false; + } + + int[] letters = new int[256]; + + char[] s_array = s.toCharArray(); + for(char c : s_array) { + letters[c]++; + } + + for(int i = 0; i < t.length(); i++) { + int c = (int)t.charAt(i); + if(--letters[c] < 0) { + return false; + } + } + + return true; + } +} diff --git a/cracking-the-coding-interview/chapter-one-arrays-and-strings/ReplaceSpaces.java b/cracking-the-coding-interview/chapter-one-arrays-and-strings/ReplaceSpaces.java new file mode 100644 index 00000000..4dddcab7 --- /dev/null +++ b/cracking-the-coding-interview/chapter-one-arrays-and-strings/ReplaceSpaces.java @@ -0,0 +1,30 @@ +// Write a method to replace all spaces in a string with '%20.' You may assum ethat the string +// has sufficient space at th eend of the string to hold the additional characters, and that you +// are given the "true" length of the string. (Note: if implementing in Java, please use a characters +// array so that you can perform this operation in place) + +public class ReplaceSpaces { + public void replaceSpaces(char[] str, int length) { + int spaceCount = 0, newLength; i; + for(int i = 0; i < length; i++) { + if(str[i] == ' ') { + spaceCount++; + } + } + + newLength = length + spaceCount * 2; + str[newLength] = '\0'; + for(int i = length - 1; i >= 0; i--) { + if(str[i] == ' ') { + str[newLength - 1] = '0'; + str[newLength - 2] = '2'; + str[newLength - 3] = '%'; + newLength = newLength - 3; + } + else { + str[newLength - 1] = str[i]; + newLength = newLength - 1; + } + } + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-seven-mathematics-and-probability/Operations.java b/cracking-the-coding-interview/chapter-seven-mathematics-and-probability/Operations.java new file mode 100644 index 00000000..b4e0c9c4 --- /dev/null +++ b/cracking-the-coding-interview/chapter-seven-mathematics-and-probability/Operations.java @@ -0,0 +1,66 @@ +/* write methods to implement the multiply, subtract, and divide operations for integers. Use only the add operator */ + +public class Operations { + /* flip a positive sign to negative or negative sign to positive */ + public static int negate(int a) { + int neg = 0; + int d = a < 0 ? 1 : -1; + while(a != 0) { + neg += d; + a += d; + } + return neg; + } + + /* subtract two numbers by negating b and adding them */ + public static int minus(int a, int b) { + return a + negate(b); + } + + /* multiply a by b by adding a to itself b times */ + public static int multiply(int a, int b) { + if(a < b) { + return multiply(b, a); //algorithm is faster is b < a + } + int sum = 0; + for(int i = abs(b); i > 0; i--) { + sum += a; + } + if(b < 0) { + sum = negate(sum); + } + return sum; + } + + /* return absolute value */ + public static int abs(int a) { + if(a < 0) { + return negate(a); + } + else { + return a; + } + } + + public int divide(int a, int b) throws ArithmeticException { + if(b == 0) { + throw new java.lang.ArithmeticException("ERROR"); + } + int absa = abs(a); + int absb = abs(b); + + int product = 0; + int x = 0; + while(product + absb <= absa) { //don't go past a + product += absb; + x++; + } + + if((a < 0 && b < 0) || (a > 0 && b > 0)) { + return x; + } + else { + return negate(x); + } + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-seven-mathematics-and-probability/WouldIntersect.java b/cracking-the-coding-interview/chapter-seven-mathematics-and-probability/WouldIntersect.java new file mode 100644 index 00000000..cfd67026 --- /dev/null +++ b/cracking-the-coding-interview/chapter-seven-mathematics-and-probability/WouldIntersect.java @@ -0,0 +1,20 @@ +/* give two lines on a Cartesian plane, determine whether the two lines would intersect */ + +public class WouldIntersect { + //placeholder for class name +} + +class Line { + static double epsilon = 0.000001; + public double slope; + public double yintercept; + + public Line(double s, double y) { + this.slope = s; + this.yintercept = y; + } + + public boolean Intersect(Line line2) { + return Math.abs(this.slope - line2.slope) > epsilon || Math.abs(this.yintercept - line2.yintercept) < epsilon; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-three-stacks-and-queues/BinaryTreeIsBalanced.java b/cracking-the-coding-interview/chapter-three-stacks-and-queues/BinaryTreeIsBalanced.java new file mode 100644 index 00000000..44ced48e --- /dev/null +++ b/cracking-the-coding-interview/chapter-three-stacks-and-queues/BinaryTreeIsBalanced.java @@ -0,0 +1,26 @@ +/* implement a function to check if a binary tree is balanced. For the purpose of this + * question, a balanced tree is defined to be a tree such that the heights of the two + * subtrees of any node never differ by more than one */ + +public class BinaryTreeIsBalanaced { + public static int getHeight(TreeNode root) { + if(root == null) { + return 0; //base case + } + return Math.max(getHeight(root.left), getHeight(root.right)) + 1; + } + + public static boolean isBalanced(TreeNode root) { + if(root == null) { //base case + return true; + } + + int heightDiff = getHeight(root.left) - getHeight(root.right); + if(Math.abs(heightDiff) > 1) { + return false; + } + else { //recurse + return isBalanced(root.left) && isBalanced(root.right); + } + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-three-stacks-and-queues/MyQueue.java b/cracking-the-coding-interview/chapter-three-stacks-and-queues/MyQueue.java new file mode 100644 index 00000000..4fd0ccbd --- /dev/null +++ b/cracking-the-coding-interview/chapter-three-stacks-and-queues/MyQueue.java @@ -0,0 +1,40 @@ +/* implement a MyQueue class which implements a queue using two stacks */ + +public class MyQueue { + Stack stackNewest, stackOldest; + + public MyQueue() { + stackNewest = new Stack(); + stackOldest = new Stack(); + } + + public int size() { + return stackNewest.size() + stackOldest.size(); + } + + public void add(T value) { + /* push onto stackNewest, which always has the newest + * elements on top */ + stackNewest.push(value); + } + + /* Move elements from stackNewest into stackOldest. This + * is usually done so that we can do operations on stackOldest */ + private void shiftStacks() { + if(stackOldest.isEmpty()) { + while(!stackNewest.isEmpty()) { + stackOldest.push(stackNewest.pop()); + } + } + } + + public T peek() { + shiftStacks(); //ensure stackOldest has the current elements + return stackOldest.peek(); //retrieve the oldest item + } + + public T remove() { + shiftStacks(); //ensure stackOldest has the current elements + return stackOldest.pop(); + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-three-stacks-and-queues/QueueUsingTwoStacks.java b/cracking-the-coding-interview/chapter-three-stacks-and-queues/QueueUsingTwoStacks.java new file mode 100644 index 00000000..5024fb8e --- /dev/null +++ b/cracking-the-coding-interview/chapter-three-stacks-and-queues/QueueUsingTwoStacks.java @@ -0,0 +1,5 @@ +/* implement a MyQueue class which implements a queue using two stacks */ + +public class QueueUsingTwoStacks { + +} \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-three-stacks-and-queues/SetOfStacks.java b/cracking-the-coding-interview/chapter-three-stacks-and-queues/SetOfStacks.java new file mode 100644 index 00000000..a00d0dc3 --- /dev/null +++ b/cracking-the-coding-interview/chapter-three-stacks-and-queues/SetOfStacks.java @@ -0,0 +1,44 @@ +/* imagine a (literal) stack of plates. If the stack gets too high, it might topple. + * Therefore, in real life, we would likely start a new stack when the previous stack + * exceeds some threshold. Implement a data structure SetOfStacks that mimics this. + * SetOfStacks should be composed of several stacks and should create a new stack once + * the previous one exceeds capacity. SetOfStacks.push() and SetOfStacks.pop() should + * behave identically to a single stack (that is, pop() should return the same values as + * it would if there were just a single stack) */ + +//in this problem, we've been told what our data structure should look like: +public class SetOfStacks { + ArrayList stacks = new ArrayList(); + //public void push(int v) {...} + //public int pop() {...} + + public void push(int v) { + Stack last = getLastStack(); + if(last != null && !last.isFull()) { //add to the last stack + last.push(v); + } + else { //must create new stack + Stack stack = new Stack(capacity); + stack.push(v); + stacks.add(stack); + } + } + + public void pop() { + Stack last = getLastStack(); + int v = last.pop(); + if(last.size == 0) { + stacks.remove(stacks.size() - 1); + } + return v; + } + + public Stack getLastStack() { + if(stacks.size() == 0) { + return null; + } + return stacks.get(stacks.size() - 1); + } +} + + diff --git a/cracking-the-coding-interview/chapter-three-stacks-and-queues/SortStack.java b/cracking-the-coding-interview/chapter-three-stacks-and-queues/SortStack.java new file mode 100644 index 00000000..0f07d890 --- /dev/null +++ b/cracking-the-coding-interview/chapter-three-stacks-and-queues/SortStack.java @@ -0,0 +1,18 @@ +/* write a program to sort a stack in ascending order (with biggest items on top). + * you may use at most one additional stack to hold items, but you may not copy the + * elements into any other data strcuture (such as an array). The stack supports the + * folowing operations: push, pop, peek, and isEmpty */ + +public class SortStack { + public static Stack sort(Stack s) { + Stack r = new Stack(); + while(!s.isEmpty()) { + int tmp = s.pop(); //step 1 + while(!r.isEmpty() && r.peek() > tmp) { //step 2 + s.push(r.pop()); + } + r.push(tmp) //step 3 + } + return r; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-three-stacks-and-queues/StackWithMin.java b/cracking-the-coding-interview/chapter-three-stacks-and-queues/StackWithMin.java new file mode 100644 index 00000000..6d640293 --- /dev/null +++ b/cracking-the-coding-interview/chapter-three-stacks-and-queues/StackWithMin.java @@ -0,0 +1,26 @@ +//How would you design a stack which, in addition to push and pop, also has a function min which returns the minimum element? Push, pop, and min should all operate in O(1) time + +public class StackWithMin extends Stack { + public void push(int value) { + int newMin = Math.min(value, min()); + super.push(new NodeWithMin(value, newMin)); + } + + public int min() { + if(this.isEmpty()) { + return Integer.MAX_VALUE; //error value + } + else { + return peek().min; + } + } +} + +class NodeWithMin { + public int value; + public int min; + public NodeWithMin(int v, int min) { + this.value = v; + this.min = min; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-three-stacks-and-queues/ThreeStacks.java b/cracking-the-coding-interview/chapter-three-stacks-and-queues/ThreeStacks.java new file mode 100644 index 00000000..90722307 --- /dev/null +++ b/cracking-the-coding-interview/chapter-three-stacks-and-queues/ThreeStacks.java @@ -0,0 +1,44 @@ +//Describe how you could use a single array to implement three stacks + +public class ThreeStacks { + int stackSize = 100; + int[] buffer = new int[stackSize * 3]; + int[] stackPointer = {-1, -1, -1}; //pointers to track top element + + void push(int stackNum, int value) throws Exception { + /* check if we have space */ + if(stackPointer[stackNum] + 1 >= stackSize) { //last element + throw new FullStackException(); + } + /* increment stack pointer and then update top value */ + stackPointer[stackNum]++; + buffer[absTopOfStack(stackNum)] = value; + } + + int pop(int stackNum) throws Exception { + if(isEmpty(stackNum)) { + throw new EmptyStackException(); + } + int value = buffer[absTopOfStack(stackNum)]; //get top + buffer[absTopOfStack(stackNum)] = 0; //clear index + stackPointer[stackNum]--; //decrement pointer + return value; + } + + int peek(int stackNum) { + if(isEmpty(stackNum)) { + throw new EmptyStackException(); + } + int index = absTopOfStack(stackNum); + return buffer[index]; + } + + boolean isEmpty(int stackNum) { + return stackPointer[stackNum] == -1; + } + + /* returns index of top of stack "stackNum", in absolute terms */ + int absTopOfStack(int stasckNum) { + return stackNum * stackSize + stackPointer[stackNum]; + } +} diff --git a/cracking-the-coding-interview/chapter-three-stacks-and-queues/TowersOfHanoi.java b/cracking-the-coding-interview/chapter-three-stacks-and-queues/TowersOfHanoi.java new file mode 100644 index 00000000..6a03ba51 --- /dev/null +++ b/cracking-the-coding-interview/chapter-three-stacks-and-queues/TowersOfHanoi.java @@ -0,0 +1,59 @@ +/* in the classic problem of the Towers of Hanoi, you have 3 towers and N disks of + * different sizes which can slide onto any tower. The puzzle starts with disks sorted + * in ascending order of size from top to bottom (i.e. each disk sits on top of an even + * larger one). You have the following constraints: + * (1) Only one disk can be moved at a time + * (2) A disk is slid off the top of one tower onto the next rod + * (3) A disk can only be placed on top of a larger disk + * Write a program to move the disks from the first tower to the last tower using Stacks */ + +public class TowersOfHanoi { + public static void main(String args[]) { + int n = 3; + Tower[] towers = new Tower[n]; + for(int i = 0; i < 3; i++) { + towers[i] = new Tower(i); + } + + for(int i = n - 1; i >= 0; i--) { + towers[0].add(i); + } + towers[0].moveDisks(n, towers[2], towers[1]); + } +} + +public class Tower { + private Stack disks; + private int index; + public Tower(int i) { + disks = new Stack(); + index = i; + } + + public int index() { + return index; + } + + public void add(int d) { + if(!disks.isEmpty() && disks.peek() <= d) { + System.out.println("Error placing disk " + d); + } + else { + disks.push(d): + } + } + + public void moveTopTo(Tower t) { + int top = disks.pop(); + t.add(top); + System.out.println("Move disk " + top + " from " + index() + " to " + t.index()); + } + + public void moveDisks(int n, Tower destination, Tower buffer) { + if(n > 0) { + moveDisks(n - 1, buffer, destination); + moveTopTo(destination); + buffer.moveDisks(n - 1, destination, this); + } + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-two-linked-lists/DeleteDups.java b/cracking-the-coding-interview/chapter-two-linked-lists/DeleteDups.java new file mode 100644 index 00000000..46e04a43 --- /dev/null +++ b/cracking-the-coding-interview/chapter-two-linked-lists/DeleteDups.java @@ -0,0 +1,18 @@ +//Write code to remove duplicates from an unsorted linked list + +public class RemoveDups { + void deleteDups(LinkedListNode n) { + HashSet set = new HashSet(); + LinkedListNode previous = null; + while(n != null) { + if(set.contains(n.data)) { + previous.next = n.next; + } + else { + set.add(n.data); + previous = n; + } + n = n.next; + } + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-two-linked-lists/DeleteNode.java b/cracking-the-coding-interview/chapter-two-linked-lists/DeleteNode.java new file mode 100644 index 00000000..c65db93c --- /dev/null +++ b/cracking-the-coding-interview/chapter-two-linked-lists/DeleteNode.java @@ -0,0 +1,14 @@ +//Implement an algorithm to delete a node in the middle of a singly linked list, give only access to that node + +public class DeleteNode { + public static boolean deleteNode(LinkedListNode n) { + if(n == null || n.next == null) { + return false; + } + + LinkedListNode next = n.next; + n.data = next.data; + n.next = next.next; + return true; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-two-linked-lists/FindBeginning.java b/cracking-the-coding-interview/chapter-two-linked-lists/FindBeginning.java new file mode 100644 index 00000000..be958bb8 --- /dev/null +++ b/cracking-the-coding-interview/chapter-two-linked-lists/FindBeginning.java @@ -0,0 +1,36 @@ +//Given a circular linked list, implement an algorithm which returns +//the node at the beginning of the loop + +public class FindBeginning { + LinkedListNode findBeginning(LinkedListNode head) { + LinkedListNode slow = head; + LinkedListNode fast = head; + + /* find meeting point. This will be LOOP_SIZE - k + * steps int othe linked list */ + while(fast != null && fast.next != null) { + slow = slow.next; + fast = fast.next.next; + if(fast == slow) { + break; + } + } + + /* error checking - no meeting point, and therefore no loop */ + if(fast == null || fast.next == null) { + return null; + } + + /* move slow to head. Keep fast at meeting point. Each are k + * steps from the loop start. If they move at the same pace, + * they must meet at the loop start */ + slow = head; + while(slow != fast) { + slow = slow.next; + fast = fast.next; + } + + /* both now point to the start of the loop */ + return fast; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-two-linked-lists/IsPalindrome.java b/cracking-the-coding-interview/chapter-two-linked-lists/IsPalindrome.java new file mode 100644 index 00000000..7eecc465 --- /dev/null +++ b/cracking-the-coding-interview/chapter-two-linked-lists/IsPalindrome.java @@ -0,0 +1,38 @@ +//Implement a function to check if a linked list is a palindrome +//don't forget import statements! + +public class IsPalindrome { + boolean isPalindrome(LinkedListNode head) { + LinkedListNode fast = head; + LinkedListNode slow = head; + + Stack stack = new Stack(); + + /* push elements from first half of linked list onto stack. + * When fast runner (which is moving at 2x speed) reaches the + * end of the linked list, then we know we're at the middle */ + while(fast != null && fast.next != null) { + stack.push(slow.data); + slow = slow.next; + fast = fast.next.next; + } + + /*has odd number of elements, so skip the middle element */ + if(fast != null) { + slow = slow.next; + } + + while(slow != null) { + int top = stack.pop().intValue(); + + /* if values are different, then it's not a palindrome */ + if(top != slow.data) { + return false; + } + + slow = slow.next; + } + + return true; + } +} \ No newline at end of file diff --git a/cracking-the-coding-interview/chapter-two-linked-lists/NthToLast.java b/cracking-the-coding-interview/chapter-two-linked-lists/NthToLast.java new file mode 100644 index 00000000..e69de29b diff --git a/cracking-the-coding-interview/chapter-two-linked-lists/Partition.java b/cracking-the-coding-interview/chapter-two-linked-lists/Partition.java new file mode 100644 index 00000000..aa692dd1 --- /dev/null +++ b/cracking-the-coding-interview/chapter-two-linked-lists/Partition.java @@ -0,0 +1,28 @@ +//Write code to partition a linked list around a value x, such that +//all nodes less than x come before all nodes greater than or equal to x. + +public class Partition { + LinkedListNode partition(LinkedListNode node, int x) { + LinkedListNode head = node; + LinkedListNode tail = node; + + while(node != null) { + LinkedListNode next = node.next; + if(node.data < x) { + /* insert node at head */ + node.next = head; + head = node; + } + else { + /* insert node at tail */ + tail.next = node; + tail = node; + } + node = next; + } + tail.next = null; + + //the head has changed, so we need to return it to the user + return head; + } +} \ No newline at end of file diff --git a/leetcode/binary-search/PowerOfXToTheN.java b/leetcode/binary-search/PowerOfXToTheN.java new file mode 100644 index 00000000..26cf76dc --- /dev/null +++ b/leetcode/binary-search/PowerOfXToTheN.java @@ -0,0 +1,20 @@ +// Implement pow(x, n). + +public class PowerOfXToTheN { + public double myPow(double x, int n) { + if(n == 0) { + return 1; + } + + if(Double.isInfinite(x)) { + return 0; + } + + if(n < 0) { + n = -n; + x = 1 / x; + } + + return n % 2 == 0 ? myPow(x * x, n / 2) : x * myPow(x * x, n / 2); + } +} diff --git a/leetcode/binary-search/SquareRootX.java b/leetcode/binary-search/SquareRootX.java new file mode 100644 index 00000000..d66448a2 --- /dev/null +++ b/leetcode/binary-search/SquareRootX.java @@ -0,0 +1,28 @@ +// Implement int sqrt(int x). + +// Compute and return the square root of x. + +public class SquareRootX{ + public int mySqrt(int x) { + if(x == 0) { + return 0; + } + + int left = 1; + int right = x; + + while(left <= right) { + int mid = left + (right - left) / 2; + + if(mid == x / mid) { + return mid; + } else if(mid > x / mid) { + right = mid - 1; + } else if(mid < x / mid) { + left = mid + 1; + } + } + + return right; + } +} diff --git a/leetcode/bit-manipulation/NumberOfOneBits.java b/leetcode/bit-manipulation/NumberOfOneBits.java new file mode 100644 index 00000000..6c98c1ae --- /dev/null +++ b/leetcode/bit-manipulation/NumberOfOneBits.java @@ -0,0 +1,21 @@ +// Write a function that takes an unsigned integer and returns the number of ’1' bits it has (also known as the Hamming weight). + +// For example, the 32-bit integer ’11' has binary representation 00000000000000000000000000001011, so the function should return 3. + +public class NumberOfOneBits { + // you need to treat n as an unsigned value + public int hammingWeight(int n) { + if(n == 0) { + return 0; + } + + int count = 0; + + while(n != 0) { + count += (n) & 1; + n >>>= 1; + } + + return count; + } +} diff --git a/leetcode/bit-manipulation/Utf8Validation.java b/leetcode/bit-manipulation/Utf8Validation.java new file mode 100644 index 00000000..b1004e31 --- /dev/null +++ b/leetcode/bit-manipulation/Utf8Validation.java @@ -0,0 +1,60 @@ +// A character in UTF8 can be from 1 to 4 bytes long, subjected to the following rules: + +// For 1-byte character, the first bit is a 0, followed by its unicode code. +// For n-bytes character, the first n-bits are all one's, the n+1 bit is 0, followed by n-1 bytes with most significant 2 bits being 10. +// This is how the UTF-8 encoding would work: + +// Char. number range | UTF-8 octet sequence +// (hexadecimal) | (binary) +// --------------------+--------------------------------------------- +// 0000 0000-0000 007F | 0xxxxxxx +// 0000 0080-0000 07FF | 110xxxxx 10xxxxxx +// 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx +// 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx +// Given an array of integers representing the data, return whether it is a valid utf-8 encoding. + +// Note: +// The input is an array of integers. Only the least significant 8 bits of each integer is used to store the data. This means each integer represents only 1 byte of data. + +// Example 1: + +// data = [197, 130, 1], which represents the octet sequence: 11000101 10000010 00000001. + +// Return true. +// It is a valid utf-8 encoding for a 2-bytes character followed by a 1-byte character. +// Example 2: + +// data = [235, 140, 4], which represented the octet sequence: 11101011 10001100 00000100. + +// Return false. +// The first 3 bits are all one's and the 4th bit is 0 means it is a 3-bytes character. +// The next byte is a continuation byte which starts with 10 and that's correct. +// But the second continuation byte does not start with 10, so it is invalid. + +public class Utf8Validation { + public boolean validUtf8(int[] data) { + int count = 0; + + for(int i : data) { + if(count == 0) { + if((i >> 5) == 0b110) { + count = 1; + } else if((i >> 4) == 0b1110) { + count = 2; + } else if((i >> 3) == 0b11110) { + count = 3; + } else if((i >> 7) == 0b1) { + return false; + } + } else { + if((i >> 6) != 0b10) { + return false; + } + + count--; + } + } + + return count == 0; + } +} diff --git a/leetcode/hashtable/BinarySearchTreeVerticalOrderTraversal.java b/leetcode/hashtable/BinarySearchTreeVerticalOrderTraversal.java new file mode 100644 index 00000000..fbe44d08 --- /dev/null +++ b/leetcode/hashtable/BinarySearchTreeVerticalOrderTraversal.java @@ -0,0 +1,115 @@ +// Given a binary tree, return the vertical order traversal of its nodes' values. (ie, from top to bottom, column by column). + +// If two nodes are in the same row and column, the order should be from left to right. + +// Examples: + +// Given binary tree [3,9,20,null,null,15,7], +// 3 +// /\ +// / \ +// 9 20 +// /\ +// / \ +// 15 7 +// return its vertical order traversal as: +// [ +// [9], +// [3,15], +// [20], +// [7] +// ] +// Given binary tree [3,9,8,4,0,1,7], +// 3 +// /\ +// / \ +// 9 8 +// /\ /\ +// / \/ \ +// 4 01 7 +// return its vertical order traversal as: +// [ +// [4], +// [9], +// [3,0,1], +// [8], +// [7] +// ] +// Given binary tree [3,9,8,4,0,1,7,null,null,null,2,5] (0's right child is 2 and 1's left child is 5), +// 3 +// /\ +// / \ +// 9 8 +// /\ /\ +// / \/ \ +// 4 01 7 +// /\ +// / \ +// 5 2 +// return its vertical order traversal as: +// [ +// [4], +// [9,5], +// [3,0,1], +// [8,2], +// [7] +// ] + +/** + * Definition for a binary tree node. + * public class TreeNode { + * int val; + * TreeNode left; + * TreeNode right; + * TreeNode(int x) { val = x; } + * } + */ +public class BinarySearchTreeVerticalOrderTraversal { + public List> verticalOrder(TreeNode root) { + List> result = new ArrayList<>(); + + if(root == null) { + return result; + } + + Map> map = new HashMap<>(); + Queue q = new LinkedList<>(); + Queue cols = new LinkedList<>(); + + q.add(root); + cols.add(0); + + int min = 0; + int max = 0; + + while(!q.isEmpty()) { + TreeNode node = q.poll(); + + int col = cols.poll(); + + if(!map.containsKey(col)) { + map.put(col, new ArrayList()); + } + + map.get(col).add(node.val); + + if(node.left != null) { + q.add(node.left); + cols.add(col - 1); + min = Math.min(min, col - 1); + } + + if(node.right != null) { + q.add(node.right); + cols.add(col + 1); + max = Math.max(max, col + 1); + } + } + + for(int i = min; i <= max; i++) { + result.add(map.get(i)); + } + + return result; + } +}