From 169cac6fbc0af9bfbb042aa2b994e5f62e86fed1 Mon Sep 17 00:00:00 2001 From: "Steven (Zen)" Date: Tue, 25 Aug 2026 19:14:07 -0600 Subject: [PATCH] =?UTF-8?q?Initial=20commit=20=E2=80=94=20imported=20from?= =?UTF-8?q?=20GitHub?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 10 + 404.html | 25 + Gemfile | 33 + Gemfile.lock | 93 + _code/arrays/bestTimeToBuyAndSellStock.py | 21 + ...bestTimeToBuyAndSellStockGlobalMinWrong.py | 38 + _code/arrays/findMinInSortedArray.py | 40 + _code/arrays/findMinInSortedArray2.py | 14 + _code/arrays/increasingTriplet.py | 24 + _code/arrays/intersectionOfTwoArrays.py | 38 + _code/arrays/intersectionOfTwoArrays2.py | 33 + _code/arrays/longestCommonPrefix.py | 37 + _code/arrays/maxProductSubarray.py | 55 + _code/arrays/maxSubarray.py | 21 + _code/arrays/maximumSubArray.py | 46 + _code/arrays/missingNum.py | 18 + _code/arrays/pascal_triangle.py | 53 + _code/arrays/plusOne.py | 29 + .../prisonCellsAfterNDays.py | 36 + _code/arrays/rotateArray.py | 26 + _code/arrays/searchInRotatedArray.py | 19 + _code/arrays/squareSortedArrays.py | 36 + _code/arrays/threeSum.py | 45 + _code/arrays/twoCityScheduling.py | 34 + _code/arrays/twoSum.py | 20 + _code/arrays/twoSumOnePass.py | 17 + _code/arrays/waterWithMostArea.py | 26 + _code/backtracking/backtrack.py | 34 + _code/backtracking/combination_sum.py | 22 + _code/backtracking/generateParenthesis.py | 25 + _code/backtracking/permutation.py | 47 + _code/backtracking/subsets.py | 130 ++ _code/bfs/bfs.py | 69 + _code/binary search/arrangecoins.py | 21 + _code/binary search/binarySearch.py | 32 + _code/binary search/binarySearch2.py | 28 + _code/binary search/searchInsertPosition.py | 41 + _code/binary search/searchMatrix.py | 35 + _code/bit manipulation/addBinaryStrings.py | 14 + _code/bit manipulation/binaryToInt.py | 38 + _code/bit manipulation/countOnesInArray.py | 44 + _code/bit manipulation/hammingDistance.py | 14 + _code/bit manipulation/hammingWeight.py | 12 + _code/bit manipulation/missingNumXor.py | 13 + _code/bit manipulation/reverseBits.py | 26 + _code/bit manipulation/singleNumber3.py | 19 + _code/bit manipulation/singleNumberii.py | 26 + _code/dfs/binaryTreeZigZagDFS.py | 39 + _code/dynamic programming/coinChange1.py | 36 + _code/dynamic programming/coinChange2.py | 20 + _code/dynamic programming/houseRobber.py | 23 + _code/dynamic programming/houseRobber2.py | 31 + .../longestCommonSubsequence.py | 31 + .../dynamic programming/perfectSquares/notes | 63 + .../perfectSquares/perfectSquares.py | 13 + .../cheapestFlightsWithinKStops.py | 33 + .../cheapestFlightsWithinKStopsDijkstra.py | 52 + .../cheapestFlightsWithinKStopsDijkstra2.py | 44 + .../grokking-algo-book-bfs.py | 25 + .../grokking-algo-book-dijkstra.py | 44 + .../network-delay/network-delay-dijkstra.py | 37 + .../reconstructIternary.py | 23 + .../reconstructIternaryDfs.py | 30 + _code/greedy/jumpGame.py | 15 + _code/greedy/queueReconstructionByHeight.py | 22 + _code/hashing/isomorphicStrings.py | 20 + _code/hashing/longestWord.py | 21 + _code/heap/heaptest.py | 14 + _code/heap/lastStoneWeight.py | 29 + _code/heap/topKfrequentElements.py | 66 + _code/implementation/lruCache.py | 126 ++ _code/implementation/minStack.py | 54 + _code/interval/mergeInterval.py | 40 + _code/interviews/hackerrank.py | 6 + _code/interviews/ikm_assessment_python3.py | 8 + .../reorderlist.py | 66 + _code/interviews/missingAndDuplicate.py | 11 + _code/interviews/pramp/helper.py | 7 + .../pramp/minAddToMakeParenthesisValid.py | 29 + _code/interviews/pramp/prodOfArray.py | 36 + _code/interviews/regexTest.py | 3 + _code/interviews/softmaxdata.py | 68 + _code/interviews/test.py | 51 + _code/linked_list/linkedListcycle.py | 54 + _code/linked_list/linkedListcyclefloydd.py | 45 + _code/linked_list/mergeSortedLinkedList.py | 38 + _code/linked_list/mergeSortedLists.py | 53 + .../linked_list/mergeSortedListsRecursive.py | 43 + _code/linked_list/palindromelinkedlist.py | 25 + .../linked_list/reverse/reverseLinkedList.py | 50 + .../reverse/reverseLinkedListRecursive.py | 35 + _code/linked_list/reverse/reverseSublist.py | 65 + _code/math/countNumbersWithUniqueDigits.py | 50 + _code/math/int_to_string.py | 39 + _code/math/plusOne.py | 28 + _code/math/reveseInteger.py | 36 + _code/math/string_to_int.py | 18 + _code/math/uglyNum2.py | 25 + _code/matrix/matrix_transversal.py | 45 + _code/matrix/rotateMatrix/rotateMatrix.py | 43 + _code/matrix/rotateMatrix/rotateMatrix2.py | 34 + _code/matrix/searchMatrix.py | 34 + .../setMatrixZeroRecordRowCol.py | 36 + .../setMatrixZero/setMatrixZeroWrong.py | 56 + _code/matrix/spiralMatrix.py | 63 + _code/matrix/spiralOrder.py | 40 + _code/matrix/sudoku.py | 34 + _code/matrix/transposeMatrix.py | 9 + .../validateSudoku/validateSudokuLeetcode.py | 94 + .../validateSudoku/validateSudokuLeetcode2.py | 61 + .../validateSudoku/validateSudokuLeetcode3.py | 64 + _code/matrix/wordSearch/wordSearch.py | 38 + _code/matrix/wordSearch/wordSearchSingle2.py | 24 + .../find_all_anagrams_in_a_string.py | 121 ++ .../sliding_window/sliding_window_template.py | 43 + .../subarray_length_k_largest_sum.py | 27 + _code/stack/valid_parenthesis.py | 39 + _code/stack/valid_parenthesis2.py | 23 + _code/stack/valid_parenthesis3.py | 35 + _code/strings/firstNonRepeating.py | 12 + _code/strings/isSubsequence.py | 49 + _code/strings/longestPalindromicSubstring.py | 51 + .../longestSubstringWithoutRepeatingChars.py | 31 + _code/strings/reverseString.py | 11 + _code/strings/reverseVowels.py | 22 + _code/strings/toLower.py | 10 + _code/strings/validate_anagram.py | 12 + _code/topological_sort/toposort.py | 34 + _code/trees/balance tree/balancedTree.py | 54 + _code/trees/balance tree/isTreeBalanced.py | 47 + _code/trees/createTreeFromArray.py | 44 + .../trees/deepestLeavesSum/deepestLeaveSum.py | 39 + .../deepestLeavesSum/deepestLeavesSumBFS.py | 53 + .../deepestLeavesSum/deepestLeavesSumDFS.py | 33 + .../deepestLeavesSum/deepestLeavesSumMay12.py | 34 + _code/trees/deepestNode.py | 37 + _code/trees/deserializeTree.py | 46 + _code/trees/invertTree/invertTree.py | 31 + _code/trees/isSameTree/isSameTree.py | 49 + _code/trees/isSameTree/sameTree.py | 25 + _code/trees/isSubTree.py | 40 + _code/trees/k_distance_from_root.py | 31 + _code/trees/lca/lcaBinaryTree.py | 43 + _code/trees/levelOrder.py | 51 + _code/trees/maxDepth.py | 31 + .../trees/maxWidthOfTree/maxWidthOfTreeBFS.py | 0 _code/trees/serializeTree.py | 31 + _code/trees/serializeTree2.py | 58 + _code/trees/sumEvenGrandparents.py | 72 + _code/trees/sumRootToLeafNumbers.py | 35 + _code/trees/symmetry/symmetricTree.py | 46 + _code/trees/symmetry/symmetricTree2.py | 42 + _code/trees/symmetry/symmetricTreeMay12.py | 38 + _code/trees/symmetry/symmetricTreeTemplate.py | 23 + .../validateBST_recurseWithLimits.py | 57 + .../validateBST_trivialButWrong.py | 56 + _code/tries/trie.py | 71 + _code/union find/floodfill.py | 52 + _code/union find/numIslands/numIslands.py | 54 + _code/union find/numIslands/numIslands2.py | 36 + _code/union find/numIslands/numIslands3.py | 33 + _code/union find/numIslands/numIslands4.py | 17 + _code/union find/rottingOranges.py | 58 + _code/union find/surroundedRegion.py | 49 + _config.yml | 31 + _includes/analytics.html | 9 + _layouts/default.html | 26 + _problems/1template.md | 37 + _problems/addStrings.md | 42 + _problems/allPathsFromSourceToTarget.md | 140 ++ _problems/arrangeCoins.md | 121 ++ _problems/bfs.md | 69 + _problems/binarySearch.md | 60 + _problems/binaryTreeLevelOrder.md | 99 ++ _problems/binaryTreeLevelOrder2.md | 82 + _problems/binaryTreeZigZag.md | 75 + _problems/binaryTreeZigZagDfs.md | 64 + _problems/buyAndSellStock.md | 64 + _problems/buyAndSellStock2.md | 68 + _problems/cheapestFlight.md | 123 ++ _problems/climbingStairs.md | 48 + _problems/coinChange.md | 56 + _problems/coinChange2.md | 96 + _problems/combinationSum2.md | 85 + _problems/combinationSum3.md | 82 + _problems/combination_sum.md | 129 ++ _problems/containsDuplicates.md | 44 + _problems/convertSortedArrayToBST.md | 59 + _problems/copyListWithRandomPointer.md | 126 ++ _problems/countCompleteBinaryNodes.md | 54 + _problems/countOnesInArray.md | 63 + _problems/cousinsInBinaryTree.md | 129 ++ _problems/deepestLeavesSumBFS.md | 43 + _problems/deepestLeavesSumDFS.md | 80 + _problems/findAllAnagramsInString.md | 85 + _problems/findAllDupsInArray.md | 84 + _problems/findMinInSortedArray.md | 134 ++ _problems/findPeakElement.md | 66 + _problems/findTheDuplicateNumber.md | 64 + _problems/firstBadVersion.md | 92 + _problems/firstNonRepeatingChar.md | 54 + .../flattenMultilevelDoublyLinkedList.md | 111 ++ _problems/floodfill.md | 90 + _problems/generateParanthesis.md | 98 ++ _problems/groupAnagrams.md | 82 + _problems/groupIsomorphicStrings.md | 75 + _problems/guessNumberHigherOrLower.md | 81 + _problems/houseRobber.md | 47 + _problems/houseRobber2.md | 44 + _problems/implementATrie.md | 113 ++ _problems/implement_strstr.md | 57 + _problems/increasingTripletSubsequence.md | 96 + _problems/insertDeleteGetRandom.md | 121 ++ _problems/insertInterval.md | 68 + _problems/insertIntoBST.md | 83 + _problems/intersectionOfLinkedList.md | 104 ++ _problems/intersectionOfTwoArrays2.md | 91 + _problems/invertTree.md | 50 + _problems/isSameTree.md | 64 + _problems/isSubSequence.md | 63 + _problems/isSubtree.md | 54 + _problems/isSymmetricTree.md | 57 + _problems/isTreeBalanced.md | 62 + _problems/islandPerimeter.md | 140 ++ _problems/isomorphicStrings.md | 73 + _problems/jumpGame.md | 94 + _problems/koko_eating_bananas.md | 86 + _problems/kthlargestElementInAStream.md | 94 + _problems/kthlargestElementInAnArray.md | 84 + _problems/lastStoneWeight.md | 67 + _problems/lcaBinaryTree.md | 58 + _problems/llcycle.md | 148 ++ _problems/llcycle2.md | 118 ++ _problems/longestCommonPrefix.md | 54 + _problems/longestCommonSubsequence.md | 61 + _problems/longestPalindromicSubstring.md | 104 ++ .../longestSubstringWithoutRepeatingChars.md | 131 ++ _problems/longestUnivaluePath.md | 91 + _problems/majorityElement.md | 62 + _problems/majorityElement2.md | 79 + _problems/matrixSearch.md | 61 + _problems/maxAreaOfIsland.md | 60 + _problems/maxDepth.md | 53 + _problems/maxDepthOfNaryTree.md | 48 + _problems/maxProductSubarray.md | 106 ++ _problems/maxSubarray.md | 45 + _problems/maxWidthOfBinaryTree.md | 154 ++ _problems/maxXorOfTwoNums.md | 86 + _problems/mergeIntervals.md | 64 + _problems/mergeKSortedLinkedLists.md | 75 + _problems/mergeSortedArray.md | 67 + _problems/mergeSortedLLiter.md | 60 + _problems/mergeSortedLLrecur.md | 66 + _problems/mergeTwoBinaryTrees.md | 103 ++ _problems/minStack.md | 99 ++ _problems/minimumAddToMakeValidParenthesis.md | 112 ++ _problems/minimumCostForTickets.md | 91 + _problems/missingNumber.md | 48 + _problems/mostCommonWord.md | 83 + _problems/moveZeros.md | 90 + _problems/networkDelayTime.md | 87 + _problems/nthdigit.md | 70 + _problems/numIslands.md | 135 ++ _problems/numOnes.md | 27 + _problems/number_compliment.md | 78 + _problems/oddEvenLinkedList.md | 64 + _problems/palindromicLinkList.md | 83 + _problems/pathSum.md | 88 + _problems/pathSum2.md | 71 + _problems/pathSum3.md | 86 + _problems/perfectSquaresa.md | 98 ++ _problems/permutations.md | 92 + _problems/permutations2.md | 105 ++ _problems/permutationsCascading.md | 84 + _problems/plusOne.md | 233 +++ _problems/powerOfFour.md | 56 + _problems/powx-n.md | 58 + _problems/printKdistanceFromRoot.md | 41 + _problems/prisonCellsAfterNDays.md | 178 ++ _problems/productOfArrayExceptSelf.md | 63 + _problems/queueReconstructionByHeight.md | 64 + _problems/ransomNote.md | 60 + _problems/reconstructIternary.md | 105 ++ _problems/removeDupFromSortedArray.md | 65 + _problems/removeLinkedListElements.md | 55 + _problems/removeNthNodeFromEndOfList.md | 90 + _problems/reorder_list.md | 161 ++ _problems/restoreIpAddresses.md | 90 + _problems/reverseBits.md | 52 + _problems/reverseInteger.md | 101 ++ _problems/reverseLLiterative.md | 35 + _problems/reverseString.md | 49 + _problems/reverseVowelsFromAString.md | 78 + _problems/reverseWordsInAString3.md | 77 + _problems/rotateArray.md | 61 + _problems/rotateImage.md | 63 + _problems/rotateMatrix.md | 68 + _problems/rottonOranges.md | 74 + _problems/searchForARange.md | 94 + _problems/searchInRotatedSortedArray.md | 93 + _problems/searchInsertPosition.md | 150 ++ _problems/searchRotatedArray.md | 72 + _problems/serializeTree.md | 75 + _problems/setMatrixZeros.md | 166 ++ _problems/shortestPathCells.md | 111 ++ _problems/singleNumber.md | 86 + _problems/singleNumber3.md | 77 + _problems/singleNumberii.md | 62 + _problems/sortColors.md | 138 ++ _problems/spiralMatrix.md | 162 ++ _problems/sql_1template.md | 26 + _problems/sql_binary_tree_nodes.md | 63 + _problems/sql_combine2tables.md | 63 + _problems/sql_customers_who_never_order.md | 77 + _problems/sql_delete_duplicate_emails.md | 57 + _problems/sql_department_highest_salary.md | 89 + _problems/sql_dupicate_emails.md | 46 + ...ql_employees_earning_more_than_managers.md | 49 + _problems/sql_facebook_practice.md | 144 ++ _problems/sql_reformat_department.md | 140 ++ _problems/sql_second_highest_salary.md | 77 + _problems/sql_thepads.md | 71 + _problems/sql_triangles.md | 86 + _problems/sqrtx.md | 135 ++ _problems/subsets.md | 211 +++ _problems/subsetsCascading.md | 121 ++ _problems/sumRootToLeaf.md | 105 ++ _problems/surroundedRegion.md | 101 ++ _problems/task_scheduler.md | 87 + _problems/threeSum.md | 105 ++ _problems/topFrequentKElements.md | 103 ++ _problems/twoCityScheduling.md | 85 + _problems/twoSum.md | 118 ++ _problems/uglyNum2.md | 59 + _problems/uniqueBST.md | 116 ++ _problems/uniquePaths.md | 60 + _problems/validParenthesis.md | 78 + _problems/validateBST.md | 127 ++ _problems/validateSudoku.md | 79 + _problems/waterWithMostWater.md | 80 + _problems/wordLadder.md | 118 ++ _problems/wordSearch.md | 67 + about.markdown | 18 + index.md | 27 + pages/_behavior_interview/behavior.md | 12 + pages/_system_design/concepts.md | 51 + pages/_system_design/instagram.md | 72 + pages/_system_design/link_shortener.md | 87 + pages/_system_design/system_design_notes | 3 + pages/bookmarkedSites.md | 96 + pages/failureAttempts.md | 10 + pages/lists/amazonTop50.md | 57 + pages/lists/blind100.md | 166 ++ pages/lists/epi.md | 430 +++++ pages/lists/reviewProblems.md | 205 +++ pages/lists/solved.md | 30 + pages/lists/solvedLastModified.md | 10 + pages/practiceJournal.md | 1568 +++++++++++++++++ site-management/fileutils.py | 24 + site-management/generateSolvedModified.py | 82 + 360 files changed, 24059 insertions(+) create mode 100644 .gitignore create mode 100644 404.html create mode 100644 Gemfile create mode 100644 Gemfile.lock create mode 100644 _code/arrays/bestTimeToBuyAndSellStock.py create mode 100644 _code/arrays/bestTimeToBuyAndSellStockGlobalMinWrong.py create mode 100644 _code/arrays/findMinInSortedArray.py create mode 100644 _code/arrays/findMinInSortedArray2.py create mode 100644 _code/arrays/increasingTriplet.py create mode 100644 _code/arrays/intersectionOfTwoArrays.py create mode 100644 _code/arrays/intersectionOfTwoArrays2.py create mode 100644 _code/arrays/longestCommonPrefix.py create mode 100644 _code/arrays/maxProductSubarray.py create mode 100644 _code/arrays/maxSubarray.py create mode 100644 _code/arrays/maximumSubArray.py create mode 100644 _code/arrays/missingNum.py create mode 100644 _code/arrays/pascal_triangle.py create mode 100644 _code/arrays/plusOne.py create mode 100644 _code/arrays/prisonCellsAfterNDays.py/prisonCellsAfterNDays.py create mode 100644 _code/arrays/rotateArray.py create mode 100644 _code/arrays/searchInRotatedArray.py create mode 100644 _code/arrays/squareSortedArrays.py create mode 100644 _code/arrays/threeSum.py create mode 100644 _code/arrays/twoCityScheduling.py create mode 100644 _code/arrays/twoSum.py create mode 100644 _code/arrays/twoSumOnePass.py create mode 100644 _code/arrays/waterWithMostArea.py create mode 100644 _code/backtracking/backtrack.py create mode 100644 _code/backtracking/combination_sum.py create mode 100644 _code/backtracking/generateParenthesis.py create mode 100644 _code/backtracking/permutation.py create mode 100644 _code/backtracking/subsets.py create mode 100644 _code/bfs/bfs.py create mode 100644 _code/binary search/arrangecoins.py create mode 100644 _code/binary search/binarySearch.py create mode 100644 _code/binary search/binarySearch2.py create mode 100644 _code/binary search/searchInsertPosition.py create mode 100644 _code/binary search/searchMatrix.py create mode 100644 _code/bit manipulation/addBinaryStrings.py create mode 100644 _code/bit manipulation/binaryToInt.py create mode 100644 _code/bit manipulation/countOnesInArray.py create mode 100644 _code/bit manipulation/hammingDistance.py create mode 100644 _code/bit manipulation/hammingWeight.py create mode 100644 _code/bit manipulation/missingNumXor.py create mode 100644 _code/bit manipulation/reverseBits.py create mode 100644 _code/bit manipulation/singleNumber3.py create mode 100644 _code/bit manipulation/singleNumberii.py create mode 100644 _code/dfs/binaryTreeZigZagDFS.py create mode 100644 _code/dynamic programming/coinChange1.py create mode 100644 _code/dynamic programming/coinChange2.py create mode 100644 _code/dynamic programming/houseRobber.py create mode 100644 _code/dynamic programming/houseRobber2.py create mode 100644 _code/dynamic programming/longestCommonSubsequence.py create mode 100644 _code/dynamic programming/perfectSquares/notes create mode 100644 _code/dynamic programming/perfectSquares/perfectSquares.py create mode 100644 _code/graphs/cheapestFlight/cheapestFlightsWithinKStops.py create mode 100644 _code/graphs/cheapestFlight/cheapestFlightsWithinKStopsDijkstra.py create mode 100644 _code/graphs/cheapestFlight/cheapestFlightsWithinKStopsDijkstra2.py create mode 100644 _code/graphs/grokking-algo-book/grokking-algo-book-bfs.py create mode 100644 _code/graphs/grokking-algo-book/grokking-algo-book-dijkstra.py create mode 100644 _code/graphs/network-delay/network-delay-dijkstra.py create mode 100644 _code/graphs/reconstructIternatry/reconstructIternary.py create mode 100644 _code/graphs/reconstructIternatry/reconstructIternaryDfs.py create mode 100644 _code/greedy/jumpGame.py create mode 100644 _code/greedy/queueReconstructionByHeight.py create mode 100644 _code/hashing/isomorphicStrings.py create mode 100644 _code/hashing/longestWord.py create mode 100644 _code/heap/heaptest.py create mode 100644 _code/heap/lastStoneWeight.py create mode 100644 _code/heap/topKfrequentElements.py create mode 100644 _code/implementation/lruCache.py create mode 100644 _code/implementation/minStack.py create mode 100644 _code/interval/mergeInterval.py create mode 100644 _code/interviews/hackerrank.py create mode 100644 _code/interviews/ikm_assessment_python3.py create mode 100644 _code/interviews/interview.io_prepared_questions/reorderlist.py create mode 100644 _code/interviews/missingAndDuplicate.py create mode 100644 _code/interviews/pramp/helper.py create mode 100644 _code/interviews/pramp/minAddToMakeParenthesisValid.py create mode 100644 _code/interviews/pramp/prodOfArray.py create mode 100644 _code/interviews/regexTest.py create mode 100644 _code/interviews/softmaxdata.py create mode 100644 _code/interviews/test.py create mode 100644 _code/linked_list/linkedListcycle.py create mode 100644 _code/linked_list/linkedListcyclefloydd.py create mode 100644 _code/linked_list/mergeSortedLinkedList.py create mode 100644 _code/linked_list/mergeSortedLists.py create mode 100644 _code/linked_list/mergeSortedListsRecursive.py create mode 100644 _code/linked_list/palindromelinkedlist.py create mode 100644 _code/linked_list/reverse/reverseLinkedList.py create mode 100644 _code/linked_list/reverse/reverseLinkedListRecursive.py create mode 100644 _code/linked_list/reverse/reverseSublist.py create mode 100644 _code/math/countNumbersWithUniqueDigits.py create mode 100644 _code/math/int_to_string.py create mode 100644 _code/math/plusOne.py create mode 100644 _code/math/reveseInteger.py create mode 100644 _code/math/string_to_int.py create mode 100644 _code/math/uglyNum2.py create mode 100644 _code/matrix/matrix_transversal.py create mode 100644 _code/matrix/rotateMatrix/rotateMatrix.py create mode 100644 _code/matrix/rotateMatrix/rotateMatrix2.py create mode 100644 _code/matrix/searchMatrix.py create mode 100644 _code/matrix/setMatrixZero/setMatrixZeroRecordRowCol.py create mode 100644 _code/matrix/setMatrixZero/setMatrixZeroWrong.py create mode 100644 _code/matrix/spiralMatrix.py create mode 100644 _code/matrix/spiralOrder.py create mode 100644 _code/matrix/sudoku.py create mode 100644 _code/matrix/transposeMatrix.py create mode 100644 _code/matrix/validateSudoku/validateSudokuLeetcode.py create mode 100644 _code/matrix/validateSudoku/validateSudokuLeetcode2.py create mode 100644 _code/matrix/validateSudoku/validateSudokuLeetcode3.py create mode 100644 _code/matrix/wordSearch/wordSearch.py create mode 100644 _code/matrix/wordSearch/wordSearchSingle2.py create mode 100644 _code/sliding_window/find_all_anagrams_in_a_string.py create mode 100644 _code/sliding_window/sliding_window_template.py create mode 100644 _code/sliding_window/subarray_length_k_largest_sum.py create mode 100644 _code/stack/valid_parenthesis.py create mode 100644 _code/stack/valid_parenthesis2.py create mode 100644 _code/stack/valid_parenthesis3.py create mode 100644 _code/strings/firstNonRepeating.py create mode 100644 _code/strings/isSubsequence.py create mode 100644 _code/strings/longestPalindromicSubstring.py create mode 100644 _code/strings/longestSubstringWithoutRepeatingChars.py create mode 100644 _code/strings/reverseString.py create mode 100644 _code/strings/reverseVowels.py create mode 100644 _code/strings/toLower.py create mode 100644 _code/strings/validate_anagram.py create mode 100644 _code/topological_sort/toposort.py create mode 100644 _code/trees/balance tree/balancedTree.py create mode 100644 _code/trees/balance tree/isTreeBalanced.py create mode 100644 _code/trees/createTreeFromArray.py create mode 100644 _code/trees/deepestLeavesSum/deepestLeaveSum.py create mode 100644 _code/trees/deepestLeavesSum/deepestLeavesSumBFS.py create mode 100644 _code/trees/deepestLeavesSum/deepestLeavesSumDFS.py create mode 100644 _code/trees/deepestLeavesSum/deepestLeavesSumMay12.py create mode 100644 _code/trees/deepestNode.py create mode 100644 _code/trees/deserializeTree.py create mode 100644 _code/trees/invertTree/invertTree.py create mode 100644 _code/trees/isSameTree/isSameTree.py create mode 100644 _code/trees/isSameTree/sameTree.py create mode 100644 _code/trees/isSubTree.py create mode 100644 _code/trees/k_distance_from_root.py create mode 100644 _code/trees/lca/lcaBinaryTree.py create mode 100644 _code/trees/levelOrder.py create mode 100644 _code/trees/maxDepth.py create mode 100644 _code/trees/maxWidthOfTree/maxWidthOfTreeBFS.py create mode 100644 _code/trees/serializeTree.py create mode 100644 _code/trees/serializeTree2.py create mode 100644 _code/trees/sumEvenGrandparents.py create mode 100644 _code/trees/sumRootToLeafNumbers.py create mode 100644 _code/trees/symmetry/symmetricTree.py create mode 100644 _code/trees/symmetry/symmetricTree2.py create mode 100644 _code/trees/symmetry/symmetricTreeMay12.py create mode 100644 _code/trees/symmetry/symmetricTreeTemplate.py create mode 100644 _code/trees/validateBST/validateBST_recurseWithLimits.py create mode 100644 _code/trees/validateBST/validateBST_trivialButWrong.py create mode 100644 _code/tries/trie.py create mode 100644 _code/union find/floodfill.py create mode 100644 _code/union find/numIslands/numIslands.py create mode 100644 _code/union find/numIslands/numIslands2.py create mode 100644 _code/union find/numIslands/numIslands3.py create mode 100644 _code/union find/numIslands/numIslands4.py create mode 100644 _code/union find/rottingOranges.py create mode 100644 _code/union find/surroundedRegion.py create mode 100644 _config.yml create mode 100644 _includes/analytics.html create mode 100644 _layouts/default.html create mode 100644 _problems/1template.md create mode 100644 _problems/addStrings.md create mode 100644 _problems/allPathsFromSourceToTarget.md create mode 100644 _problems/arrangeCoins.md create mode 100644 _problems/bfs.md create mode 100644 _problems/binarySearch.md create mode 100644 _problems/binaryTreeLevelOrder.md create mode 100644 _problems/binaryTreeLevelOrder2.md create mode 100644 _problems/binaryTreeZigZag.md create mode 100644 _problems/binaryTreeZigZagDfs.md create mode 100644 _problems/buyAndSellStock.md create mode 100644 _problems/buyAndSellStock2.md create mode 100644 _problems/cheapestFlight.md create mode 100644 _problems/climbingStairs.md create mode 100644 _problems/coinChange.md create mode 100644 _problems/coinChange2.md create mode 100644 _problems/combinationSum2.md create mode 100644 _problems/combinationSum3.md create mode 100644 _problems/combination_sum.md create mode 100644 _problems/containsDuplicates.md create mode 100644 _problems/convertSortedArrayToBST.md create mode 100644 _problems/copyListWithRandomPointer.md create mode 100644 _problems/countCompleteBinaryNodes.md create mode 100644 _problems/countOnesInArray.md create mode 100644 _problems/cousinsInBinaryTree.md create mode 100644 _problems/deepestLeavesSumBFS.md create mode 100644 _problems/deepestLeavesSumDFS.md create mode 100644 _problems/findAllAnagramsInString.md create mode 100644 _problems/findAllDupsInArray.md create mode 100644 _problems/findMinInSortedArray.md create mode 100644 _problems/findPeakElement.md create mode 100644 _problems/findTheDuplicateNumber.md create mode 100644 _problems/firstBadVersion.md create mode 100644 _problems/firstNonRepeatingChar.md create mode 100644 _problems/flattenMultilevelDoublyLinkedList.md create mode 100644 _problems/floodfill.md create mode 100644 _problems/generateParanthesis.md create mode 100644 _problems/groupAnagrams.md create mode 100644 _problems/groupIsomorphicStrings.md create mode 100644 _problems/guessNumberHigherOrLower.md create mode 100644 _problems/houseRobber.md create mode 100644 _problems/houseRobber2.md create mode 100644 _problems/implementATrie.md create mode 100644 _problems/implement_strstr.md create mode 100644 _problems/increasingTripletSubsequence.md create mode 100644 _problems/insertDeleteGetRandom.md create mode 100644 _problems/insertInterval.md create mode 100644 _problems/insertIntoBST.md create mode 100644 _problems/intersectionOfLinkedList.md create mode 100644 _problems/intersectionOfTwoArrays2.md create mode 100644 _problems/invertTree.md create mode 100644 _problems/isSameTree.md create mode 100644 _problems/isSubSequence.md create mode 100644 _problems/isSubtree.md create mode 100644 _problems/isSymmetricTree.md create mode 100644 _problems/isTreeBalanced.md create mode 100644 _problems/islandPerimeter.md create mode 100644 _problems/isomorphicStrings.md create mode 100644 _problems/jumpGame.md create mode 100644 _problems/koko_eating_bananas.md create mode 100644 _problems/kthlargestElementInAStream.md create mode 100644 _problems/kthlargestElementInAnArray.md create mode 100644 _problems/lastStoneWeight.md create mode 100644 _problems/lcaBinaryTree.md create mode 100644 _problems/llcycle.md create mode 100644 _problems/llcycle2.md create mode 100644 _problems/longestCommonPrefix.md create mode 100644 _problems/longestCommonSubsequence.md create mode 100644 _problems/longestPalindromicSubstring.md create mode 100644 _problems/longestSubstringWithoutRepeatingChars.md create mode 100644 _problems/longestUnivaluePath.md create mode 100644 _problems/majorityElement.md create mode 100644 _problems/majorityElement2.md create mode 100644 _problems/matrixSearch.md create mode 100644 _problems/maxAreaOfIsland.md create mode 100644 _problems/maxDepth.md create mode 100644 _problems/maxDepthOfNaryTree.md create mode 100644 _problems/maxProductSubarray.md create mode 100644 _problems/maxSubarray.md create mode 100644 _problems/maxWidthOfBinaryTree.md create mode 100644 _problems/maxXorOfTwoNums.md create mode 100644 _problems/mergeIntervals.md create mode 100644 _problems/mergeKSortedLinkedLists.md create mode 100644 _problems/mergeSortedArray.md create mode 100644 _problems/mergeSortedLLiter.md create mode 100644 _problems/mergeSortedLLrecur.md create mode 100644 _problems/mergeTwoBinaryTrees.md create mode 100644 _problems/minStack.md create mode 100644 _problems/minimumAddToMakeValidParenthesis.md create mode 100644 _problems/minimumCostForTickets.md create mode 100644 _problems/missingNumber.md create mode 100644 _problems/mostCommonWord.md create mode 100644 _problems/moveZeros.md create mode 100644 _problems/networkDelayTime.md create mode 100644 _problems/nthdigit.md create mode 100644 _problems/numIslands.md create mode 100644 _problems/numOnes.md create mode 100644 _problems/number_compliment.md create mode 100644 _problems/oddEvenLinkedList.md create mode 100644 _problems/palindromicLinkList.md create mode 100644 _problems/pathSum.md create mode 100644 _problems/pathSum2.md create mode 100644 _problems/pathSum3.md create mode 100644 _problems/perfectSquaresa.md create mode 100644 _problems/permutations.md create mode 100644 _problems/permutations2.md create mode 100644 _problems/permutationsCascading.md create mode 100644 _problems/plusOne.md create mode 100644 _problems/powerOfFour.md create mode 100644 _problems/powx-n.md create mode 100644 _problems/printKdistanceFromRoot.md create mode 100644 _problems/prisonCellsAfterNDays.md create mode 100644 _problems/productOfArrayExceptSelf.md create mode 100644 _problems/queueReconstructionByHeight.md create mode 100644 _problems/ransomNote.md create mode 100644 _problems/reconstructIternary.md create mode 100644 _problems/removeDupFromSortedArray.md create mode 100644 _problems/removeLinkedListElements.md create mode 100644 _problems/removeNthNodeFromEndOfList.md create mode 100644 _problems/reorder_list.md create mode 100644 _problems/restoreIpAddresses.md create mode 100644 _problems/reverseBits.md create mode 100644 _problems/reverseInteger.md create mode 100644 _problems/reverseLLiterative.md create mode 100644 _problems/reverseString.md create mode 100644 _problems/reverseVowelsFromAString.md create mode 100644 _problems/reverseWordsInAString3.md create mode 100644 _problems/rotateArray.md create mode 100644 _problems/rotateImage.md create mode 100644 _problems/rotateMatrix.md create mode 100644 _problems/rottonOranges.md create mode 100644 _problems/searchForARange.md create mode 100644 _problems/searchInRotatedSortedArray.md create mode 100644 _problems/searchInsertPosition.md create mode 100644 _problems/searchRotatedArray.md create mode 100644 _problems/serializeTree.md create mode 100644 _problems/setMatrixZeros.md create mode 100644 _problems/shortestPathCells.md create mode 100644 _problems/singleNumber.md create mode 100644 _problems/singleNumber3.md create mode 100644 _problems/singleNumberii.md create mode 100644 _problems/sortColors.md create mode 100644 _problems/spiralMatrix.md create mode 100644 _problems/sql_1template.md create mode 100644 _problems/sql_binary_tree_nodes.md create mode 100644 _problems/sql_combine2tables.md create mode 100644 _problems/sql_customers_who_never_order.md create mode 100644 _problems/sql_delete_duplicate_emails.md create mode 100644 _problems/sql_department_highest_salary.md create mode 100644 _problems/sql_dupicate_emails.md create mode 100644 _problems/sql_employees_earning_more_than_managers.md create mode 100644 _problems/sql_facebook_practice.md create mode 100644 _problems/sql_reformat_department.md create mode 100644 _problems/sql_second_highest_salary.md create mode 100644 _problems/sql_thepads.md create mode 100644 _problems/sql_triangles.md create mode 100644 _problems/sqrtx.md create mode 100644 _problems/subsets.md create mode 100644 _problems/subsetsCascading.md create mode 100644 _problems/sumRootToLeaf.md create mode 100644 _problems/surroundedRegion.md create mode 100644 _problems/task_scheduler.md create mode 100644 _problems/threeSum.md create mode 100644 _problems/topFrequentKElements.md create mode 100644 _problems/twoCityScheduling.md create mode 100644 _problems/twoSum.md create mode 100644 _problems/uglyNum2.md create mode 100644 _problems/uniqueBST.md create mode 100644 _problems/uniquePaths.md create mode 100644 _problems/validParenthesis.md create mode 100644 _problems/validateBST.md create mode 100644 _problems/validateSudoku.md create mode 100644 _problems/waterWithMostWater.md create mode 100644 _problems/wordLadder.md create mode 100644 _problems/wordSearch.md create mode 100644 about.markdown create mode 100644 index.md create mode 100644 pages/_behavior_interview/behavior.md create mode 100644 pages/_system_design/concepts.md create mode 100644 pages/_system_design/instagram.md create mode 100644 pages/_system_design/link_shortener.md create mode 100644 pages/_system_design/system_design_notes create mode 100644 pages/bookmarkedSites.md create mode 100644 pages/failureAttempts.md create mode 100644 pages/lists/amazonTop50.md create mode 100644 pages/lists/blind100.md create mode 100644 pages/lists/epi.md create mode 100644 pages/lists/reviewProblems.md create mode 100644 pages/lists/solved.md create mode 100644 pages/lists/solvedLastModified.md create mode 100644 pages/practiceJournal.md create mode 100644 site-management/fileutils.py create mode 100644 site-management/generateSolvedModified.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e650806 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +_site +.sass-cache +.jekyll-cache +.jekyll-metadata +vendor + +__pycache__ +*.pyc + +.idea diff --git a/404.html b/404.html new file mode 100644 index 0000000..086a5c9 --- /dev/null +++ b/404.html @@ -0,0 +1,25 @@ +--- +permalink: /404.html +layout: default +--- + + + +
+

404

+ +

Page not found :(

+

The requested page could not be found.

+
diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..582d05a --- /dev/null +++ b/Gemfile @@ -0,0 +1,33 @@ +source "https://rubygems.org" +# Hello! This is where you manage which Jekyll version is used to run. +# When you want to use a different version, change it below, save the +# file and run `bundle install`. Run Jekyll with `bundle exec`, like so: +# +# bundle exec jekyll serve +# +# This will help ensure the proper Jekyll version is running. +# Happy Jekylling! +gem "jekyll", "~> 4.0.0" +# This is the default theme for new Jekyll sites. You may change this to anything you like. +# gem "minima", "~> 2.5.1" +gem "minima", git: "https://github.com/jekyll/minima" +# If you want to use GitHub Pages, remove the "gem "jekyll"" above and +# uncomment the line below. To upgrade, run `bundle update github-pages`. +# gem "github-pages", group: :jekyll_plugins +# If you have any plugins, put them here! +group :jekyll_plugins do + gem "jekyll-feed", "~> 0.12" +end + +# Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem +# and associated library. +install_if -> { RUBY_PLATFORM =~ %r!mingw|mswin|java! } do + gem "tzinfo", "~> 1.2" + gem "tzinfo-data" +end + +# Performance-booster for watching directories on Windows +gem "wdm", "~> 0.1.1", :install_if => Gem.win_platform? + + +gem "webrick", "~> 1.8" diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..e4b4c16 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,93 @@ +GIT + remote: https://github.com/jekyll/minima + revision: 2863624b903b17f838d6ce8d2f77900fa9d3c864 + specs: + minima (3.0.0.dev) + jekyll (>= 3.5, < 5.0) + jekyll-feed (~> 0.9) + jekyll-seo-tag (~> 2.1) + +GEM + remote: https://rubygems.org/ + specs: + addressable (2.8.4) + public_suffix (>= 2.0.2, < 6.0) + colorator (1.1.0) + concurrent-ruby (1.2.2) + em-websocket (0.5.3) + eventmachine (>= 0.12.9) + http_parser.rb (~> 0) + eventmachine (1.2.7) + ffi (1.15.5) + forwardable-extended (2.6.0) + http_parser.rb (0.8.0) + i18n (1.13.0) + concurrent-ruby (~> 1.0) + jekyll (4.0.1) + addressable (~> 2.4) + colorator (~> 1.0) + em-websocket (~> 0.5) + i18n (>= 0.9.5, < 2) + jekyll-sass-converter (~> 2.0) + jekyll-watch (~> 2.0) + kramdown (~> 2.1) + kramdown-parser-gfm (~> 1.0) + liquid (~> 4.0) + mercenary (~> 0.3.3) + pathutil (~> 0.9) + rouge (~> 3.0) + safe_yaml (~> 1.0) + terminal-table (~> 1.8) + jekyll-feed (0.17.0) + jekyll (>= 3.7, < 5.0) + jekyll-sass-converter (2.2.0) + sassc (> 2.0.1, < 3.0) + jekyll-seo-tag (2.8.0) + jekyll (>= 3.8, < 5.0) + jekyll-watch (2.2.1) + listen (~> 3.0) + kramdown (2.4.0) + rexml + kramdown-parser-gfm (1.1.0) + kramdown (~> 2.0) + liquid (4.0.4) + listen (3.8.0) + rb-fsevent (~> 0.10, >= 0.10.3) + rb-inotify (~> 0.9, >= 0.9.10) + mercenary (0.3.6) + pathutil (0.16.2) + forwardable-extended (~> 2.6) + public_suffix (5.0.1) + rb-fsevent (0.11.2) + rb-inotify (0.10.1) + ffi (~> 1.0) + rexml (3.2.5) + rouge (3.30.0) + safe_yaml (1.0.5) + sassc (2.4.0) + ffi (~> 1.9) + terminal-table (1.8.0) + unicode-display_width (~> 1.1, >= 1.1.1) + thread_safe (0.3.6) + tzinfo (1.2.11) + thread_safe (~> 0.1) + tzinfo-data (1.2023.3) + tzinfo (>= 1.0.0) + unicode-display_width (1.8.0) + wdm (0.1.1) + webrick (1.8.1) + +PLATFORMS + ruby + +DEPENDENCIES + jekyll (~> 4.0.0) + jekyll-feed (~> 0.12) + minima! + tzinfo (~> 1.2) + tzinfo-data + wdm (~> 0.1.1) + webrick (~> 1.8) + +BUNDLED WITH + 2.1.4 diff --git a/_code/arrays/bestTimeToBuyAndSellStock.py b/_code/arrays/bestTimeToBuyAndSellStock.py new file mode 100644 index 0000000..eb118c7 --- /dev/null +++ b/_code/arrays/bestTimeToBuyAndSellStock.py @@ -0,0 +1,21 @@ +import sys + +arr = [7,1,5,3,6,4] +# arr = [7,6,4,3,1] +# arr = [2,4,1] + +def maxProfit(arr): + + if not arr or len(arr)==0: + return 0 + + maxProfit = 0 + for i in range(len(arr)): + for j in range(i+1, len(arr)): + if arr[j]-arr[i]>maxProfit: + maxProfit = arr[j]-arr[i] + + return maxProfit + + +print(maxProfit(arr)) \ No newline at end of file diff --git a/_code/arrays/bestTimeToBuyAndSellStockGlobalMinWrong.py b/_code/arrays/bestTimeToBuyAndSellStockGlobalMinWrong.py new file mode 100644 index 0000000..6f5d16f --- /dev/null +++ b/_code/arrays/bestTimeToBuyAndSellStockGlobalMinWrong.py @@ -0,0 +1,38 @@ +import sys + +arr = [7,1,5,3,6,4] +arr = [7,6,4,3,1] +arr = [2,4,1] + +def maxProfit(arr): + + if not arr or len(arr)==0: + return 0 + + + # find lowest pt + globalMin = sys.maxsize + globalMinIndex = -1 + for i in range(len(arr)): + if arr[i]globalMax: + globalMax=arr[i] + globalMaxIndex=i + + print(globalMinIndex, globalMaxIndex) + + if globalMaxIndex!=-1: # a max was found after global min + return globalMax-globalMin + else: + return 0 + + +print(maxProfit(arr)) \ No newline at end of file diff --git a/_code/arrays/findMinInSortedArray.py b/_code/arrays/findMinInSortedArray.py new file mode 100644 index 0000000..49d35bd --- /dev/null +++ b/_code/arrays/findMinInSortedArray.py @@ -0,0 +1,40 @@ +arr = [4,5,6,7,2,3] + +def findMin(nums): + + # 1-elem array + if len(nums)==1: + return nums[0] + + left = 0 + right = len(nums)-1 + + # this condition means arr is already sorted, so just return first element + if nums[right] > nums[0]: + return nums[0] + + + while right>=left: + + mid = left + (right-left) // 2 + + # min found: case 1 + if nums[mid] > nums[mid+1]: # 3 4 5 1 2 where 5 is mid + return nums[mid+1] + + # min found: case 2 + if nums[mid-1] > nums[mid]: # 4 5 1 2 3 where 1 is mid + return nums[mid] + + + ### min not found cases below + # mid is greater than first elem so ignore left half + if nums[mid] > nums[0]: + left = mid+1 + + # mid is less than first elem, ignore right half + else: + right = mid-1 + + +print(findMin(arr)) diff --git a/_code/arrays/findMinInSortedArray2.py b/_code/arrays/findMinInSortedArray2.py new file mode 100644 index 0000000..57f6b72 --- /dev/null +++ b/_code/arrays/findMinInSortedArray2.py @@ -0,0 +1,14 @@ +arr = [4,5,6,7,2,3] + +def findMin(nums): + + l, r = 0, len(nums) - 1 + while nums[l] > nums[r]: + mid = int((l+r)/2) + if nums[mid] >= nums[l]: + l = mid + 1 + else: + r = mid + return nums[l] + +print(findMin(arr)) diff --git a/_code/arrays/increasingTriplet.py b/_code/arrays/increasingTriplet.py new file mode 100644 index 0000000..2083782 --- /dev/null +++ b/_code/arrays/increasingTriplet.py @@ -0,0 +1,24 @@ +nums = [2,5,3,4,5] +nums = [6,5,3,4,0] + +def increasingTriplet(nums): + + first = nums[0] + second = float('inf') + third = float('inf') + + for n in nums: + + if nfirst and nsecond and n List[int]: + + map = {} + for num in nums1: + if num not in map: + map[num] = 1 + else: + map[num] = map[num] + 1 + + + for k,v in map.items(): + print( k, v) + + # iter thru num2, if exist in map, minus it + res = [] + for num in nums2: + if num in map: + res.append(num) + if map[num]>1: + map[num] = map[num]-1 + else: + map.pop(num) + + print(res) + + # set1 = set(nums1) + # set2 = set(nums2) + + # res = set1.intersection(set2) + # return list(res) + + +nums1 = [1,1,2,2] +nums2 = [2,2] +print( Solution().intersect(nums1, nums2) ) \ No newline at end of file diff --git a/_code/arrays/intersectionOfTwoArrays2.py b/_code/arrays/intersectionOfTwoArrays2.py new file mode 100644 index 0000000..be70db9 --- /dev/null +++ b/_code/arrays/intersectionOfTwoArrays2.py @@ -0,0 +1,33 @@ +nums1 = [1,2,2,1] +nums2 = [2,2] + + +def intersect(nums1, nums2): + + nums1.sort() + nums2.sort() + + i=0 + j=0 + + #1,1,2,2 + #2,2 + + ans = [] + + # logic is similar to merging + while( i <= len(nums1)-1 and j <= len(nums2)-1 ): + + if nums1[i]==nums2[j]: + ans.append(nums1[i]) + i+=1 + j+=1 + elif nums1[i] < nums2[j]: + i+=1 + else: + j+=1 + + return ans + + +print( intersect(nums1, nums2) ) \ No newline at end of file diff --git a/_code/arrays/longestCommonPrefix.py b/_code/arrays/longestCommonPrefix.py new file mode 100644 index 0000000..00c9d6b --- /dev/null +++ b/_code/arrays/longestCommonPrefix.py @@ -0,0 +1,37 @@ +strs = ["flower","flow","flight"] +strs = ["c","acc","ccc"] + + +''' +''' +def lcp(strs): + + prefix = strs[0] + + for i in range(1, len(strs)): + + # if substring is found, it will return the first index + # if that element isn't the first char, then chop off + while strs[i].find(prefix) != 0: + + # keep chopping off the last character + prefix = prefix[0: len(prefix)-1] + if not prefix: return "" + + return prefix + + # for s in strs: + + # # compare s to longest + # for i in range(len(s)): + # print(s[i], longest[i]) + # if s[i]==longest[i]: + # continue + # else: + # longest = longest[:i] # cut off longest to length of common characters of s + + # print("longest: ", flower) + + # return prefix + +print( lcp(strs) ) \ No newline at end of file diff --git a/_code/arrays/maxProductSubarray.py b/_code/arrays/maxProductSubarray.py new file mode 100644 index 0000000..6608270 --- /dev/null +++ b/_code/arrays/maxProductSubarray.py @@ -0,0 +1,55 @@ +arr1 = [2, 3, -2,4] +arr2 = [2, 3, 6] +arr3 = [2, -3, 6] + +def getMaxProductSubarray(nums): + if not nums: return + left, right, record = 0, 0, -float('inf') + for i in range(len(nums)): + left = (left or 1) * nums[i] + right = (right or 1) * nums[-i-1] + record = max(record, left, right) + return record + +def getMaxProductSubarray(arr): + + minCurrent = 1 + maxCurrent = 1 + maxRes = -99999 + + for i in range(len(arr)): + + current = arr[i] + + print(i, current, minCurrent, maxCurrent) + + if current>0: + maxCurrent = maxCurrent * current + minCurrent = min( minCurrent * current, 1) + elif current==0: + maxCurrent=1 + minCurrent=1 + else: + x = maxCurrent + maxCurrent = max( minCurrent * current, 1) + minCurrent = x * current + + print(i, current, minCurrent, maxCurrent) + + if maxRes maxSum: + maxSum = sum + + print 'max sum is ' + str(maxSum) + + + + +if __name__ == "__main__": + main() diff --git a/_code/arrays/missingNum.py b/_code/arrays/missingNum.py new file mode 100644 index 0000000..8e69eff --- /dev/null +++ b/_code/arrays/missingNum.py @@ -0,0 +1,18 @@ +nums = [3,0,1] + +n = len(nums) + +# sum total if number wasn't missing +total = 0 +for i in range(0, n+1): + total = total + i + + +# sum actual numbers in array +arr_total = 0 +for i in range(0, n): + arr_total = arr_total + nums[i] + +print(total) +print(arr_total) +print(total-arr_total) diff --git a/_code/arrays/pascal_triangle.py b/_code/arrays/pascal_triangle.py new file mode 100644 index 0000000..473034c --- /dev/null +++ b/_code/arrays/pascal_triangle.py @@ -0,0 +1,53 @@ +''' + + https://leetcode.com/problems/pascals-triangle/ + +''' + + + +def main(): + + def generate(numRows): + + triangle = [] + + if numRows==0: + return [] + + # add first row + triangle.append([1]) + + # add other rows + for i in range(1, numRows): + + curr_row = i + + # append placeholders to each row + row = [] + for i in range(0, curr_row+1): + + if i==0: + row.append(1) + elif i==curr_row: + row.append(1) + else: + # print triangle[curr_row-1][i] + # print triangle[curr_row-1][i-1] + + # row.append(None) + row.append( triangle[curr_row-1][i] + triangle[curr_row-1][i-1] ) + + triangle.append(row) + + + return triangle + + + print generate(5) + + + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/_code/arrays/plusOne.py b/_code/arrays/plusOne.py new file mode 100644 index 0000000..0ccb636 --- /dev/null +++ b/_code/arrays/plusOne.py @@ -0,0 +1,29 @@ +digits = [9] + +def plusOne(digits): + + ptr = len(digits)-1 + carry = 1 # just set carry=1 to do get into the loop + + while carry==1: + + # edge case when carry=1 and ptr goes left off the edge (ie: '9') + if ptr<0: + digits.insert(0, 1) + return digits + + # normal case: just add one to last digit + if digits[ptr]>=0 and digits[ptr]<9: + digits[ptr] = digits[ptr]+1 + carry=0 + return digits + + # edge case, set carry and move left + elif digits[ptr]==9: + digits[ptr] = 0 + carry = 1 + ptr-=1 + + return digits + +print( plusOne(digits) ) \ No newline at end of file diff --git a/_code/arrays/prisonCellsAfterNDays.py/prisonCellsAfterNDays.py b/_code/arrays/prisonCellsAfterNDays.py/prisonCellsAfterNDays.py new file mode 100644 index 0000000..6f7c1bd --- /dev/null +++ b/_code/arrays/prisonCellsAfterNDays.py/prisonCellsAfterNDays.py @@ -0,0 +1,36 @@ +arr = [0,1,0,1,1,0,0,1] +N=1000000000 +# N=7 + +def prisonAfterNDays(arr, N): + + def computeNext(arr): + + arr2 = [0]*len(arr) + + for i in range(1, len(arr)-1): + + # not xor the middle + arr2[i] = int(not arr[i-1] ^ arr[i+1]) + + # make ends zero + arr2[0], arr2[len(arr)-1] = 0,0 + + # copy arr2 to arr + return arr2.copy() + + + + seen = {str(arr): N} + while N: + seen.setdefault(str(arr), N) + N -= 1 + # arr = [0] + [arr[i - 1] ^ arr[i + 1] ^ 1 for i in range(1, 7)] + [0] + arr = computeNext(arr) + if str(arr) in seen: + N %= seen[str(arr)] - N + + return arr + + +print( prisonAfterNDays(arr, N) ) \ No newline at end of file diff --git a/_code/arrays/rotateArray.py b/_code/arrays/rotateArray.py new file mode 100644 index 0000000..54b146c --- /dev/null +++ b/_code/arrays/rotateArray.py @@ -0,0 +1,26 @@ +arr = [1,2,3,4,5,6,7] +arr = [-1] +arr = [1,2] + +def rotate(nums, k): + + if not nums: return + if len(nums) == 1: return + + def reverse(nums, start, end): + + while start < end: + tmp = nums[start] + nums[start] = nums[end] + nums[end] = tmp + + start += 1 + end -= 1 + + reverse(nums, 0, len(nums) - 1) + reverse(nums, 0, k - 1) + reverse(nums, k, len(nums) - 1) + +rotate(arr, 3) + +print(arr) \ No newline at end of file diff --git a/_code/arrays/searchInRotatedArray.py b/_code/arrays/searchInRotatedArray.py new file mode 100644 index 0000000..d4589ba --- /dev/null +++ b/_code/arrays/searchInRotatedArray.py @@ -0,0 +1,19 @@ +nums = [4,5,6,7,2,3] +target = 1 + +def search(nums, target): + + left = 0 + right = len(nums)-1 + + # this loop gets left to the smallest element + while left nums[right]: + left = mid+1 + else: + right = mid + + +print( search(nums, target) ) \ No newline at end of file diff --git a/_code/arrays/squareSortedArrays.py b/_code/arrays/squareSortedArrays.py new file mode 100644 index 0000000..3728e2d --- /dev/null +++ b/_code/arrays/squareSortedArrays.py @@ -0,0 +1,36 @@ + + +def main(): + + arr = [-3,-2,-1,0,1,2,3] + + # move ptrs to middle section, j moves forward, i moves backwards + j = 0 + while arr[j]<0: + j+=1 + + i=j-1 + + + # create new array to store results + ans = [] + while i>=0 and j target: # optimization + return + for i in range(start, len(nums)): + backtrack(currentList + [nums[i]], nums, i) + # currentList.append( nums[i] ) + # backtrack( currentList, nums, start) + + allValidCombos = [] + backtrack([], candidates, 0 ) + return allValidCombos + +print( combinationSum(candidates, target) ) \ No newline at end of file diff --git a/_code/backtracking/generateParenthesis.py b/_code/backtracking/generateParenthesis.py new file mode 100644 index 0000000..d37afdf --- /dev/null +++ b/_code/backtracking/generateParenthesis.py @@ -0,0 +1,25 @@ +n=3 + +def generateParenthesis(n): + + def backtrack(outputList, currentString, open, close, n): + + if len(currentString)==2*n: + outputList.append(currentString) + print("output " + currentString) + return + + print( currentString ) + + if open < n: + backtrack( outputList, currentString+"(", open+1, close, n ) + + if close < open: + backtrack( outputList, currentString+")", open, close+1, n) + + outputList = [] + backtrack( outputList, "", 0, 0, n) + return outputList + + +print( generateParenthesis(n) ) \ No newline at end of file diff --git a/_code/backtracking/permutation.py b/_code/backtracking/permutation.py new file mode 100644 index 0000000..c919628 --- /dev/null +++ b/_code/backtracking/permutation.py @@ -0,0 +1,47 @@ +# nums = [10,20,30] +nums = [1,1,2] + +def permute1(nums): + + def backtrack(currentList, allPermutations, nums): + + if len(currentList)==len(nums): + allPermutations.append(currentList[:]) # or currentList.copy() because Python passes by reference + else: + for i in range(0, len(nums)): + if nums[i] in currentList: + continue + currentList.append(nums[i]) + backtrack( currentList, allPermutations, nums ) + currentList.remove(currentList[-1]) # currentList.pop() also does the same thing + + + allPermutations = [] + backtrack([], allPermutations, nums) + return allPermutations + + +def permute2(nums): + + def backtrack(currentList, allPermutations, nums): + + if len(currentList)==len(nums): + allPermutations.append(currentList.copy()) + else: + for i in range(len(nums)): + + currentList.append(nums[i]) + print(currentList) + + backtrack(currentList, allPermutations, nums) + currentList.pop() + print(currentList) + + + allPermutations = [] + backtrack([], allPermutations, nums) + return allPermutations + +# print(permute1(nums)) +# print() +print(permute2(nums)) \ No newline at end of file diff --git a/_code/backtracking/subsets.py b/_code/backtracking/subsets.py new file mode 100644 index 0000000..63a2b74 --- /dev/null +++ b/_code/backtracking/subsets.py @@ -0,0 +1,130 @@ +nums = [1,2,3] + + +# def subsets(nums): + +# def backtrack(first = 0, curr = []): +# # if the combination is done +# if len(curr) == k: +# output.append(curr[:]) +# for i in range(first, n): +# # add nums[i] into the current combination +# curr.append(nums[i]) +# # use next integers to complete the combination +# backtrack(i + 1, curr) +# # backtrack +# curr.pop() + +# output = [] +# n = len(nums) +# for k in range(n + 1): +# backtrack() +# return output + + +def subsets(nums): + subsets = [] + + def generateSubsets(index, nums, current, subsets): + subsets.append(current[:]) + for i in range(index, len(nums)): + current.append(nums[i]) + generateSubsets(i + 1, nums, current, subsets) + current.remove(current[-1]) + + generateSubsets(0, nums, [], subsets) + return subsets + + +def subsets2(nums): + + def backtrack(startIndex, currentSubset, allSubsets, nums): + + allSubsets.append(currentSubset[:]) + + for i in range(startIndex, len(nums)): + currentSubset.append(nums[i]) + print(currentSubset) + + backtrack( i+1, currentSubset, allSubsets, nums) + + currentSubset.remove( currentSubset[-1] ) + print(currentSubset) + + allSubsets = [] + backtrack( 0, [], allSubsets, nums ) + return allSubsets + + + +def subsets3(nums): + + def backtrack(currentSubset, allSubsets, nums, index): + + allSubsets.append( currentSubset.copy() ) + + for i in range(index, len(nums)): + + currentSubset.append(nums[i]) + print(currentSubset) + + backtrack( currentSubset, allSubsets, nums, i+1 ) + currentSubset.pop() + print(currentSubset) + + + ans = [] + backtrack([], ans, nums, 0) + return ans + + + + +''' + recursion without backtracking from timonthy chang + https://www.youtube.com/watch?v=Mi_C_CMW7vQ +''' +def subsets4(nums): + + output = [] + + def helper(start, currentSubset, output): + # output += [tmp] + output.append(currentSubset) + for i in range(start, len(nums)): + print( (i+1, currentSubset+[nums[i]]) ) + helper( i+1, currentSubset+[nums[i]], output ) + + helper(0, [], output) + + return output + + +def subsets5(nums): + + def helper(start, currentSubset, allSubsets): + + output.append( currentSubset.copy() ) + + for i in range(start, len(nums) ): + + currentSubset.append( nums[i] ) + print(i+1, currentSubset) + helper(i+1, currentSubset, output) + currentSubset.pop() + + output = [] + helper(0, [], output) + return output + + +''' + https://medium.com/leetcode-patterns/leetcode-pattern-3-backtracking-5d9e5a03dc26 +''' + + +# print(subsets2(nums)) +# print() +# print(subsets3(nums)) +print(subsets4(nums)) +print(subsets5(nums)) diff --git a/_code/bfs/bfs.py b/_code/bfs/bfs.py new file mode 100644 index 0000000..f61b19e --- /dev/null +++ b/_code/bfs/bfs.py @@ -0,0 +1,69 @@ +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + + + +def levelOrder(root): + + q = [root] + ans = [] + + + while q: + + level_size = len(q) + level = [] + + for i in range(level_size): + + curr = q.pop(0) + + level.append(curr.val) + + if curr.left: + q.append(curr.left) + if curr.right: + q.append(curr.right) + + if level: + ans.append(level) + + return ans[::-1] + + # q = [root] + # ans = [] + + # while q: + + # level_size = len(q) + # level = [] + + # for _ in range(level_size): + + # curr = q.pop(0) + # level.append(curr.val) + + # if curr.left: + # q.append(curr.left) + # if curr.right: + # q.append(curr.right) + + # ans.append(level) + + # return ans[::-1] + +root = TreeNode(3) +root.left = TreeNode(9) +root.right = TreeNode(20) +# root.left.left = TreeNode(4) +# root.left.right = TreeNode(5) +root.right.left = TreeNode(15) +root.right.right = TreeNode(7) +# root.right.right.right = TreeNode(8) + +print( levelOrder(root) ) \ No newline at end of file diff --git a/_code/binary search/arrangecoins.py b/_code/binary search/arrangecoins.py new file mode 100644 index 0000000..6d2e409 --- /dev/null +++ b/_code/binary search/arrangecoins.py @@ -0,0 +1,21 @@ + +n=5 + +def arrangeCoins(n): + l = 1 + h = n + while l<=h: + mid = l + (h-l)//2 + temp = int(mid*(mid+1)/2) + + print(l, mid, h, temp, [ (x*(x+1)//2) for x in range(l,h)]) + + if temp == n: + return mid + if temp < n: + l = mid + 1 + else: + h = mid - 1 + return h + +print(arrangeCoins(n)) \ No newline at end of file diff --git a/_code/binary search/binarySearch.py b/_code/binary search/binarySearch.py new file mode 100644 index 0000000..4b07fd8 --- /dev/null +++ b/_code/binary search/binarySearch.py @@ -0,0 +1,32 @@ +# arr = [1,2,3,4,5,6,7,8,9,10] +arr = [-1,0,3,5,9,12] + + + +def binSearch(low, high, arr, target): + + while low<=high: + + print(low, high, arr, target) + + mid = int((low+high)/2) + # mid = low+high//2 + + if arr[mid]==target: + return mid + + # if target is greater, ignore left half + elif arr[mid]arr[mid]: + left = mid+1 + else: + right = mid-1 + + return -1 + + +print(binarySearch(0, len(arr)-1, arr, 4)) \ No newline at end of file diff --git a/_code/binary search/searchInsertPosition.py b/_code/binary search/searchInsertPosition.py new file mode 100644 index 0000000..bba38cf --- /dev/null +++ b/_code/binary search/searchInsertPosition.py @@ -0,0 +1,41 @@ +def searchInsert(nums, target): + + left = 0 + right = len(nums)-1 + + while left<=right: + + mid = (left+right)//2 + + if target==nums[mid]: + return mid + + # # left and right beside each other + # elif right-left<=1: + + # # and target is inbetween (ie: [4,6], tar=5) + # if target>=nums[left] and target<=nums[right]: + # return left+1 + + # # target is outside of array (to the right) + # elif target>nums[right]: + # return right+1 + + # # target is outside of array (to the left) + # elif targetnums[mid]: + left = mid+1 + elif target0: + if tmp&1==1: + count+=1 + tmp>>=1 + + +print( count ) \ No newline at end of file diff --git a/_code/bit manipulation/hammingWeight.py b/_code/bit manipulation/hammingWeight.py new file mode 100644 index 0000000..9988c5b --- /dev/null +++ b/_code/bit manipulation/hammingWeight.py @@ -0,0 +1,12 @@ + def hammingWeight(self, n: int) -> int: + + count = 0 + while n>0: + + if n&1==1: + count+=1 + + n>>=1 + + return count + \ No newline at end of file diff --git a/_code/bit manipulation/missingNumXor.py b/_code/bit manipulation/missingNumXor.py new file mode 100644 index 0000000..e0ea7f3 --- /dev/null +++ b/_code/bit manipulation/missingNumXor.py @@ -0,0 +1,13 @@ +nums = [3,0,1] + +n = len(nums) + +# xor index with value +xor = 0 +for i, num in enumerate(nums): + xor ^= i^num + +# xor with length gives you missing num +missing = xor^n + +print(missing) \ No newline at end of file diff --git a/_code/bit manipulation/reverseBits.py b/_code/bit manipulation/reverseBits.py new file mode 100644 index 0000000..85d3eab --- /dev/null +++ b/_code/bit manipulation/reverseBits.py @@ -0,0 +1,26 @@ + + + +def reverseBits(str): + + n = int(str) + + rev = 0 + + # tranverse bits from right to left + while n>0: + + rev = rev << 1 + + # if current bit is 1 + if (n&1==1): + rev = rev ^ 1 + + n = n >> 1 + + return rev + + +print reverseBits("4567") + + diff --git a/_code/bit manipulation/singleNumber3.py b/_code/bit manipulation/singleNumber3.py new file mode 100644 index 0000000..a7f587f --- /dev/null +++ b/_code/bit manipulation/singleNumber3.py @@ -0,0 +1,19 @@ + +nums = [1,2,1,3,2,5] + +def singleNumber(nums): + + xor = 0 + for n in nums: + xor ^= n + + # xor = num1 ^ num2 + firstbit = xor & (xor-1) ^ xor + num1 = 0 + for n in nums: + if n & firstbit: + num1 ^= n + + return [num1, num1^xor] + +print( singleNumber(nums) ) \ No newline at end of file diff --git a/_code/bit manipulation/singleNumberii.py b/_code/bit manipulation/singleNumberii.py new file mode 100644 index 0000000..509ad23 --- /dev/null +++ b/_code/bit manipulation/singleNumberii.py @@ -0,0 +1,26 @@ +nums = [2,2,3,2] + +def singleNumber(nums): + single = 0 + for i in range(32): + count = 0 + for num in nums: + # if num & (1< 4 +12=4+4+4 -> 3 + + + +1 -> 1 (1) +2 -> 2 (1+1) +3 -> 3 (1+1+1) +4 -> 1 (4) +5 -> 2 (4+1) +6 -> 3 (4+1+1) +7 -> 4 4+1+1+1 +8 -> 2 4+4 + + + +f(1) = 1 +f(2) = f(1) + f(1) = 1+1=2 + +f(7) = f(4) + f(3) = 1+3=4 +f(8) = f(4) + f(4) = 1+1=2 +f(12) = f(8) + f(4) = 2+1=3 + +identify subproblems? + +https://leetcode.com/problems/perfect-squares/discuss/696436/Python-Simple-DP-Solution + +n=7 +square_sums = [0,1,4] +dp = [0, inf, inf, inf, inf, inf, inf, inf] + + 0 1 2 3 4 5 6 7 +dp = [0, 1, 2, 3, 1, 2, 3, 4] + +dp = [0, 1, inf, inf, 1, inf, inf, inf] + +i: 1->n +iter all squares +min( dp[i], dp[i-square] ) + + + + +f(1)=1 +f(2)=2 +f(12)= + + + + + +these are the candidates + diff --git a/_code/dynamic programming/perfectSquares/perfectSquares.py b/_code/dynamic programming/perfectSquares/perfectSquares.py new file mode 100644 index 0000000..5c5d7e7 --- /dev/null +++ b/_code/dynamic programming/perfectSquares/perfectSquares.py @@ -0,0 +1,13 @@ +import math + +n = 7 + +def numSquares(n): + + squares = [i**2 for i in range(0, int(math.sqrt(n))+1) ] + dp = [float(inf)] * n + + print(squares) + print(dp) + +print( numSquares(n) ) \ No newline at end of file diff --git a/_code/graphs/cheapestFlight/cheapestFlightsWithinKStops.py b/_code/graphs/cheapestFlight/cheapestFlightsWithinKStops.py new file mode 100644 index 0000000..730baf5 --- /dev/null +++ b/_code/graphs/cheapestFlight/cheapestFlightsWithinKStops.py @@ -0,0 +1,33 @@ +import collections + +n = 3 +edges = [[0,1,100],[1,2,200],[0,2,500]] +src = 0 +dst = 2 +k = 1 + + + +def findCheapestPrice(n, flights, src, dst, K): + + if src == dst: return 0 + + d, seen = collections.defaultdict(list), collections.defaultdict(lambda: float('inf')) + for u, v, p in flights: + d[u] += [(v, p)] + + q = [(src, -1, 0)] + + while q: + pos, k, cost = q.pop(0) + if pos == dst or k == K: continue + for nei, p in d[pos]: + if cost + p >= seen[nei]: + continue + else: + seen[nei] = cost+p + q += [(nei, k+1, cost+p)] + + return seen[dst] if seen[dst] < float('inf') else -1 + +print( findCheapestPrice(n, edges, src, dst, k) ) \ No newline at end of file diff --git a/_code/graphs/cheapestFlight/cheapestFlightsWithinKStopsDijkstra.py b/_code/graphs/cheapestFlight/cheapestFlightsWithinKStopsDijkstra.py new file mode 100644 index 0000000..ec5a46e --- /dev/null +++ b/_code/graphs/cheapestFlight/cheapestFlightsWithinKStopsDijkstra.py @@ -0,0 +1,52 @@ +from collections import deque + +''' +https://www.youtube.com/watch?v=Jbb9qNIAyg0 +''' +import collections + +n = 3 +flights = [[0,1,100],[1,2,200],[0,2,500]] +src = 0 +dest = 2 +k = 1 + + + +def findCheapestPrice(n, flights, src, dest, K): + + # d = collections.defaultdict(list) + # seen = collections.defaultdict(lambda: float('inf')) + + adj = [[] for _ in range(n)] + output = [float('inf') for _ in range(n)] + output[src] = 0 + + # add to adj list where key is src, and value is destination+cost + for u, v, w in flights: + adj[u] += [(v, w)] + + + graph = deque() + graph.append((src, -1)) # where -1 is the number of stops + + while graph: + + u, stop = graph.popleft() + if stop >= K: + continue + + for v, w in adj[u]: + + output[v] = output[u]+w + graph.append((v,stop+1)) + + if output[dest] == float('inf'): + return -1 + else: + return output[dest] + + + + +print( findCheapestPrice(n, flights, src, dest, k) ) \ No newline at end of file diff --git a/_code/graphs/cheapestFlight/cheapestFlightsWithinKStopsDijkstra2.py b/_code/graphs/cheapestFlight/cheapestFlightsWithinKStopsDijkstra2.py new file mode 100644 index 0000000..628ae1c --- /dev/null +++ b/_code/graphs/cheapestFlight/cheapestFlightsWithinKStopsDijkstra2.py @@ -0,0 +1,44 @@ +import heapq +from collections import deque +from collections import defaultdict + +''' +https://www.youtube.com/watch?v=Jbb9qNIAyg0 +''' + + +n = 3 +flights = [[0,1,100],[1,2,200],[0,2,500]] +src = 0 +dest = 2 +k = 1 + + + +def findCheapestPrice(n, flights, src, dest, K): + + output = [float("inf")] * n + output[src] = 0 + + graph = defaultdict(list) + heap = [(src, -1)] # dest, costs + + # add to adj hash table + for u, v, w in flights: + graph[u].append((v,w)) + + while heap: + + v, w = heapq.heappop(heap) + + for v, w in graph[v]: + output[v] = output[u]+w + heapq.heappush(heap, (v, output[u]+w)) + + print( output ) + + + + + +print( findCheapestPrice(n, flights, src, dest, k) ) \ No newline at end of file diff --git a/_code/graphs/grokking-algo-book/grokking-algo-book-bfs.py b/_code/graphs/grokking-algo-book/grokking-algo-book-bfs.py new file mode 100644 index 0000000..875f306 --- /dev/null +++ b/_code/graphs/grokking-algo-book/grokking-algo-book-bfs.py @@ -0,0 +1,25 @@ +from collections import deque + +# graph as adjacency lists (dictionary of lists) +graph = {} +graph["you"] = ["alice", "bob", "claire"] +graph["bob"] = ["anuj", "peggy"] +graph["alice"] = ["peggy"] +graph["claire"] = ["thom", "jonny"] +graph["anuj"] = [] +graph["peggy"] = [] +graph["thom"] = [] +graph["jonny"] = [] + + +print(graph) + + +# create queue +search_queue = deque() +search_queue += graph["you"] + +while search_queue: + + person = search_queue.popleft() + if p \ No newline at end of file diff --git a/_code/graphs/grokking-algo-book/grokking-algo-book-dijkstra.py b/_code/graphs/grokking-algo-book/grokking-algo-book-dijkstra.py new file mode 100644 index 0000000..5c8bd7f --- /dev/null +++ b/_code/graphs/grokking-algo-book/grokking-algo-book-dijkstra.py @@ -0,0 +1,44 @@ + + + +# dijkstra needs 3 hashtables and a list to keep track of processed nodes +graph = {} +costs = {} +parents = {} + +processed = [] + +# graph: a hashtable of more hash tables to store edges and weights +graph["start"] = {} +graph["start"]["a"] = 6 +graph["start"]["b"] = 2 + +graph["a"] = {} +graph["a"]["fin"] = 1 + +graph["b"] = {} +graph["b"]["a"] = 3 +graph["b"]["fin"] = 5 + +graph["fin"] = {} + + + +# costs: a hashtable to store costs of each node +infinity = float("inf") +costs["a"] = 6 +costs["b"] = 2 +costs["fin"] = infinity + + +# parents hashtable +parents["a"] = "start" +parents["b"] = "start" +parents["fin"] = None + + + + +print( graph ) +print( costs ) +print( parents ) diff --git a/_code/graphs/network-delay/network-delay-dijkstra.py b/_code/graphs/network-delay/network-delay-dijkstra.py new file mode 100644 index 0000000..6324f56 --- /dev/null +++ b/_code/graphs/network-delay/network-delay-dijkstra.py @@ -0,0 +1,37 @@ +import heapq +from collections import deque +from collections import defaultdict + +times = [[2,1,1],[2,3,1],[3,4,1]] +N = 4 +K = 2 + +def networkDelayTime(times, N, K): + + elapsedTime = [0] + [float("inf")] * N + graph = defaultdict(list) + heap = [(0, K)] + + # add to adj hash table, where group + for u, v, w in times: + graph[u].append((v, w)) + + + while heap: + + # pop off heap/queue + time, node = heapq.heappop(heap) + if time < elapsedTime[node]: + + # process (add to elapsed time array) + elapsedTime[node] = time + + # add neighbours, include weight + for v, w in graph[node]: + heapq.heappush(heap, (time + w, v)) + + + mx = max(elapsedTime) + return mx if mx < float("inf") else -1 + +print( networkDelayTime(times, N, K) ) \ No newline at end of file diff --git a/_code/graphs/reconstructIternatry/reconstructIternary.py b/_code/graphs/reconstructIternatry/reconstructIternary.py new file mode 100644 index 0000000..e1096c0 --- /dev/null +++ b/_code/graphs/reconstructIternatry/reconstructIternary.py @@ -0,0 +1,23 @@ +# tickets = [["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]] +tickets = [["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]] + +def findTicketIndForStartCity(startCity): + + for ticketInd, cities in enumerate(tickets): + if cities[0]==startCity: + return ticketInd + + + + +tickets.sort(key=lambda x: x[1]) + + +output = ['JFK'] +for i in range(0, len(tickets)): + + currTicketIndex = findTicketIndForStartCity( output[-1] ) + nextCity = tickets[currTicketIndex][1] + output.append(nextCity) + +print(output) \ No newline at end of file diff --git a/_code/graphs/reconstructIternatry/reconstructIternaryDfs.py b/_code/graphs/reconstructIternatry/reconstructIternaryDfs.py new file mode 100644 index 0000000..0d20246 --- /dev/null +++ b/_code/graphs/reconstructIternatry/reconstructIternaryDfs.py @@ -0,0 +1,30 @@ +tickets = [["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]] +# tickets = [["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]] + +def findTicketIndForStartCity(startCity): + + graph = {} + + tickets.sort(key=lambda x: x[1]) + + # add all to graph hashmap + for u, v in tickets: + if u in graph: + graph[u].append(v) + else: + graph[u] = [v] + + # put jfk on stack + itinerary, stack = [], [("JFK")] + + while stack: + curr = stack[-1] + + if curr in graph and len(graph[curr]) > 0: + stack.append(graph[curr].pop(0)) + else: + itinerary.append(stack.pop()) + return itinerary[::-1] + + +print( findTicketIndForStartCity(tickets) ) \ No newline at end of file diff --git a/_code/greedy/jumpGame.py b/_code/greedy/jumpGame.py new file mode 100644 index 0000000..8fea76f --- /dev/null +++ b/_code/greedy/jumpGame.py @@ -0,0 +1,15 @@ +arr = [2,3,1,1,4] + +def canJump(nums) -> bool: + + lastGoodPos = len(nums) - 1 + for i in reversed(range(len(nums))): + + print(i, nums[i], lastGoodPos, i + nums[i] >= lastGoodPos) + + if i + nums[i] >= lastGoodPos: + lastGoodPos = i + + return lastGoodPos == 0 + +canJump(arr) \ No newline at end of file diff --git a/_code/greedy/queueReconstructionByHeight.py b/_code/greedy/queueReconstructionByHeight.py new file mode 100644 index 0000000..bb9847f --- /dev/null +++ b/_code/greedy/queueReconstructionByHeight.py @@ -0,0 +1,22 @@ +people = [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]] +# turn to [[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]] + +def reconstructQueue(people): + + print(people) + + # sort ppl by decending height first and k second + people.sort(key=lambda x: (-x[0], x[1])) + + print(people) + + ans = [] + for person, num in people: + + if num >= len(ans): + ans.append([person, num]) + else: + ans.insert(num, [person, num]) + return ans + +print( reconstructQueue(people) ) \ No newline at end of file diff --git a/_code/hashing/isomorphicStrings.py b/_code/hashing/isomorphicStrings.py new file mode 100644 index 0000000..9ae9874 --- /dev/null +++ b/_code/hashing/isomorphicStrings.py @@ -0,0 +1,20 @@ + + +def normalize(word): + + # map[char] -> [mapped integer] + myMap = {} + count=0 + normalized="" + for c in word: + if c not in myMap: + myMap[c] = count + count+=1 + normalized += str(myMap[c]) + else: + normalized += str(myMap[c]) + + return normalized + + +print( normalize("aa") ) diff --git a/_code/hashing/longestWord.py b/_code/hashing/longestWord.py new file mode 100644 index 0000000..bd4eae3 --- /dev/null +++ b/_code/hashing/longestWord.py @@ -0,0 +1,21 @@ +import re + +def LongestWord(sen): + + # code goes here + tokens = sen.split(" ") + + maxWord = "" + maxLength = 0 + for token in tokens: + + token = re.sub('[^a-zA-Z]','', token) + + if len(token) > maxLength: + maxLength = len(token) + maxWord = token + + return maxWord + +# keep this function call here +print(LongestWord(input())) \ No newline at end of file diff --git a/_code/heap/heaptest.py b/_code/heap/heaptest.py new file mode 100644 index 0000000..f1c7492 --- /dev/null +++ b/_code/heap/heaptest.py @@ -0,0 +1,14 @@ +import heapq + +li = [5, 7, 9, 1, 3] + +heapq.heapify(li) + +# printing created heap +print ("The created heap is : ",end="") +print (list(li)) + +heapq.heappush(li,4) + +print ("The modified heap after push is : ",end="") +print (list(li)) \ No newline at end of file diff --git a/_code/heap/lastStoneWeight.py b/_code/heap/lastStoneWeight.py new file mode 100644 index 0000000..64c5ef1 --- /dev/null +++ b/_code/heap/lastStoneWeight.py @@ -0,0 +1,29 @@ +import heapq + +stones = [2,7,4,1,8,1] + +def lastStoneWeight(stones): + + while len(stones)>=2: + + # negate values for max heap + stones = list(map(lambda x: -x if x>0 else x, stones)) + # stones = [-x for x in stones if x>0 else x] + print(stones) + + # get top 2 heaviest stones + heapq.heapify(stones) + print(stones) + heavy1 = heapq.heappop(stones) + heavy2 = heapq.heappop(stones) + + # smash the heaviest stones + diff = abs(heavy1-heavy2) + heapq.heappush(stones, diff) + print(stones) + + print(stones) + return stones[0] + + +print(lastStoneWeight(stones)) \ No newline at end of file diff --git a/_code/heap/topKfrequentElements.py b/_code/heap/topKfrequentElements.py new file mode 100644 index 0000000..e8acf62 --- /dev/null +++ b/_code/heap/topKfrequentElements.py @@ -0,0 +1,66 @@ +''' +https://leetcode.com/problems/top-k-frequent-elements/solution/ +https://hg.python.org/cpython/file/2.7/Lib/heapq.py#l16 +https://www.youtube.com/watch?v=Gj4-8sRi7W0 +''' + +from collections import Counter +import heapq + +nums = [1,1,1,2,2,3] + +def topKFrequent1(nums, k): + + count = Counter(nums) + + return heapq.nlargest(k, count.keys(), key=count.get) + + +def topKFrequent2(nums, k): + + c = Counter(nums) # {1: 3, 2: 2, 3: 1} + + + c = [(-v,k) for k,v in c.items()] # (v,k) [(3, 1), (2, 2), (1, 3)] + # (-v,k) [(-3, 1), (-2, 2), (-1, 3)] + + heapq.heapify(c) + + output = [] + for i in range(k): + item = heapq.heappop(c) + output.append(item[1]) + + return output + + +print(topKFrequent2(nums, 2)) + + +____________ + + +{% highlight python %} + +def topKFrequent(self, nums: List[int], k: int) -> List[int]: + + minHeap=[] + c = Counter(nums) + + for n in c.values(): + + heapq.heappush(minHeap, n) + + if len(minHeap)>k: + heapq.heappop(minHeap) + + + out = [] + for k,v in c.items(): + if v in minHeap: + out.append(k) + + return out + + +{% endhighlight %} diff --git a/_code/implementation/lruCache.py b/_code/implementation/lruCache.py new file mode 100644 index 0000000..c651026 --- /dev/null +++ b/_code/implementation/lruCache.py @@ -0,0 +1,126 @@ + +class DLLNode: + + def __init__(self, key, val): + + self.key = key + self.val = val + self.next = None + self.prev = None + +class LruCache: + + def __init__(self, capacity): + + # hashtable for fast lookup + self.hashmap = {} + self.capacity = capacity + + self.head = None # most recently used item + self.tail = None # least recently used item + + + def get(self, key): + + ## TODO + + return hashmap.get(key) + + ''' + put will need to put elements into + ''' + def put(self, key, val): + + # if capacity is reached, evict last elem + # if len(self.hashmap)==self.capacity: + + # print "capacity reached" + # lastNode = self.tail + # self.tail = lastNode.prev + # lastNode.prev = None + + + + # key exists in hash table + if key in self.hashmap: + + # update node's value + currentNode = self.hashmap[key] + currentNode.val = val + + # if current node is not head + if not currentNode == self.head: + + # remove yourself from list + if currentNode.prev: + currentNode.prev.next = currentNode.next + if currentNode.next: + currentNode.next.prev = currentNode.prev + + # add to beginning of list + currentNode.next = self.head + self.head = currentNode # reassign head node + + # if current node is tail node + if currentNode == self.tail: + self.tail = currentNode.prev + currentNode.prev = None + + + + + # not in hash table + else: + + # put it at the front of the list + newNode = DLLNode(key, val) + + if not self.head: + self.head = newNode + self.tail = newNode + else: + newNode.next = self.head + self.head.prev = newNode + self.head = newNode # reassign head node + + + # add node to hash table + self.hashmap[key] = newNode + + def show(self): + + # print hashmap + print( self.hashmap ) + print ("head: " + str(self.head.val)) + print ("tail: " + str(self.tail.val)) + + # iterate doubly linked list + node = self.head + while node: + print( node.val ) + node = node.next + + print("") + + + + + +cache = LruCache(3) +cache.put(1,10) +cache.put(2,20) +cache.put(3,30) +cache.show() + + +cache.put(2, 200) # move elem to head +cache.show() + +cache.put(1, 100) # move end elem to beginning +cache.show() + +cache.put(1, 1000) # move start elem to beginning (breaks) +cache.show() + +cache.put(4, 40) +cache.show() # test new eviction logic diff --git a/_code/implementation/minStack.py b/_code/implementation/minStack.py new file mode 100644 index 0000000..08c124e --- /dev/null +++ b/_code/implementation/minStack.py @@ -0,0 +1,54 @@ + +class MinStack: + + def __init__(self): + + self.s1 = [] + self.s2 = [] + + + def push(self, num): + + self.s1.append( num ) + + if len(self.s2)==0 or num < self.s2[-1]: + self.s2.append( num ) + else: + self.s2.append( self.s2[-1] ) + + + def pop(self): + + self.s2.pop() + + return self.s1.pop() + + + def show(self): + + print(self.s1) + print(self.s2) + print("Min: ", self.s2[-1] ) + print('') + +def main(): + + minStack = MinStack() + + minStack.push(3) + minStack.show() + + minStack.push(1) + minStack.show() + + minStack.push(2) + minStack.show() + + minStack.pop() + minStack.show() + + minStack.pop() + minStack.show() + +if __name__ == "__main__": + main() diff --git a/_code/interval/mergeInterval.py b/_code/interval/mergeInterval.py new file mode 100644 index 0000000..b17bfbf --- /dev/null +++ b/_code/interval/mergeInterval.py @@ -0,0 +1,40 @@ +''' + LL56: Merge Sorted Intervals +''' + + +# nonSorted = [[2,6],[8,10],[15,18],[1,30]] +# nonSorted.sort(key=lambda x: x[0]) +# print(nonSorted) # [[1, 3], [2, 6], [8, 10], [15, 18]] + + +intervals = [[1,3],[2,6],[8,10],[15,18]] + + +def merge(intervals): + + intervals.sort(key=lambda x: x[0]) + + merged = [] + + # add the first interval to merged[] + merged.append(intervals[0]) + + for interval in intervals: + + print(interval) + + if merged[-1][1] < interval[0]: # no merge, [2,6] compared to [8,10] + + print('no merge') + merged.append(interval) + else: + print('merge', merged[-1][1], interval[1]) + merged[-1][1] = max(merged[-1][1], interval[1] ) # choose the max of "prev" (aka: merged[-1]) or the current interval + + print() + + print(merged) + + +merge(intervals) \ No newline at end of file diff --git a/_code/interviews/hackerrank.py b/_code/interviews/hackerrank.py new file mode 100644 index 0000000..172743e --- /dev/null +++ b/_code/interviews/hackerrank.py @@ -0,0 +1,6 @@ +def foo(n): + for x in range(n): + yield x**3 + +for x in foo(5): + print (x), \ No newline at end of file diff --git a/_code/interviews/ikm_assessment_python3.py b/_code/interviews/ikm_assessment_python3.py new file mode 100644 index 0000000..ef6b0c9 --- /dev/null +++ b/_code/interviews/ikm_assessment_python3.py @@ -0,0 +1,8 @@ +num=[1,2,3,4] +result=[] + + +for x in num: + result.append(x**2) + +print(result) \ No newline at end of file diff --git a/_code/interviews/interview.io_prepared_questions/reorderlist.py b/_code/interviews/interview.io_prepared_questions/reorderlist.py new file mode 100644 index 0000000..ce18009 --- /dev/null +++ b/_code/interviews/interview.io_prepared_questions/reorderlist.py @@ -0,0 +1,66 @@ +# Given a singly linked list L: L0→L1→…→Ln-1→Ln, +# reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→… + +# You may not modify the values in the list's nodes, only nodes itself may be changed. + +# Example 1: + +# Given 1->2->3->4, reorder it to 1->4->2->3. +# Example 2: + +# Given 1->2->3->4->5, reorder it to 1->5->2->4->3. + +from collections import deque + +class LinkedListNode: + + def __init__(self, val): + + self.val = val + self.next = None + + + +def reorderList(head): + + # push all into list + q = deque() + while head: + q.append(head) + head = head.next + + + dummy = LinkedListNode(0) + cur = dummy + even = False + + while q: + + node = q.pop() if even else q.popleft() + node.next = None + + cur.next = node + cur = cur.next + + even ^= True + + return dummy.next + + +# create sample linked list +head = LinkedListNode(1) +head.next = LinkedListNode(2) +head.next.next = LinkedListNode(3) +head.next.next.next = LinkedListNode(4) +head.next.next.next.next = LinkedListNode(5) + +# run the code +head = reorderList(head) + + +while head: + print(head.val, end=" ") + head=head.next + + + diff --git a/_code/interviews/missingAndDuplicate.py b/_code/interviews/missingAndDuplicate.py new file mode 100644 index 0000000..201c69a --- /dev/null +++ b/_code/interviews/missingAndDuplicate.py @@ -0,0 +1,11 @@ +a = [6, 5, 4, 2, 6] + +# 1 . continuous integers randomly sorted +# 2. min, max +# 3. missing -> 3 +# 4. duplicate -> 6 + + +Q: are we given min and max? + +for i \ No newline at end of file diff --git a/_code/interviews/pramp/helper.py b/_code/interviews/pramp/helper.py new file mode 100644 index 0000000..cc917b3 --- /dev/null +++ b/_code/interviews/pramp/helper.py @@ -0,0 +1,7 @@ +def helper(listt): + prod = 1 + for val in listt: + prod = prod*val + return prod + +print(helper([1,2,3])) \ No newline at end of file diff --git a/_code/interviews/pramp/minAddToMakeParenthesisValid.py b/_code/interviews/pramp/minAddToMakeParenthesisValid.py new file mode 100644 index 0000000..3e3d30f --- /dev/null +++ b/_code/interviews/pramp/minAddToMakeParenthesisValid.py @@ -0,0 +1,29 @@ + numInvalid=0 + stack=[] + + for c in text: + if c=='(': + stack.append(c) + numInvalid+=1 + + elif c==')': + if not stack: + numInvalid+=1 + else: + stack.pop() + numInvalid-=1 + + return numInvalid + len(stack) + + +res = 0 +stack = 0 + for bracket in text: + if bracket == '(': + stack += 1 + if bracket == ')' and stack != 0: + stack -= 1 + elif bracket == ')' and stack == 0: + res += 1 + return res + stack + \ No newline at end of file diff --git a/_code/interviews/pramp/prodOfArray.py b/_code/interviews/pramp/prodOfArray.py new file mode 100644 index 0000000..4133cf4 --- /dev/null +++ b/_code/interviews/pramp/prodOfArray.py @@ -0,0 +1,36 @@ +arr = [8,10,2] +# arr = [2,2] + +def array_of_array_products(arr): + #[8, 10, 2] + # i = 0. left = [], right [10,2] + res = [] + def helper(listt): + prod = 1 + for val in listt: + prod = prod*val + return prod + + print(arr) + print(helper(arr)) + +# for i, val in enumerate(arr): +# left = None +# right = None +# if i != 0: +# left = helper(arr[:i]) +# if i != len(arr)-1: +# right = helper(arr[i+1:]) +# if left and right: +# res.append(left*right) +# elif left: +# res.append(left) +# elif right: +# res.append(right) + return res + + + + + +print( array_of_array_products(arr) ) \ No newline at end of file diff --git a/_code/interviews/regexTest.py b/_code/interviews/regexTest.py new file mode 100644 index 0000000..2995f21 --- /dev/null +++ b/_code/interviews/regexTest.py @@ -0,0 +1,3 @@ +import re + +print( re.search("[aeiou]", "test") ) \ No newline at end of file diff --git a/_code/interviews/softmaxdata.py b/_code/interviews/softmaxdata.py new file mode 100644 index 0000000..7d591d3 --- /dev/null +++ b/_code/interviews/softmaxdata.py @@ -0,0 +1,68 @@ +a = [6, 5, 4, 2, 6] + +# 1 . continuous integers randomly sorted +# 2. min, max +# 3. missing -> 3 +# 4. duplicate -> 6 + +# similar to this hard LC question +# https://leetcode.com/problems/first-missing-positive/ + +def detect(l): + pass + +assert detect(a) == (3, 6) + + + +[2,4,5,6,6]=23 +[2,3,4,5,6]=17 +min=2 +max=6 + + + +===== +6:2 +2:1 +5:1 +4:1 +===== + +2,3 + +sum(keys)=17 + + + + + + + +min=2 +max=6 + +max-min=4 + + + +[1,2,4] +[1,2,3] + + +min+...+max + +expect +2+3+4+5+6 +20 + +actual +23 + + +2+3+4+5+6=20 +2+4+5+6+6=23 + +missing = sum(actual) - sum(expected) +duplicate = + diff --git a/_code/interviews/test.py b/_code/interviews/test.py new file mode 100644 index 0000000..c4f0844 --- /dev/null +++ b/_code/interviews/test.py @@ -0,0 +1,51 @@ + +# map and lambda +arr = [1,2,3] +sqrt = map(lambda x: x*x, arr) +print(arr) +print( list(sqrt) ) + + +# list comprehension +# Find all of the numbers from 1-1000 that are divisible by 7 +# results = [num for num in range(1000) if num % 7 == 0] +# print(results) + +# res = [] +# for n in range(1000): +# if n % 7 == 0: +# res.append(n) +# print(res) + + +# new_list = [expression(i) for i in old_list if filter(i)] +new_list = [i**2 for i in range(1,10) if i>5] +print(new_list) + +arr = [1,6,7,5,9] +list2 = [ i/2 for i in arr if i > 3 ] # expression happens first, then the filter on i happens before the expression +print( list2 ) + +# zip + + +print("start fib testing") + +def fib(n): + + res = [ 0 for i in range(n) ] + res[1] = 1 + + i=3 + while i<=n: + + res[i-1] = res[i-2] + res[i-3] + i+=1 + + print(res) + + +fib(3) +fib(4) +fib(10) + diff --git a/_code/linked_list/linkedListcycle.py b/_code/linked_list/linkedListcycle.py new file mode 100644 index 0000000..d9587b1 --- /dev/null +++ b/_code/linked_list/linkedListcycle.py @@ -0,0 +1,54 @@ + + +class LinkedListNode: + + def __init__(self, val): + + self.val = val + self.next = None + + +def hasCycle(head): + + if not head: + return False + + set = {} + + while head: + + if head in set: + return True # cycle detected + else: + set[head] = None # add node to set + + # next node + head = head.next + + # exited loop + return False + + # map = {} + # while head: + + # if head.next and head.next.val not in map: + # map[head.val] = head.next.val + # else: + + # if head.next == None: + # return False + # else: + # return True + + # head = head.next + + # return False + + +head = LinkedListNode(1) +head.next = LinkedListNode(2) +head.next.next = LinkedListNode(3) +# head.next.next.next = head.next + + +print( hasCycle(head) ) \ No newline at end of file diff --git a/_code/linked_list/linkedListcyclefloydd.py b/_code/linked_list/linkedListcyclefloydd.py new file mode 100644 index 0000000..980cd04 --- /dev/null +++ b/_code/linked_list/linkedListcyclefloydd.py @@ -0,0 +1,45 @@ + + +class LinkedListNode: + + def __init__(self, val): + + self.val = val + self.next = None + + +def hasCycle(head): + + if not head: + return False + + slow = head + fast = head.next + + while True: + + # if either pointer is null, reached end of list and return False + if slow is None or fast is None or fast.next is None: + return False + + # cycle detected, exit and return True + if slow is fast: + return True + + # advance pointers + slow=slow.next + fast=fast.next.next + + + + return False + + +head = LinkedListNode(1) +head.next = LinkedListNode(2) +head.next = head +# head.next.next = LinkedListNode(3) +# # head.next.next.next = head.next + + +print( hasCycle(head) ) \ No newline at end of file diff --git a/_code/linked_list/mergeSortedLinkedList.py b/_code/linked_list/mergeSortedLinkedList.py new file mode 100644 index 0000000..ecb9be9 --- /dev/null +++ b/_code/linked_list/mergeSortedLinkedList.py @@ -0,0 +1,38 @@ +class LinkedListNode: + + def __init__(self, val): + + self.val = val + self.next = None + + + +def mergeSortedLinkedList(l1, l2): + + dummy = ListNode(0) + head = dummy + while l1 and l2 : + if l1.val < l2.val : + dummy.next = l1 + l1 = l1.next + else : + dummy.next = l2 + l2 = l2.next + dummy = dummy.next + + if l1 : + dummy.next = l1 + elif l2 : + dummy.next = l2 + return head.next + + +l1 = LinkedListNode(1) +l1.next = LinkedListNode(2) +l1.next.next = LinkedListNode(4) + +l2 = LinkedListNode(1) +l2.next = LinkedListNode(3) +l2.next = LinkedListNode(4) + +mergeSortedLinkedList() \ No newline at end of file diff --git a/_code/linked_list/mergeSortedLists.py b/_code/linked_list/mergeSortedLists.py new file mode 100644 index 0000000..c707173 --- /dev/null +++ b/_code/linked_list/mergeSortedLists.py @@ -0,0 +1,53 @@ +class LinkedListNode: + + def __init__(self, val): + + self.val = val + self.next = None + + +l1 = LinkedListNode(1) +l1.next = LinkedListNode(2) +l1.next.next = LinkedListNode(4) + + +l2 = LinkedListNode(1) +l2.next = LinkedListNode(3) +l2.next.next = LinkedListNode(4) + + + +def mergeSortedLists(l1, l2): + + dummy = LinkedListNode(0) + curr = dummy + + while l1 and l2: + + if l1.val <= l2.val: + curr.next = l1 + curr = l1 + l1 = l1.next + else: + curr.next = l2 + curr = l2 + l2 = l2.next + + while l1: + curr.next = l1 + curr = l1 + l1 = l1.next + + while l2: + curr.next = l2 + curr = l2 + l2 = l2.next + + return dummy.next + +head = mergeSortedLists(l1, l2) + +curr = head +while curr: + print(curr.val) + curr=curr.next diff --git a/_code/linked_list/mergeSortedListsRecursive.py b/_code/linked_list/mergeSortedListsRecursive.py new file mode 100644 index 0000000..21f80ad --- /dev/null +++ b/_code/linked_list/mergeSortedListsRecursive.py @@ -0,0 +1,43 @@ +class LinkedListNode: + + def __init__(self, val): + + self.val = val + self.next = None + + +l1 = LinkedListNode(1) +l1.next = LinkedListNode(2) +l1.next.next = LinkedListNode(4) + + +l2 = LinkedListNode(2) +l2.next = LinkedListNode(3) +l2.next.next = LinkedListNode(4) + + + +def mergeSortedLists(l1, l2): + + if not l1: + return l2 + + if not l2: + return l1 + + if l1.val < l2.val: + l1.next = mergeSortedLists(l1.next, l2) + return l1 + else: + l2.next = mergeSortedLists(l2.next, l1) + return l2 + + + + +head = mergeSortedLists(l1, l2) + +curr = head +while curr: + print(curr.val) + curr=curr.next diff --git a/_code/linked_list/palindromelinkedlist.py b/_code/linked_list/palindromelinkedlist.py new file mode 100644 index 0000000..6c21f0c --- /dev/null +++ b/_code/linked_list/palindromelinkedlist.py @@ -0,0 +1,25 @@ +class LinkedListNode: + + def __init__(self, val): + + self.val = val + self.next = None + + +def palindromeLinkedList(head): + + slow, fast = head, head + + while fast and fast.next: + slow = slow.next + fast = fast.next.next + + print(slow) + print(fast) + +head = LinkedListNode(1) +head.next = LinkedListNode(2) +head.next.next = LinkedListNode(2) +head.next.next.next = LinkedListNode(1) + +palindromeLinkedList(head) \ No newline at end of file diff --git a/_code/linked_list/reverse/reverseLinkedList.py b/_code/linked_list/reverse/reverseLinkedList.py new file mode 100644 index 0000000..cfaf7d7 --- /dev/null +++ b/_code/linked_list/reverse/reverseLinkedList.py @@ -0,0 +1,50 @@ +class LinkedListNode: + + def __init__(self, val): + + self.val = val + self.next = None + + + +def reverse(head): + + curr = head + prev = None + next = None + + while curr: + + # save next node + next = curr.next + + # reverse curr's pointer + curr.next = prev + + # advance curr and prev + prev = curr + curr = next + + head = prev + return head + + +head = LinkedListNode(1) +head.next = LinkedListNode(2) +head.next.next = LinkedListNode(3) + +# print list +node = head +while node: + print(node.val) + node = node.next + + +head = reverse(head) + + +# print list +node = head +while node: + print(node.val) + node = node.next diff --git a/_code/linked_list/reverse/reverseLinkedListRecursive.py b/_code/linked_list/reverse/reverseLinkedListRecursive.py new file mode 100644 index 0000000..41d45fa --- /dev/null +++ b/_code/linked_list/reverse/reverseLinkedListRecursive.py @@ -0,0 +1,35 @@ +class LinkedListNode: + + def __init__(self, val): + + self.val = val + self.next = None + + +def reverse(head): + + if not head: + return + + head.next = reverse(head) + + +head = LinkedListNode(1) +head.next = LinkedListNode(2) +head.next.next = LinkedListNode(3) + +# print list +node = head +while node: + print(node.val) + node = node.next + + +head = reverse(head) + + +# print list +node = head +while node: + print(node.val) + node = node.next \ No newline at end of file diff --git a/_code/linked_list/reverse/reverseSublist.py b/_code/linked_list/reverse/reverseSublist.py new file mode 100644 index 0000000..c604043 --- /dev/null +++ b/_code/linked_list/reverse/reverseSublist.py @@ -0,0 +1,65 @@ +class LinkedListNode: + + def __init__(self, val): + + self.val = val + self.next = None + + + +def reverseBetween(head, m, n): + + prev = None + curr = head + + # move prev and curr up to m + while m>1: + prev = curr + curr = curr.next + m-=1 + n-=1 + + # connect beginning with reversed part + connection = prev + tail = curr + + while n>0: + next = curr.next + curr.next = prev + prev = curr + curr = next + n-=1 + + if connection: + connection.next = prev + else: + head = prev + + tail.next = curr + return head + + + +head = LinkedListNode(1) +head.next = LinkedListNode(2) +head.next.next = LinkedListNode(3) +head.next.next.next = LinkedListNode(4) +head.next.next.next.next = LinkedListNode(5) + +# print list +node = head +while node: + print(node.val) + node = node.next + + +head = reverseBetween(head, 2, 4) + + +# print list + +print("\nresults:") +node = head +while node: + print(node.val) + node = node.next diff --git a/_code/math/countNumbersWithUniqueDigits.py b/_code/math/countNumbersWithUniqueDigits.py new file mode 100644 index 0000000..ff733e7 --- /dev/null +++ b/_code/math/countNumbersWithUniqueDigits.py @@ -0,0 +1,50 @@ +''' + + https://leetcode.com/problems/count-numbers-with-unique-digits/ + +''' + +# from math import * +import math + + +def isUniqueInteger(n): + + mymap = dict() + + while(n>0): + digit=n%10 + #print(digit) + + if not digit in mymap: + mymap[digit] = 1 + else: + return False + + n=n//10 + + #print(mymap) + + return True + + +def countNumbersWithUniqueDigits(n): + + count = 0 + + for i in range(0, pow(10, n)): + if isUniqueInteger(i): + count = count + 1 + + return count + + +def main(): + + # countNumbersWithUniqueDigits(None, 2) + print( countNumbersWithUniqueDigits(2) ) + + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/_code/math/int_to_string.py b/_code/math/int_to_string.py new file mode 100644 index 0000000..b7313e0 --- /dev/null +++ b/_code/math/int_to_string.py @@ -0,0 +1,39 @@ + + +''' + EPI; 6.1 + +''' + + + +def main(): + + # the input + x = -123 + + s = [] + + # deal with negative case + is_neg = False + if x < 0: + is_neg = True + x = abs(x) + + # deal with the happy case + while True: + + s.append( chr( ord('0') + x%10 ) ) # ord() returns unicode of digit, chr() returns char of unicode + x//=10 + + if x==0: + break + + print (s) + + print ('-' + ''.join(reversed(s)) if is_neg else reversed(s)) # reversed() returns an iterator, ''.join() concontenates iterators + # print ('-' if is_neg else '') + ''.join(reversed(s)) + + +if __name__ == "__main__": + main() diff --git a/_code/math/plusOne.py b/_code/math/plusOne.py new file mode 100644 index 0000000..2fc6323 --- /dev/null +++ b/_code/math/plusOne.py @@ -0,0 +1,28 @@ +import math + +# digits = [6,1,4,5,3,9,0,1,9,5,1,8,6,7,0,5,5,4,3] +digits = [7,2,8,5,0,9,1,2,9,5,3,6,6,7,3,2,8,4,3,7,9,5,7,7,4,7,4,9,4,7,0,1,1,1,7,4,0,0,6] + +def plusOne(digits): + num = 0 + exp = 0 + for i in reversed(range(len(digits))): + print(num, math.pow(10, exp), pow(10, exp), 10**exp) + num += math.floor( digits[i] * (10**exp)) + exp+=1 + + + plusOne = int(num+1) + + + res = [] + while plusOne>0: + + pop = plusOne%10 + res = [pop] + res + plusOne = plusOne//10 + + return res + + +print(plusOne(digits)) \ No newline at end of file diff --git a/_code/math/reveseInteger.py b/_code/math/reveseInteger.py new file mode 100644 index 0000000..7a7b36e --- /dev/null +++ b/_code/math/reveseInteger.py @@ -0,0 +1,36 @@ +import math + +num = 1534236469 + +def reverse(num): + + # handle negative case + neg = False + if num<0: + neg = True + num = abs(num) + + rev = 0 + + while num>0: + + # pop last digit + popped = num % 10 + num = math.floor(num / 10) + + # handle overflow + if (rev > 2**31 / 10) or (rev == 2**31 / 10 and popped>7): return 0 + if (rev < -2**31 / 10) or (rev == -2**31 / 10 and popped<-8): return 0 + + rev = rev * 10 + popped + + print(num, popped, rev) + + + return rev*-1 if neg else rev + +print( reverse(num) ) +# print( reverse(123) ) +# print( reverse(-123) ) +# print( reverse(2**31) ) +# print( reverse(-2**31) ) \ No newline at end of file diff --git a/_code/math/string_to_int.py b/_code/math/string_to_int.py new file mode 100644 index 0000000..6c641ec --- /dev/null +++ b/_code/math/string_to_int.py @@ -0,0 +1,18 @@ + + +''' + EPI; 6.1 + +''' + + + +def main(): + + # the input + x = -123 + + + +if __name__ == "__main__": + main() diff --git a/_code/math/uglyNum2.py b/_code/math/uglyNum2.py new file mode 100644 index 0000000..f87db6d --- /dev/null +++ b/_code/math/uglyNum2.py @@ -0,0 +1,25 @@ +n=1690 + +def nthUglyNumber(n): + + uglyNums = [1] + + curr = 2 + while len(uglyNums)=rows: return + else: + mat[i][j]=0 + zeroDownward(i+1,j) + + def zeroLeft(i,j): + + if j<0: return + else: + mat[i][j]=0 + zeroLeft(i,j-1) + + def zeroRight(i,j): + + if j>=cols: return + else: + mat[i][j]=0 + zeroRight(i,j+1) + + # go over mat first time to add cells to set (without modify matrix) + for i in range(0, rows): + for j in range(0, cols): + if mat[i][j]==0: + zeroUpward(i,j) + zeroDownward(i,j) + zeroLeft(i,j) + zeroRight(i,j) + + return mat + +setZeroes(mat) + +print(mat) diff --git a/_code/matrix/spiralMatrix.py b/_code/matrix/spiralMatrix.py new file mode 100644 index 0000000..226b722 --- /dev/null +++ b/_code/matrix/spiralMatrix.py @@ -0,0 +1,63 @@ + +matrix1 = [ + [ 1, 2, 3 ], + [ 4, 5, 6 ], + [ 7, 8, 9 ] +] + +matrix2 = [ + [1, 2, 3, 4], + [4,5,6,7], + [7,8,9,10] +] + +matrix3 = [ + [2,5,8],[4,0,-1] +] + +def spiralMatrix1(matrix): + + if not matrix: return [] + + start_row = 0 + end_row = len(matrix) + start_col = 0 + end_col = len(matrix[0]) + + output = [] + while start_row=R or j<0 or j>=C or board[i][j]!=word[index]: + return False + + tmp = board[i][j] + board[i][j] = ' ' + # found = searchWord(i+1,j,word,index+1) + found = searchWord(i-1,j,word,index+1) or \ + searchWord(i+1,j,word,index+1) or \ + searchWord(i,j-1,word,index+1) or \ + searchWord(i,j+1,word,index + 1) + + board[i][j] = tmp + return found + + for i in range(R): + for j in range(C): + if board[i][j]==word[0] and searchWord(i,j,word,0): + return True + + return False + +print( exist(board, "ABC") ) diff --git a/_code/matrix/wordSearch/wordSearchSingle2.py b/_code/matrix/wordSearch/wordSearchSingle2.py new file mode 100644 index 0000000..dd7f171 --- /dev/null +++ b/_code/matrix/wordSearch/wordSearchSingle2.py @@ -0,0 +1,24 @@ +board = [ + ['A','B','C','E'], + ['S','F','C','S'], + ['A','D','E','E'] +] + +def exist(board, word): + + R = len(board) + C = len(board[0]) + + def exist(i, j, word, index): + + # found word + if index==len(word): + return True + + # boundary checks or next letter is not right (backtrack) + if i<0 or i>=R or j<0 or j>=C or board[i][j]!=word[index]: + return False + + + +print( exist(board, "ABC") ) diff --git a/_code/sliding_window/find_all_anagrams_in_a_string.py b/_code/sliding_window/find_all_anagrams_in_a_string.py new file mode 100644 index 0000000..4dfa5d6 --- /dev/null +++ b/_code/sliding_window/find_all_anagrams_in_a_string.py @@ -0,0 +1,121 @@ +''' +Given two strings s and p, return an array of all the start indices of p's anagrams in s. You may return the answer in any order. + +An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once. + +Input: s = "cbaebabacd", p = "abc" +Output: [0,6] +Explanation: +The substring with start index = 0 is "cba", which is an anagram of "abc". +The substring with start index = 6 is "bac", which is an anagram of "abc". + +''' + +from collections import defaultdict +from typing import List + +# ''' +# using sliding window template +# TLE because nested for loop +# ''' +# def findAnagrams(s: str, p: str) -> List[int]: + +# res = [] +# len_s = len(s) +# len_p = len(p) + +# # build map of p +# resetP = defaultdict(int) +# for char in p: +# resetP[char] += 1 + +# for i in range(len_s - len_p+1): + +# freq = resetP.copy() + +# for j in range(i, i+len_p): + +# if s[j] in freq: +# freq[s[j]] -= 1 + +# if not any(freq.values()): +# res.append(i) + +# return res + + +def findAnagrams(s: str, p: str) -> List[int]: + + + freq = defaultdict(int) + res = [] + + if (len(p) > len(s)): + return res + + # build map of freq in p + for char in p: + freq[char] +=1 + + # start with initial pass (so later pass can include entire slide in/slide out) + for i in range(0, len(p)-1): + if s[i] in freq: + freq[s[i]] -= 1 + + + for i in range(-1, len(s)-len(p)+1): + + # if slide in, subtract + if i+len(p)-1 and s[i] in freq: + freq[s[i]] += 1 + + if not any(freq.values()): + res.append(i+1) # because in this iteration, 'i' will be behind by 1 when the slide in char will be p ahead + + return res + + +# def findAnagrams(s: str, p: str) -> List[int]: +# char_freqs, indices, len_p, len_s = defaultdict(int), [], len(p), len(s) +# +# # s cannot have p anangrams if len(p) > len(s) +# if len_p > len_s: +# return indices +# +# # build map of character frequencies in p +# for char in p: +# char_freqs[char] += 1 +# +# # initial full pass over the window, except last element which we will pass over later +# for i in range(len_p - 1): +# if s[i] in char_freqs: +# char_freqs[s[i]] -= 1 +# +# # slide the window with stride 1, adding the value "sliding out" and subtracting the value "sliding in" +# for i in range(-1, len_s - len_p + 1): +# if i > -1 and s[i] in char_freqs: +# char_freqs[s[i]] += 1 +# if i + len_p < len_s and s[i + len_p] in char_freqs: +# char_freqs[s[i + len_p]] -= 1 +# +# # check whether we encountered an anagram by seeing if all frequencies add up to 0 +# if not any(char_freqs.values()): +# indices.append(i + 1) +# +# return indices + +def main(): + s = "cbaebabacd" + p = "abc" + + res = findAnagrams(s, p) + + print(res) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/_code/sliding_window/sliding_window_template.py b/_code/sliding_window/sliding_window_template.py new file mode 100644 index 0000000..e23eec7 --- /dev/null +++ b/_code/sliding_window/sliding_window_template.py @@ -0,0 +1,43 @@ + +''' + + Find the max sum subarray with size k + [4,2,1,7,8,1,2,8,1,0] k=3 + + 1,7,8 produces 16 + + https://www.youtube.com/watch?v=MK-NZ4hN7rs +''' + + +''' + my solution - may 17, 2023 +''' +def maxSubarray(arr, k): + maxSum = 0 + + for i in range(len(arr) - k + 1): + sum = 0 + + for j in range(i, i + k): + print(arr[j]) + sum = sum + arr[j] + + maxSum = max(sum, maxSum) + + print("sum: " + str(sum)) + print("maxSum: " + str(maxSum)) + + print() + return maxSum + + +def main(): + arr = [4,2,1,7,8,1,2,8,1,0] + k = 3 + + res = maxSubarray(arr, k) + print(res) + +if __name__ == "__main__": + main() diff --git a/_code/sliding_window/subarray_length_k_largest_sum.py b/_code/sliding_window/subarray_length_k_largest_sum.py new file mode 100644 index 0000000..c483901 --- /dev/null +++ b/_code/sliding_window/subarray_length_k_largest_sum.py @@ -0,0 +1,27 @@ +''' +Find Subsequence of Length K With the Largest Sum + +Input: nums = [2,1,3,3], k = 2 +Output: [3,3] +Explanation: +The subsequence has the largest sum of 3 + 3 = 6. +''' + + +class Solution: + def maxSubsequence(self, nums: List[int], k: int) -> List[int]: + + maxSum = 0 + res = [] + + for i in range(len(nums)-k+1): + + sum=0 + for j in range(i, i+k): + sum+=nums[j] + + if sum>maxSum: + maxSum = sum + res = nums[i:j+1] + + return res diff --git a/_code/stack/valid_parenthesis.py b/_code/stack/valid_parenthesis.py new file mode 100644 index 0000000..029dbb7 --- /dev/null +++ b/_code/stack/valid_parenthesis.py @@ -0,0 +1,39 @@ + +def main(): + + str = "([{{}])" + + roundStack = [] + squareStack = [] + curlyStack = [] + + # push all to stack + for i in range(0, len(str)): + + char = str[i] + + if char == "(": + roundStack.append("(") + elif char == "[": + squareStack.append("[") + elif char == "{": + curlyStack.append("{") + + # iterate str backwards + for char in reversed(str): + + if char == ")": + roundStack.pop() + elif char == "]": + squareStack.pop() + elif char == "}": + curlyStack.pop() + + + if not roundStack and not squareStack and not curlyStack: + print 'parenthese are valid' + else: + print 'parenthese are NOT valid' + +if __name__ == "__main__": + main() diff --git a/_code/stack/valid_parenthesis2.py b/_code/stack/valid_parenthesis2.py new file mode 100644 index 0000000..c9f3ae5 --- /dev/null +++ b/_code/stack/valid_parenthesis2.py @@ -0,0 +1,23 @@ + +def main(): + + str = "(]" + + stack = [] + + for i in range(0, len(str)): + + char = str[i] + + if char=="(" or char=="[" or char=="{": + stack.append(char) + elif char==")" or char=="]" or char=="}": + stack.pop() + + if not stack: + print 'parenthese are valid' + else: + print 'parenthese are NOT valid' + +if __name__ == "__main__": + main() diff --git a/_code/stack/valid_parenthesis3.py b/_code/stack/valid_parenthesis3.py new file mode 100644 index 0000000..95b665f --- /dev/null +++ b/_code/stack/valid_parenthesis3.py @@ -0,0 +1,35 @@ +s = "]" + + +def isValid(s): + + open_list = ["(", "{", "["] + close_list = [")", "}", "]"] + + + stack=[] + + for i in range(0, len(s)): + + char = s[i] + + if char in open_list: + stack.append(char) + elif char in close_list: + + # find index of closing char + index = close_list.index(char) + matching_open_char = open_list[index] + + if stack and stack[-1]==matching_open_char: + stack.pop() + else: + return False # in case str="]" + + if not stack: + return True + else: + return False + + +print isValid(s) \ No newline at end of file diff --git a/_code/strings/firstNonRepeating.py b/_code/strings/firstNonRepeating.py new file mode 100644 index 0000000..6e03f80 --- /dev/null +++ b/_code/strings/firstNonRepeating.py @@ -0,0 +1,12 @@ +s = "eleetcode" + +def firstUniqChar(s): + visited = set() + for i in range(len(s)): + if s[i] not in visited: + visited.add(s[i]) + if s.count(s[i]) == 1: + return i + return -1 + +print( firstUniqChar(s) ) \ No newline at end of file diff --git a/_code/strings/isSubsequence.py b/_code/strings/isSubsequence.py new file mode 100644 index 0000000..12a54d9 --- /dev/null +++ b/_code/strings/isSubsequence.py @@ -0,0 +1,49 @@ +s = "abc" +t = "ahbgdc" + + +def isSubsequence(s, t): + + sp = 0 + tp = 0 + + while sp=0 and rlen(res): + res = oddPalin + if len(evenPalin)>len(res): + res = evenPalin + + return res + + + + # start, end = 0,0 + + # for i in range(len(s)): + # len1 = expandAroundCenter(s, i, i) + # len2 = expandAroundCenter(s, i, i+1) + + # print(len1, len2) + # length = max(len1, len2) + + # if length > end-start: + # start = i-(length-1)/2 + # end = i + length/2 + + # return s[start:end+1] + + + + + +print(longestPalindrome(s)) diff --git a/_code/strings/longestSubstringWithoutRepeatingChars.py b/_code/strings/longestSubstringWithoutRepeatingChars.py new file mode 100644 index 0000000..1e8a967 --- /dev/null +++ b/_code/strings/longestSubstringWithoutRepeatingChars.py @@ -0,0 +1,31 @@ + +s = "abcabcbb" +s2 = "bbbbb" +s3 = "pwwkew" + +def lengthOfLongestSubstring(s): + + start = 0 + end = 0 + maxRes = 0 + + charSet = set() + + while end < len(s): + + print(s[start], s[end], charSet, maxRes) + + if not s[end] in charSet: + charSet.add(s[end]) + end+=1 + maxRes = max(len(charSet), maxRes) # why max? of max + else: + charSet.remove(s[start]) + start+=1 + + return maxRes + + +print(lengthOfLongestSubstring(s)) # 3 abc +# print(lengthOfLongestSubstring(s2)) # 1 b +# print(lengthOfLongestSubstring(s3)) # 3 wke diff --git a/_code/strings/reverseString.py b/_code/strings/reverseString.py new file mode 100644 index 0000000..129fb9b --- /dev/null +++ b/_code/strings/reverseString.py @@ -0,0 +1,11 @@ +def FirstReverse(str): + + + # code goes here + return str[::-1] + + +input = "test" + +# keep this function call here +print(FirstReverse(input)) \ No newline at end of file diff --git a/_code/strings/reverseVowels.py b/_code/strings/reverseVowels.py new file mode 100644 index 0000000..0240025 --- /dev/null +++ b/_code/strings/reverseVowels.py @@ -0,0 +1,22 @@ +import re + +str = "hello" + + +arr = [] +for i, c in enumerate(str): + if re.search("[aeiou]", c): + arr.append(i) + +print( arr ) + + +# for i in range(int(len(arr)/2)): + +# # swap arr[i] and arr[-i] +# tmp = str[i] +# str[i] = str[arr[-i]] +# str[arr[-i]] = tmp + + +# print(str) \ No newline at end of file diff --git a/_code/strings/toLower.py b/_code/strings/toLower.py new file mode 100644 index 0000000..f5ba65c --- /dev/null +++ b/_code/strings/toLower.py @@ -0,0 +1,10 @@ +def toLowerCase(str: str) -> str: + + new_str = "" + for c in str: + new_str += c.lower() + + return new_str + + +print( toLowerCase("Hello") ) \ No newline at end of file diff --git a/_code/strings/validate_anagram.py b/_code/strings/validate_anagram.py new file mode 100644 index 0000000..7d5f786 --- /dev/null +++ b/_code/strings/validate_anagram.py @@ -0,0 +1,12 @@ +class Solution: + def isAnagram(self, s: str, t: str) -> bool: + + return sorted(s) == sorted(t) + + + + +if __name__ == "__main__": + + s = Solution() + print( s.isAnagram("abc", "cbaa") ) \ No newline at end of file diff --git a/_code/topological_sort/toposort.py b/_code/topological_sort/toposort.py new file mode 100644 index 0000000..4cbab53 --- /dev/null +++ b/_code/topological_sort/toposort.py @@ -0,0 +1,34 @@ +''' + This is the basic topo sort from: + https://www.educative.io/courses/grokking-the-coding-interview/m25rBmwLV00 + + There isn't a problem on leetcode +''' + + +from collections import deque + + +def topological_sort(vertices, edges): + + inDegree = {i: 0 for i in range(vertices)} + + + +def main(): + + ans1 = topological_sort(4, [[3, 2], [3, 0], [2, 0], [2, 1]]) + print("Topological sort: " + str(ans1)) + assert( ans1==[3, 2, 0, 1] ) + + # ans2 = topological_sort(5, [[4, 2], [4, 3], [2, 0], [2, 1], [3, 1]]) + # print("Topological sort: " + str(ans2)) + # assert( ans2==[4, 2, 3, 0, 1]) + + # ans3 = topological_sort(7, [[6, 4], [6, 2], [5, 3], [5, 4], [3, 0], [3, 1], [3, 2], [4, 1]]) + # print("Topological sort: " + str(ans3)) + # assert( ans3==[5, 6, 3, 4, 0, 2, 1] ) + + + +main() \ No newline at end of file diff --git a/_code/trees/balance tree/balancedTree.py b/_code/trees/balance tree/balancedTree.py new file mode 100644 index 0000000..6705671 --- /dev/null +++ b/_code/trees/balance tree/balancedTree.py @@ -0,0 +1,54 @@ +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + +''' + A tree is balanced if the height of the left and right subtrees do not differ by more than 1 + + + two approaches given by: https://www.youtube.com/watch?v=LU4fGD-fgJQ + this is approach #1 (inefficient because all nodes will call the height() function) +''' + + +def isTreeBalanced(root): + + if not root: + return True + + if root: + + leftHeight = height(root.left) + rightHeight = height(root.right) + + currNodeBalanced = abs(leftHeight-rightHeight) <= 1 + + lesRes = isTreeBalanced(root.left) + rightRes = isTreeBalanced(root.right) + + return currNodeBalanced and lesRes and rightRes + + +def height(root): + + if not root: + return 0 + else: + return 1+max( height(root.left), height(root.right) ) + + +root = TreeNode(1) +root.left = TreeNode(2) +root.right = TreeNode(3) +root.right.right = TreeNode(20) +# root.right.right.right = TreeNode(20) + + +# print(height(root.right)) + + +print( isTreeBalanced(root) ) \ No newline at end of file diff --git a/_code/trees/balance tree/isTreeBalanced.py b/_code/trees/balance tree/isTreeBalanced.py new file mode 100644 index 0000000..c1620c1 --- /dev/null +++ b/_code/trees/balance tree/isTreeBalanced.py @@ -0,0 +1,47 @@ +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + +''' + A tree is balanced if the height of the left and right subtrees do not differ by more than 1 + + + two approaches given by: https://www.youtube.com/watch?v=LU4fGD-fgJQ + this is approach #1 (inefficient because all nodes will call the height() function) +''' +def isTreeBalanced(root): + + if not root: + return True + + leftHeight = height(root.left) + rightHeight = height(root.right) + + if abs( leftHeight - rightHeight ) <= 1 and isTreeBalanced(root.left) and isTreeBalanced(root.right): + return True + + return False + + +''' + this is the function to get height of any node +''' +def height(root): + + if not root: + return 1 + else: + return 1 + max( height(root.left), height(root.right) ) + + +root = TreeNode(1) +root.left = TreeNode(2) +root.right = TreeNode(3) +root.right.right = TreeNode(20) +# root.right.right.right = TreeNode(20) + +print( isTreeBalanced(root) ) \ No newline at end of file diff --git a/_code/trees/createTreeFromArray.py b/_code/trees/createTreeFromArray.py new file mode 100644 index 0000000..dcff1bd --- /dev/null +++ b/_code/trees/createTreeFromArray.py @@ -0,0 +1,44 @@ +# Python3 program to construct binary +# tree from given array in level +# order fashion Tree Node + +# Helper function that allocates a +# new node +class newNode: + def __init__(self, data): + self.data = data + self.left = self.right = None + + +# Function to insert nodes in level order +def insertLevelOrder(arr, root, i, n): + # Base case for recursion + if i < n: + temp = newNode(arr[i]) + root = temp + + # insert left child + root.left = insertLevelOrder(arr, root.left, 2 * i + 1, n) + + # insert right child + root.right = insertLevelOrder(arr, root.right, 2 * i + 2, n) + return root + + +# Function to print tree nodes in +# InOrder fashion +def inOrder(root): + if root != None: + inOrder(root.left) + print root.data + " " + inOrder(root.right) + + # Driver Code + + +if __name__ == '__main__': + arr = [1, 2, 3, 4, 5, 6, 6, 6, 6] + n = len(arr) + root = None + root = insertLevelOrder(arr, root, 0, n) + inOrder(root) diff --git a/_code/trees/deepestLeavesSum/deepestLeaveSum.py b/_code/trees/deepestLeavesSum/deepestLeaveSum.py new file mode 100644 index 0000000..586384d --- /dev/null +++ b/_code/trees/deepestLeavesSum/deepestLeaveSum.py @@ -0,0 +1,39 @@ +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + + + +def deepestLeavesSum(root): + + d = dict() # keeps track of level:sum + + def dfs(root, level): + + print d + + d[level] = root.val + d.get(level, 0) # the "0" is the default return value if level is not in dictionary, otherwise None would be returned + + if root.left: + dfs(root.left, level+1) + if root.right: + dfs(root.right, level+1) + + dfs(root, 0) + return d[ max(d) ] # max() on dictionary gives max key + + + +root = TreeNode(1) +root.left = TreeNode(2) +root.right = TreeNode(3) +root.left.left = TreeNode(4) +root.right.right = TreeNode(5) + +print( deepestLeavesSum(root) ) + + \ No newline at end of file diff --git a/_code/trees/deepestLeavesSum/deepestLeavesSumBFS.py b/_code/trees/deepestLeavesSum/deepestLeavesSumBFS.py new file mode 100644 index 0000000..04f28f6 --- /dev/null +++ b/_code/trees/deepestLeavesSum/deepestLeavesSumBFS.py @@ -0,0 +1,53 @@ +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + + +def deepestLeavesSum(root): + + q = [root] + level = 0 + hashmap = {} + + while q: + + level_size = len(q) + + for i in reversed( range( level_size ) ): + + node = q.pop(0) + + if level not in hashmap: + hashmap[level] = [node.val] + else: + list = hashmap[level] + list.append(node.val) + hashmap[level] = list + + # print node.val, level + + if node.left: + q.append(node.left) + if node.right: + q.append(node.right) + + level += 1 + + # print hashmap + # print max(hashmap) + # list = hashmap[max(hashmap)] + # print sum(list) + return sum( hashmap[max(hashmap)] ) + +root = TreeNode(1) +root.left = TreeNode(2) +root.right = TreeNode(3) +root.left.left = TreeNode(4) +root.left.right = TreeNode(5) +root.left.left.left = TreeNode(6) + +print deepestLeavesSum(root) \ No newline at end of file diff --git a/_code/trees/deepestLeavesSum/deepestLeavesSumDFS.py b/_code/trees/deepestLeavesSum/deepestLeavesSumDFS.py new file mode 100644 index 0000000..331fc5f --- /dev/null +++ b/_code/trees/deepestLeavesSum/deepestLeavesSumDFS.py @@ -0,0 +1,33 @@ +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + + +def deepestLeavesSum(root): + + map = {} + + def dfs(root, depth): + + map[depth] = root.val + map.get(depth, 0) + + if root.left: + dfs(root.left, depth+1) + if root.right: + dfs(root.right, depth+1) + + + dfs(root, 0) + return map[max(map)] + +root = TreeNode(1) +root.left = TreeNode(2) +root.right = TreeNode(3) +root.left.left = TreeNode(4) +root.left.right = TreeNode(5) + +print deepestLeavesSum(root) \ No newline at end of file diff --git a/_code/trees/deepestLeavesSum/deepestLeavesSumMay12.py b/_code/trees/deepestLeavesSum/deepestLeavesSumMay12.py new file mode 100644 index 0000000..cb5eac5 --- /dev/null +++ b/_code/trees/deepestLeavesSum/deepestLeavesSumMay12.py @@ -0,0 +1,34 @@ +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + + +def deepestLeavesSum(root): + + levelMap = dict() + + def dfs(root, level): + + if not root: + return + + # add val to the levelMap + levelMap[level] = root.val + levelMap.get(level, 0) + + dfs(root.left, level+1) + dfs(root.right, level+1) + + dfs(root, 0) + print(levelMap) + +root = TreeNode(1) +root.left = TreeNode(2) +root.right = TreeNode(3) +root.left.left = TreeNode(4) +root.left.right = TreeNode(5) + +deepestLeavesSum(root) diff --git a/_code/trees/deepestNode.py b/_code/trees/deepestNode.py new file mode 100644 index 0000000..edc0c5f --- /dev/null +++ b/_code/trees/deepestNode.py @@ -0,0 +1,37 @@ + +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + + +def deepestNode(root, level, maxLevel): + + if not root: + return maxLevel + + if level > maxLevel: + maxLevel = level + + + leftRes = deepestNode(root.left, level + 1, maxLevel) + rightRes = deepestNode(root.right, level + 1, maxLevel) + + + if leftRes and rightRes: + return max(leftRes, rightRes) + + + +root = TreeNode(3) +root.left = TreeNode(9) +root.right = TreeNode(20) +root.right.left = TreeNode(15) +root.right.right = TreeNode(7) + + + +print deepestNode(root, 1, 0) diff --git a/_code/trees/deserializeTree.py b/_code/trees/deserializeTree.py new file mode 100644 index 0000000..19aea80 --- /dev/null +++ b/_code/trees/deserializeTree.py @@ -0,0 +1,46 @@ + +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + +''' + +''' +def deserialize(nodesLeft): + + # treat nodesLeft like a queue of incoming nodes to be serialized + char = nodesLeft.pop(0) + + if char=='X': + return None + + n = TreeNode(char) + n.left = deserialize(nodesLeft) + n.right = deserialize(nodesLeft) + + return n + + + +# serialized = "1,2,3,X,X,X,X" +# serialized = "1,2,X,X,3,4,X,X,5,X,X" +serialized = "3,9,20,X,X,15,7" + +nodesLeft = serialized.split(",") # a helper fuction can do this +n = deserialize( nodesLeft ) # this is the actual recursive call + +print n.val +print n.left.val +print n.right.val +print n.right.left.val +print n.right.right.val + +# split = serialized.split(",") + +# print( split.pop(0) ) +# print( split.pop(0) ) +# print( split.pop(0) ) diff --git a/_code/trees/invertTree/invertTree.py b/_code/trees/invertTree/invertTree.py new file mode 100644 index 0000000..84c779f --- /dev/null +++ b/_code/trees/invertTree/invertTree.py @@ -0,0 +1,31 @@ +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + + + +def invert(root): + + if not root: + return + + tmp = root.left + root.left = root.right + root.right = tmp + + invert(root.left) + invert(root.right) + + +root = TreeNode(1) +root.left = TreeNode(2) +root.right = TreeNode(3) +root.left.left = TreeNode(4) +root.right.right = TreeNode(5) + + +print( root.left.left.val ) # 4 \ No newline at end of file diff --git a/_code/trees/isSameTree/isSameTree.py b/_code/trees/isSameTree/isSameTree.py new file mode 100644 index 0000000..923ebf3 --- /dev/null +++ b/_code/trees/isSameTree/isSameTree.py @@ -0,0 +1,49 @@ +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + + + +def isSameTree(p, q): + + if not p and not q: + return True + + # both null already covered above + if not p or not q: + return False + + if p.val != q.val: + return False + + leftRes = isSameTree(p.left, q.left) + rightRes = isSameTree(p.right, q.right) + + return leftRes and rightRes + + +# def isSameTree(p,q): +# if p and q: +# return p.val == q.val and isSameTree(p.left, q.left) and isSameTree(p.right, q.right) +# return p is q + + +root = TreeNode(1) +root.left = TreeNode(2) +root.right = TreeNode(3) + + +root2 = TreeNode(1) +root2.left = TreeNode(2) +root2.right = TreeNode(3) + +p = root +q = root2 + +print p +print q +print isSameTree(p, q) \ No newline at end of file diff --git a/_code/trees/isSameTree/sameTree.py b/_code/trees/isSameTree/sameTree.py new file mode 100644 index 0000000..93d4b67 --- /dev/null +++ b/_code/trees/isSameTree/sameTree.py @@ -0,0 +1,25 @@ +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + + + +def sameTree(p, q): + + if not p and not q: + return True + + elif p and not q: + return False + + elif not p and q: + return False + + else: + + return p.val==q.val and sameTree(p.left, q.left) and sameTree(p.right, q.right) + \ No newline at end of file diff --git a/_code/trees/isSubTree.py b/_code/trees/isSubTree.py new file mode 100644 index 0000000..ae64e30 --- /dev/null +++ b/_code/trees/isSubTree.py @@ -0,0 +1,40 @@ +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + + +def isSubTree(s, t): + + if not s: + return False + if isSameTree(s, t): + return True + return isSubTree(s.left, t) or isSubTree(s.right, t) + + + +def isSameTree(p, q): + + if p and q: + return p.val==q.val and isSameTree(p.left, q.left) and isSameTree(p.right, q.right) + return p is q + + + +root = TreeNode(1) +root.left = TreeNode(2) +root.right = TreeNode(3) + + +root2 = TreeNode(1) +root2.left = TreeNode(2) +root2.right = TreeNode(3) + +p = root +q = root2 + +print isSubTree(p, q) \ No newline at end of file diff --git a/_code/trees/k_distance_from_root.py b/_code/trees/k_distance_from_root.py new file mode 100644 index 0000000..70a6b66 --- /dev/null +++ b/_code/trees/k_distance_from_root.py @@ -0,0 +1,31 @@ + +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + +''' + +''' +def printKdistance(root, k): + + if k==0: + print( root.val ) + return + + printKdistance(root.left, k-1) + printKdistance(root.right, k-1) + + + + + +root = TreeNode(1) +root.left = TreeNode(2) +root.right = TreeNode(3) + +printKdistance(root, 1) + diff --git a/_code/trees/lca/lcaBinaryTree.py b/_code/trees/lca/lcaBinaryTree.py new file mode 100644 index 0000000..67eee7c --- /dev/null +++ b/_code/trees/lca/lcaBinaryTree.py @@ -0,0 +1,43 @@ +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + + + +def lca(root, x, y): + + if not root: + return None + + print(root.val) + + if root.val==x or root.val==y: + print('returning ' + str(root.val)) + return root + + leftRes = lca(root.left, x, y) + rightRes = lca(root.right, x, y) + + if not rightRes: + return leftRes + if not leftRes: + return rightRes + if leftRes and rightRes: + print('returning ' + str(root.val)) + return root + + + + +root = TreeNode(1) +root.left = TreeNode(2) +root.right = TreeNode(3) +root.left.left = TreeNode(4) +root.left.right = TreeNode(5) + + +print( lca(root, 4, 5).val ) \ No newline at end of file diff --git a/_code/trees/levelOrder.py b/_code/trees/levelOrder.py new file mode 100644 index 0000000..b15be6f --- /dev/null +++ b/_code/trees/levelOrder.py @@ -0,0 +1,51 @@ +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + + + +def levelOrder(root): + + queue = [] + queue.append( root ) + levels = [] + + while queue: + + level_size = len(queue) + level = [] + + while level_size: + + node = queue.pop(0) + + if node: + level.append( node.val ) + + if node.left: + queue.append( node.left ) + if node.right: + queue.append( node.right ) + + level_size -= 1 + + if level: + levels.append( level ) + + print levels + +root = TreeNode(0) +root.left = TreeNode(1) +root.right = TreeNode(2) +root.left.left = TreeNode(3) +root.left.right = TreeNode(4) +# root.right.left = TreeNode(5) +root.right.right = TreeNode(6) +root.right.right.right = TreeNode(7) + +levelOrder(root) + diff --git a/_code/trees/maxDepth.py b/_code/trees/maxDepth.py new file mode 100644 index 0000000..1aee182 --- /dev/null +++ b/_code/trees/maxDepth.py @@ -0,0 +1,31 @@ + +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + + +''' + https://leetcode.com/submissions/detail/48266023/ +''' +def maxDepth(root): + + if not root: + return 0 + else: + return 1 + max( maxDepth(root.left), maxDepth(root.right) ) + + +root = TreeNode(3) +root.left = TreeNode(9) +root.right = TreeNode(20) +root.right.left = TreeNode(15) +root.right.right = TreeNode(7) +#root.right.right.right = TreeNode(5) + + + +print maxDepth(root) diff --git a/_code/trees/maxWidthOfTree/maxWidthOfTreeBFS.py b/_code/trees/maxWidthOfTree/maxWidthOfTreeBFS.py new file mode 100644 index 0000000..e69de29 diff --git a/_code/trees/serializeTree.py b/_code/trees/serializeTree.py new file mode 100644 index 0000000..ed98bec --- /dev/null +++ b/_code/trees/serializeTree.py @@ -0,0 +1,31 @@ + +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + + +def serialize(root): + + if not root: + return "X" + + leftSerialized = serialize(root.left) + rightSerialized = serialize(root.right) + + return str(root.val) + leftSerialized + rightSerialized + + + +root = TreeNode(1) +root.left = TreeNode(2) +root.right = TreeNode(3) +root.right.left = TreeNode(4) +root.right.right = TreeNode(5) + + +print serialize(root) + diff --git a/_code/trees/serializeTree2.py b/_code/trees/serializeTree2.py new file mode 100644 index 0000000..d43ca73 --- /dev/null +++ b/_code/trees/serializeTree2.py @@ -0,0 +1,58 @@ + +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + + +def serialize(root): + + if not root: + return "X" + + leftRes = serialize(root.left) + rightRes = serialize(root.right) + + return str(root.val) + "," + leftRes + "," + rightRes + + +def deserialize(str): + + def dfs(nodesLeftList): + + # treat nodesLeft like a queue of incoming nodes to be serialized + char = nodesLeftList.pop(0) + + if char=='X': + return None + + node = TreeNode(char) + node.left = dfs(nodesLeftList) + node.right = dfs(nodesLeftList) + + return node + + nodesLeftList = str.split(",") + n = dfs( nodesLeftList ) # this is the actual recursive call + return n + +print("Serialize..") +root = TreeNode(1) +root.left = TreeNode(2) +root.right = TreeNode(3) +root.right.left = TreeNode(4) +root.right.right = TreeNode(5) +serialized = serialize(root) +print(serialized) +print() + +print("Deserialize..") +root2 = deserialize(serialized) +print( root2.val ) +print( root2.left.val ) +print( root2.right.val ) +print( root2.right.left.val ) +print( root2.right.right.val ) diff --git a/_code/trees/sumEvenGrandparents.py b/_code/trees/sumEvenGrandparents.py new file mode 100644 index 0000000..75df288 --- /dev/null +++ b/_code/trees/sumEvenGrandparents.py @@ -0,0 +1,72 @@ +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + + + + +def sumEvenGrandparent(root): + + sum = 0 # global var + + def dfs(root, sum): + + if not root: + return 0 + + # moving recursive calls up here (making this postorder instead of preorder) and adding sum = make this work + if root.left: + sum = dfs(root.left, sum) + if root.right: + sum = dfs(root.right, sum) + + if root.val % 2 == 0: + + if root.left and root.left.left: + print( "even grandparent is %s" % root.val ) + print( "sum " + str(sum) + " adding " + str(root.left.left.val)) + sum = sum + root.left.left.val + + + if root.left and root.left.right: + print( "even grandparent is %s" % root.val ) + print( "sum " + str(sum) + " adding " + str(root.left.right.val)) + sum = sum + root.left.right.val + + + if root.right and root.right.left: + print( "even grandparent is %s" % root.val ) + print( "sum " + str(sum) + " adding " + str(root.right.left.val)) + sum = sum + root.right.left.val + + + if root.right and root.right.right: + print( "even grandparent is %s" % root.val ) + print( "sum " + str(sum) + " adding " + str(root.right.right.val)) + sum = sum + root.right.right.val + + # dfs(root.left, sum) + # dfs(root.right, sum) + + return sum + + # call inner function + return dfs(root, sum) + +root = TreeNode(6) +root.left = TreeNode(7) +root.right = TreeNode(8) +root.left.left = TreeNode(2) +root.left.right = TreeNode(7) +root.right.left = TreeNode(1) +root.right.right = TreeNode(3) +# root.left.left = TreeNode(9) +# root.left.right.left = TreeNode(1) +# root.left.right.right = TreeNode(4) +root.right.right.right = TreeNode(5) + +print( sumEvenGrandparent(root) ) \ No newline at end of file diff --git a/_code/trees/sumRootToLeafNumbers.py b/_code/trees/sumRootToLeafNumbers.py new file mode 100644 index 0000000..2757bd0 --- /dev/null +++ b/_code/trees/sumRootToLeafNumbers.py @@ -0,0 +1,35 @@ +class TreeNode: + def __init__(self, val=0, left=None, right=None): + self.val = val + self.left = left + self.right = right + +def sumNumbers(root): + + if not root: return 0 + + output = [] # list of strings of each path: ["12", "13"] + + def dfs(root, sofar): # sofar is list of integers as we recurse down the tree + + if root.left is None and root.right is None: + output.append("".join(sofar+[str(root.val)])) + + if root.left: + # sofar.append(str(root.val)) + dfs(root.left, sofar+[str(root.val)]) + + if root.right: + # sofar.append(str(root.val)) + dfs(root.right, sofar+[str(root.val)]) + + dfs(root, []) + + return sum([ int(x) for x in output ]) + + +root = TreeNode(1) +root.left = TreeNode(2) +root.right = TreeNode(3) + +print( sumNumbers(root) ) \ No newline at end of file diff --git a/_code/trees/symmetry/symmetricTree.py b/_code/trees/symmetry/symmetricTree.py new file mode 100644 index 0000000..3e1200b --- /dev/null +++ b/_code/trees/symmetry/symmetricTree.py @@ -0,0 +1,46 @@ +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + + + +def isSymmetric(root): + + if not root: + return True + + # no child nodes + if not root.left and not root.right: + return True + # only left exists + elif root.left and not root.right: + return False + # only right exists + elif not root.left and root.right: + return False + # both exists + if root.left.val == root.right.val: + return True + + if root.left: + leftRes = isSymmetric(root.left) + if root.right: + rightRes = isSymmetric(root.right) + + return leftRes and rightRes + + + + +root = TreeNode(0) +root.left = TreeNode(2) +root.right = TreeNode(2) +root.left.right = TreeNode(3) +root.right.right = TreeNode(3) + + +print(isSymmetric(root)) \ No newline at end of file diff --git a/_code/trees/symmetry/symmetricTree2.py b/_code/trees/symmetry/symmetricTree2.py new file mode 100644 index 0000000..6ee3ad9 --- /dev/null +++ b/_code/trees/symmetry/symmetricTree2.py @@ -0,0 +1,42 @@ +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + + + +def isSymmetric(root): + + def isMirror(left, right): + + if not left and not right: + return True + + if left and not right: + return False + + if right and not left: + return False + + if left and right and left.val == right.val: + return isMirror(left.left, right.right) and isMirror(left.right, right.left) + + return False + + if not root: + return True + + return isMirror(root.left, root.right) + + +root = TreeNode(0) +root.left = TreeNode(2) +root.right = TreeNode(2) +root.left.left = TreeNode(3) +root.right.right = TreeNode(3) + + +print(isSymmetric(root)) \ No newline at end of file diff --git a/_code/trees/symmetry/symmetricTreeMay12.py b/_code/trees/symmetry/symmetricTreeMay12.py new file mode 100644 index 0000000..24e8968 --- /dev/null +++ b/_code/trees/symmetry/symmetricTreeMay12.py @@ -0,0 +1,38 @@ +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + + + +def isSymmetric(root): + + if not root: + return True + + def isMirror(p, q): + + if not p and not q: + return True + + if (p and not q) and (not p and q): + return False + + if p and q and p.val==q.val and isMirror(p.left, q.right) and isMirror(p.right, q.left): + return True + + return False + + return isMirror(root.left, root.right) + +root = TreeNode(1) +root.left = TreeNode(2) +root.right = TreeNode(2) +root.left.right = TreeNode(3) +root.right.right = TreeNode(3) + + +print(isSymmetric(root)) \ No newline at end of file diff --git a/_code/trees/symmetry/symmetricTreeTemplate.py b/_code/trees/symmetry/symmetricTreeTemplate.py new file mode 100644 index 0000000..90ffb7d --- /dev/null +++ b/_code/trees/symmetry/symmetricTreeTemplate.py @@ -0,0 +1,23 @@ +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + + + +def isSymmetric(root): + + + + +root = TreeNode(0) +root.left = TreeNode(2) +root.right = TreeNode(2) +root.left.left = TreeNode(3) +root.right.right = TreeNode(3) + + +print(isSymmetric(root)) \ No newline at end of file diff --git a/_code/trees/validateBST/validateBST_recurseWithLimits.py b/_code/trees/validateBST/validateBST_recurseWithLimits.py new file mode 100644 index 0000000..168684f --- /dev/null +++ b/_code/trees/validateBST/validateBST_recurseWithLimits.py @@ -0,0 +1,57 @@ +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + + + +def validateBST(root): + + if not root: + return True + + def helper(node, lower, upper): + + if not node: + return True + + if node.val<=lower or node.val>=upper: # current node violates left and right conditions + return False + + leftValid = helper(node.left, lower, node.val) + rightValid = helper(node.right, node.val, upper) + + return leftValid and rightValid + + return helper(root, float('-inf'), float('inf')) + +# # 5 +# # 3 7 +# # 2 4 6 8 + +# root = TreeNode(5) +# root.left = TreeNode(3) +# root.right = TreeNode(7) +# root.left.left = TreeNode(2) +# root.left.right = TreeNode(4) +# root.right.left = TreeNode(6) +# root.right.right = TreeNode(8) + + +# [10,5,15,null,null,6,20] + +# 10 +# 5 15 +# X X 6 20 + +root = TreeNode(10) +root.left = TreeNode(5) +root.right = TreeNode(15) +root.right.left = TreeNode(6) +root.right.right = TreeNode(20) + + +print(validateBST(root)) \ No newline at end of file diff --git a/_code/trees/validateBST/validateBST_trivialButWrong.py b/_code/trees/validateBST/validateBST_trivialButWrong.py new file mode 100644 index 0000000..d20df6c --- /dev/null +++ b/_code/trees/validateBST/validateBST_trivialButWrong.py @@ -0,0 +1,56 @@ +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + + + +def validateBST(root): + + if not root: + return True + + # check BST conditions for current node + validBST = True + + if root.left and not root.left.val < root.val: + validBST = False + + if root.right and not root.right.val > root.val: + validBST = False + + leftRes = validateBST(root.left) + rightRes = validateBST(root.right) + + return validBST and leftRes and rightRes + +# # 5 +# # 3 7 +# # 2 4 6 8 + +# root = TreeNode(5) +# root.left = TreeNode(3) +# root.right = TreeNode(7) +# root.left.left = TreeNode(2) +# root.left.right = TreeNode(4) +# root.right.left = TreeNode(6) +# root.right.right = TreeNode(8) + + +# [10,5,15,null,null,6,20] + +# # 10 +# # 5 15 +# # X X 6 20 + +root = TreeNode(10) +root.left = TreeNode(5) +root.right = TreeNode(15) +root.right.left = TreeNode(6) +root.right.right = TreeNode(20) + + +print(validateBST(root)) \ No newline at end of file diff --git a/_code/tries/trie.py b/_code/tries/trie.py new file mode 100644 index 0000000..28cfe68 --- /dev/null +++ b/_code/tries/trie.py @@ -0,0 +1,71 @@ +class Node: + def __init__(self): + self.children = {} # the children that this node points to + self.endofword = False + +class Trie: + + def __init__(self): + self.root = Node() + + + def insert(self, word: str) -> None: + ptr = self.root + + for letter in word: + + if letter not in ptr.children: + ptr.children[letter] = Node() + + # traverse down the tree + ptr = ptr.children[letter] + ptr.endofword = True + + + + def search(self, word: str) -> bool: + + ptr = self.root + + for letter in word: + + if letter not in ptr.children: + return False + ptr = ptr.children[letter] + + # check end of word? + if ptr.endofword: + return True + else: + return False + + + + + + def startsWith(self, prefix: str) -> bool: + + ptr = self.root + + for letter in prefix: + + if letter not in ptr.children: + return False + ptr = ptr.children[letter] + + return True + + + + +trie = Trie(); + +output = [] +output.append( trie.insert("apple") ) +output.append( trie.search("apple") ) +output.append( trie.search("app") ) +output.append( trie.startsWith("app") ) +output.append( trie.insert("app") ) +output.append( trie.search("app") ) + +print(output) \ No newline at end of file diff --git a/_code/union find/floodfill.py b/_code/union find/floodfill.py new file mode 100644 index 0000000..d9be188 --- /dev/null +++ b/_code/union find/floodfill.py @@ -0,0 +1,52 @@ +image = [[1,1,1], + [1,1,0], + [1,0,1]] + + +# def floodFill( image, sr, sc, newColor): +# R, C = len(image), len(image[0]) +# color = image[sr][sc] +# if color == newColor: return image +# def dfs(r, c): + +# print(r,c) + +# if image[r][c] == color: +# image[r][c] = newColor +# if r >= 1: dfs(r-1, c) +# if r+1 < R: dfs(r+1, c) +# if c >= 1: dfs(r, c-1) +# if c+1 < C: dfs(r, c+1) + +# dfs(sr, sc) +# return image + +def floodFill(image, startRow, startCol, newColor): + + R = len(image) + C = len(image[0]) + oldColor = image[startRow][startCol] + if oldColor == newColor: return image + + def dfs(r, c): + + # choose whether or not to advance + # if image[r][c]==oldColor: + + print(r,c) + + if image[r][c] == oldColor: + image[r][c] = newColor + if r>=1: dfs(r-1, c) # go up + if r+1=1: dfs(r, c-1) # go left + if c+1=1: floodFill(grid, r-1, c) + if r+1=1: floodFill(grid, r, c-1) + if c+1=R or c < 0 or c >= C or grid[r][c] == "0": + return 0 + else: + print(r,c,grid[r][c]) + + grid[r][c] = '0' # mark as visited + floodFill(grid, r-1, c) + floodFill(grid, r+1, c) + floodFill(grid, r, c-1) + floodFill(grid, r, c+1) + + + for i in range(R): + for j in range(C): + if grid[i][j]=='1': + numIslands+=1 + floodFill(grid, i, j) + + + print(grid) + return numIslands + +print(numIslands(grid)) \ No newline at end of file diff --git a/_code/union find/numIslands/numIslands2.py b/_code/union find/numIslands/numIslands2.py new file mode 100644 index 0000000..5e44b76 --- /dev/null +++ b/_code/union find/numIslands/numIslands2.py @@ -0,0 +1,36 @@ +grid = [ + ["1","1","1","1","0"], + ["1","1","0","1","0"], + ["1","1","0","0","1"], + ["0","0","0","1","0"] +] + + + +def numIslands(grid): + + rows = len(grid) + cols = len(grid[0]) + + def dfs(i, j): + + if i<0 or i>=rows or j<0 or j>=cols or grid[i][j]=="0": + return + else: + grid[i][j]="0" + dfs(i-1,j) + dfs(i+1,j) + dfs(i,j-1) + dfs(i,j+1) + + count = 0 + for i in range(rows): + for j in range(cols): + + if grid[i][j]=="1": + count += 1 + dfs(i, j) + + return count + +print( numIslands(grid) ) \ No newline at end of file diff --git a/_code/union find/numIslands/numIslands3.py b/_code/union find/numIslands/numIslands3.py new file mode 100644 index 0000000..59559bc --- /dev/null +++ b/_code/union find/numIslands/numIslands3.py @@ -0,0 +1,33 @@ +from itertools import product + +grid = [ + ["1","1","1","1","0"], + ["1","1","0","1","0"], + ["1","1","0","0","1"], + ["0","0","0","1","0"] +] + +def numIslands(grid): + + rows = len(grid) + cols = len(grid[0]) + + def dfs(i, j): + + if i<0 or i>=rows or j<0 or j>=cols or grid[i][j]=="0": + return + + neib_list = [[i+1,j],[i-1,j],[i,j-1],[i,j+1]] + for x, y in neib_list: + grid[i][j]="0" + dfs(x, y) + + count = 0 + for i, j in product(range(rows), range(cols)): + if grid[i][j]=="1": + count += 1 + dfs(i, j) + + return count + +print( numIslands(grid) ) \ No newline at end of file diff --git a/_code/union find/numIslands/numIslands4.py b/_code/union find/numIslands/numIslands4.py new file mode 100644 index 0000000..bec698b --- /dev/null +++ b/_code/union find/numIslands/numIslands4.py @@ -0,0 +1,17 @@ +from itertools import product + +grid = [ + ["1","1","1","1","0"], + ["1","1","0","1","0"], + ["1","1","0","0","1"], + ["0","0","0","1","0"] +] + +def numIslands(grid): + + + def dfs(i, j): + + if i<0 and + +print( numIslands(grid) ) \ No newline at end of file diff --git a/_code/union find/rottingOranges.py b/_code/union find/rottingOranges.py new file mode 100644 index 0000000..bd805f7 --- /dev/null +++ b/_code/union find/rottingOranges.py @@ -0,0 +1,58 @@ +grid = [[2,1,1],[1,1,0],[0,1,1]] + + + +def orangesRotting(grid): + + R = len(grid) + C = len(grid[0]) + + fresh_count=0 + + # get all cells with rotton oranges + rottonQueue = [] + for i in range(R): + for j in range(C): + if grid[i][j]==2: + rottonQueue.append( (i,j) ) + elif grid[i][j]==1: + fresh_count+=1 + + minutes_passed = 0 + + while rottonQueue and fresh_count>0: + + minutes_passed+=1 + + # process orange at the current level + for i in range(len(rottonQueue)): + + # get rotton + x, y = rottonQueue.pop(0) + + # visit neighbours + for dx, dy in [(1,0), (-1,0), (0,1), (0,-1)]: + + # calculate coordinates of adjacent cells + xx, yy = x+dx, y+dy + + # ignore cell if it's out of boundary + if xx<0 or xx==R or yy<0 or yy==C: + continue + + # ignore cell if it is empty '0' or visited before '2' + if grid[xx][yy]==0 or grid[xx][yy]==2: + continue + + # update fresh count + fresh_count-=1 + + # mark current cell as rotton + grid[xx][yy]=2 + + # add to queue + rottonQueue.append((xx,yy)) + + return minutes_passed if fresh_count==0 else -1 + +print( orangesRotting(grid) ) \ No newline at end of file diff --git a/_code/union find/surroundedRegion.py b/_code/union find/surroundedRegion.py new file mode 100644 index 0000000..7e77c8c --- /dev/null +++ b/_code/union find/surroundedRegion.py @@ -0,0 +1,49 @@ +from itertools import product + +''' + https://leetcode.com/problems/surrounded-regions/discuss/691646/Python-O(mn)-3-colors-dfs-explained +''' + +board = [ + ["X","X","X","X"], + ["X","O","O","X"], + ["X","X","O","X"], + ["X","O","X","X"] +] + + +class Solution: + + def dfs(self, i, j): + + if i<0 or j<0 or i>=self.M or j>=self.N or self.board[i][j] != "O": + return + self.board[i][j] = 'T' + neib_list = [[i+1,j],[i-1,j],[i,j-1],[i,j+1]] + for x, y in neib_list: + self.dfs(x, y) + + def solve(self, board): + if not board: return 0 + self.board, self.M, self.N = board, len(board), len(board[0]) + + # run dfs on sides + for i in range(0, self.M): + self.dfs(i,0) # left side + self.dfs(i,self.N-1) # right side + + # run dfs on top and bottom + for j in range(0, self.N): + self.dfs(0,j) # top + self.dfs(self.M-1,j) # bottom + + print(board) + + # itertools.product() is equivalent to nested forloop + for i,j in product(range(self.M), range(self.N)): + board[i][j] = "X" if board[i][j] != "T" else "O" + +sol = Solution() +sol.solve(board) + +print(board) \ No newline at end of file diff --git a/_config.yml b/_config.yml new file mode 100644 index 0000000..c5b21eb --- /dev/null +++ b/_config.yml @@ -0,0 +1,31 @@ +title: Leetcode Gym + +theme: minima +plugins: + - jekyll-feed + +minima: + skin: dark + date_format: "%b %-d, %Y" + +# this is the header on top of every page +header_pages: + - pages/lists/reviewProblems.md + - pages/lists/solvedLastModified.md + + +# this lets you access it on your local area network +host: 0.0.0.0 + + +collections: + problems: + output: true + order: + - 1template.md + + code: + output: true + + cp: + output: true \ No newline at end of file diff --git a/_includes/analytics.html b/_includes/analytics.html new file mode 100644 index 0000000..42d9caf --- /dev/null +++ b/_includes/analytics.html @@ -0,0 +1,9 @@ + + + diff --git a/_layouts/default.html b/_layouts/default.html new file mode 100644 index 0000000..6fdd459 --- /dev/null +++ b/_layouts/default.html @@ -0,0 +1,26 @@ + + + + + + {%- include head.html -%} + + {% include analytics.html %} + + + + + + {%- include header.html -%} + +
+
+ {{ content }} +
+
+ + {%- include footer.html -%} + + + + \ No newline at end of file diff --git a/_problems/1template.md b/_problems/1template.md new file mode 100644 index 0000000..756a363 --- /dev/null +++ b/_problems/1template.md @@ -0,0 +1,37 @@ +--- +layout: page +title: Tempalte +last_solved: +category: +leetcode_url: +status: Attempted +--- + +Problem +------- + +``` + +``` + +Solution +---------- + + + +{% highlight python %} + + + +{% endhighlight %} + +______________ + + + +{% highlight python %} + + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/addStrings.md b/_problems/addStrings.md new file mode 100644 index 0000000..cccf734 --- /dev/null +++ b/_problems/addStrings.md @@ -0,0 +1,42 @@ +--- +layout: page +title: Add Strings +last_solved: 2020-05-30 +category: math +leetcode_url: https://leetcode.com/problems/add-strings/ +status: Attempted +--- + +##### Problem + +Given "12" and "3", return "15". +You must not use any built-in BigInteger library or convert the inputs to integer directly. + + +##### Solution + +Wasn't suppose to convert to integers + +{% highlight python %} + +def addStrings(self, num1: str, num2: str) -> str: + + + def itoa(num1): + + sum=0 + digitCol = 0 + for i in reversed( range(len(num1)) ): + + digit = ord(num1[i])-ord('0') # '2'-'0' = 2 + sum += (digit * (10**digitCol)) + digitCol+=1 + + return(sum) + + return itoa(num1)+itoa(num2) + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/allPathsFromSourceToTarget.md b/_problems/allPathsFromSourceToTarget.md new file mode 100644 index 0000000..564a48c --- /dev/null +++ b/_problems/allPathsFromSourceToTarget.md @@ -0,0 +1,140 @@ +--- +layout: page +title: All Paths from Source To Target +last_solved: 2020-07-24 +category: graph, bfs, dfs +leetcode_url: https://leetcode.com/problems/all-paths-from-source-to-target/ +status: Attempted +--- + +Problem +------- + +``` +Given a directed, acyclic graph of N nodes. Find all possible paths from node 0 to node N-1, and return them in any order. + +The graph is given as follows: the nodes are 0, 1, ..., graph.length - 1. graph[i] is a list of all nodes j for which the edge (i, j) exists. + +Example: +Input: [[1,2], [3], [3], []] +Output: [[0,1,3],[0,2,3]] +Explanation: The graph looks like this: +0--->1 +| | +v v +2--->3 +There are two paths: 0 -> 1 -> 3 and 0 -> 2 -> 3. + +``` + +Solution +---------- + +[Timothy's Change DFS](https://www.youtube.com/watch?v=xM8uxH0vcRw) + +{% highlight python %} + +def allPathsSourceTarget(self, graph: List[List[int]]) -> List[List[int]]: + + end = len(graph)-1 + + def dfs(node, path, output): + + # base condition + if node == end: + output.append(path) + + for nxt in graph[node]: + dfs(nxt, path+[nxt], output) + + output = [] + dfs( 0, [0], output) + return output + +{% endhighlight %} + + +My Attempt at DFS +------------- + +{% highlight python %} + +def allPathsSourceTarget(self, graph: List[List[int]]) -> List[List[int]]: + + output = [] + + def dfs(node, path, output): # node is current Node 0,1,2,3 + + # base condition + if node==len(graph)-1: + output.append(path) + + else: + + # recurse dfs on all children/neighbours + for neighbour in graph[node]: + dfs(neighbour, path + [neighbour], output) + + dfs(0, [0], output) + return output + + +def allPathsSourceTarget(self, graph: List[List[int]]) -> List[List[int]]: + + output = [] + + def dfs(node, path): # node is current Node 0,1,2,3 + + #nonlocal output + + # base condition + if node==len(graph)-1: + output.append(path) + + else: + + # recurse dfs on all children/neighbours + for neighbour in graph[node]: + dfs(neighbour, path + [neighbour]) + + dfs(0, [0]) + return output + +{% endhighlight %} + +______________- + +BFS SOlution + +[Anish](https://www.youtube.com/watch?time_continue=9&v=qkWfHH0Qevw&feature=emb_logo) + + +{% highlight python %} + + def allPathsSourceTarget(self, graph: List[List[int]]) -> List[List[int]]: + + q = [[0]] + + output = [] + + end = len(graph)-1 + + while q: + + curr = q.pop(0) + + # base condition + if curr[-1]==end: + output.append(curr) + + else: + + for neighbour in graph[curr[-1]]: + q.append(curr + [neighbour]) + + return output + + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/arrangeCoins.md b/_problems/arrangeCoins.md new file mode 100644 index 0000000..8863b1c --- /dev/null +++ b/_problems/arrangeCoins.md @@ -0,0 +1,121 @@ +--- +layout: page +title: Arrange Coins +last_solved: 2020-07-01 +category: binary search +leetcode_url: https://leetcode.com/problems/arranging-coins +status: Attempted +--- + +Problem +------- + +``` +You have a total of n coins that you want to form in a staircase shape, where every k-th row must have exactly k coins. + +Given n, find the total number of full staircase rows that can be formed. + +n is a non-negative integer and fits within the range of a 32-bit signed integer. + +Example 1: + +n = 5 + +The coins can form the following rows: +¤ +¤ ¤ +¤ ¤ + +Because the 3rd row is incomplete, we return 2. +Example 2: + +n = 8 + +The coins can form the following rows: +¤ +¤ ¤ +¤ ¤ ¤ +¤ ¤ + +Because the 4th row is incomplete, we return 3. + +``` + +Solution +---------- + +Tried the intuitive solution first but it ran into TLE. + +It's actually a binary search question similar to [Search Insert Position](/problems/searchInsertPosition) + +There's suppose to be a binary search solution to this but I don't get it. I"m just using the brute force solution. + + +``` + +1 +2 3 +4 5 6 +7 8 9 10 + + +so array would be like: +0 1 2 3 4 5 6 7 8 9 10 +0 1 1 2 3 3 3 4 4 4 4 + + +``` + + + +{% highlight python %} + +def arrangeCoins(self, n: int) -> int: + + curr = 0 + count = 0 + + a = [0]*(n+1) + + for i in range(0, n+1): + a[i] = curr + + print(curr, count) + + if curr!=count: + count += 1 + else: + curr += 1 + count = 0 + + + print(a) + return a[n] + +{% endhighlight %} + +_________ + +Another solution that worked is from [Timonthy H Chang](https://www.youtube.com/watch?v=vPvnYNjqSh0) + + +{% highlight python %} + +def arrangeCoins(self, n: int) -> int: + + stairs, coins, i = 0,1,1 + + while coins<=n: + + stairs +=1 + i+=1 + coins+=i + + return stairs + +{% endhighlight %} + + + +![image1](https://5wk0dw.dm.files.1drv.com/y4mDOQ_Aow8T07qO5MeTglwEhC1FGZodPmP_3PEBa6wm4eaDUIDb7DosTOGVGDBxSiVFrVe7xxBuUfn804lAkQthVjHQODZoYhqM3Ahrf5d_h_ZU_ffSnDmqTAIBlKK-TVlq-VY-nDkOd1TZpRWjlqbsnbw9fxoQSiltW1MbXy4eTW9JIkzOmxIoglcZNJzns2ldLzMY0cLK3SDwxoxu85Upw?width=1401&height=1049&cropmode=none) + diff --git a/_problems/bfs.md b/_problems/bfs.md new file mode 100644 index 0000000..cd77245 --- /dev/null +++ b/_problems/bfs.md @@ -0,0 +1,69 @@ +--- +layout: page +title: BFS +last_solved: 2020-08-08 +category: bfs +leetcode_url: +status: Solved +--- + +Time complexity is O(N) +Space complexity is O(W) where W is the max number of nodes on any level. + + +{% highlight python %} + +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + + + +def levelOrder(root): + + queue = [] + queue.append( root ) + levels = [] + + while queue: + + level_size = len(queue) + level = [] + + while level_size: + + node = queue.pop(0) + + if node: + level.append( node.val ) + + if node.left: + queue.append( node.left ) + if node.right: + queue.append( node.right ) + + level_size -= 1 + + if level: + levels.append( level ) + + print levels + +root = TreeNode(0) +root.left = TreeNode(1) +root.right = TreeNode(2) +root.left.left = TreeNode(3) +root.left.right = TreeNode(4) +# root.right.left = TreeNode(5) +root.right.right = TreeNode(6) +root.right.right.right = TreeNode(7) + +levelOrder(root) + + +{% endhighlight %} + diff --git a/_problems/binarySearch.md b/_problems/binarySearch.md new file mode 100644 index 0000000..2d25edd --- /dev/null +++ b/_problems/binarySearch.md @@ -0,0 +1,60 @@ +--- +layout: page +title: Binary Search +last_solved: 2020-07-23 +category: binary search +leetcode_url: https://leetcode.com/tag/binary-search/ +status: Attempted +--- + +Problem +------- + +``` +Given a sorted (in ascending order) integer array nums of n elements and a target value, write a function to search target in nums. If target exists, then return its index, otherwise return -1. + + +Example 1: + +Input: nums = [-1,0,3,5,9,12], target = 9 +Output: 4 +Explanation: 9 exists in nums and its index is 4 + +Example 2: + +Input: nums = [-1,0,3,5,9,12], target = 2 +Output: -1 +Explanation: 2 does not exist in nums so return -1 + +``` + +Solution +---------- + +{% highlight python %} + +def search(self, nums: List[int], target: int) -> int: + + def binSearch(low, high, target, nums): + + print(low, high, nums, target) + + while low<=high: + + mid = (low+high)//2 + + if nums[mid]==target: + return mid + elif target>nums[mid]: # if target is greater, ignore left half + low = mid+1 + else: # if target is smaller, ignore right half + high = mid-1 + + return -1 + + return binSearch(0, len(nums)-1, target, nums) + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/binaryTreeLevelOrder.md b/_problems/binaryTreeLevelOrder.md new file mode 100644 index 0000000..eeb8fd5 --- /dev/null +++ b/_problems/binaryTreeLevelOrder.md @@ -0,0 +1,99 @@ +--- +layout: page +title: Binary Tree Level Order Traversal +last_solved: 2020-07-28 +category: bfs/dfs +leetcode_url: https://leetcode.com/problems/binary-tree-level-order-traversal +status: Solved +--- + +Problem +------- + +``` +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] +] + +``` + +Solution +---------- + +BFS + +{% highlight python %} + +def levelOrder(self, root: TreeNode) -> List[List[int]]: + + if not root: return [] + + q = [root] + output = [] + + while q: + + level = [] + + for _ in range(len(q)): + + curr = q.pop(0) + + if curr: + + level.append(curr.val) + + if curr.left: q.append(curr.left) + if curr.right: q.append(curr.right) + + output.append(level) + + return output + +{% endhighlight %} + + +________________ + +DFS + +{% highlight python %} + + def levelOrder(self, root: TreeNode) -> List[List[int]]: + + if not root: return [] + + output = [] + + def dfs(node, level, output): + + if not node: + return + + if len(output) <= level: # create new inner list if level doesn't exist [[], []], so you can do `output[level]=xxx' later + output += [[]] # or output.append([]) + + dfs(node.left, level+1, output) + dfs(node.right, level+1, output) + + output[level].append(node.val) + + dfs(root, 0, output) + return output + + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/binaryTreeLevelOrder2.md b/_problems/binaryTreeLevelOrder2.md new file mode 100644 index 0000000..b944e92 --- /dev/null +++ b/_problems/binaryTreeLevelOrder2.md @@ -0,0 +1,82 @@ +--- +layout: page +title: Binary Tree Level Order Traversal II +last_solved: 2020-07-01 +category: bfs +leetcode_url: https://leetcode.com/problems/binary-tree-level-order-traversal-ii/ +status: Not Solved +--- + +Problem +------- + +``` +Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root). + +For example: +Given binary tree [3,9,20,null,null,15,7], + 3 + / \ + 9 20 + / \ + 15 7 +return its bottom-up level order traversal as: +[ + [15,7], + [9,20], + [3] +] + +``` + +Solution +---------- + +Got the wrong answer even though it seems like I've been doing the same in the past. Review it tmr. + +Update: make sure to pop left. It makes a difference. + +``` +Your input +[3,9,20,null,null,15,7] +Output +[[15,9],[20,7],[3]] +Expected +[[15,7],[9,20],[3]] +``` + +{% highlight python %} + +def levelOrderBottom(self, root: TreeNode) -> List[List[int]]: + + q = [root] + ans = [] + + + while q: + + level_size = len(q) + level = [] + + for i in range(level_size): + + curr = q.pop(0) + + if curr: + + level.append(curr.val) + + if curr.left: + q.append(curr.left) + if curr.right: + q.append(curr.right) + + if level: + ans.append(level) + + return ans[::-1] + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/binaryTreeZigZag.md b/_problems/binaryTreeZigZag.md new file mode 100644 index 0000000..0a19719 --- /dev/null +++ b/_problems/binaryTreeZigZag.md @@ -0,0 +1,75 @@ +--- +layout: page +title: Binary Tree Zig Zag +last_solved: 2020-07-22 +category: bfs +leetcode_url: https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal +status: Solved +--- + +Problem +------- + +``` +Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between). + +For example: +Given binary tree [3,9,20,null,null,15,7], + 3 + / \ + 9 20 + / \ + 15 7 +return its zigzag level order traversal as: +[ + [3], + [20,9], + [15,7] +] + + +``` + +Solution +---------- + +{% highlight python %} + +def zigzagLevelOrder(self, root: TreeNode) -> List[List[int]]: + + if not root: return + + q = [root] + ans = [] + odd = True + + while q: + + level_len = len(q) + level = [] + + for _ in range(level_len): + + curr = q.pop(0) + + if curr: + + level.append(curr.val) + + if curr.left: + q.append(curr.left) + if curr.right: + q.append(curr.right) + + if odd: + ans.append(level) + else: + ans.append(reversed(level)) + odd = not odd + + return ans + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/binaryTreeZigZagDfs.md b/_problems/binaryTreeZigZagDfs.md new file mode 100644 index 0000000..512ee0d --- /dev/null +++ b/_problems/binaryTreeZigZagDfs.md @@ -0,0 +1,64 @@ +--- +layout: page +title: Binary Tree Zig Zag (DFS) +last_solved: 2020-07-22 +category: bfs +leetcode_url: https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal +status: Attempted +--- + +Problem +------- + +``` +Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between). + +For example: +Given binary tree [3,9,20,null,null,15,7], + 3 + / \ + 9 20 + / \ + 15 7 +return its zigzag level order traversal as: +[ + [3], + [20,9], + [15,7] +] + + +``` + +Solution +---------- + +{% highlight python %} + +def zigzagLevelOrder(self, root: TreeNode) -> List[List[int]]: + + output = [] + + def dfs(node, level, output): + + if not node: + return + + if len(output) <= level: + output += [[]] + + dfs(node.left, level+1, output) + dfs(node.right, level+1, output) + + if level%2==0: + output[level].append(node.val) + else: + output[level].insert(0, node.val) + + dfs(root, 0, output) + return output + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/buyAndSellStock.md b/_problems/buyAndSellStock.md new file mode 100644 index 0000000..962ddc9 --- /dev/null +++ b/_problems/buyAndSellStock.md @@ -0,0 +1,64 @@ +--- +layout: page +title: Buy and Sell Stock +last_solved: 2020-06-02 +category: array +leetcode_url: https://leetcode.com/problems/best-time-to-buy-and-sell-stock +status: Solved +--- + +### Naive O(n^2) way + + +{% highlight python %} + +def maxProfit(self, arr: List[int]) -> int: + + if not arr or len(arr)==0: + return 0 + + maxProfit = 0 + for i in range(len(arr)): + for j in range(i+1, len(arr)): + if arr[j]-arr[i]>maxProfit: + maxProfit = arr[j]-arr[i] + + return maxProfit + +{% endhighlight %} + +This takes too long if the input is [999, 998, 997, ...etc] + + + +### 1 pass solution + +{% highlight python %} + + def maxProfit(self, prices): + + # keep track of 2 variables + minPrice = 99999 + maxProfit = 0 + + # in each iteration, one of two things happen + for i in range(0, len(prices)): + + # this if condition gets triggered if a new minPrice is detected + if prices[i] < minPrice: + minPrice = prices[i] + + # this if condition gets triggered if the current value's GAP from the minPrice is more than the maxProfit + elif prices[i] - minPrice > maxProfit: + maxProfit = prices[i] - minPrice + + return maxProfit + +{% endhighlight %} + +Try it with [2,1,6,-8] + +- i=0: minPrice set to 2 (first condition) +- i=1: minPrice set to 1 (first condition) +- i=2: 6-1 is the gap, and it replaces the maxProfit of 0 +- i=3: first condition is triggered but it doesn't matter, maxProfit is returned \ No newline at end of file diff --git a/_problems/buyAndSellStock2.md b/_problems/buyAndSellStock2.md new file mode 100644 index 0000000..e0a7518 --- /dev/null +++ b/_problems/buyAndSellStock2.md @@ -0,0 +1,68 @@ +--- +layout: page +title: Buy and Sell Stock 2 +last_solved: 2020-06-02 +category: array +leetcode_url: https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii +status: Solved +--- + + + +Problem +------- + +{% highlight text %} + +Say you have an array prices for which the ith element is the price of a given stock on day i. + +Design an algorithm to find the maximum profit. You may complete as many transactions as you like (i.e., buy one and sell one share of the stock multiple times). + +Note: You may not engage in multiple transactions at the same time (i.e., you must sell the stock before you buy again). + +Example 1: + +Input: [7,1,5,3,6,4] +Output: 7 +Explanation: Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit = 5-1 = 4. + Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 = 3. +Example 2: + +Input: [1,2,3,4,5] +Output: 4 +Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4. + Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are + engaging multiple transactions at the same time. You must sell before buying again. +Example 3: + +Input: [7,6,4,3,1] +Output: 0 +Explanation: In this case, no transaction is done, i.e. max profit = 0. + +{% endhighlight %} + +Solution +---------- + +This one is actually easier than the first one (Buy and Sell Stock 1) because you're not restricted to making only one trade. + +Since you can make multiple trades, you can buy and sell at every peak and valley. In that case, just sum up all the positive days and sum it up. + +{% highlight python %} + +def maxProfit(self, prices: List[int]) -> int: + + positive_days = [] + + for i in range(len(prices)-1): + + if prices[i+1]-prices[i]>0: + positive_days.append( prices[i+1]-prices[i] ) + + return sum(positive_days) + +{% endhighlight %} + +We can make it constant space by changing ```positive_days``` to a variable that we continously sum up. + +![image1]() \ No newline at end of file diff --git a/_problems/cheapestFlight.md b/_problems/cheapestFlight.md new file mode 100644 index 0000000..ee1deef --- /dev/null +++ b/_problems/cheapestFlight.md @@ -0,0 +1,123 @@ +--- +layout: page +title: Cheapest Flight Within K Stops +last_solved: 2020-06-20 +category: graph, dijkstra +leetcode_url: https://leetcode.com/problems/cheapest-flights-within-k-stops +status: Attempted +--- + +Problem +------- + +``` +There are n cities connected by m flights. Each flight starts from city u and arrives at v with a price w. + +Now given all the cities and flights, together with starting city src and the destination dst, your task is to find the cheapest price from src to dst with up to k stops. If there is no such route, output -1. + +Example 1: +Input: +n = 3, edges = [[0,1,100],[1,2,100],[0,2,500]] +src = 0, dst = 2, k = 1 +Output: 200 +Explanation: +The graph looks like this: + + +The cheapest price from city 0 to city 2 with at most 1 stop costs 200, as marked red in the picture. +Example 2: +Input: +n = 3, edges = [[0,1,100],[1,2,100],[0,2,500]] +src = 0, dst = 2, k = 0 +Output: 500 +Explanation: +The graph looks like this: + + +The cheapest price from city 0 to city 2 with at most 0 stop costs 500, as marked blue in the picture. + +``` + +![image1](https://s3-lc-upload.s3.amazonaws.com/uploads/2018/02/16/995.png) + +Solution +---------- + +Variation on Dijkstra (see network delay problem) + +The end result of this problem is an array that keeps track of costs. + +Value is the cost it takes to get to get from ```src``` node to ```dest``` node. + +``` +output: [0, 100, 300] + +``` + +{% highlight python %} + +def findCheapestPrice(n, flights, src, dest, K): + + # d = collections.defaultdict(list) + # seen = collections.defaultdict(lambda: float('inf')) + + adj = [[] for _ in range(n)] + output = [float('inf') for _ in range(n)] + output[src] = 0 + + # add to adj list where key is src, and value is destination+cost + for u, v, w in flights: + adj[u] += [(v, w)] + + + graph = deque() + graph.append((src, -1)) # where -1 is the number of stops + + while graph: + + u, stop = graph.popleft() + if stop >= K: + continue + + for v, w in adj[u]: + + output[v] = output[u]+w + graph.append((v,stop+1)) + + if output[dest] == float('inf'): + return -1 + else: + return output[dest] + +{% endhighlight %} + + +___________- + +Tried Dijkstra on my own but no luck. + +{% highlight python %} + +def findCheapestPrice(n, flights, src, dest, K): + + output = [float("inf")] * n + output[src] = 0 + + graph = defaultdict(list) + heap = [(src, -1)] # dest, costs + + # add to adj hash table + for u, v, w in flights: + graph[u].append((v,w)) + + while heap: + + v, w = heapq.heappop(heap) + + for v, w in graph[v]: + output[v] = output[u]+w + heapq.heappush(heap, (v, output[u]+w)) + + print( output ) + +{% endhighlight %} \ No newline at end of file diff --git a/_problems/climbingStairs.md b/_problems/climbingStairs.md new file mode 100644 index 0000000..7d7724d --- /dev/null +++ b/_problems/climbingStairs.md @@ -0,0 +1,48 @@ +--- +layout: page +title: Climbing Stairs +--- + +Basically just fib but start dp array at [1,1] + +n=3 +[1, 1, 2, 3] + +Gotcha's +- don't get variable 'i' and 'n' mixed up + + + +{% highlight python %} + +def climbStairs(self, n: int) -> int: + + dp = [1,1] + + for i in range(2, n+1): + dp.append(dp[i-1]+dp[i-2]) + + print(dp) + + return dp[n] + +{% endhighlight %} + + +The actual fib problem is written like this: + +{% highlight python %} + +class Solution: + def fib(self, N: int) -> int: + + dp = [0,1] + + for i in range(2, N+1): + dp.append(dp[i-1]+dp[i-2]) + + return dp[N] + +{% endhighlight %} + +![image1](https://gndbsg.dm.files.1drv.com/y4mxURBADYcPSgB7iiPXin_y8EP4Ne6SnaivuuMy0d2fjbl65EQUWxCKmc4P2GjfthE1Fxh4jy4sblxQ0UyMvH2NKTGNZez-2b4ZazYT28ksKM-xByG-GLQYx0pmZUSMjd825h3auNWJ8qh17Bw09HHbqT3WPtV2FIuM2pS-ZjYVMBk39inqkBlPaVGybJSO881FWiRbcaVUhPw94fAkN6lHA?width=1523&height=960&cropmode=none) \ No newline at end of file diff --git a/_problems/coinChange.md b/_problems/coinChange.md new file mode 100644 index 0000000..5167129 --- /dev/null +++ b/_problems/coinChange.md @@ -0,0 +1,56 @@ +--- +layout: page +title: Coin Change +last_solved: 2020-07-17, 2020-08-25 +category: dp [bottom up] +leetcode_url: https://leetcode.com/problems/coin-change +status: Solved +--- + +``` +You are given coins of different denominations and a total amount of money amount. Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1. + +Example 1: + +Input: coins = [1, 2, 5], amount = 11 +Output: 3 +Explanation: 11 = 5 + 5 + 1 +Example 2: + +Input: coins = [2], amount = 3 +Output: -1 + +``` + +The solution is to build an array where the current index tells you what's the minimum # of coin for the current index(amount). +Ie: arr[2] = 1 will mean 1 coin is needed for $2. + +The key formula is ```min_coins[i] = min(min_coins[i], min_coins[i - c] + 1)``` + + + +[This video](https://www.youtube.com/watch?v=jgiZlGzXMBw) actually does the best job at explaining the bottom up approach. + +{% highlight python %} + + def coinChange(self, coins: List[int], amount: int) -> int: + + dp = [0] + [float('inf')] * amount + + for a in range(1, amount+1): + for c in coins: + if a-c>=0: + dp[a] = min( dp[a], dp[a-c]+1 ) + + print(dp) + + return dp[-1] if dp[-1]!=float('inf') else -1 + +{% endhighlight %} + + +![image1](https://5wig4g.dm.files.1drv.com/y4mboD94pR7HKG8_TUT5aIpOrHQ-N26HFp9PZXq-66IZ7Ox1CUYeorQptNRSuO2o3ZjETMuZEz6t4j0Y73fZcZrMJEH3W2DcLsJiW90FBkuO3aSyXUvYga9a4DcaMCNBEPWAdfCbSGWnviU_-G3xQj07tQavrS13DNLmVIdT6n_xJNcgLw53mY59fz7eNjLmidmB_vH8dP9JVnF0BeJaU3O9w?width=2785&height=1072&cropmode=none) + +![image1](https://4ltnmw.dm.files.1drv.com/y4mFdpZT99VPwwCDNYanxPWBWunyqkFPrQjP79USuho-fuY7GvHZMWIdQ-6KIULEqYLul1axknGVS49qSSoN4KgzC7FshCOMn6Y5v78WT2tn3PIrzy7jMk9dJPxOeizAq6wVRXsuAWYTcuX7DQKzvxZNDigiGQimlRG_WNSfo3dyvbQkkVumjt4UIkDIKpKw6ZhF8j4EyqSIOkS9VTOv3epFA?width=2874&height=1245&cropmode=none) + + diff --git a/_problems/coinChange2.md b/_problems/coinChange2.md new file mode 100644 index 0000000..20e752b --- /dev/null +++ b/_problems/coinChange2.md @@ -0,0 +1,96 @@ +--- +layout: page +title: Coin Change 2 +last_solved: 2020-06-07 +category: dp +leetcode_url: https://leetcode.com/problems/coin-change-2 +status: Not Solved +--- + +Problem +------- + +``` +You are given coins of different denominations and a total amount of money. Write a function to compute the number of combinations that make up that amount. You may assume that you have infinite number of each kind of coin. + +Example 1: + +Input: amount = 5, coins = [1, 2, 5] +Output: 4 +Explanation: there are four ways to make up the amount: +5=5 +5=2+2+1 +5=2+1+1+1 +5=1+1+1+1+1 +Example 2: + +Input: amount = 3, coins = [2] +Output: 0 +Explanation: the amount of 3 cannot be made up just with coins of 2. +Example 3: + +Input: amount = 10, coins = [10] +Output: 1 + +``` + +Solution +---------- + +[This](https://www.youtube.com/watch?v=DJ4a7cmjZY0) video from backtobackswe explains why you subtract the coin. + +``` + 0 1 2 3 4 5 +[1] 1 1 1 1 ^1^ 1 +[1,2] 1 1 `2` 2 *3* 3 +[1,2,5] 1 1 2 2 3 4 +``` + +```*3* = ^1^ + `2` ``` + +Think of "ways to make $4 with [1,2]" is equal to: + +It's equal to (ways to make $4 with [1] coin) + (ways to make $2 with [1,2] coins) + +``` (1+1+1+1) + ( [1,1] + [2] ) "+2 if we use the $2 coin" ``` + +The reason it's "ways to make $2 with [1,2] coins" is because if **we USE THE 2 coin, then it's $4-$2 coin, and we solve subproblem of ways to make $2 with [1,2] coins** + +{% highlight python %} + + def change(self, amount: int, coins: List[int]) -> int: + + dp = [ [1]+[0]*amount for _ in range(len(coins)+1)] + + for c in range(1, len(coins)+1): + for a in range(1, amount+1): + if coins[c-1] <= a: + dp[c][a] = dp[c-1][a] + dp[c][a-coins[c-1]] + else: + dp[c][a] = dp[c-1][a] + + print(dp) + return dp[len(coins)][amount] # or dp[-1][-1] + +{% endhighlight %} + +______ + +This code is simplier, try to analyze this one instead + +{% highlight python %} + + def change(self, amount: int, coins: List[int]) -> int: + dp = [0] * (amount + 1) # DP Array of size (Amount +1) initialized to 0 + dp[0] = 1 + + for currCoin in coins: + for currAmount in range(currCoin, amount + 1): + dp[currAmount] += dp[currAmount - currCoin] + + return dp[-1] + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/combinationSum2.md b/_problems/combinationSum2.md new file mode 100644 index 0000000..29d9330 --- /dev/null +++ b/_problems/combinationSum2.md @@ -0,0 +1,85 @@ +--- +layout: page +title: Combination Sum II +last_solved: +category: backtrack +leetcode_url: https://leetcode.com/problems/combination-sum-ii +status: Attempted +--- + +Problem +------- + +``` +Given a collection of candidate numbers (candidates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target. + +Each number in candidates may only be used once in the combination. + +Note: + +All numbers (including target) will be positive integers. +The solution set must not contain duplicate combinations. +Example 1: + +Input: candidates = [10,1,2,7,6,1,5], target = 8, +A solution set is: +[ + [1, 7], + [1, 2, 5], + [2, 6], + [1, 1, 6] +] +Example 2: + +Input: candidates = [2,5,2,1,2], target = 5, +A solution set is: +[ + [1,2,2], + [5] +] +``` + +Solution +---------- + + + +{% highlight python %} + + def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]: + + output = [] + candidates = sorted(candidates) + + def backtrack(currentList, remaining, start): + + if remaining<0: + return + elif remaining==0: + output.append(currentList.copy()) + else: + + for i in range(start, len(candidates)): + + if i==start or candidates[i]!=candidates[i-1]: + + currentList.append(candidates[i]) + backtrack(currentList, remaining-candidates[i], i+1) + currentList.pop() + + backtrack([], target, 0) + return output + + +{% endhighlight %} + +______________ + + + +{% highlight python %} + + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/combinationSum3.md b/_problems/combinationSum3.md new file mode 100644 index 0000000..f0774a7 --- /dev/null +++ b/_problems/combinationSum3.md @@ -0,0 +1,82 @@ +--- +layout: page +title: Combination Sum III +last_solved: +category: backtrack +leetcode_url: https://leetcode.com/problems/combination-sum-iii +status: Attempted +--- + +Problem +------- + +``` +Find all possible combinations of k numbers that add up to a number n, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers. + +Note: + +The solution set must not contain duplicate combinations. + + +Example 1: + +Input: k = 3, n = 7 +Output: [[1,2,4]] +Example 2: + +Input: k = 3, n = 9 +Output: [[1,2,6],[1,3,5],[2,3,4]] +Example 3: + +Input: k = 4, n = 1 +Output: [] +Example 4: + +Input: k = 3, n = 2 +Output: [] +Example 5: + +Input: k = 9, n = 45 +Output: [[1,2,3,4,5,6,7,8,9]] +``` + +Solution +---------- + + + +{% highlight python %} + + def combinationSum3(self, k: int, n: int) -> List[List[int]]: + + + output = [] + + def backtrack(output, current, num, sumsofar): + + if len(current)==k and sumsofar==n: + output.append(current.copy()) + return + + for i in range(num, 10): + if sumsofar+1 > n: break + backtrack(output, current+[i], i+1, sumsofar+i) + + + + backtrack(output, [], 1, 0) + return output + + +{% endhighlight %} + +______________ + + + +{% highlight python %} + + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/combination_sum.md b/_problems/combination_sum.md new file mode 100644 index 0000000..9cd792a --- /dev/null +++ b/_problems/combination_sum.md @@ -0,0 +1,129 @@ +--- +layout: page +title: Combination Sum +last_solved: 2020-06-27 +category: permutations +leetcode_url: https://leetcode.com/problems/combination-sum/ +status: Attempted +--- + +Problem +------- + +``` +Given a set of candidate numbers (candidates) (without duplicates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target. + +The same repeated number may be chosen from candidates unlimited number of times. + +Note: + +All numbers (including target) will be positive integers. +The solution set must not contain duplicate combinations. +Example 1: + +Input: candidates = [2,3,6,7], target = 7, +A solution set is: +[ + [7], + [2,2,3] +] +Example 2: + +Input: candidates = [2,3,5], target = 8, +A solution set is: +[ + [2,2,2,2], + [2,3,3], + [3,5] +] + +``` + +Solution +---------- + +{% highlight python %} + +candidates = [2,3,6,7] +target = 7 + +def combinationSum(candidates, target): + + def backtrack(currentList, nums, start): + + if sum(currentList)==target: + allValidCombos.append( currentList.copy() ) + return + if sum(currentList) > target: # optimization + return + for i in range(start, len(nums)): + backtrack(currentList + [nums[i]], nums, i) + # currentList.append( nums[i] ) + # backtrack( currentList, nums, start) + + allValidCombos = [] + backtrack([], candidates, 0 ) + return allValidCombos + +print( combinationSum(candidates, target) ) + +{% endhighlight %} + +______________ + +{% highlight python %} + + def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]: + + output = [] + + def backtrack(currentList, start): + + if sum(currentList)==target: + output.append(currentList.copy()) + return + + if sum(currentList) > target: # optimization + return + + for i in range(start, len(candidates)): + backtrack(currentList + [candidates[i]], i) + + + backtrack([], 0) + return output + +{% endhighlight %} + + +____________ + + +- [watch this explaination](https://www.youtube.com/watch?v=irFtGMLbf-s) +- [watch this too](https://www.youtube.com/watch?v=MTI2wc8s0BY) + +{% highlight python %} + + def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]: + + output = [] + + def backtrack(currentList, remaining, start): + + if remaining<0: + return + elif remaining==0: + output.append(currentList.copy()) + else: + + for i in range(start, len(candidates)): + currentList.append(candidates[i]) + backtrack(currentList, remaining-candidates[i], i) + currentList.pop() + + backtrack([], target, 0) + return output + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/containsDuplicates.md b/_problems/containsDuplicates.md new file mode 100644 index 0000000..89ec561 --- /dev/null +++ b/_problems/containsDuplicates.md @@ -0,0 +1,44 @@ +--- +layout: page +title: Contains Duplicates +--- + +#### Sorting solution + +Sort then check if consecutive numbers are increasing. +O(1) space, O(nlogn) time + + + + +#### HashTable/Set Solution + +O(n) time, O(n) space + +{% highlight python %} + +def containsDuplicate(self, nums: List[int]) -> bool: + + set = {} + for num in nums: + if num in set: + return True + else: + set[num] = None + + return False + +{% endhighlight %} + + +#### Check len(set)==len(list) + +{% highlight python %} + +def containsDuplicate(self, nums: List[int]) -> bool: + + return len(set(nums))!=len(nums) + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/convertSortedArrayToBST.md b/_problems/convertSortedArrayToBST.md new file mode 100644 index 0000000..9bd6fd0 --- /dev/null +++ b/_problems/convertSortedArrayToBST.md @@ -0,0 +1,59 @@ +--- +layout: page +title: Convert Sorted Array to Binary Search Tree +last_solved: +category: +leetcode_url: https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/ +status: Attempted +--- + +Problem +------- + +``` +Given an array where elements are sorted in ascending order, convert it to a height balanced BST. + +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. + +Example: + +Given the sorted array: [-10,-3,0,5,9], + +One possible answer is: [0,-3,9,-10,null,5], which represents the following height balanced BST: + + 0 + / \ + -3 9 + / / + -10 5 + +``` + +Solution +---------- + +{% highlight python %} + +def sortedArrayToBST(self, nums: List[int]) -> TreeNode: + + def buildTree(nums, left, right): + + if left>right: return + + mid = (left+right) // 2 + + node = TreeNode(nums[mid]) + + node.left = buildTree(nums, left, mid-1) + node.right = buildTree(nums, mid+1, right) + + return node + + if not nums: return None + + return buildTree(nums, 0, len(nums)-1) + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/copyListWithRandomPointer.md b/_problems/copyListWithRandomPointer.md new file mode 100644 index 0000000..e498f92 --- /dev/null +++ b/_problems/copyListWithRandomPointer.md @@ -0,0 +1,126 @@ +--- +layout: page +title: Copy List with Random Pointer +last_solved: +category: linked list +leetcode_url: https://leetcode.com/problems/copy-list-with-random-pointer/ +status: Attempted +--- + +Problem +------- + +``` +A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null. + +Return a deep copy of the list. + +The Linked List is represented in the input/output as a list of n nodes. Each node is represented as a pair of [val, random_index] where: + +val: an integer representing Node.val +random_index: the index of the node (range from 0 to n-1) where random pointer points to, or null if it does not point to any node. + + +Example 1: + + +Input: head = [[7,null],[13,0],[11,4],[10,2],[1,0]] +Output: [[7,null],[13,0],[11,4],[10,2],[1,0]] +Example 2: + + +Input: head = [[1,1],[2,1]] +Output: [[1,1],[2,1]] +Example 3: + + + +Input: head = [[3,null],[3,0],[3,null]] +Output: [[3,null],[3,0],[3,null]] +Example 4: + +Input: head = [] +Output: [] +Explanation: Given linked list is empty (null pointer), so return null. +``` + +Solution +---------- + +It's trivial to clone the linked list but not with the random pointer. +The random pointer would point to a node that hasn't been cloned yet. + +1) Go thru list and build a hashmap with K=original node and V=cloned node +2) Go thru the list again and wire up the `next` and `random` cloned nodes + + +This has a bug and haven't been able to figure it out. + +{% highlight python %} + +from collections import defaultdict + +class Solution: + def copyRandomList(self, head: 'Node') -> 'Node': + + + curr = head + mapping = defaultdict(Node) + + # go thru list once and just create nodes and add to mapping + while curr: + + # create new node + newNode = Node(curr.val, None, None) + + # add to map + mapping[curr] = newNode + + # move to next node + curr = curr.next + + + # go thru list again and wire up the next and random pointers + curr = head + + while curr: + + # get cloned node + clonedCurr = mapping[curr] + + # get next and random of original node + origNext = curr.next + origRandom = curr.random + + # get cloned version of orig next and random + clonedNext = mapping.get(origNext, None) + clonedRandom = mapping.get(origRandom, None) + + # print(clonedCurr.val) + # print(clonedNext.val) + # print() + # print(clonedCurr.val, origNext.val, clonedNext.val) + + # wire up cloned nodes + clonedCurr.next = clonedNext + clonedCurr.next = clonedRandom + + + # move to next node + curr = curr.next + + + return mapping[head] + +{% endhighlight %} + +______________ + + + +{% highlight python %} + + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/countCompleteBinaryNodes.md b/_problems/countCompleteBinaryNodes.md new file mode 100644 index 0000000..7a1ce7f --- /dev/null +++ b/_problems/countCompleteBinaryNodes.md @@ -0,0 +1,54 @@ +--- +layout: page +title: Count Complete Tree Nodes +last_solved: 2020-06-23 +category: trees +leetcode_url: https://leetcode.com/problems/count-complete-tree-nodes/ +status: Attempted +--- + +Problem +------- + +``` +Given a complete binary tree, count the number of nodes. + +Note: + +Definition of a complete binary tree from Wikipedia: +In a complete binary tree every level, except possibly the last, is completely filled, and all nodes in the last level are as far left as possible. It can have between 1 and 2h nodes inclusive at the last level h. + +Example: + +Input: + 1 + / \ + 2 3 + / \ / +4 5 6 + +Output: 6 + +``` + +Solution +---------- + +There should be a better way to do this than O(n) if you take advantage of the complete binary tree property. + +{% highlight python %} + +def countNodes(self, root: TreeNode) -> int: + + if not root: + return 0 + + leftRes = self.countNodes(root.left) + rightRes = self.countNodes(root.right) + + return 1 + leftRes + rightRes + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/countOnesInArray.md b/_problems/countOnesInArray.md new file mode 100644 index 0000000..9a0060b --- /dev/null +++ b/_problems/countOnesInArray.md @@ -0,0 +1,63 @@ +--- +layout: page +title: Count Ones (In Array) +--- + +{% highlight text %} + +''' + https://leetcode.com/problems/counting-bits/ + + Problem: + + Given num, return array which contains numOnes + Ie, input = 2, return [0,1,1] + + Do it in O(n) time, and not O(n*numBits) + + Solution: dynamic programming (build table bottom up) + + d[i] = d[i//2] + (i%2) + + ex: + d[3] = d[3//2] + 3%2 + = d[1] + 1 + = 2 + d[6] = d[6//2] + 6%2 + = d[3] + 0 + = 2 + 0 + = 2 + d[7] = d[7//2] + 7%2 + = d[3] + 1 + = 2 + 1 = 3 + + https://leetcode.com/problems/counting-bits/discuss/626777/Easy-DP-Explanation-%3A-Python-Solution +''' + +{% endhighlight %} + + +{% highlight python %} + + + +def countOnes(num): + + if num==0: return [0] + if num==1: return [0,1] + + + dp=[0,1] + + for i in range(2, num+1): + # dp[i] = dp[i//2] + (i%2) + dp.append( dp[i//2] + (i%2) ) + + return dp + +print(countOnes(2)) + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/cousinsInBinaryTree.md b/_problems/cousinsInBinaryTree.md new file mode 100644 index 0000000..4398673 --- /dev/null +++ b/_problems/cousinsInBinaryTree.md @@ -0,0 +1,129 @@ +--- +layout: page +title: Cousins in Binary Tree +last_solved: +category: bfs/dfs +leetcode_url: https://leetcode.com/problems/cousins-in-binary-tree +status: Solved +--- + +Problem +------- + +``` +In a binary tree, the root node is at depth 0, and children of each depth k node are at depth k+1. + +Two nodes of a binary tree are cousins if they have the same depth, but have different parents. + +We are given the root of a binary tree with unique values, and the values x and y of two different nodes in the tree. + +Return true if and only if the nodes corresponding to the values x and y are cousins. + + + +Example 1: + + +Input: root = [1,2,3,4], x = 4, y = 3 +Output: false +Example 2: + + +Input: root = [1,2,3,null,4,null,5], x = 5, y = 4 +Output: true +Example 3: + + + +Input: root = [1,2,3,null,4], x = 2, y = 3 +Output: false + +``` + +![image1](https://assets.leetcode.com/uploads/2019/02/12/q1248-02.png) + +Solution +---------- + +BFS + +{% highlight python %} + +def isCousins(self, root: TreeNode, x: int, y: int) -> bool: + + if not root: + return [] + + q = [root] + parents = defaultdict(list) # track parents in a dictionary + levels = [] + + + parents[root.val] = None + + while q: + + level = [] + + for _ in range(len(q)): + + curr = q.pop(0) + level.append(curr.val) + + if curr.left: + q.append(curr.left) + parents[curr.left.val] = curr.val + + + if curr.right: + q.append(curr.right) + parents[curr.right.val] = curr.val + + levels.append(level) + + print(levels) + print(parents) + + + # loop thru rows and check if they have different parents + for row in levels: + if x in row and y in row and parents[x] != parents[y]: + return True + + return False + +{% endhighlight %} + +______________ + +DFS + +[How does this work with self](https://leetcode.com/problems/cousins-in-binary-tree/discuss/741717/Python-beats-98-(easy-to-understand)-with-explanation) + +Note: use `self.xxx` instead of `nonlocal` + +{% highlight python %} + +def isCousins(self, root: TreeNode, x: int, y: int) -> bool: + + def dfs(node, level, parent): + + if not node: + return + + if node.val == x: + self.x_level = level + self.x_parent = parent + elif node.val == y: + self.y_level = level + self.y_parent = parent + + dfs(node.left, level+1, node) + dfs(node.right, level+1, node) + + + dfs(root, 0, None) + + return self.x_level==self.y_level and self.x_parent!=self.y_parent + +{% endhighlight %} \ No newline at end of file diff --git a/_problems/deepestLeavesSumBFS.md b/_problems/deepestLeavesSumBFS.md new file mode 100644 index 0000000..101de72 --- /dev/null +++ b/_problems/deepestLeavesSumBFS.md @@ -0,0 +1,43 @@ +--- +layout: page +title: Deepest Leaves Sum (BFS) +last_solved: 2020-08-31 +category: bfs +leetcode_url: https://leetcode.com/problems/deepest-leaves-sum/ +status: Solved +--- + + + + +{% highlight python %} + + def deepestLeavesSum(self, root: TreeNode) -> int: + + if not root: return 0 + + queue = [root] + levels = [] + + while queue: + + level = [] + + for _ in range(len(queue)): + + node = queue.pop(0) + + level.append(node.val) + + if node.left: + queue.append(node.left) + if node.right: + queue.append(node.right) + + levels.append(level) + + return sum(levels[-1]) + +{% endhighlight %} + + diff --git a/_problems/deepestLeavesSumDFS.md b/_problems/deepestLeavesSumDFS.md new file mode 100644 index 0000000..b43fc44 --- /dev/null +++ b/_problems/deepestLeavesSumDFS.md @@ -0,0 +1,80 @@ +--- +layout: page +title: Deepest Leaves Sum (DFS) +last_solved: 2020-07-17 +category: trees +leetcode_url: https://leetcode.com/problems/deepest-leaves-sum/ +status: Solved +--- + +``` +Given a binary tree, return the sum of values of its deepest leaves. +``` + + +{% highlight python %} + +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + + +def deepestLeavesSum(root): + + map = {} + + def dfs(root, depth): + + map[depth] = root.val + map.get(depth, 0) + + if root.left: + dfs(root.left, depth+1) + if root.right: + dfs(root.right, depth+1) + + + dfs(root, 0) + return map[max(map)] + +root = TreeNode(1) +root.left = TreeNode(2) +root.right = TreeNode(3) +root.left.left = TreeNode(4) +root.left.right = TreeNode(5) + +print deepestLeavesSum(root) + +{% endhighlight %} + +_______________ + + +{% highlight python %} + +def deepestLeavesSum(self, root: TreeNode) -> int: + + lookup = defaultdict(int) + + def dfs(node, level): + + if not node: + return + + lookup[level] = lookup[level]+node.val + + dfs(node.left, level+1) + dfs(node.right, level+1) + + dfs(root, 0) + + print(lookup) + + return lookup[max(lookup)] + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/findAllAnagramsInString.md b/_problems/findAllAnagramsInString.md new file mode 100644 index 0000000..8204402 --- /dev/null +++ b/_problems/findAllAnagramsInString.md @@ -0,0 +1,85 @@ +--- +layout: page +title: Find All Anagrams in a String +last_solved: +category: sliding window +leetcode_url: https://leetcode.com/problems/find-all-anagrams-in-a-string +status: Attempted +--- + +Problem +------- + +``` +Given a string s and a non-empty string p, find all the start indices of p's anagrams in s. + +Strings consists of lowercase English letters only and the length of both strings s and p will not be larger than 20,100. + +The order of output does not matter. + +Example 1: + +Input: +s: "cbaebabacd" p: "abc" + +Output: +[0, 6] + +Explanation: +The substring with start index = 0 is "cba", which is an anagram of "abc". +The substring with start index = 6 is "bac", which is an anagram of "abc". +Example 2: + +Input: +s: "abab" p: "ab" + +Output: +[0, 1, 2] + +Explanation: +The substring with start index = 0 is "ab", which is an anagram of "ab". +The substring with start index = 1 is "ba", which is an anagram of "ab". +The substring with start index = 2 is "ab", which is an anagram of "ab". +``` + +Solution +---------- + +Initially did this, but TLE +TC is n*nlogn + +sort is expensive + +{% highlight python %} + + def findAnagrams(self, s: str, p: str) -> List[int]: + + if not s: return [] + + length = len(p) + + + output = [] + for i in range(len(s)-length+1): + + # sliding window of s + window = s[i:i+length] + + if sorted(window)==sorted(p): + output.append(i) + + return output + + +{% endhighlight %} + +______________ + + + +{% highlight python %} + + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/findAllDupsInArray.md b/_problems/findAllDupsInArray.md new file mode 100644 index 0000000..ec7eb43 --- /dev/null +++ b/_problems/findAllDupsInArray.md @@ -0,0 +1,84 @@ +--- +layout: page +title: Find all Duplicates in Array +last_solved: 2020-08-06 +category: array +leetcode_url: https://leetcode.com/problems/find-all-duplicates-in-an-array +status: Attempted +--- + +Problem +------- + +``` +Given an array of integers, 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once. + +Find all the elements that appear twice in this array. + +Could you do it without extra space and in O(n) runtime? + +Example: +Input: +[4,3,2,7,8,2,3,1] + +Output: +[2,3] + +``` + +Solution +---------- + +If you can use extra space for a hashmap. Then you can use this one-liner + +{% highlight python %} + +def findDuplicates(self, nums: List[int]) -> List[int]: + + c = Counter(nums) + + print(c) + + # output = [] + # for k, v in c.items(): + # if v==2: + # output.append(k) + + return [k for k,v in c.items() if v==2] + +{% endhighlight %} + +________________ + +To not use any additional space, we can only modify the existing array. +Use the constraint `1-7) +- If there is another 4 in the array, it will check the 7 and see that it's negative. If it's negative, add it to the output array. + + + +{% highlight python %} + +def findDuplicates(self, nums: List[int]) -> List[int]: + + # [4,3,2,7,8,2,3,1] + # [2,2] + + output = [] + + for i,v in enumerate(nums): + + pos_v = abs(v) + + if nums[pos_v-1]<0: + output.append(pos_v) + + # mark as visited + nums[pos_v-1] = abs(nums[pos_v-1])*-1 + +{% endhighlight %} + +________________ + +![image1]() \ No newline at end of file diff --git a/_problems/findMinInSortedArray.md b/_problems/findMinInSortedArray.md new file mode 100644 index 0000000..43359eb --- /dev/null +++ b/_problems/findMinInSortedArray.md @@ -0,0 +1,134 @@ +--- +layout: page +title: Find Min in Sorted Array +last_solved: 2020-07-27 +category: binary search +leetcode_url: https://leetcode.com/problems/find-minimum-in-rotated-sorted-array +status: Attempted +--- + +Problem +------- + +``` +Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. + +(i.e., [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2]). + +Find the minimum element. + +You may assume no duplicate exists in the array. + +Example 1: + +Input: [3,4,5,1,2] +Output: 1 +Example 2: + +Input: [4,5 + +``` + +Solution +---------- + +Try a more concise solution: + +{% highlight python %} + +l, r = 0, len(nums) - 1 +while nums[l] > nums[r]: + mid = int((l+r)/2) + if nums[mid] >= nums[l]: + l = mid + 1 + else: + r = mid +return nums[l] + +{% endhighlight %} + + +Think of examples with each of the if statements + + +if nums[mid] > nums[mid+1]: + +mid = 1, nums=1 +[2,1,3] + + + + +{% highlight python %} + +arr = [4,5,6,7,2,3] + +def findMin(nums): + + # 1-elem array + if len(nums)==1: + return nums[0] + + left = 0 + right = len(nums)-1 + + # this condition means arr is already sorted, so just return first element + if nums[right] > nums[0]: + return nums[0] + + + while right>=left: + + mid = left + (right-left) // 2 + + # min found: case 1 + if nums[mid] > nums[mid+1]: # 3 4 5 1 2 where 5 is mid + return nums[mid+1] + + # min found: case 2 + if nums[mid-1] > nums[mid]: # 4 5 1 2 3 where 1 is mid + return nums[mid] + + + ### min not found cases below + # mid is greater than first elem so ignore left half + if nums[mid] > nums[0]: + left = mid+1 + + # mid is less than first elem, ignore right half + else: + right = mid-1 + + +print(findMin(arr)) + + +{% endhighlight %} + + +____________- + + +Using the [powerful binary search template](https://leetcode.com/discuss/general-discussion/786126/python-powerful-ultimate-binary-search-template-solved-many-problems) + +{% highlight python %} + +def findMin(self, nums: List[int]) -> int: + + left, right = 0, len(nums)-1 + + while left int: + + left, right = 0, len(nums)-1 + + while left int: + + slow = nums[0] + fast = nums[0] + + # find intersection point of 2 ptrs in cycle + while True: + slow = nums[slow] + fast = nums[nums[fast]] + + if slow==fast: + break + + # key point: after they meet in cycle, the gap between beginning to entrance and where fast pointer resides to entrace are equal + + # find the entrace + slow = nums[0] # reset slow back to beginning + while slow != fast: + slow = nums[slow] + fast = nums[fast] + + return fast + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/firstBadVersion.md b/_problems/firstBadVersion.md new file mode 100644 index 0000000..4e377ac --- /dev/null +++ b/_problems/firstBadVersion.md @@ -0,0 +1,92 @@ +--- +layout: page +title: First Bad Version +last_solved: +category: binary search +leetcode_url: https://leetcode.com/problems/first-bad-version +status: Attempted +--- + +Problem +------- + +``` +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. + +Example: + +Given n = 5, and version = 4 is the first bad version. + +call isBadVersion(3) -> false +call isBadVersion(5) -> true +call isBadVersion(4) -> true + +Then 4 is the first bad version. + +``` + +Solution +---------- + +Check for condition at mid and to the right of mid. + +``` + + | | +1 2 3 4 5 +F F F T T + +``` + +{% highlight python %} + +def firstBadVersion(self, n): + + low, high = 1, n + + while low<=high: + + mid = (low+high)//2 + + if isBadVersion(mid) and not isBadVersion(mid-1): + return mid + elif not isBadVersion(mid): + low = mid+1 + else: + high = mid-1 + + return -1 + +{% endhighlight %} + + +________________ + + +{% highlight python %} + +def firstBadVersion(self, n): + + left, right = 1, n + + while left < right: + + mid = (left+right)//2 + + if isBadVersion(mid): + + right = mid + + else: + + left = mid + 1 + + return left + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/firstNonRepeatingChar.md b/_problems/firstNonRepeatingChar.md new file mode 100644 index 0000000..74462aa --- /dev/null +++ b/_problems/firstNonRepeatingChar.md @@ -0,0 +1,54 @@ +--- +layout: page +title: First Unque Char in String +last_solved: 2020-06-06 +category: string +leetcode_url: https://leetcode.com/problems/first-unique-character-in-a-string +status: Solved +--- + +Problem +------- + +``` +Given a string, find the first non-repeating character in it and return it's index. If it doesn't exist, return -1. + +Examples: + +s = "leetcode" +return 0. + +s = "loveleetcode", +return 2. + +``` + +Solution +---------- + +{% highlight python %} + +def firstUniqChar(self, s: str) -> int: + + if not s: return -1 + + dict = {} + + # add to dict + for c in s: + if c not in dict.keys(): + dict[c] = 1 + else: + dict[c] = dict[c]+1 + + # find first char with count=1 and return it + for i, c in enumerate(s): + if dict[c]==1: + return i + + return -1 + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/flattenMultilevelDoublyLinkedList.md b/_problems/flattenMultilevelDoublyLinkedList.md new file mode 100644 index 0000000..5084232 --- /dev/null +++ b/_problems/flattenMultilevelDoublyLinkedList.md @@ -0,0 +1,111 @@ +--- +layout: page +title: Flatten a Multilevel Doubly Linked List +last_solved: 2020-07-10 +category: linked list +leetcode_url: https://leetcode.com/problems/flatten-a-multilevel-doubly-linked-list/ +status: Attempted +--- + +Problem +------- + +``` +You are given a doubly linked list which in addition to the next and previous pointers, it could have a child pointer, which may or may not point to a separate doubly linked list. These child lists may have one or more children of their own, and so on, to produce a multilevel data structure, as shown in the example below. + +Flatten the list so that all the nodes appear in a single-level, doubly linked list. You are given the head of the first level of the list. + + + +Example 1: + +Input: head = [1,2,3,4,5,6,null,null,null,7,8,9,10,null,null,11,12] +Output: [1,2,3,7,8,11,12,9,10,4,5,6] +Explanation: + +The multilevel linked list in the input is as follows: + + + +After flattening the multilevel linked list it becomes: + + +Example 2: + +Input: head = [1,2,null,3] +Output: [1,3,2] +Explanation: + +The input multilevel linked list is as follows: + + 1---2---NULL + | + 3---NULL +Example 3: + +Input: head = [] +Output: [] + + +How multilevel linked list is represented in test case: + +We use the multilevel linked list from Example 1 above: + + 1---2---3---4---5---6--NULL + | + 7---8---9---10--NULL + | + 11--12--NULL +The serialization of each level is as follows: + +[1,2,3,4,5,6,null] +[7,8,9,10,null] +[11,12,null] +To serialize all levels together we will add nulls in each level to signify no node connects to the upper node of the previous level. The serialization becomes: + +[1,2,3,4,5,6,null] +[null,null,7,8,9,10,null] +[null,11,12,null] +Merging the serialization of each level and removing trailing nulls we obtain: + +[1,2,3,4,5,6,null,null,null,7,8,9,10,null,null,11,12] + +``` + +Solution +---------- + +{% highlight python %} + +def flatten(self, head: 'Node') -> 'Node': + + + if not head: return head + + dummy = Node(0) + + curr = dummy + stack = [head] + + while stack: + + tmp = stack.pop() + + if tmp.next: stack.append( tmp.next ) + if tmp.child: stack.append( tmp.child ) + + print( tmp.val ) + + curr.next = tmp + tmp.prev = curr + + tmp.child = None # no child pointers + curr = tmp # move ahead + + dummy.next.prev = None + return dummy.next + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/floodfill.md b/_problems/floodfill.md new file mode 100644 index 0000000..cc5021d --- /dev/null +++ b/_problems/floodfill.md @@ -0,0 +1,90 @@ +--- +layout: page +title: Flood Fill +last_solved: 2020-06-19 +category: union find +leetcode_url: https://leetcode.com/problems/flood-fill/ +status: Solved +--- + +Be careful with this critical tranversal section, if you make a mistake (ie: > instead of <, than it may not visit the entire grid) + +{% highlight text %} + +if r>=1: dfs(r-1, c) # go up +if r+1=1: dfs(r, c-1) # go left +if c+1=1: dfs(r-1, c) # go up + if r+1=1: dfs(r, c-1) # go left + if c+1 List[List[int]]: + + R = len(image) + C = len(image[0]) + + oldColor = image[startRow][startCol] + if newColor==oldColor: return image + + def dfs(i,j, newColor): + + if i<0 or i>=R or j<0 or j>=C or image[i][j]!=oldColor: # conditions to "retrack back" + return + + dirs = [[i-1,j],[i+1,j],[i,j-1],[i,j+1]] + for x,y in dirs: + image[i][j]=newColor # the processing that you want to do + dfs(x, y, newColor) + + dfs(startRow, startCol, newColor) + + return image + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/generateParanthesis.md b/_problems/generateParanthesis.md new file mode 100644 index 0000000..c6d6ad4 --- /dev/null +++ b/_problems/generateParanthesis.md @@ -0,0 +1,98 @@ +--- +layout: page +title: Generate Parenthesis +last_solved: 2020-08-18 +category: backtracking +leetcode_url: https://leetcode.com/problems/generate-parentheses/ +status: Attempted +--- + +Problem +------- + +``` +Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses. + +For example, given n = 3, a solution set is: + +[ + "((()))", + "(()())", + "(())()", + "()(())", + "()()()" +] + +``` + +Solution +---------- + +For backtracking problems, think of the base case and decisions. Then follow the backtracking template. + +base case is when current string == n*2 because when () is a pair. +the decision is when to put the open and close braces. + + +{% highlight python %} + +n=3 + +def generateParenthesis(n): + + def backtrack(outputList, currentString, open, close, n): + + # base case + if len(currentString)==2*n: + outputList.append(currentString) + print("output " + currentString) + return + + print( currentString ) + + # decisions below + if open < n: + backtrack( outputList, currentString+"(", open+1, close, n ) + + if close < open: + backtrack( outputList, currentString+")", open, close+1, n) + + outputList = [] + backtrack( outputList, "", 0, 0, n) + return outputList + + +print( generateParenthesis(n) ) + + +{% endhighlight %} + + +``` + +( +(( +((( +((() +((()) +output ((())) +(() +(()( +(()() +output (()()) +(()) +(())( +output (())() +() +()( +()(( +()(() +output ()(()) +()() +()()( +output ()()() +['((()))', '(()())', '(())()', '()(())', '()()()'] + +``` + +![image1](https://i.ibb.co/Dr9xNgv/image.png) \ No newline at end of file diff --git a/_problems/groupAnagrams.md b/_problems/groupAnagrams.md new file mode 100644 index 0000000..1dc12bc --- /dev/null +++ b/_problems/groupAnagrams.md @@ -0,0 +1,82 @@ +--- +layout: page +title: Group Anagrams +last_solved: 2020-07-13 +category: hashmap +leetcode_url: https://leetcode.com/problems/group-anagrams/ +status: Solved +--- + +Problem +------- + +``` +Given an array of strings, group anagrams together. + +Example: + +Input: ["eat", "tea", "tan", "ate", "nat", "bat"], +Output: +[ + ["ate","eat","tea"], + ["nat","tan"], + ["bat"] +] + +``` + +Solution +---------- + +My solution: + +{% highlight python %} + +def groupAnagrams(self, strs: List[str]) -> List[List[str]]: + + def sortWord(word): + return ''.join(sorted(word)) + + mapping = {} + for word in strs: + + print(word) + + if sortWord(word) not in mapping: + mapping[sortWord(word)] = [word] + else: + mapping[sortWord(word)] = mapping[sortWord(word)] + [word] + + # mapping[sortWord(word)] = mapping[sortWord(word)].append(word) + + print(mapping) + + return list(mapping.values()) + + +{% endhighlight %} + + +_________ + + + +Timonthy's More Concise Solution. Using defaultdict() so you don't have to do "if value not in" code. + +{% highlight python %} + +def groupAnagrams(self, strs: List[str]) -> List[List[str]]: + + def sortWord(word): + return ''.join(sorted(word)) + + lookup = defaultdict(list) + + for word in strs: + lookup[ sortWord(word) ].append( word ) + + return list(lookup.values()) + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/groupIsomorphicStrings.md b/_problems/groupIsomorphicStrings.md new file mode 100644 index 0000000..1ade03e --- /dev/null +++ b/_problems/groupIsomorphicStrings.md @@ -0,0 +1,75 @@ +--- +layout: page +title: Group Isometric Strings +last_solved: 2020-06-11 +category: hashmap +leetcode_url: https://leetcode.com/discuss/interview-question/368038/Amazon-or-Onsite-or-Group-Isomorphic-Strings +status: Solved +--- + +Problem +------- + +Two strings are isomorphic if each character of their strings can be mapped to another character and retain the same "structure". + +`egg` and `add` are isomorphic +`e->a, g->d` + +``` +Given: [“foo”, “bar”, “paper”, “title”, “egg”, “add”] +Expected: [[“bar”],[“paper” “title”], [“egg”, “add”, "foo”]] + +``` + +Solution +---------- + +{% highlight python %} + +def normalize(word): + + res = "" + count = 0 + + map = {} + for c in word: + if c not in map: + map[c] = count + count+=1 + res += str(map[c]) + else: + res += str(map[c]) + + return res + +def findIso(arr): + + map = {} + + # first pass to build map + for word in arr: + if normalize(word) not in map: + map[ normalize(word) ] = [word] + else: + # existingList = map[ normalize(word) ] + # existingList.append(word) + # map[ normalize(word) ] = existingList + map[ normalize(word) ].append(word) + + # second pass to extract grouped words in the map +# result = [] +# for groupedWords in map.values(): +# result.append( groupedWords ) + +# return result + + return list( map.values() ) + +input1 = ["foo", "bar", "paper", "title", "egg", "add"] +res = findIso(input1) +print(res) + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/guessNumberHigherOrLower.md b/_problems/guessNumberHigherOrLower.md new file mode 100644 index 0000000..1ded46a --- /dev/null +++ b/_problems/guessNumberHigherOrLower.md @@ -0,0 +1,81 @@ +--- +layout: page +title: Guess Number Higher or Lower +last_solved: +category: binary search +leetcode_url: https://leetcode.com/problems/guess-number-higher-or-lower +status: Attempted +--- + +Problem +------- + +``` +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 : + +Input: n = 10, pick = 6 +Output: 6 + +``` + +Solution +---------- + +Simplist binary search ever + +{% highlight python %} + +def guessNumber(self, n: int) -> int: + + low, high = 1, n + + while low<=high: + + mid = (low+high)//2 + + if guess(mid)==0: + return mid + elif guess(mid)==-1: + high = mid-1 + else: + low = mid+1 + + return None + +{% endhighlight %} + +__________ + +{% highlight python %} + +def guessNumber(self, n: int) -> int: + + left, right = 1, n + + while left=3, it's the max of alternating sequences. + + +Gotcha: +- be careful when to use nums array and when to use dp array +- make sure to use a different dp array and don't overwrite the given `nums` array + +{% highlight python %} + +nums = [1,2,3,1] + + +def rob(nums): + + if not nums: return 0 + if len(nums)==1: return nums[0] + + dp = [1] * len(nums) + dp[0] = nums[0] + dp[1] = max(nums[0], nums[1]) + + for i in range(2, len(nums)): + # dp.append( max( nums[i] + dp[i-2], dp[i-1] ) ) + dp[i] = max( nums[i] + dp[i-2], dp[i-1] ) + + + return dp[-1] + +print(rob(nums)) + +{% endhighlight %} + +The dp array looks like ```[1, 2, 4, 4]``` + + +![image1]() \ No newline at end of file diff --git a/_problems/houseRobber2.md b/_problems/houseRobber2.md new file mode 100644 index 0000000..12f5726 --- /dev/null +++ b/_problems/houseRobber2.md @@ -0,0 +1,44 @@ +--- +layout: page +title: House Robber 2 +--- + + +Do house robber twice with a helper function. First time exclude first element, second exclude last element. Then take max. + +Handle corner cases first. + + + + +{% highlight python %} + +def rob(nums): + + # handle edge cases + if not nums: return 0 + if len(nums)==1: return nums[0] + if len(nums)==2: return max(nums[0], nums[1]) + + def robHelper(nums): + + dp = [1] * len(nums) + dp[0] = nums[0] + dp[1] = max(nums[0], nums[1]) + + for i in range(2, len(nums)): + dp[i] = max( nums[i] + dp[i-2], dp[i-1] ) + + print(dp) + + return dp[-1] + + excludeFirst = nums[1:] + excludeLast = nums[:-1] + + return max( robHelper(excludeFirst), robHelper(excludeLast) ) + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/implementATrie.md b/_problems/implementATrie.md new file mode 100644 index 0000000..75526db --- /dev/null +++ b/_problems/implementATrie.md @@ -0,0 +1,113 @@ +--- +layout: page +title: Implement Trie +last_solved: 2020-06-30 +category: Attempted +leetcode_url: https://leetcode.com/problems/implement-trie-prefix-tree/ +status: Attempted +--- + +Problem +------- + +``` +Implement a trie with insert, search, and startsWith methods. + +Example: + +Trie trie = new Trie(); + +trie.insert("apple"); +trie.search("apple"); // returns true +trie.search("app"); // returns false +trie.startsWith("app"); // returns true +trie.insert("app"); +trie.search("app"); // returns true + +``` + +Solution +---------- + +This code doesn't work correctly. Need to check it and debug it. + +[source](https://www.youtube.com/watch?v=KX2GdDZPxQA) + +{% highlight python %} + +class Node: + def __init__(self): + self.children = {} # the children that this node points to + self.endofword = False + +class Trie: + + def __init__(self): + self.root = Node() + + + def insert(self, word: str) -> None: + ptr = self.root + + for letter in word: + + if letter not in ptr.children: + ptr.children[letter] = Node() + + # traverse down the tree + ptr = ptr.children[letter] + ptr.endofword = True + + + + def search(self, word: str) -> bool: + + ptr = self.root + + for letter in word: + + if letter not in ptr.children: + return False + ptr = ptr.children[letter] + + # check end of word? + if ptr.endofword: + return True + else: + return False + + + + + + def startsWith(self, prefix: str) -> bool: + + ptr = self.root + + for letter in prefix: + + if letter not in ptr.children: + return False + ptr = ptr.children[letter] + + return True + + + + +trie = Trie(); + +output = [] +output.append( trie.insert("apple") ) +output.append( trie.search("apple") ) +output.append( trie.search("app") ) +output.append( trie.startsWith("app") ) +output.append( trie.insert("app") ) +output.append( trie.search("app") ) + +print(output) + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/implement_strstr.md b/_problems/implement_strstr.md new file mode 100644 index 0000000..c60703f --- /dev/null +++ b/_problems/implement_strstr.md @@ -0,0 +1,57 @@ +--- +layout: page +title: Implement strstr +last_solved: +category: string +leetcode_url: https://leetcode.com/problems/implement-strstr +status: Attempted +--- + +Problem +------- + +``` +Implement strStr(). + +Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack. + +Example 1: + +Input: haystack = "hello", needle = "ll" +Output: 2 +Example 2: + +Input: haystack = "aaaaa", needle = "bba" +Output: -1 + +``` + +Solution +---------- + +{% highlight python %} + + def strStr(self, haystack: str, needle: str) -> int: + + # "hello" "ll" + + if not needle: return 0 + + for i in range(len(haystack)): + + if haystack[i]==needle[0]: + + substr = haystack[i:i+len(needle)] + + if substr==needle: + + return i + + + return -1 + + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/increasingTripletSubsequence.md b/_problems/increasingTripletSubsequence.md new file mode 100644 index 0000000..e596519 --- /dev/null +++ b/_problems/increasingTripletSubsequence.md @@ -0,0 +1,96 @@ +--- +layout: page +title: Increasing Triplet Subsequence +last_solved: 2020-07-05 +category: dp +leetcode_url: https://leetcode.com/problems/increasing-triplet-subsequence +status: Solved +--- + +Problem +------- + +``` +Given an unsorted array return whether an increasing subsequence of length 3 exists or not in the array. + +Formally the function should: + +Return true if there exists i, j, k +such that arr[i] < arr[j] < arr[k] given 0 ≤ i < j < k ≤ n-1 else return false. +Note: Your algorithm should run in O(n) time complexity and O(1) space complexity. + +Example 1: + +Input: [1,2,3,4,5] +Output: true +Example 2: + +Input: [5,4,3,2,1] +Output: false + +``` + +Solution +---------- + +Initially tried this, but it would fail for ```[2,5,3,4,5]``` + +{% highlight python %} + + def increasingTriplet(self, nums: List[int]) -> bool: + + if not nums: return false + + first = nums[0] + second = None + third = None + + for i in range(1, len(nums)): + + if first and not second and not third and nums[i]>first: + second = nums[i] + elif first and second and not third and nums[i]>second: + third = nums[i] + + + print(first, second, third) + return True if third else False + + +{% endhighlight %} + +_____________ + +[A simpler solution involving thresholds](https://leetcode.com/problems/increasing-triplet-subsequence/discuss/78995/Python-Easy-O(n)-Solution/373508) + +{% highlight python %} + +def increasingTriplet(self, nums: List[int]) -> bool: + + + first = float('inf') + second = float('inf') + third = float('inf') + + for n in nums: + + if nfirst and nsecond and n List[List[int]]: + + merged = [] + i=0 + + # add all intervals that come before newInterval + while i TreeNode: + + if not root: + return TreeNode(val) + + # root is bigger, it goes on left side + if root.val > val: + if not root.left: + root.left = TreeNode(val) + else: + self.insertIntoBST(root.left, val) + + else: + if not root.right: + root.right = TreeNode(val) + else: + self.insertIntoBST(root.right, val) + + return root + +{% endhighlight %} + +______________ + + + +{% highlight python %} + + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/intersectionOfLinkedList.md b/_problems/intersectionOfLinkedList.md new file mode 100644 index 0000000..c6e5a4d --- /dev/null +++ b/_problems/intersectionOfLinkedList.md @@ -0,0 +1,104 @@ +--- +layout: page +title: Intersection of Two Linked Lists +last_solved: 2020-07-22 +category: linked list +leetcode_url: https://leetcode.com/problems/intersection-of-two-linked-lists/ +status: Attempted +--- + +Problem +------- + +``` +Write a program to find the node at which the intersection of two singly linked lists begins. + +For example, the following two linked lists: + + +begin to intersect at node c1. + + + +Example 1: + + +Input: intersectVal = 8, listA = [4,1,8,4,5], listB = [5,6,1,8,4,5], skipA = 2, skipB = 3 +Output: Reference of the node with value = 8 +Input Explanation: The intersected node's value is 8 (note that this must not be 0 if the two lists intersect). From the head of A, it reads as [4,1,8,4,5]. From the head of B, it reads as [5,6,1,8,4,5]. There are 2 nodes before the intersected node in A; There are 3 nodes before the intersected node in B. + + +Example 2: + + +Input: intersectVal = 2, listA = [1,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1 +Output: Reference of the node with value = 2 +Input Explanation: The intersected node's value is 2 (note that this must not be 0 if the two lists intersect). From the head of A, it reads as [1,9,1,2,4]. From the head of B, it reads as [3,2,4]. There are 3 nodes before the intersected node in A; There are 1 node before the intersected node in B. + + +Example 3: + + +Input: intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2 +Output: null +Input Explanation: From the head of A, it reads as [2,6,4]. From the head of B, it reads as [1,5]. Since the two lists do not intersect, intersectVal must be 0, while skipA and skipB can be arbitrary values. +Explanation: The two lists do not intersect, so return null. + + +Notes: + +If the two linked lists have no intersection at all, return null. +The linked lists must retain their original structure after the function returns. +You may assume there are no cycles anywhere in the entire linked structure. +Each value on each linked list is in the range [1, 10^9]. +Your code should preferably run in O(n) time and use only O(1) memory. + +``` + +Solution +---------- + +- Solution 1: O(MN) solution, iterate thru every node in list A, check to see if it's in list B +- Solution 2: Use hashmap and store reference +- Solution 3: This is a trick to do it in O(n), you just have to know it. + - Iterate listA and listB at the same time, when listA ends, move it to listB's head (and vice versa) + - Where they meet is the intersection +- Solution 4: Find length difference + - Iterate Both list and get lengths + - Find the difference between the lengths + - The intersection is at the length difference + +{% highlight python %} + +# Solution 3: Iterate and move to alternate list when at the end +def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode: + + if not headA or not headB: return None + + listAhead = headA + listBhead = headB + + while headA is not headB: + + # if there's no cycles, both pointers will eventually get to each other's end of list + if headA.next is None and headB.next is None: + return None + + # transverse A + if headA.next: + headA = headA.next + else: + headA = listBhead + + # transverse B + if headB.next: + headB = headB.next + else: + headB = listAhead + + return headA + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/intersectionOfTwoArrays2.md b/_problems/intersectionOfTwoArrays2.md new file mode 100644 index 0000000..6f14b39 --- /dev/null +++ b/_problems/intersectionOfTwoArrays2.md @@ -0,0 +1,91 @@ +--- +layout: page +title: Intersection of Two Arrays II +last_solved: 2020-07-22 +category: array +leetcode_url: https://leetcode.com/problems/intersection-of-two-arrays-ii +status: Solved +--- + +Problem +------- + +``` +Given two arrays, write a function to compute their intersection. + +Example 1: + +Input: nums1 = [1,2,2,1], nums2 = [2,2] +Output: [2,2] +Example 2: + +Input: nums1 = [4,9,5], nums2 = [9,4,9,8,4] +Output: [4,9] + +``` + +Solution +---------- + +### Sort & Merge Solution + +{% highlight python %} + +def intersect(nums1, nums2): + + nums1.sort() + nums2.sort() + + i=0 + j=0 + + #1,1,2,2 + #2,2 + + ans = [] + + # logic is similar to merging + while( i <= len(nums1)-1 and j <= len(nums2)-1 ): + + if nums1[i]==nums2[j]: + ans.append(nums1[i]) + i+=1 + j+=1 + elif nums1[i] < nums2[j]: + i+=1 + else: + j+=1 + + return ans + +{% endhighlight %} + +### HashMap Solution + +{% highlight python %} + +def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]: + + map = {} + for num in nums1: + if num not in map: + map[num] = 1 + else: + map[num] = map[num] + 1 + + # iter thru num2, if exist in map, minus it + res = [] + for num in nums2: + if num in map: + res.append(num) + if map[num]>1: + map[num] = map[num]-1 + else: + map.pop(num) + + return res + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/invertTree.md b/_problems/invertTree.md new file mode 100644 index 0000000..9f40018 --- /dev/null +++ b/_problems/invertTree.md @@ -0,0 +1,50 @@ +--- +layout: page +title: invert Tree +last_solved: 2020-06-01 +category: tree +leetcode_url: https://leetcode.com/problems/invert-binary-tree/ +status: Solved +--- + + + + +{% highlight python %} + +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + + + +def invert(root): + + if not root: + return + + tmp = root.left + root.left = root.right + root.right = tmp + + invert(root.left) + invert(root.right) + + +root = TreeNode(1) +root.left = TreeNode(2) +root.right = TreeNode(3) +root.left.left = TreeNode(4) +root.right.right = TreeNode(5) + + +print( root.left.left.val ) # 4 + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/isSameTree.md b/_problems/isSameTree.md new file mode 100644 index 0000000..3044d2c --- /dev/null +++ b/_problems/isSameTree.md @@ -0,0 +1,64 @@ +--- +layout: page +title: Is Same Tree? +--- + + + + +{% highlight python %} + +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + + + +def isSameTree(p, q): + + if not p and not q: + return True + + # both null already covered above + if not p or not q: + return False + + if p.val != q.val: + return False + + leftRes = isSameTree(p.left, q.left) + rightRes = isSameTree(p.right, q.right) + + return leftRes and rightRes + + +# def isSameTree(p,q): +# if p and q: +# return p.val == q.val and isSameTree(p.left, q.left) and isSameTree(p.right, q.right) +# return p is q + + +root = TreeNode(1) +root.left = TreeNode(2) +root.right = TreeNode(3) + + +root2 = TreeNode(1) +root2.left = TreeNode(2) +root2.right = TreeNode(3) + +p = root +q = root2 + +print p +print q +print isSameTree(p, q) + +{% endhighlight %} + + +![image1](https://srk2ka.dm.files.1drv.com/y4mjDbmv7Vtxnh6G4RGcukbQFQMS77M9yp4O6b8Tvl2aC1oYemtm6Ug-E69benEJDd1KlSHea-m_CvmbQM-yuhAdgdYUaGbANgQ4x8UnBicvytnRoVECx8jxBbbSkhkhC8p_FWtPTiXWlHAu1z2rwuq7aS70iQiNABQoTM71CiVTGCWaE1Z8h8Dkl27iFhcwAOtyOiOEjGD56LWhoIpuAue_w?width=1537&height=1324&cropmode=none) diff --git a/_problems/isSubSequence.md b/_problems/isSubSequence.md new file mode 100644 index 0000000..5b9e812 --- /dev/null +++ b/_problems/isSubSequence.md @@ -0,0 +1,63 @@ +--- +layout: page +title: Is Subsequence +last_solved: 2020-07-08 +category: strings, 2ptr +leetcode_url: https://leetcode.com/problems/is-subsequence +status: Attempted +--- + +Problem +------- + +``` +Given a string s and a string t, check if s is subsequence of t. + +A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie, "ace" is a subsequence of "abcde" while "aec" is not). + +Follow up: +If there are lots of incoming S, say S1, S2, ... , Sk where k >= 1B, and you want to check one by one to see if T has its subsequence. In this scenario, how would you change your code? + + + + +Example 1: + +Input: s = "abc", t = "ahbgdc" +Output: true +Example 2: + +Input: s = "axc", t = "ahbgdc" +Output: false + +``` + +Solution +---------- + +Gotchas: +- 2 ptrs on string, have two conditions on while loop + +{% highlight python %} + +def isSubsequence(s, t): + + sp = 0 + tp = 0 + + while sp int: + + R = len(grid) + C = len(grid[0]) + perimeter = 0 + + for x,y in product(range(R), range(C)): + + if grid[x][y]==1: + + perimeter+=4 + + if x>0 and grid[x-1][y]==1: + perimeter-=2 + + if y>0 and grid[x][y-1]==1: + perimeter-=2 + + + return perimeter + +{% endhighlight %} + + +-------------- + +Using DFS and nonlocal + +{% highlight python %} + +def islandPerimeter(self, grid: List[List[int]]) -> int: + + R = len(grid) + C = len(grid[0]) + + perimeter=0 + + def dfs(i,j): + + nonlocal perimeter + + if i<0 or i>=R or j<0 or j>=C or grid[i][j]==0: # if border or water, add 1 + perimeter+=1 + return + + if grid[i][j]==1: + grid[i][j]=2 # mark as visited + dfs(i-1,j) + dfs(i+1,j) + dfs(i,j-1) + dfs(i,j+1) + + for i in range(R): + for j in range(C): + if grid[i][j]==1: + dfs(i,j) + + return perimeter + +{% endhighlight %} + + +______________ + + +using `self.variable` instead of nonlocal + +{% highlight python %} + + def islandPerimeter(self, grid: List[List[int]]) -> int: + + R = len(grid) + C = len(grid[0]) + + self.perimeter = 0 + + def dfs(i,j): + + + # if out of bounds, add 1 to perimeter + if i<0 or i>=R or j<0 or j>=C or grid[i][j]==0: + self.perimeter+=1 + return + + # recurse + if grid[i][j]==1: + grid[i][j] = 2 # mark visited + dfs(i-1,j) + dfs(i+1,j) + dfs(i,j-1) + dfs(i,j+1) + + for i in range(R): + for j in range(C): + + if grid[i][j]==1: + dfs(i,j) + + return self.perimeter + +{% endhighlight %} \ No newline at end of file diff --git a/_problems/isomorphicStrings.md b/_problems/isomorphicStrings.md new file mode 100644 index 0000000..e93c3f4 --- /dev/null +++ b/_problems/isomorphicStrings.md @@ -0,0 +1,73 @@ +--- +layout: page +title: Isomorphic Strings +last_solved: 2020-08-04 +category: hashmap +leetcode_url: https://leetcode.com/problems/isomorphic-strings +status: Solved +--- + +Problem +------- + +``` +Given two strings s and t, determine if they are isomorphic. + +Two strings are isomorphic if the characters in s can be replaced to get t. + +All occurrences of a character must be replaced with another character while preserving the order of characters. No two characters may map to the same character but a character may map to itself. + +Example 1: + +Input: s = "egg", t = "add" +Output: true +Example 2: + +Input: s = "foo", t = "bar" +Output: false +Example 3: + +Input: s = "paper", t = "title" +Output: true + +``` + +Solution +---------- + +{% highlight python %} + +def isIsomorphic(self, s: str, t: str) -> bool: + + """ + egg -> 011 + add -> 011 + """ + def isohash(word): + + mapping = defaultdict(int) # key=character, value=seqNum + res = "" + seqNum = 0 # seqNum is number that was assigned to char, for "egg": e is assigned '1', g is assigned '2' + + """ + mapping[e]=1 + mapping[g]=2 + """ + for c in word: + if c not in mapping: + mapping[c] = seqNum # assign a number to char (keep track of it in hashmap) + seqNum+=1 # increment seqNum by 1 for the next character + res += str(mapping[c]) # add seqNum to res + else: + res += str(mapping[c]) # if already assigned, just add to res + + + return res + + + return isohash(s)==isohash(t) + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/jumpGame.md b/_problems/jumpGame.md new file mode 100644 index 0000000..1390d95 --- /dev/null +++ b/_problems/jumpGame.md @@ -0,0 +1,94 @@ +--- +layout: page +title: Jump Game +last_solved: 2020-06-04 +category: greedy, dp, backtracking +leetcode_url: https://leetcode.com/problems/jump-game +status: Semi-Solved, Multiple solutions +--- + +Problem +------- + +``` +Given an array of non-negative integers, you are initially positioned at the first index of the array. + +Each element in the array represents your maximum jump length at that position. + +Determine if you are able to reach the last index. + + + +Example 1: + +Input: nums = [2,3,1,1,4] +Output: true +Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index. +Example 2: + +Input: nums = [3,2,1,0,4] +Output: false +Explanation: You will always arrive at index 3 no matter what. Its maximum jump length is 0, which makes it impossible to reach the last index. + +``` + +Solution +---------- + +There are 4 solutions to this: +- backtracking +- dp - top down +- dp - bottom up +- greedy + + +The solutions article in leetcode is actually really good for this question. [here](https://leetcode.com/problems/jump-game/solution/) + +#### Greedy Approach + +Go backwards from the last position. If you can reach the first element from the last element, then you are good. + +This is a O(n) time and O(1) space solution. + +{% highlight python %} + +def canJump(nums) -> bool: + + lastGoodPos = len(nums) - 1 + for i in reversed(range(len(nums))): + + if i + nums[i] >= lastGoodPos: + lastGoodPos = i + + return lastGoodPos == 0 + +{% endhighlight %} + + +``` + +walk thru each iteration: + +4+4>=4 +8>=4 is true +lastgoodPos = 4 + +3+1>=4 +4>=4 is true +lastGoodPos = 3 + +2+1>=3 +3>=3 is true +lastGoodPos = 2 + +1+3>=2 +4>=2 is true +lastGoodPos = 1 + +0+2>=1 +2>=1 is true +lastGoodPos = 0 + +``` + +![image1]() \ No newline at end of file diff --git a/_problems/koko_eating_bananas.md b/_problems/koko_eating_bananas.md new file mode 100644 index 0000000..f1bf332 --- /dev/null +++ b/_problems/koko_eating_bananas.md @@ -0,0 +1,86 @@ +--- +layout: page +title: Koko Eating Bananas +last_solved: +category: binary search +leetcode_url: https://leetcode.com/problems/koko-eating-bananas +status: Attempted +--- + +Problem +------- + +``` +Koko loves to eat bananas. There are N piles of bananas, the i-th pile has piles[i] bananas. The guards have gone and will come back in H hours. + +Koko can decide her bananas-per-hour eating speed of K. Each hour, she chooses some pile of bananas, and eats K bananas from that pile. If the pile has less than K bananas, she eats all of them instead, and won't eat any more bananas during this hour. + +Koko likes to eat slowly, but still wants to finish eating all the bananas before the guards come back. + +Return the minimum integer K such that she can eat all the bananas within H hours. + + + +Example 1: + +Input: piles = [3,6,7,11], H = 8 +Output: 4 +Example 2: + +Input: piles = [30,11,23,4,20], H = 5 +Output: 30 +Example 3: + +Input: piles = [30,11,23,4,20], H = 6 +Output: 23 +``` + +Solution +---------- + +Itiotion from [this video](https://leetcode.com/problems/koko-eating-bananas/) + +Code from [powerful binary search template](https://leetcode.com/discuss/general-discussion/786126/python-powerful-ultimate-binary-search-template-solved-many-problems) + +{% highlight python %} + + def minEatingSpeed(self, piles: List[int], H: int) -> int: + + + def feasible(speed): # mid is like "eating speed" + + total = 0 + for pile in piles: + div = pile // speed + if pile % speed != 0: + div +=1 + total += div + + return total <= H + + + left, right = 1, max(piles) + + while left < right: + + mid = (left + right) // 2 # mid is like "eating speed" + + if feasible(mid): + right = mid # it's feasible but we want to find the smallest k, so ignore right side + else: + left = mid + 1 + + return left + +{% endhighlight %} + +______________ + + + +{% highlight python %} + + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/kthlargestElementInAStream.md b/_problems/kthlargestElementInAStream.md new file mode 100644 index 0000000..7d022ea --- /dev/null +++ b/_problems/kthlargestElementInAStream.md @@ -0,0 +1,94 @@ +--- +layout: page +title: Kth Largest Element in a Stream +last_solved: +category: heap +leetcode_url: https://leetcode.com/problems/kth-largest-element-in-a-stream +status: Attempted +--- + +Problem +------- + +``` +Design a class to find the kth largest element in a stream. Note that it is the kth largest element in the sorted order, not the kth distinct element. + +Your KthLargest class will have a constructor which accepts an integer k and an integer array nums, which contains initial elements from the stream. For each call to the method KthLargest.add, return the element representing the kth largest element in the stream. + +Example: + +int k = 3; +int[] arr = [4,5,8,2]; +KthLargest kthLargest = new KthLargest(3, arr); +kthLargest.add(3); // returns 4 +kthLargest.add(5); // returns 5 +kthLargest.add(10); // returns 5 +kthLargest.add(9); // returns 8 +kthLargest.add(4); // returns 8 + +``` + +Solution +---------- + +Sorting Solution = nlogn + +{% highlight python %} + +class KthLargest: + + def __init__(self, k: int, nums: List[int]): + + self.k = k + self.nums = nums + + + def add(self, val: int) -> int: + + self.nums.append(val) + + # sort + self.nums = sorted(self.nums, reverse=True) + + return self.nums[self.k-1] + +{% endhighlight %} + + +__________- + + +use heap -> log(n) for insertion and removal, o(1) for peeking at root + +{% highlight python %} + +class KthLargest: + + def __init__(self, k: int, nums: List[int]): + + self.k = k + # self.nums = nums + self.nums = heapq.nlargest(self.k, nums)[::-1] + + + def add(self, val: int) -> int: + + # push new element onto heap + heapq.heappush(self.nums, val) + + # print(self.nums) + + # if length exceeds k, pop off the smallest (make room for a larger one) + if len(self.nums)>self.k: + heapq.heappop(self.nums) + + + # print(self.nums) + # print() + + return self.nums[0] # kth largest element is sitting at root (min of non evicted elements) + + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/kthlargestElementInAnArray.md b/_problems/kthlargestElementInAnArray.md new file mode 100644 index 0000000..76bf6ce --- /dev/null +++ b/_problems/kthlargestElementInAnArray.md @@ -0,0 +1,84 @@ +--- +layout: page +title: Kth Largest Element in an Array +last_solved: +category: heap +leetcode_url: https://leetcode.com/problems/kth-largest-element-in-an-array/ +status: Attempted +--- + +Problem +------- + +``` +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. + +Example 1: + +Input: [3,2,1,5,6,4] and k = 2 +Output: 5 +Example 2: + +Input: [3,2,3,1,2,4,5,5,6] and k = 4 +Output: 4 + +``` + +Solution +---------- + +- If you're trying to find the largest kth element, use a min heap. +- As you're adding elements, evict elements if length is greater than k +- The result is the kth largest element sitting at the root + +{% highlight python %} + +def findKthLargest(self, nums: List[int], k: int) -> int: + + min_heap = [] + + for n in nums: + + heapq.heappush(min_heap, n) + + print(min_heap) # added element n + + # if len>5, pop the smallest element (make room for a LARGER one) + if len(min_heap)>k: + heapq.heappop(min_heap) + + print(min_heap) + print() + + return heapq.heappop(min_heap) # can also do `return min_heap[0]` + +{% endhighlight %} + +``` + +Your input +[3,2,1,5,6,4] +k=2 + +stdout +[3] +[3] + +[2, 3] +[2, 3] + +[1, 3, 2] +[2, 3] + +[2, 3, 5] +[3, 5] + +[3, 5, 6] +[5, 6] + +[4, 6, 5] +[5, 6] + +``` + +![image1]() \ No newline at end of file diff --git a/_problems/lastStoneWeight.md b/_problems/lastStoneWeight.md new file mode 100644 index 0000000..1c433f9 --- /dev/null +++ b/_problems/lastStoneWeight.md @@ -0,0 +1,67 @@ +--- +layout: page +title: Last Stone Weight +last_solved: +category: heap +leetcode_url: https://leetcode.com/problems/last-stone-weight +status: Attempted +--- + +Problem +------- + +``` +We have a collection of stones, each stone has a positive integer weight. + +Each turn, we choose the two heaviest stones and smash them together. Suppose the stones have weights x and y with x <= y. The result of this smash is: + +If x == y, both stones are totally destroyed; +If x != y, the stone of weight x is totally destroyed, and the stone of weight y has new weight y-x. +At the end, there is at most 1 stone left. Return the weight of this stone (or 0 if there are no stones left.) + + + +Example 1: + +Input: [2,7,4,1,8,1] +Output: 1 +Explanation: +We combine 7 and 8 to get 1 so the array converts to [2,4,1,1,1] then, +we combine 2 and 4 to get 2 so the array converts to [2,1,1,1] then, +we combine 2 and 1 to get 1 so the array converts to [1,1,1] then, +we combine 1 and 1 to get 0 so the array converts to [1] then that's the value of last stone. + +``` + +Solution +---------- + +{% highlight python %} + +def lastStoneWeight(self, stones: List[int]) -> int: + + while len(stones)>=2: + + # negate values for max heap + stones = list(map(lambda x: -x if x>0 else x, stones)) + # stones = [-x for x in stones if x>0 else x] + print(stones) + + # get top 2 heaviest stones + heapq.heapify(stones) + print(stones) + heavy1 = heapq.heappop(stones) + heavy2 = heapq.heappop(stones) + + # smash the heaviest stones + diff = abs(heavy1-heavy2) + heapq.heappush(stones, diff) + print(stones) + + print(stones) + return stones[0] + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/lcaBinaryTree.md b/_problems/lcaBinaryTree.md new file mode 100644 index 0000000..c0239cb --- /dev/null +++ b/_problems/lcaBinaryTree.md @@ -0,0 +1,58 @@ +--- +layout: page +title: LCA of binary tree +--- + + + + +{% highlight python %} + +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + + + +def lca(root, x, y): + + if not root: + return None + + print(root.val) + + if root.val==x or root.val==y: + print('returning ' + str(root.val)) + return root + + leftRes = lca(root.left, x, y) + rightRes = lca(root.right, x, y) + + if not rightRes: + return leftRes + if not leftRes: + return rightRes + if leftRes and rightRes: + print('returning ' + str(root.val)) + return root + + + + +root = TreeNode(1) +root.left = TreeNode(2) +root.right = TreeNode(3) +root.left.left = TreeNode(4) +root.left.right = TreeNode(5) + + +print( lca(root, 4, 5).val ) + +{% endhighlight %} + + +![image1](https://srmuba.dm.files.1drv.com/y4mjQ4fvTsdlacL5xumNsVzQqLEDQaxCFdrXcoyJFTs9aqCCJWjMr8jJaYvkOIg12cpO1JtFD1giwPbygRfq0ju1TYMXTJzfSYpxVMFBwUebhp3vhzJw_3bF7Qxp2DzfE2usG5kjMmQYJnMWKJZAmATlnhkev2N9oJa_glDY_UTZxfmytLPepbwK4vYmUblwg3hpVOyX-6596pfhNFGESWB0w?width=1824&height=2225&cropmode=none) \ No newline at end of file diff --git a/_problems/llcycle.md b/_problems/llcycle.md new file mode 100644 index 0000000..8a233a9 --- /dev/null +++ b/_problems/llcycle.md @@ -0,0 +1,148 @@ +--- +layout: page +title: Linked List Cycle +last_solved: 2020-07-22 +category: linked list, cycle detection +leetcode_url: https://leetcode.com/problems/linked-list-cycle +status: Solved +--- + +##### Hashmap solution + +{% highlight python %} + + def hasCycle(self, head: ListNode) -> bool: + + if not head: + return False + + seen = set() + + while head: + if head in seen: + return True + else: + seen.add(head) + + head=head.next + + return False + +{% endhighlight %} + +#### Flodd - buggy + +Ran into some infinite loops and wrong answer with input [1,2] with no cycles. +Turns outs slow and fast needs to be advanced at same time. + +{% highlight python %} + +def hasCycle(head): + + if not head: + return False + + slow = head + fast = head.next + + while fast: + + if slow is fast: + return True + + if slow: + slow=slow.next + + if fast and fast.next: + fast=fast.next.next + + return False + +{% endhighlight %} + + +#### Flodd - working + +Just keep it clean and clear and keep all 1) termination checks and 2) pointer advancements together. + +Some tips (to reduce chances of bugs): +- add null checks for everything that could be null (ie: slow, fast and fast.next) +- keep slow and fast pointer advancements in one if block (had bug when one was advanced but not the other) +- use While True (instead of while fast) and have return True and return False cases +- initialize slow and fast to be different, the check "if slow is fast" could get triggered too early + + + +{% highlight python %} + +def hasCycle(head): + + if not head: + return False + + slow = head + fast = head.next + + while True: + + # if either pointer is null, reached end of list and return False + if slow is None or fast is None or fast.next is None: + return False + + # cycle detected, exit and return True + if slow is fast: + return True + + # advance pointers + slow=slow.next + fast=fast.next.next + +{% endhighlight %} + +___________ + +{% highlight python %} + +def hasCycle(self, head: ListNode) -> bool: + + if not head: return False + + slow, fast = head, head.next + + while slow!=fast: + + if not fast or not fast.next: + return False + + # advance pointers + slow = slow.next + fast = fast.next.next + + return True + +{% endhighlight %} + +_____________ + +{% highlight python %} + +def hasCycle(self, head: ListNode) -> bool: + + if not head: return False + + slow = head + fast = head.next + + while fast and fast.next: + + if slow is fast: + return True + + slow = slow.next + fast = fast.next.next + + return False + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/llcycle2.md b/_problems/llcycle2.md new file mode 100644 index 0000000..a434e57 --- /dev/null +++ b/_problems/llcycle2.md @@ -0,0 +1,118 @@ +--- +layout: page +title: Linked List Cycle II +last_solved: 2020-06-25 +category: linked list, cycle detection +leetcode_url: https://leetcode.com/problems/linked-list-cycle-ii +status: Solved +--- + +Problem +------- + +``` +Given a linked list, return the node where the cycle begins. If there is no cycle, return null. + +To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list. + +Note: Do not modify the linked list. + + + +Example 1: + +Input: head = [3,2,0,-4], pos = 1 +Output: tail connects to node index 1 +Explanation: There is a cycle in the linked list, where tail connects to the second node. + + +Example 2: + +Input: head = [1,2], pos = 0 +Output: tail connects to node index 0 +Explanation: There is a cycle in the linked list, where tail connects to the first node. + + +Example 3: + +Input: head = [1], pos = -1 +Output: no cycle +Explanation: There is no cycle in the linked list. + +``` + +Solution +---------- + +Here's the correct algorithm (similiar to [Find the Duplicate Number](/problems/findTheDuplicateNumber)). However, since we're dealing with linked lists, we have to do error checks. + +{% highlight python %} + +def detectCycle(self, head: ListNode) -> ListNode: + + slow = head + fast = head + + # find intersection in cycle + while True: + slow = slow.next + fast = fast.next.next + + if slow is fast: + break + + + # reset slow back to head and find entrance + # the gap between the beginning and entrance == gap between fast and entrance + # (this only applies if fast moved 2x as fast as slow) + slow = head + while slow!=fast: + slow = slow.next + fast = fast.next + + return slow + +{% endhighlight %} + +_____________________ + + +After adding null checks and followed the tips from [Linked List Cycle I](/problems/llcycle) + +This one we need to start both slow and fast at head. `fast` cannot be `head.next` because where fast ends needs to be equidistance to the entrance. + +{% highlight python %} + +def detectCycle(self, head: ListNode) -> ListNode: + + if not head: return None + + slow = head + fast = head + + # find intersection in cycle + while True: + + if slow is None or fast is None or fast.next is None: + return None + + slow = slow.next + fast = fast.next.next + + if slow is fast: + break + + + # reset slow back to head and find entrance + # the gap between the beginning and entrance == gap between fast and entrance + # (this only applies if fast moved 2x as fast as slow) + slow = head + while slow!=fast: + slow = slow.next + fast = fast.next + + return slow + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/longestCommonPrefix.md b/_problems/longestCommonPrefix.md new file mode 100644 index 0000000..f8c5bf5 --- /dev/null +++ b/_problems/longestCommonPrefix.md @@ -0,0 +1,54 @@ +--- +layout: page +title: Longest Common Prefix +last_solved: 2020-06-05 +category: string +leetcode_url: https://leetcode.com/problems/longest-common-prefix +status: Solved +--- + +Problem +------- + +``` +Write a function to find the longest common prefix string amongst an array of strings. + +If there is no common prefix, return an empty string "". + +Example 1: + +Input: ["flower","flow","flight"] +Output: "fl" +Example 2: + +Input: ["dog","racecar","car"] +Output: "" +Explanation: There is no common prefix among the input strings. + +``` + +Solution +---------- + +{% highlight python %} + +def lcp(strs): + + prefix = strs[0] + + for i in range(1, len(strs)): + + # if substring is found, it will return the first index + # if that element isn't the first char, then chop off + while strs[i].find(prefix) != 0: + + # keep chopping off the last character + prefix = prefix[0: len(prefix)-1] + if not prefix: return "" + + return prefix + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/longestCommonSubsequence.md b/_problems/longestCommonSubsequence.md new file mode 100644 index 0000000..fed6493 --- /dev/null +++ b/_problems/longestCommonSubsequence.md @@ -0,0 +1,61 @@ +--- +layout: page +title: Longest Common Subsequence +--- + + + +``` +Input: text1 = "abcde", text2 = "ace" +Output: 3 +Explanation: The longest common subsequence is "ace" and its length is +``` + +Gotchas +------- +- look out for the dimension with which you build the grid (ie: m<->i, n<->j) + - table=[[0]*(n+1) for x in range(m+1)] + - otherwise you could run into a array out of bounds error + + +{% highlight python %} + +str1 = "AAB" +str2 = "AZB" + +def lcs(text1, text2): + + n= len(text1) + m= len(text2) + + # creates an [m+1][n+1] matrix, filled with zeros + table=[[0]*(n+1) for x in range(m+1)] + + for i in range(1, m+1): + for j in range (1, n+1): + + # first char is the same, so add 1 to count + if text2[i-1]==text1[j-1]: + table[i][j]= 1+table[i-1][j-1] + # first char is different, so break into subproblems and take the max + else: + table[i][j]=max(table[i-1][j],table[i][j-1]) + + + print [0]*(n+1) + print range(m+1) + print table + print max(table) # this get the last element at the end of the list + return max(max(table)) # this gets the last element at the bottom right corner (last element of both lists) + + + +print lcs(str1, str2) + + +{% endhighlight %} + + +![image1](https://gnfapq.dm.files.1drv.com/y4mZlth_qJCTlKJzsxVXX98_AG9IK8AYIiD6xyAEMPDfxF1FJFbE0z_rpEBOkZe0I65WDkyjiWZj3x4fGkqPjBT7ZrN1gmNos7vavy-EjgFiz6lFt3odQOYxbrxIxuCA8dEfPOcvqC2p_rKtb2nD6FGhClcL58TZMnbH2JEvsUZ2OdOWSd14TqjsqIut8vAdOWie9ZWU-J7qm_gnKrQcVv1Pg?width=1782&height=2278&cropmode=none) + +![image1](https://gnermw.dm.files.1drv.com/y4m9BSW0Ft1fHxdtWnT1V0IGF9Sxj3TFojEDo_HiaMd9YGeSK_vN3LtRkRbvzR-vnySZ1qd3PuPpdgyIim_pE9LnQG4TErnFMrBOgK-oFlMCr1Ao13C6FmeZKYfuGKiqqI8rRrSpM44Du8nNVoqUK2awKIa1u3E5TcJepJsdItmXpf7vw8LfB8FilU_qF04a9hBiLn3oQEMJcee-WnUvZQkkQ?width=2579&height=1198&cropmode=none) diff --git a/_problems/longestPalindromicSubstring.md b/_problems/longestPalindromicSubstring.md new file mode 100644 index 0000000..705f750 --- /dev/null +++ b/_problems/longestPalindromicSubstring.md @@ -0,0 +1,104 @@ +--- +layout: page +title: Longest Palindromic Substring +last_solved: +category: string, palindrome +leetcode_url: +status: Solved +--- + +Problem +------- + +``` +Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000. + +Example 1: + +Input: "babad" +Output: "bab" +Note: "aba" is also a valid answer. +Example 2: + +Input: "cbbd" +Output: "bb" + +``` + +Solution +---------- + +This only works for both even and odd palindromes but TLE on "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb...." + +{% highlight python %} + +class Solution: + def longestPalindrome(self, s: str) -> str: + + def isPalindrome(s): + return s==s[::-1] + + longestPalindrome="" + + for i in range(len(s)): + + l=i + r=i + + while l>=0 and rlen(longestPalindrome): + longestPalindrome = currPalindrome + + # even case + currPalindrome = s[l:r+2] + if isPalindrome(currPalindrome): + if len(currPalindrome)>len(longestPalindrome): + longestPalindrome = currPalindrome + + l-=1 + r+=1 + + print(isPalindrome("bab")) + return longestPalindrome + +{% endhighlight %} + +_______________ + +Same as approach above (Expand around center) but without the isPalindrome() method. +I think that's what is causing it to time out. + +{% highlight python %} + +def longestPalindrome(self, s: str) -> str: + + # return the actual palindrome + def expandAroundCenter(s, l, r): + + while l>=0 and rlen(res): + res = oddPalin + if len(evenPalin)>len(res): + res = evenPalin + + return res + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/longestSubstringWithoutRepeatingChars.md b/_problems/longestSubstringWithoutRepeatingChars.md new file mode 100644 index 0000000..efe01e0 --- /dev/null +++ b/_problems/longestSubstringWithoutRepeatingChars.md @@ -0,0 +1,131 @@ +--- +layout: page +title: Longest Substring without Repeating Characters +--- + + + + +{% highlight python %} + + + +s = "abcabcbb" +s2 = "bbbbb" +s3 = "pwwkew" + +def lengthOfLongestSubstring(s): + + start = 0 + end = 0 + maxRes = 0 + + charSet = set() + + while end < len(s): + + print(s[start], s[end], charSet, maxRes) + + if not s[end] in charSet: + charSet.add(s[end]) + end+=1 + maxRes = max(len(charSet), maxRes) # why max? of max + else: + charSet.remove(s[start]) + start+=1 + + return maxRes + + +print(lengthOfLongestSubstring(s)) # 3 abc +# print(lengthOfLongestSubstring(s2)) # 1 b +# print(lengthOfLongestSubstring(s3)) # 3 wke + +{% endhighlight %} + +Time Complexity O(2n) = O(n), where i and j will visit each char twice (see printout section) +Space O(min(size of n, size of charset)) + + +#### Printouts + + +{% highlight text %} + +For s = "abcabcbb" +print(s[start], s[end], charSet, maxRes) + +a a set() 0 +a b {'a'} 1 +a c {'b', 'a'} 2 +a a {'b', 'c', 'a'} 3 +b a {'b', 'c'} 3 +b b {'b', 'c', 'a'} 3 +c b {'c', 'a'} 3 +c c {'b', 'c', 'a'} 3 +a c {'b', 'a'} 3 +a b {'b', 'c', 'a'} 3 +b b {'b', 'c'} 3 +c b {'c'} 3 +c b {'b', 'c'} 3 +b b {'b'} 3 +b b set() 3 +3 + +{% endhighlight %} + + +#### Dry Run + + +{% highlight text %} + + + +s="abcabcbb" + + +iter=1 + s[start]=a + s[end]=a + + a not in charSet + charSet = {a} + maxRes = max(1, 0) = 1 + +iter=2 + start=a, end=b + + charSet = {a,b} + maxRes = max(2, 1) =2 + +iter=3 + start=a, end=c + + charSet = {a,b,c} + maxRes = max(3, 2) + +iter=4 + start=a, end=a + + charSet.remove('a') -> charSet={b,c} + maxres = 3 (still 3 from last iteration) + +iter=5 + abcbb + + charSEt={b,c} + end=b in charSet -> charSEt.remove(c) -> charSEt={c} + maxres = max(1, oldMaxres), max(1,3) = 3 <- this is why we have maxres=max(len,oldMaxres) + start+=1 + +iter=6 + abcbb + + start=c, end=b + end=b not in charSEt -> charSEt={b,c} + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/longestUnivaluePath.md b/_problems/longestUnivaluePath.md new file mode 100644 index 0000000..1c73712 --- /dev/null +++ b/_problems/longestUnivaluePath.md @@ -0,0 +1,91 @@ +--- +layout: page +title: Longest Univar Path +last_solved: +category: tree +leetcode_url: https://leetcode.com/problems/longest-univalue-path/ +status: Not Solved +--- + +Problem +------- + +``` + +Given a binary tree, find the length of the longest path where each node in the path has the same value. This path may or may not pass through the root. + +The length of path between two nodes is represented by the number of edges between them. + + + +Example 1: + +Input: + + 5 + / \ + 4 5 + / \ \ + 1 1 5 +Output: 2 + + + +Example 2: + +Input: + + 1 + / \ + 4 5 + / \ \ + 4 4 5 + +``` + +Solution +---------- + +This is not solved. Gotten close but fails some test cases + +{% highlight python %} + + def longestUnivaluePath(self, root: TreeNode) -> int: + + def dfs2(node, currentLongest): + + if not node: return currentLongest + + if node.left: + if node.val==node.left.val: + currentLongest+=1 + else: + currentLongest=0 + + + if node.right: + if node.val==node.right.val: + currentLongest+=1 + else: + currentLongest=0 + + leftRes = dfs2(node.left, currentLongest) + rightRes = dfs2(node.right, currentLongest) + + return max(leftRes, rightRes) + + + return dfs2(root, 0) + +{% endhighlight %} + +______________ + + + +{% highlight python %} + + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/majorityElement.md b/_problems/majorityElement.md new file mode 100644 index 0000000..f9279fd --- /dev/null +++ b/_problems/majorityElement.md @@ -0,0 +1,62 @@ +--- +layout: page +title: Majority Element +last_solved: +category: boyer moore +leetcode_url: https://leetcode.com/problems/majority-element/ +status: Attempted +--- + +Problem +------- + +``` +Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times. + +You may assume that the array is non-empty and the majority element always exist in the array. + +Example 1: + +Input: [3,2,3] +Output: 3 +Example 2: + +Input: [2,2,1,1,1,2,2] +Output: 2 +``` + +Solution +---------- + + + +{% highlight python %} + + count, cand = 0, None + + for n in nums: + + if count==0: + cand=n + + if cand==n: + count+=1 + else: + count-=1 + + + + return cand + +{% endhighlight %} + +______________ + + + +{% highlight python %} + + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/majorityElement2.md b/_problems/majorityElement2.md new file mode 100644 index 0000000..eff9172 --- /dev/null +++ b/_problems/majorityElement2.md @@ -0,0 +1,79 @@ +--- +layout: page +title: Majority Element II +last_solved: +category: boyer moore +leetcode_url: https://leetcode.com/problems/majority-element-ii +status: Attempted +--- + +Problem +------- + +``` + +Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. + +Note: The algorithm should run in linear time and in O(1) space. + +Example 1: + +Input: [3,2,3] +Output: [3] +Example 2: + +Input: [1,1,1,3,3,2,2,2] +Output: [1,2] +``` + +Solution +---------- + + + +{% highlight python %} + + count1, count2, cand1, cand2 = 0,0,None, None + + for n in nums: + + if cand1==n: + count1+=1 + elif cand2==n: + count2+=1 + elif count1==0: + cand1=n + count1+=1 + elif count2==0: + cand2=n + count2+=1 + else: + count1-=1 + count2-=1 + + + print( count1, count2, cand1, cand2) + + # 2nd pass + result = [] + for c in [cand1, cand2]: + if nums.count(c) > len(nums)//3: + result.append(c) + + + return result + + + +{% endhighlight %} + +______________ + + + +{% highlight python %} + + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/matrixSearch.md b/_problems/matrixSearch.md new file mode 100644 index 0000000..d0ae33f --- /dev/null +++ b/_problems/matrixSearch.md @@ -0,0 +1,61 @@ +--- +layout: page +title: Matrix Search +--- + +Trick: +- think of matrix as 1D array +- turn 1D array index to row/col mapping +- ie: to access 16 (in array index 6), we know row=1 and col=2 +- the magic leap is to realize row=6//4 and col=6%4 or ```(index//col_len``` and ```index%col_len)``` + + +Gotcha: +- if you don't get a handle on your off by one errors, you'll run into infinite loops +- row is mid//col_len, not mid//row_len + + + +{% highlight python %} + +# mat = [ +# [1,2,3,4], +# [5,6,7,8], +# [9,10,11,12] +# ] + +mat = [[1,3,5,7],[10,11,16,20],[23,30,34,50]] + + +def searchMatrix(mat, target): + + if not mat: return False + + row_len=len(mat) + col_len=len(mat[0]) + + low = 0 + high = row_len * col_len -1 + + while low<=high: + + mid = (low+high)//2 + + print(low, high, mid) + + if mat[mid//col_len][mid%col_len]==target: + return True + elif mat[mid//col_len][mid%col_len] int: + + if not grid: return 0 + + rows = len(grid) + cols = len(grid[0]) + + + def dfs(i, j): + + nonlocal count + + if i<0 or i>=rows or j<0 or j>=cols or grid[i][j]==0: + return count + else: + grid[i][j]=0 # mark as visited + count+=1 # increment nonlocal count + + dfs(i-1,j) + dfs(i+1,j) + dfs(i,j-1) + dfs(i,j+1) + + return count + + + count = 0 + maxArea = 0 + + for i in range(rows): + for j in range(cols): + if grid[i][j]==1: + + count = 0 # set nonlocal count to 0 + + dfs(i,j) + + if count > maxArea: + maxArea = count + + count = 0 # reset nonlocal count + + + return maxArea + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/maxDepth.md b/_problems/maxDepth.md new file mode 100644 index 0000000..470e15a --- /dev/null +++ b/_problems/maxDepth.md @@ -0,0 +1,53 @@ +--- +layout: page +title: Max Depth of Tree +--- + + + + +{% highlight python %} + + +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + + +def deepestNode(root, level, maxLevel): + + if not root: + return maxLevel + + if level > maxLevel: + maxLevel = level + + + leftRes = deepestNode(root.left, level + 1, maxLevel) + rightRes = deepestNode(root.right, level + 1, maxLevel) + + + if leftRes and rightRes: + return max(leftRes, rightRes) + + + +root = TreeNode(3) +root.left = TreeNode(9) +root.right = TreeNode(20) +root.right.left = TreeNode(15) +root.right.right = TreeNode(7) + + + +print deepestNode(root, 1, 0) + + +{% endhighlight %} + + +![image1](https://bubblesortblog.files.wordpress.com/2020/03/img_20200331_164909.jpg?w=768) \ No newline at end of file diff --git a/_problems/maxDepthOfNaryTree.md b/_problems/maxDepthOfNaryTree.md new file mode 100644 index 0000000..845582c --- /dev/null +++ b/_problems/maxDepthOfNaryTree.md @@ -0,0 +1,48 @@ +--- +layout: page +title: Maximum Depth of N-ary Tree +last_solved: 2020-07-23 +category: trees +leetcode_url: https://leetcode.com/problems/maximum-depth-of-n-ary-tree/ +status: Solved +--- + +Problem +------- + +``` +Given a n-ary 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. + +Nary-Tree input serialization is represented in their level order traversal, each group of children is separated by the null value (See examples). + +Example 1: + +Input: root = [1,null,3,2,4,null,5,6] +Output: 3 + +``` + +![image1](https://assets.leetcode.com/uploads/2018/10/12/narytreeexample.png) + +Solution +---------- + +{% highlight python %} + +def maxDepth(self, root: 'Node') -> int: + + if not root: + return 0 + + maxDepthAtThisRoot = 0 + if root.children: + for child in root.children: + maxDepthAtThisRoot = max(maxDepthAtThisRoot, self.maxDepth(child)) + + return maxDepthAtThisRoot+1 + +{% endhighlight %} + + diff --git a/_problems/maxProductSubarray.md b/_problems/maxProductSubarray.md new file mode 100644 index 0000000..c72cb0b --- /dev/null +++ b/_problems/maxProductSubarray.md @@ -0,0 +1,106 @@ +--- +layout: page +title: Maximum Product Subarray +--- + + + + +#### Solution + +One pass, keep track of minCurrent and maxCurrent + +{% highlight python %} + +arr1 = [2, 3, -2,4] +arr2 = [2, 3, 6] +arr3 = [2, -3, 6] + +def getMaxProductSubarray(nums): + if not nums: return + left, right, record = 0, 0, -float('inf') + for i in range(len(nums)): + left = (left or 1) * nums[i] + right = (right or 1) * nums[-i-1] + record = max(record, left, right) + return record + +def getMaxProductSubarray(arr): + + minCurrent = 1 + maxCurrent = 1 + maxRes = -99999 + + for i in range(len(arr)): + + current = arr[i] + + print(i, current, minCurrent, maxCurrent) + + if current>0: + maxCurrent = maxCurrent * current + minCurrent = min( minCurrent * current, 1) + elif current==0: + maxCurrent=1 + minCurrent=1 + else: + x = maxCurrent + maxCurrent = max( minCurrent * current, 1) + minCurrent = x * current + + print(i, current, minCurrent, maxCurrent) + + if maxRes int: + + q = [(root, 0)] + maxWidth = 0 + + while q: + + lvl = [] + lvl_size = len(q) + + for _ in range(lvl_size): + + maxWidth = max(maxWidth, q[-1][1]-q[0][1]+1 ) + + node, num = q.pop(0) + lvl.append( (node.val, num) ) + + + if node.left: + q.append( (node.left, 2*num) ) + if node.right: + q.append( (node.right, 2*num+1)) + + + print(lvl, maxWidth) + + return maxWidth + +{% endhighlight %} + +``` +Your input +[1,3,2,5,3,null,9] + +stdout +[(1, 0)] 1 +[(3, 0), (2, 1)] 2 +[(5, 0), (3, 1), (9, 3)] 4 + +``` + + +__________ + +The one works. Check the difference. + +{% highlight python %} + +def widthOfBinaryTree(self, root: TreeNode) -> int: + + q = [(root, 0)] + maxWidth = 0 + + while q: + + new_lvl = [] + lvl_size = len(q) + + for _ in range(lvl_size): + + maxWidth = max(maxWidth, q[-1][1]-q[0][1]+1 ) + + node, num = q.pop(0) + # new_lvl.append( (node, num) ) + + if node.left: + new_lvl.append( (node.left, 2*num) ) + if node.right: + new_lvl.append( (node.right, 2*num+1)) + + q = new_lvl # need to "reset" the nums so the left most is zero again + + return maxWidth + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/maxXorOfTwoNums.md b/_problems/maxXorOfTwoNums.md new file mode 100644 index 0000000..dd66b1c --- /dev/null +++ b/_problems/maxXorOfTwoNums.md @@ -0,0 +1,86 @@ +--- +layout: page +title: Maximum XOR of Two Numbers in an Array +last_solved: +category: bits +leetcode_url: https://leetcode.com/problems/maximum-xor-of-two-numbers-in-an-array/ +status: Attempted +--- + +Problem +------- + +``` +Given a non-empty array of numbers, a0, a1, a2, … , an-1, where 0 ≤ ai < 231. + +Find the maximum result of ai XOR aj, where 0 ≤ i, j < n. + +Could you do this in O(n) runtime? + +Example: + +Input: [3, 10, 5, 25, 2, 8] + +Output: 28 + +Explanation: The maximum result is 5 ^ 25 = 28. +``` + +Solution +---------- + + + +{% highlight python %} + + def findMaximumXOR(self, nums: List[int]) -> int: + + output, mask = 0,0 + + for i in range(4,-1,-1): + + mask = mask | (1< curr[0], that means there's a merge and you just replace it with the ```max(prev[1],curr[1])``` + +Otherwise, just append to the merged output array. + +O(n*logn) time (linear time to go thru intervals, sort at beginning takes logn) +O(n) space + +{% highlight python %} + + +intervals = [[1,3],[2,6],[8,10],[15,18]] + + +def merge(intervals): + + intervals.sort(key=lambda x: x[0]) + + merged = [] + + # add the first interval to merged[] + merged.append(intervals[0]) + + for interval in intervals: + + print(interval) + + if merged[-1][1] < interval[0]: # no merge, [2,6] compared to [8,10] + + print('no merge') + merged.append(interval) + else: + print('merge', merged[-1][1], interval[1]) + merged[-1][1] = max(merged[-1][1], interval[1] ) # choose the max of "prev" (aka: merged[-1]) or the current interval + + print() + + print(merged) + + +{% endhighlight %} + + +![1](https://gncsea.dm.files.1drv.com/y4mjA3je8pcrbSN4OeIyS6_Fbp3CccXJ_TNvSRzIRVqPR1FqKHQBJ3Se-BkQXL8E7ERPH4epEPNYVkveF7AsUgleTVjV11zb0hwLTYRBXLoTTmLs9K2LceSew1OItMb5cinpieckIkHkbirHvvZECTMjYs_nyU4X9Xb9-TRF6fpQlwtuB5vfxnk717JiS7RNnBnG5N60a_9MJQTy7isyZ3coA?width=2790&height=1030&cropmode=none) + +![2](https://gnclyq.dm.files.1drv.com/y4mo6iX6isxgelOx67T_9bxo5-kMe5dekj4FGDn3lXlqLWKfFpgZfkGoTfFX8rL9CLWJavxlnYFfEG-Utz_kqWJvAzDsr6W0bEOav2tQQ8KuQrZU3BiYrSLkGKtVcFMH6gDO3qpC1pYn0FV-_-uO8vVhyrPYRfT5wxYhlRGT0N0qjJ6kHPDGv1buTrI6vlaoxTnGxFuZ6EQ_cNqtAYAwpnN9w?width=1817&height=2183&cropmode=none) +![3](https://gnekva.dm.files.1drv.com/y4mUVOcDYT0nz9z9jc9JevipHYRKKrxZ4HPG5t4Cxb4GlGhFHuQYZxzV34nmMhw3Ogv_PAX8Z_-9aOFoU7f8N2vh27CXVpKAhkLGG4BiSZkr8TEUIfAb9HWSZXuLqjjILBErFhYYMCwqq66C_JcQkBjfw66Wqh_dXyNrZo2hnq2kaOlKj1YFr8mSmc2pfXNpcJTLceIrUIm4etzfw2cPSHXzw?width=1365&height=2974&cropmode=none) + diff --git a/_problems/mergeKSortedLinkedLists.md b/_problems/mergeKSortedLinkedLists.md new file mode 100644 index 0000000..b988bb6 --- /dev/null +++ b/_problems/mergeKSortedLinkedLists.md @@ -0,0 +1,75 @@ +--- +layout: page +title: Merge K Sorted Linked Lists +last_solved: 2020-08-09 +category: heap +leetcode_url: https://leetcode.com/problems/merge-k-sorted-lists/ +status: Solved +--- + +Problem +------- + +``` +Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. + +Example: + +Input: +[ + 1->4->5, + 1->3->4, + 2->6 +] +Output: 1->1->2->3->4->4->5->6 + +``` + +Solution +---------- + + +1) Push all elements into a minHeap. +2) Pop them out and create a new linked list. + +time is O(n*logk) where n=total number of elements in k list +- because each insert into minheap is logk, and we do it n times for each element + +space is O(n) to hold all elements in minHeap + +{% highlight python %} + +def mergeKLists(self, lists): + """ + :type lists: List[ListNode] + :rtype: ListNode + """ + + + minHeap = [] + + # push all elements into minHeap + for currList in lists: + + head = currList + + while head: + heapq.heappush(minHeap, head.val) + head = head.next + + + # pop all elements from minHeap (and craete new linked list) + dummy = ListNode(0) + head = dummy + + while minHeap: + head.next = ListNode( heapq.heappop(minHeap) ) + head = head.next + + return dummy.next + + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/mergeSortedArray.md b/_problems/mergeSortedArray.md new file mode 100644 index 0000000..2f8572d --- /dev/null +++ b/_problems/mergeSortedArray.md @@ -0,0 +1,67 @@ +--- +layout: page +title: Merge Sorted Array +last_solved: +category: +leetcode_url: https://leetcode.com/problems/merge-sorted-array/ +status: Attempted +--- + +Problem +------- + +``` +Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. + +Note: + +The number of elements initialized in nums1 and nums2 are m and n respectively. +You may assume that nums1 has enough space (size that is equal to m + n) to hold additional elements from nums2. +Example: + +Input: +nums1 = [1,2,3,0,0,0], m = 3 +nums2 = [2,5,6], n = 3 + +Output: [1,2,2,3,5,6] + +``` + +Solution +---------- + +{% highlight python %} + +def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None: + """ + Do not return anything, modify nums1 in-place instead. + """ + + # nums1 = [1,2,3,0,0,0], m = 3 + # nums2 = [2,5,6], n = 3 + + # start from the back (avoid overwriting) + i = m-1 + j = n-1 + + end = len(nums1)-1 + + while i>=0 and j>=0: + + if nums2[j]>=nums1[i]: + nums1[end] = nums2[j] + j-=1 + else: + nums1[end] = nums1[i] + i-=1 + + end-=1 + + # this part need to take care of edge case with nums1=[0] and nums2=[1] + if i==-1: + nums1[:j+1] = nums2[:j+1] + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/mergeSortedLLiter.md b/_problems/mergeSortedLLiter.md new file mode 100644 index 0000000..d50dee3 --- /dev/null +++ b/_problems/mergeSortedLLiter.md @@ -0,0 +1,60 @@ +--- +layout: page +title: Merge Sorted Linked List (Iterative) +last_solved: 2020-06-26 +category: linked list +leetcode_url: https://leetcode.com/problems/merge-two-sorted-lists/ +status: Solved +--- + +- Use dummy node +- First part, compare l1 and l2 and merge +- Second part, just use "if statement" to add the rest of the list if there's still any left (do not use "while loop") + + +{% highlight python %} + +class LinkedListNode: + + def __init__(self, val): + + self.val = val + self.next = None + + + +def mergeSortedLinkedList(l1, l2): + + dummy = ListNode(0) + head = dummy + while l1 and l2 : + if l1.val < l2.val : + dummy.next = l1 + l1 = l1.next + else : + dummy.next = l2 + l2 = l2.next + dummy = dummy.next + + if l1 : + dummy.next = l1 + elif l2 : + dummy.next = l2 + return head.next + + +l1 = LinkedListNode(1) +l1.next = LinkedListNode(2) +l1.next.next = LinkedListNode(4) + +l2 = LinkedListNode(1) +l2.next = LinkedListNode(3) +l2.next = LinkedListNode(4) + +mergeSortedLinkedList() + + + +{% endhighlight %} + + diff --git a/_problems/mergeSortedLLrecur.md b/_problems/mergeSortedLLrecur.md new file mode 100644 index 0000000..98edfa1 --- /dev/null +++ b/_problems/mergeSortedLLrecur.md @@ -0,0 +1,66 @@ +--- +layout: page +title: Merge Sorted Linked List (Recursive) +--- + + + + +{% highlight python %} + +class LinkedListNode: + + def __init__(self, val): + + self.val = val + self.next = None + + +l1 = LinkedListNode(1) +l1.next = LinkedListNode(2) +l1.next.next = LinkedListNode(4) + + +l2 = LinkedListNode(2) +l2.next = LinkedListNode(3) +l2.next.next = LinkedListNode(4) + + + +def mergeSortedLists(l1, l2): + + # if either list is empty, just return the other list + # these are the base cases + if not l1: + return l2 + + if not l2: + return l1 + + + # recursively + if l1.val < l2.val: + l1.next = mergeSortedLists(l1.next, l2) + return l1 + else: + l2.next = mergeSortedLists(l2.next, l1) + return l2 + + + + + +head = mergeSortedLists(l1, l2) + +curr = head +while curr: + print(curr.val) + curr=curr.next + + + + +{% endhighlight %} + + +![image1](https://bubblesortblog.files.wordpress.com/2020/04/mergesortedlinkedlistsrecursive-1.jpg?w=768) diff --git a/_problems/mergeTwoBinaryTrees.md b/_problems/mergeTwoBinaryTrees.md new file mode 100644 index 0000000..6476349 --- /dev/null +++ b/_problems/mergeTwoBinaryTrees.md @@ -0,0 +1,103 @@ +--- +layout: page +title: Merge Two Binary Trees +last_solved: +category: trees +leetcode_url: https://leetcode.com/problems/merge-two-binary-trees +status: Attempted +--- + +Problem +------- + +``` +Given two binary trees and imagine that when you put one of them to cover the other, some nodes of the two trees are overlapped while the others are not. + +You need to merge them into a new binary tree. The merge rule is that if two nodes overlap, then sum node values up as the new value of the merged node. Otherwise, the NOT null node will be used as the node of new tree. + +Example 1: + +Input: + Tree 1 Tree 2 + 1 2 + / \ / \ + 3 2 1 3 + / \ \ + 5 4 7 +Output: +Merged tree: + 3 + / \ + 4 5 + / \ \ + 5 4 7 +``` + +Solution +---------- + + + +{% highlight python %} + + def mergeTrees(self, t1: TreeNode, t2: TreeNode) -> TreeNode: + + def dfs(t1, t2, t3): + + # sums up the roots + t3.val = t1.val + t2.val + + # if only t1 has left child + if t1.left and not t2.left: + t3.left = t1.left + + # if only t1 has right child + if t1.right and not t2.right: + t3.right = t1.right + + # if only t2 has left child + if t2.left and not t1.left: + t3.left = t2.left + + # if only t2 has right child + if t2.right and not t1.right: + t3.right = t2.right + + # recurse down left if both have left + if t1.left and t2.left: + t3.left = TreeNode(0) + dfs(t1.left, t2.left, t3.left) + + if t1.right and t2.right: + t3.right = TreeNode(0) + dfs(t1.right, t2.right, t3.right) + + + # start of main + if not t1 and not t2: + return + + if t1 and not t2: + return t1 + if t2 and not t1: + return t2 + + # if t1 and t2 + t3 = TreeNode(0) + dfs(t1, t2, t3) + + return t3 + + +{% endhighlight %} + +______________ + + + +{% highlight python %} + + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/minStack.md b/_problems/minStack.md new file mode 100644 index 0000000..132e1f5 --- /dev/null +++ b/_problems/minStack.md @@ -0,0 +1,99 @@ +--- +layout: page +title: Tempalte +last_solved: +category: +leetcode_url: +status: Attempted +--- + +Problem +------- + +``` +Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. + +push(x) -- Push element x onto stack. +pop() -- Removes the element on top of the stack. +top() -- Get the top element. +getMin() -- Retrieve the minimum element in the stack. + + +Example 1: + +Input +["MinStack","push","push","push","getMin","pop","top","getMin"] +[[],[-2],[0],[-3],[],[],[],[]] + +Output +[null,null,null,null,-3,null,0,-2] + +Explanation +MinStack minStack = new MinStack(); +minStack.push(-2); +minStack.push(0); +minStack.push(-3); +minStack.getMin(); // return -3 +minStack.pop(); +minStack.top(); // return 0 +minStack.getMin(); // return -2 +``` + +Solution +---------- + + + +{% highlight python %} + +class MinStack: + + def __init__(self): + + self.stack = [] + + + def push(self, x: int) -> None: + + if not self.stack: + minSoFar = x + else: + + prevMin = self.stack[-1][1] + minSoFar = min(prevMin, x) + + item = (x, minSoFar) + self.stack.append( item ) + + + def pop(self) -> None: + + if self.stack: + item = self.stack.pop() + return item[0] + + + def top(self) -> int: + + if self.stack: + item = self.stack[-1] + return item[0] + + def getMin(self) -> int: + + if self.stack: + item = self.stack[-1] + return item[1] + +{% endhighlight %} + +______________ + + + +{% highlight python %} + + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/minimumAddToMakeValidParenthesis.md b/_problems/minimumAddToMakeValidParenthesis.md new file mode 100644 index 0000000..54abe0f --- /dev/null +++ b/_problems/minimumAddToMakeValidParenthesis.md @@ -0,0 +1,112 @@ +--- +layout: page +title: Minimum Add to Make Parentheses Valid +last_solved: +category: stack +leetcode_url: https://leetcode.com/problems/minimum-add-to-make-parentheses-valid/ +status: Attempted +--- + +Problem +------- + +``` +Given a string S of '(' and ')' parentheses, we add the minimum number of parentheses ( '(' or ')', and in any positions ) so that the resulting parentheses string is valid. + +Formally, a parentheses string is valid if and only if: + +It is the empty string, or +It can be written as AB (A concatenated with B), where A and B are valid strings, or +It can be written as (A), where A is a valid string. +Given a parentheses string, return the minimum number of parentheses we must add to make the resulting string valid. + + + +Example 1: + +Input: "())" +Output: 1 +Example 2: + +Input: "(((" +Output: 3 +Example 3: + +Input: "()" +Output: 0 +Example 4: + +Input: "()))((" +Output: 4 +``` + +Solution +---------- + + + +{% highlight python %} + + def minAddToMakeValid(self, S: str) -> int: + + numInvalid = 0 + stack = [] + + for c in S: + + if c=="(": + stack.append(1) + + elif c==")": + + if not stack: + numInvalid+=1 + else: + stack.pop() + + return numInvalid + len(stack) + +{% endhighlight %} + +______________ + +Some other solutions + +{% highlight python %} + + + numInvalid=0 + stack=[] + + for c in text: + if c=='(': + stack.append(c) + numInvalid+=1 + + elif c==')': + if not stack: + numInvalid+=1 + else: + stack.pop() + numInvalid-=1 + + return numInvalid + +''' +''' + +res = 0 +stack = 0 + for bracket in text: + if bracket == '(': + stack += 1 + if bracket == ')' and stack != 0: + stack -= 1 + elif bracket == ')' and stack == 0: + res += 1 + return res + stack + + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/minimumCostForTickets.md b/_problems/minimumCostForTickets.md new file mode 100644 index 0000000..70d30c1 --- /dev/null +++ b/_problems/minimumCostForTickets.md @@ -0,0 +1,91 @@ +--- +layout: page +title: Minimum Cost For Tickets +last_solved: +category: dp +leetcode_url: https://leetcode.com/problems/minimum-cost-for-tickets/ +status: Attempted +--- + +Problem +------- + +``` +In a country popular for train travel, you have planned some train travelling one year in advance. The days of the year that you will travel is given as an array days. Each day is an integer from 1 to 365. + +Train tickets are sold in 3 different ways: + +a 1-day pass is sold for costs[0] dollars; +a 7-day pass is sold for costs[1] dollars; +a 30-day pass is sold for costs[2] dollars. +The passes allow that many days of consecutive travel. For example, if we get a 7-day pass on day 2, then we can travel for 7 days: day 2, 3, 4, 5, 6, 7, and 8. + +Return the minimum number of dollars you need to travel every day in the given list of days. + + + +Example 1: + +Input: days = [1,4,6,7,8,20], costs = [2,7,15] +Output: 11 +Explanation: +For example, here is one way to buy passes that lets you travel your travel plan: +On day 1, you bought a 1-day pass for costs[0] = $2, which covered day 1. +On day 3, you bought a 7-day pass for costs[1] = $7, which covered days 3, 4, ..., 9. +On day 20, you bought a 1-day pass for costs[0] = $2, which covered day 20. +In total you spent $11 and covered all the days of your travel. +Example 2: + +Input: days = [1,2,3,4,5,6,7,8,9,10,30,31], costs = [2,7,15] +Output: 17 +Explanation: +For example, here is one way to buy passes that lets you travel your travel plan: +On day 1, you bought a 30-day pass for costs[2] = $15 which covered days 1, 2, ..., 30. +On day 31, you bought a 1-day pass for costs[0] = $2 which covered day 31. +In total you spent $17 and covered all the days of your travel. +``` + +Solution +---------- + + + +{% highlight python %} + + def mincostTickets(self, days: List[int], costs: List[int]) -> int: + + last_day = days[-1] + dp = [0] * (last_day + 1) + days = set(days) # convert day to set for fast look up later + for d in range(1, last_day + 1): + # to make sure we have pass, we either buy a 1-d pass today, a 7-d pass 6 days ago, or a 30-d pass 29 days ago + if d in days: + dp[d] = min(costs[2] + dp[max(d - 30, 0)], + costs[1] + dp[max(d - 7, 0)], + costs[0] + dp[d - 1]) + else: # we don't buy pass on day not in days + dp[d] = dp[d - 1] + + print(days) + return dp[-1] + +{% endhighlight %} + +______________ + + + +``` +Your input +[1,4,6,7,8,20] +[2,7,15] +stdout +{1, 4, 6, 7, 8, 20} + +Output +11 +Expected +11 +``` + +![image1]() \ No newline at end of file diff --git a/_problems/missingNumber.md b/_problems/missingNumber.md new file mode 100644 index 0000000..7acb831 --- /dev/null +++ b/_problems/missingNumber.md @@ -0,0 +1,48 @@ +--- +layout: page +title: Missing Number +--- + +#### sort + + +#### hashset + + + +#### gauss equation + +{% highlight python %} + +def missingNumber(self, nums: List[int]) -> int: + + n=len(nums) + expected = (n*(n+1))//2 + actual = sum(nums) + return expected-actual + +{% endhighlight %} + +#### xor + + +{% highlight python %} + +nums = [3,0,1] + +n = len(nums) + +# xor index with value +xor = 0 +for i, num in enumerate(nums): + xor ^= i^num + +# xor with length gives you missing num +missing = xor^n + +print(missing) + +{% endhighlight %} + + +![image1](https://bubblesortblog.files.wordpress.com/2020/04/img_20200409_102858.jpg) \ No newline at end of file diff --git a/_problems/mostCommonWord.md b/_problems/mostCommonWord.md new file mode 100644 index 0000000..c53aa02 --- /dev/null +++ b/_problems/mostCommonWord.md @@ -0,0 +1,83 @@ +--- +layout: page +title: Most Common Word +last_solved: +category: heap +leetcode_url: https://leetcode.com/problems/most-common-word +status: Attempted +--- + +Problem +------- + +``` +Given a paragraph and a list of banned words, return the most frequent word that is not in the list of banned words. It is guaranteed there is at least one word that isn't banned, and that the answer is unique. + +Words in the list of banned words are given in lowercase, and free of punctuation. Words in the paragraph are not case sensitive. The answer is in lowercase. + + + +Example: + +Input: +paragraph = "Bob hit a ball, the hit BALL flew far after it was hit." +banned = ["hit"] +Output: "ball" +Explanation: +"hit" occurs 3 times, but it is a banned word. +"ball" occurs twice (and no other word does), so it is the most frequent non-banned word in the paragraph. +Note that words in the paragraph are not case sensitive, +that punctuation is ignored (even if adjacent to words, such as "ball,"), +and that "hit" isn't the answer even though it occurs more because it is banned. + +``` + +Solution +---------- + +{% highlight python %} + +def mostCommonWord(self, paragraph: str, banned: List[str]) -> str: + +# # tokens = paragraph.split() +# tokens re.split(', | .', paragraph) +# print(tokens) + +# words = [] +# for word in tokens: +# # words.append( word.lower().strip(',') ) +# words.append( re.sub('[^A-Za-z0-9]+', '', word.lower()) ) + +# print(words) + + #1). replace the punctuations with spaces, + # and put all letters in lower case + normalized_str = ''.join([c.lower() if c.isalnum() else ' ' for c in paragraph]) + + #2). split the string into words + words = normalized_str.split() + + c = Counter(words) + print(c) + + # set banned words to zero + for k,v in c.items(): + if k in banned: + c[k] = 0 + + #4). return the word with the highest frequency + # https://stackoverflow.com/questions/18595686/how-does-operator-itemgetter-and-sort-work-in-python + return max(c.items(), key=operator.itemgetter(1))[0] + + +# # turn counter into a list +# c = [(-v,k) for k,v in c.items()] +# print(c) + +# heapq.heapify(c) +# return heapq.heappop(c)[1] + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/moveZeros.md b/_problems/moveZeros.md new file mode 100644 index 0000000..a6800db --- /dev/null +++ b/_problems/moveZeros.md @@ -0,0 +1,90 @@ +--- +layout: page +title: Move Zeros +last_solved: 2020-06-02 +category: array +leetcode_url: https://leetcode.com/problems/move-zeroes/ +status: Solved +--- + +Problem +------- + +{% highlight text %} + +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. + +Example: + +Input: [0,1,0,3,12] +Output: [1,3,12,0,0] + +{% endhighlight %} + +Solution +---------- + +- Use two pointers, one to keep track of last location and another to find nonZeros +- Move nonZeros to front (oveeride) +- fill the rest of the array with zeros + + +Override and replace the rest with zeros + +{% highlight python %} + +def moveZeroes(self, nums: List[int]) -> None: + + lastNonZero = 0 + fast = 0 + + # move nonZeros to front (override) + while fast None: + + z = None + for i in range(len(nums)): + + if nums[i]==0 and z is None: + z = i + + elif nums[i]!=0 and z is None: + + continue + + elif nums[i]!=0: + + tmp = nums[i] + nums[i]=nums[z] + nums[z]=tmp + + z+=1 + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/networkDelayTime.md b/_problems/networkDelayTime.md new file mode 100644 index 0000000..194d742 --- /dev/null +++ b/_problems/networkDelayTime.md @@ -0,0 +1,87 @@ +--- +layout: page +title: Network Delay Time +last_solved: 2020-06-19 +category: graph, dijkstra +leetcode_url: https://leetcode.com/problems/network-delay-time +status: Attempted +--- + +Problem +------- + +``` +There are N network nodes, labelled 1 to N. + +Given times, a list of travel times as directed edges times[i] = (u, v, w), where u is the source node, v is the target node, and w is the time it takes for a signal to travel from source to target. + +Now, we send a signal from a certain node K. How long will it take for all nodes to receive the signal? If it is impossible, return -1. + + +Input: times = [[2,1,1],[2,3,1],[3,4,1]], N = 4, K = 2 +Output: 2 +``` + +![image1](https://assets.leetcode.com/uploads/2019/05/23/931_example_1.png) + +Solution +---------- + +Dijkstra is written very similar to BFS but with weights. + +The end result of this problem is an array that keeps track of elaped time. + +``` + node 0,1,2,3,4 <-- index corresponds to node +elapsedTime: [0,1,0,1,2] <-- value corresponds to time for signal to reach node i from node K (ie: takes 2 seconds to reach node 4 from node 2) + +``` + +{% highlight python %} + +import heapq +from collections import deque +from collections import defaultdict + +times = [[2,1,1],[2,3,1],[3,4,1]] +N = 4 +K = 2 + +def networkDelayTime(times, N, K): + + elapsedTime = [0] + [float("inf")] * N + graph = defaultdict(list) + heap = [(0, K)] # time, start node (ie: (0,2)) + + # add to adj hash table, where values = (edge,weight) + for u, v, w in times: + graph[u].append((v, w)) + + ''' + graph: + 2: [(1,1),(1,3)] + 3: [(4,1)] + ''' + + while heap: + + # pop off heap/queue + time, node = heapq.heappop(heap) + if time < elapsedTime[node]: + + # process (add to elapsed time array) + elapsedTime[node] = time + + # add neighbours, include weight + for v, w in graph[node]: + heapq.heappush(heap, (time + w, v)) # at node 3, add neighbour 4 (time+w, v)=(1+1,4) and heap=[(2,4)] -> time to reach node 4=2 + + + mx = max(elapsedTime) + return mx if mx < float("inf") else -1 + +print( networkDelayTime(times, N, K) ) + +{% endhighlight %} + + diff --git a/_problems/nthdigit.md b/_problems/nthdigit.md new file mode 100644 index 0000000..ebcbb4a --- /dev/null +++ b/_problems/nthdigit.md @@ -0,0 +1,70 @@ +--- +layout: page +title: nth digit +last_solved: +category: math +leetcode_url: https://leetcode.com/problems/nth-digit/ +status: Attempted +--- + +Problem +------- + +``` +Find the nth digit of the infinite integer sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... + +Note: +n is positive and will fit within the range of a 32-bit signed integer (n < 231). + +Example 1: + +Input: +3 + +Output: +3 +Example 2: + +Input: +11 + +Output: +0 + +Explanation: +The 11th digit of the sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... is a 0, which is part of the number 10. + +``` + +Solution +---------- + +Do not understand logic yet. Learn from [this discussion](https://leetcode.com/problems/nth-digit/discuss/88369/0ms-C%2B%2B-Solution-with-Detail-Explanation) + +{% highlight python %} + + def findNthDigit(self, n: int) -> int: + + # https://leetcode.com/problems/nth-digit/discuss/88369/0ms-C%2B%2B-Solution-with-Detail-Explanation + + # 1) find out how many digits the number has (n=250, digits=3) + base=9 + digits=1 + while n-base*digits > 0: + n-=base*digits + base*=10 + digits+=1 + print(n, base, digits) + + # 2) calc what the number is + index = (n-1) % digits + offset = (n-1) / digits + start = pow(10, digits-1) + + print(index, offset, start) + return str(int(start+offset))[index] + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/numIslands.md b/_problems/numIslands.md new file mode 100644 index 0000000..ce7d522 --- /dev/null +++ b/_problems/numIslands.md @@ -0,0 +1,135 @@ +--- +layout: page +title: Number of Islands +last_solved: 2020-06-19 +category: union find +leetcode_url: https://leetcode.com/problems/number-of-islands +status: Solved +--- + +Use the flood fill algorithm. + +Some gotchas: +- check for string "1" and not integer 1 +- check for empty grid "[]" +- can do if (out of bounds) or if curr='1', then many "directional ifs" + + +{% highlight python %} + + +def numIslands(self, grid): + + if not grid: return 0 + + rows = len(grid) + cols = len(grid[0]) + + def dfs(i, j): + + if i<0 or i>=rows or j<0 or j>=cols or grid[i][j]=="0": + return + else: + grid[i][j]="0" + dfs(i-1,j) + dfs(i+1,j) + dfs(i,j-1) + dfs(i,j+1) + + count = 0 + for i in range(rows): + for j in range(cols): + + if grid[i][j]=="1": + count += 1 + dfs(i, j) + + return count + +{% endhighlight %} + + +The flood fill recursive algorithm could also be written in two ways: + +- first with boundary checks +- second with "directional ifs", maybe just forget about this one + +The difference is that the first if statements checks for out of bounds and the "0" boundary. + +Then you dont have to have "directional ifs" after. + +{% highlight python %} + + # Approach 1 - check out of bounds + def floodFill(grid, r,c): + + + if r < 0 or r >=R or c < 0 or c >= C or grid[r][c] == "0": + return + else: + print(r,c,grid[r][c]) + + grid[r][c] = '0' # mark as visited + floodFill(grid, r-1, c) + floodFill(grid, r+1, c) + floodFill(grid, r, c-1) + floodFill(grid, r, c+1) + + # Approach 2 + def floodFill(grid, r,c): + + print(r,c,grid[r][c]) + + if grid[r][c] == '1': # this means we can advance + grid[r][c] = '0' # mark as visited + if r>=1: floodFill(grid, r-1, c) + if r+1=1: floodFill(grid, r, c-1) + if c+1=rows or j<0 or j>=cols or grid[i][j]=="0": + return + + neib_list = [[i+1,j],[i-1,j],[i,j-1],[i,j+1]] + for x, y in neib_list: + grid[i][j]="0" + dfs(x, y) + + count = 0 + for i, j in product(range(rows), range(cols)): + if grid[i][j]=="1": + count += 1 + dfs(i, j) + + return count + +print( numIslands(grid) ) + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/numOnes.md b/_problems/numOnes.md new file mode 100644 index 0000000..d86af34 --- /dev/null +++ b/_problems/numOnes.md @@ -0,0 +1,27 @@ +--- +layout: page +title: Num Ones +--- + + +#### Loop and Bit Mask + +{% highlight python %} + + def hammingWeight(self, n: int) -> int: + + count = 0 + while n>0: + + if n&1==1: + count+=1 + + n>>=1 + + return count + + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/number_compliment.md b/_problems/number_compliment.md new file mode 100644 index 0000000..708e756 --- /dev/null +++ b/_problems/number_compliment.md @@ -0,0 +1,78 @@ +--- +layout: page +title: Number Complement +last_solved: +category: binary +leetcode_url: https://leetcode.com/problems/number-complement +status: Attempted +--- + +Problem +------- + +``` +Given a positive integer num, output its complement number. The complement strategy is to flip the bits of its binary representation. + + + +Example 1: + +Input: num = 5 +Output: 2 +Explanation: The binary representation of 5 is 101 (no leading zero bits), and its complement is 010. So you need to output 2. +Example 2: + +Input: num = 1 +Output: 0 +Explanation: The binary representation of 1 is 1 (no leading zero bits), and its complement is 0. So you need to output 0. + +``` + +Solution +---------- + +Using binary string. + +{% highlight python %} + + def findComplement(self, num: int) -> int: + + binString = bin(num).replace('0b', '') + + output = '' + for c in binString: + + if c=='0': + output+='1' + else: + output+='0' + + return int(output, 2) + +{% endhighlight %} + +______________ + +using bit manipulation + +{% highlight python %} + + def findComplement(self, num: int) -> int: + ## RC ## + ## APPROACH : BIT MANIPULATION ## + ## LOGIC ## + # 1. 1 xor 1 = 0 and 0 or 1 = 1, from these we can say that XORing with 1 will give its complement bit + # 2. so, for 5 ==> 101, bitmask is 111, for 6 ==> 110, bitmask is 111, so bitmask is (length number of 1's) + # 3. How do we length of given bit ? we use log function + # 4. (ex: for 5), we take 1 and left shift by length obtained from 3, i.e (1000) now, substract 1, it will give (111) ==> bitmask + + ## TIME COMPLEXICITY : O(1) ## (coz make n= 32) + ## SPACE COMPLEXICITY : O(1) ## + + n = floor(log2(num)) + 1 # n is a length of num in binary representation + bitmask = (1 << n) - 1 # bitmask has the same length as num and contains only ones 1...1 + return bitmask ^ num + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/oddEvenLinkedList.md b/_problems/oddEvenLinkedList.md new file mode 100644 index 0000000..7ad0be6 --- /dev/null +++ b/_problems/oddEvenLinkedList.md @@ -0,0 +1,64 @@ +--- +layout: page +title: Odd Even Linked List +last_solved: 2020-07-21 +category: linked list +leetcode_url: https://leetcode.com/problems/odd-even-linked-list +status: Attempted +--- + +Problem +------- + +``` +Given a singly linked list, group all odd nodes together followed by the even nodes. Please note here we are talking about the node number and not the value in the nodes. + +You should try to do it in place. The program should run in O(1) space complexity and O(nodes) time complexity. + +Example 1: + +Input: 1->2->3->4->5->NULL +Output: 1->3->5->2->4->NULL +Example 2: + +Input: 2->1->3->5->6->4->7->NULL +Output: 2->3->6->7->1->5->4->NULL + +``` + +Solution +---------- + + + +Explained in [Nick White's video](https://www.youtube.com/watch?v=C_LA6SOwVTM) + +- Build even list and odd list seperately +- Join end of odd list to head of even list + + +{% highlight python %} + + def oddEvenList(self, head: ListNode) -> ListNode: + + if not head: return None + + odd = head + even = head.next + evenHead = even + + while even and even.next: + + odd.next = even.next # make odd jump over "even" + odd = odd.next # move odd to next + + even.next = odd.next # make even jump over + even = even.next # move even to next + + + odd.next = evenHead + return head + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/palindromicLinkList.md b/_problems/palindromicLinkList.md new file mode 100644 index 0000000..130d604 --- /dev/null +++ b/_problems/palindromicLinkList.md @@ -0,0 +1,83 @@ +--- +layout: page +title: Palindrome Linked List +last_solved: 2020-07-22 +category: linked lists, palindrome +leetcode_url: https://leetcode.com/problems/palindrome-linked-list/ +status: Attempted +--- + +Problem +------- + +``` +Given a singly linked list, determine if it is a palindrome. + +Example 1: + +Input: 1->2 +Output: false +Example 2: + +Input: 1->2->2->1 +Output: true + +``` + +Solution +---------- + +- Have a slow and fast poiner, and find middle. +- Once at middle, reverse the second half of the list +- Then Iterate both first half and second half to ensure they are the same + +Note: +- Whichever pointer gets to the end of the list first, make that your break condition (in while loop) + +{% highlight python %} + +def isPalindrome(self, head: ListNode) -> bool: + + + def reversed(head): + + prev = None + curr = head + next = None + + while curr: + next = curr.next + curr.next = prev + prev = curr + curr = next + + return prev + + # find mid + slow = head + fast = head + + while fast and fast.next: + fast = fast.next.next + slow = slow.next + + # reverse second half of list + slow = reversed(slow) + fast = head + + # iterate both slow and fast and make sure they're the same + while slow: + + if slow.val!=fast.val: + return False + slow = slow.next + fast = fast.next + + return True + + + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/pathSum.md b/_problems/pathSum.md new file mode 100644 index 0000000..bb93b41 --- /dev/null +++ b/_problems/pathSum.md @@ -0,0 +1,88 @@ +--- +layout: page +title: Path Sum +last_solved: +category: tree +leetcode_url: https://leetcode.com/problems/path-sum +status: Attempted +--- + +Problem +------- + +``` +Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum. + +Note: A leaf is a node with no children. + +Example: + +Given the below binary tree and sum = 22, + + 5 + / \ + 4 8 + / / \ + 11 13 4 + / \ \ +7 2 1 +return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22. + +``` + +Solution +---------- + +Use dfs helper to pass down currentSum. Check if leaf node and sumTotal==targetSum. + +{% highlight python %} + + def hasPathSum(self, root: TreeNode, sum: int) -> bool: + + def dfs(node, currentSum, targetSum): + + if not node: + return False + + # if current node is leaf and sum of all vals == targetSum + if node.left is None and node.right is None and currentSum + node.val == targetSum: + return True + + leftRes = dfs(node.left, currentSum + node.val, targetSum) + rightRes = dfs(node.right, currentSum + node.val, targetSum) + + return leftRes or rightRes + + return dfs(root, 0, sum) + +{% endhighlight %} + +_______________ + + + +{% highlight python %} + +def dfs(root, sum): + + if not root: + return False + + # if the current node is a leaf and it's value is equal to the sum, we found a path + if root.val==sum and root.left is None and root.right is None: + return True + + # recursively call to traverse the left and right sub-tree + # return true if any of the two recursive call return true + leftRes = dfs(root.left, sum-root.val) + rightRes = dfs(root.right, sum-root.val) + + return leftRes or rightRes + +return dfs(root, sum) + + +{% endhighlight %} + + +![image1](https://5wkfbq.dm.files.1drv.com/y4m1LAF1rJH3rvE6Fvoa19b9yQaMDbSKWiaK30lMziT7NLyxl8pZnpAV9b8fA4kYg-9pbglZXrlKtwQ6m57t3x1Eup0UAeaUw2l8He8myjMvgvUpiOVvhQD9Tr_5i5mw3hLqErN-otBc4QQanjNm0ye7UiqB-b8ymiORnOz7TAHQLWcHuuZR5k0Can1XRKt846BNzH5OzeZbTMuifNt2NXGbQ?width=1477&height=2053&cropmode=none) \ No newline at end of file diff --git a/_problems/pathSum2.md b/_problems/pathSum2.md new file mode 100644 index 0000000..d55171f --- /dev/null +++ b/_problems/pathSum2.md @@ -0,0 +1,71 @@ +--- +layout: page +title: Path Sum 2 +last_solved: +category: tree +leetcode_url: https://leetcode.com/problems/path-sum-ii/ +status: Attempted +--- + +Problem +------- + +``` +Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum. + +Note: A leaf is a node with no children. + +Example: + +Given the below binary tree and sum = 22, + + 5 + / \ + 4 8 + / / \ + 11 13 4 + / \ / \ +7 2 5 1 +Return: + +[ + [5,4,11,2], + [5,8,4,5] +] + +``` + +Solution +---------- + +Use dfs helper to pass down currentSum. Check if leaf node and sumTotal==targetSum. + +{% highlight python %} + + def dfs(node, currentSum, targetSum, path): + + if not node: + return + + # if current node is leaf and sum of all vals == targetSum + if node.left is None and node.right is None and currentSum + node.val == targetSum: + output.append(path+[node.val]) + + leftRes = dfs(node.left, currentSum + node.val, targetSum, path+[node.val]) + rightRes = dfs(node.right, currentSum + node.val, targetSum, path+[node.val]) + + return + + output = [] + dfs(root, 0, sum, []) + return output + +{% endhighlight %} + +_______________ + +{% highlight python %} + + + +{% endhighlight %} \ No newline at end of file diff --git a/_problems/pathSum3.md b/_problems/pathSum3.md new file mode 100644 index 0000000..6c56907 --- /dev/null +++ b/_problems/pathSum3.md @@ -0,0 +1,86 @@ +--- +layout: page +title: Path Sum 3 +last_solved: +category: tree +leetcode_url: https://leetcode.com/problems/path-sum-iii/ +status: Attempted +--- + +Problem +------- + +``` +You are given a binary tree in which each node contains an integer value. + +Find the number of paths that sum to a given value. + +The path does not need to start or end at the root or a leaf, but it must go downwards (traveling only from parent nodes to child nodes). + +The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000. + +Example: + +root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8 + + 10 + / \ + 5 -3 + / \ \ + 3 2 11 + / \ \ +3 -2 1 + +Return 3. The paths that sum to 8 are: + +1. 5 -> 3 +2. 5 -> 2 -> 1 +3. -3 -> 11 + +``` + +Solution +---------- + +This is a double nested dfs solution so runtime is horrible but it still works. + +{% highlight python %} + + def pathSum(self, root: TreeNode, sum: int) -> int: + + self.total = 0 + + def helper(node, currSum): + if not node: + return + + helper(node.left, currSum+node.val) + helper(node.right, currSum+node.val) + + if node.val + currSum == sum: + self.total+=1 + + + def dfs(node): + + if not node: return + + helper(node, 0) + + dfs(node.left) + dfs(node.right) + + + dfs(root) + + return self.total + +{% endhighlight %} + +_______________ + +{% highlight python %} + + + +{% endhighlight %} \ No newline at end of file diff --git a/_problems/perfectSquaresa.md b/_problems/perfectSquaresa.md new file mode 100644 index 0000000..8eec5c0 --- /dev/null +++ b/_problems/perfectSquaresa.md @@ -0,0 +1,98 @@ +--- +layout: page +title: Perfect Squares +last_solved: 2020-06-28 +category: dp [bottom up] +leetcode_url: https://leetcode.com/problems/perfect-squares/ +status: Semi-Solved +--- + +Problem +------- + +``` +Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, ...) which sum to n. + +Example 1: + +Input: n = 12 +Output: 3 +Explanation: 12 = 4 + 4 + 4. +Example 2: + +Input: n = 13 +Output: 2 +Explanation: 13 = 4 + 9. + +``` + + + +Solution +---------- + +This is suppose to be similar to the coin change problem somehow. + +``` + +1 -> 1 (1) +2 -> 2 (1+1) +3 -> 3 (1+1+1) +4 -> 1 (4) +5 -> 2 (4+1) +6 -> 3 (4+1+1) +7 -> 4 4+1+1+1 +8 -> 2 4+4 + + + +f(1) = 1 +f(2) = f(1) + f(1) = 1+1=2 + +f(7) = f(4) + f(3) = 1+3=4 +f(8) = f(4) + f(4) = 1+1=2 +f(12) = f(8) + f(4) = 2+1=3 + +identify subproblems? + +https://leetcode.com/problems/perfect-squares/discuss/696436/Python-Simple-DP-Solution + +n=7 +square_sums = [0,1,4] +dp = [0, inf, inf, inf, inf, inf, inf, inf] + + 0 1 2 3 4 5 6 7 +dp = [0, 1, 2, 3, 1, 2, 3, 4] + +dp = [0, 1, inf, inf, 1, inf, inf, inf] + +i: 1->n +iter all squares +min( dp[i], dp[i-square] ) + +``` + +{% highlight python %} + +def numSquares(self, n: int) -> int: + ## RC ## + ## APPROACH : DP ## + + ## TIME COMPLEXITY : O(N^2) ## + ## SPACE COMPLEXITY : O(N) ## + + if( n < 3) : return n + square_nums = [i**2 for i in range(0, int(math.sqrt(n))+1)] + + dp = [float('inf')] * (n+1) + dp[0] = 0 + for i in range(1, n+1): + for square in square_nums: + if(i < square): break + dp[i] = min(dp[i], dp[i-square] + 1) # +1 is for that square we are substracting. + return dp[-1] + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/permutations.md b/_problems/permutations.md new file mode 100644 index 0000000..0780435 --- /dev/null +++ b/_problems/permutations.md @@ -0,0 +1,92 @@ +--- +layout: page +title: Permutations +last_solved: 2020-06-22 +category: recursion, backtracking +leetcode_url: https://leetcode.com/problems/permutations +status: Solved +--- + +Problem +------- + +``` +Given a collection of distinct integers, return all possible permutations. + +Example: + +Input: [1,2,3] +Output: +[ + [1,2,3], + [1,3,2], + [2,1,3], + [2,3,1], + [3,1,2], + [3,2,1] +] + +``` + +Solution +---------- + +A generic backtracking skeleton is [here](https://leetcode.com/problems/permutations/discuss/18239/A-general-approach-to-backtracking-questions-in-Java-(Subsets-Permutations-Combination-Sum-Palindrome-Partioning)) + + +[medium article on permutation/subsets](https://medium.com/algorithms-and-leetcode/backtracking-e001561b9f28) + + +``` + """ + Level0: [] + level1: [1] [2] [3] + level2: [1,2] [1,3] [2,1] [2,3] [3,1] [3,2] + level3: [1,2,3] [1,3,2] [2,1,3][2,3,1] [3,1,2][3,2,1] + + """ +``` + +The vanilla backtracking template would do this to `currList`. +So that's why you need to check to that nums[i] is not in `currList` + + +________________________ + + +Following the generic backtracking structure: + +_________ + + +{% highlight python %} + +def permute(nums): + + output = [] + + def backtrack(currentList): + + print(currentList) + + # base case + if len(currentList)==len(nums): + output.append(currentList.copy()) + + # imagine you're at [1] (your currentList) and you want to append 1,2,3 to your child branches + # so they become 11, 12, 13 + for i in range(0, len(nums)): + + if nums[i] in currentList: + continue + + currentList.append(nums[i]) + backtrack(currentList) + currentList.pop() + + backtrack([]) + return output + +{% endhighlight %} + +![image1](https://i.ibb.co/S7488mz/16009729542977295723811940825272.jpg) \ No newline at end of file diff --git a/_problems/permutations2.md b/_problems/permutations2.md new file mode 100644 index 0000000..97fecad --- /dev/null +++ b/_problems/permutations2.md @@ -0,0 +1,105 @@ +--- +layout: page +title: Permutations II +last_solved: 2020-09-24 +category: recursion, backtracking +leetcode_url: https://leetcode.com/problems/permutations-ii +status: Solved +--- + +Problem +------- + +``` +Given a collection of numbers that might contain duplicates, return all possible unique permutations. + +Example: + +Input: [1,1,2] +Output: +[ + [1,1,2], + [1,2,1], + [2,1,1] +] + +``` + +Solution +---------- + +This solution works for small cases but TLE on larger cases + +{% highlight python %} + + def permuteUnique(self, nums: List[int]) -> List[List[int]]: + + + output = [] + + def backtrack(currentList): + + if len(currentList)==len(nums): + + if sorted(currentList)==sorted(nums) and currentList not in output: + output.append(currentList.copy()) + + return + + + for i in range(0, len(nums)): + + currentList.append(nums[i]) + backtrack(currentList) + currentList.pop() + + backtrack([]) + return output + + +{% endhighlight %} + + +________________ + + +To combat TLE, I added a visited set to prune the recursion tree. + +{% highlight python %} + + def permuteUnique(self, nums: List[int]) -> List[List[int]]: + + output = [] + visited = set() + + def backtrack(currentList): + + # this caches visited nodes so we don't go down duplicated recursion tree paths + if tuple(currentList) in visited: + return + else: + visited.add(tuple(currentList)) + + + # base case + if len(currentList)==len(nums): + + # when these conditions are met, add it to output + if sorted(currentList)==sorted(nums) and currentList not in output: + output.append(currentList.copy()) + + return + + # going down the recursion tree (similar to permutation 1 but without duplicate check) + for i in range(0, len(nums)): + + currentList.append(nums[i]) + backtrack(currentList) + currentList.pop() + + backtrack([]) + return output + +{% endhighlight %} + +![image1](https://i.ibb.co/8XfLcRH/16009806513183664237674845577197.jpg) \ No newline at end of file diff --git a/_problems/permutationsCascading.md b/_problems/permutationsCascading.md new file mode 100644 index 0000000..44a45bb --- /dev/null +++ b/_problems/permutationsCascading.md @@ -0,0 +1,84 @@ +--- +layout: page +title: Permutations (Cascading) +last_solved: 2020-06-22 +category: cascading +leetcode_url: https://leetcode.com/problems/permutations +status: Solved +--- + +Problem +------- + +``` +Given a collection of distinct integers, return all possible permutations. + +Example: + +Input: [1,2,3] +Output: +[ + [1,2,3], + [1,3,2], + [2,1,3], + [2,3,1], + [3,1,2], + [3,2,1] +] + +``` + +Solution +---------- + +``` + +Let’s take [1,3,5] as an example. Following a BFS approach, we will consider one number at a time: + +If the given set is empty then we have only an empty permutation set: [] +Let’s add the first element (1), the permutations will be: [1] +Let’s add the second element (3), the permutations will be: [3,1], [1,3] +Let’s add the third element (5), the permutations will be: [5,3,1], [3,5,1], [3,1,5], [5,1,3], [1,5,3], [1,3,5] +Let’s analyze the permutations in the 3rd and 4th step. How can we generate permutations in the 4th step from the permutations of the 3rd step? + +If we look closely, we will realize that when we add a new number (5), we take each permutation of the previous step and insert the new number in every position to generate the new permutations. For example, inserting ‘5’ in different positions of [3,1] will give us the following permutations: + +Inserting ‘5’ before ‘3’: [5,3,1] +Inserting ‘5’ between ‘3’ and ‘1’: [3,5,1] +Inserting ‘5’ after ‘1’: [3,1,5] + +``` + + +{% highlight python %} + +def permute(self, nums): + + result = [] + + permutations = [] + permutations.append([]) + + for currNum in nums: + + # we will take all existing permutations and add currNum to create new permutations + n = len(permutations) + + for _ in range(n): + + oldPermutation = permutations.pop(0) + + # create new permutation by adding the currNum at every position + for j in range( len(oldPermutation)+1 ): + + newPermutation = list(oldPermutation) + newPermutation.insert(j, currNum) + + if len(newPermutation)==len(nums): + result.append(newPermutation) + else: + permutations.append(newPermutation) + + return result + +{% endhighlight %} \ No newline at end of file diff --git a/_problems/plusOne.md b/_problems/plusOne.md new file mode 100644 index 0000000..0373b66 --- /dev/null +++ b/_problems/plusOne.md @@ -0,0 +1,233 @@ +--- +layout: page +title: Plus One +last_solved: 2020-06-05 +category: array, math +leetcode_url: https://leetcode.com/problems/plus-one/ +status: Solved +--- + +Problem +------- + +``` +Given a non-empty array of digits representing a non-negative integer, plus one to the integer. + +The digits are stored such that the most significant digit is at the head of the list, and each element in the array contain a single digit. + +You may assume the integer does not contain any leading zero, except the number 0 itself. + +Example 1: + +Input: [1,2,3] +Output: [1,2,4] +Explanation: The array represents the integer 123. +Example 2: + +Input: [4,3,2,1] +Output: [4,3,2,2] +Explanation: The array represents the integer 4321. + +``` + +Solution +---------- + +{% highlight python %} + +def plusOne(self, digits: List[int]) -> List[int]: + + ptr = len(digits)-1 + carry = 1 # just set carry=1 to do get into the loop + + while carry==1: + + # edge case when carry=1 and ptr goes left off the edge (ie: '9') + if ptr<0: + digits.insert(0, 1) + return digits + + # normal case: just add one to last digit + if digits[ptr]>=0 and digits[ptr]<9: + digits[ptr] = digits[ptr]+1 + carry=0 + return digits + + # edge case, set carry and move left + elif digits[ptr]==9: + digits[ptr] = 0 + carry = 1 + ptr-=1 + + return digits + +{% endhighlight %} + +________________ + +Another solution by converting to int, adding 1 and converting back to list. + + +For really big numbers, use ```//``` instead of ```/``` and ```pow(x,y)``` or ```x**y``` instead of ```math.pow(x,y)```. +It makes a difference when N is large. + +{% highlight python %} + +import math + +# digits = [6,1,4,5,3,9,0,1,9,5,1,8,6,7,0,5,5,4,3] +digits = [7,2,8,5,0,9,1,2,9,5,3,6,6,7,3,2,8,4,3,7,9,5,7,7,4,7,4,9,4,7,0,1,1,1,7,4,0,0,6] + +def plusOne(digits): + num = 0 + exp = 0 + for i in reversed(range(len(digits))): + print(num, i, exp, digits[i], pow(10, exp), math.floor( digits[i] * pow(10, exp))) + num += math.floor( digits[i] * pow(10, exp)) + exp+=1 + + + plusOne = int(num+1) + + + res = [] + while plusOne>0: + + pop = plusOne%10 + res = [pop] + res + plusOne = plusOne//10 + + return res + + +print(plusOne(digits)) + +{% endhighlight %} + +__________________ + + +- [stackoverflow about //](https://stackoverflow.com/questions/27946595/how-to-manage-division-of-huge-numbers-in-python) +- [stackoverflow about pow](https://stackoverflow.com/questions/10282674/difference-between-the-built-in-pow-and-math-pow-for-floats-in-python) + +``` + +Using ```math.pow(x,y)``` + +0 38 0 6 1.0 6 +6 37 1 0 10.0 0 +6 36 2 0 100.0 0 +6 35 3 4 1000.0 4000 +4006 34 4 7 10000.0 70000 +74006 33 5 1 100000.0 100000 +174006 32 6 1 1000000.0 1000000 +1174006 31 7 1 10000000.0 10000000 +11174006 30 8 0 100000000.0 0 +11174006 29 9 7 1000000000.0 7000000000 +7011174006 28 10 4 10000000000.0 40000000000 +47011174006 27 11 9 100000000000.0 900000000000 +947011174006 26 12 4 1000000000000.0 4000000000000 +4947011174006 25 13 7 10000000000000.0 70000000000000 +74947011174006 24 14 4 100000000000000.0 400000000000000 +474947011174006 23 15 7 1000000000000000.0 7000000000000000 +7474947011174006 22 16 7 1e+16 70000000000000000 +77474947011174006 21 17 5 1e+17 500000000000000000 +577474947011174006 20 18 9 1e+18 9000000000000000000 +9577474947011174006 19 19 7 1e+19 70000000000000000000 +79577474947011174006 18 20 3 1e+20 300000000000000000000 +379577474947011174006 17 21 4 1e+21 4000000000000000000000 + + +4379577474947011174006 16 22 8 1e+22 80000000000000000000000 +84379577474947011174006 15 23 2 1e+23 199999999999999983222784 + + + +284379577474946994396790 14 24 3 1e+24 2999999999999999949668352 +3284379577474946944065142 13 25 7 1e+25 70000000000000008489271296 +73284379577474955433336438 12 26 6 1e+26 600000000000000062948114432 +673284379577475018381450870 11 27 6 1e+27 6000000000000000629481144320 +6673284379577475647862595190 10 28 3 1e+28 30000000000000000948382466048 +36673284379577476596245061238 9 29 5 1e+29 499999999999999939573568241664 +536673284379577416169813302902 8 30 9 1e+30 8999999999999999897486646837248 +9536673284379577313656460140150 7 31 2 1e+31 19999999999999999271792589930496 +29536673284379576585449050070646 6 32 1 1e+32 100000000000000005366162204393472 +129536673284379581951611254464118 5 33 9 1e+33 9000000000000000086637831186808832 +9129536673284379668589442441272950 4 34 0 1e+34 0 +9129536673284379668589442441272950 3 35 5 1e+35 499999999999999947423342392170774528 +509129536673284327091931834612047478 2 36 8 1e+36 8000000000000000339365098992143695872 +8509129536673284666457030826755743350 1 37 2 1e+37 19999999999999999077525316404242284544 +28509129536673283743982347230998027894 0 38 7 1e+38 700000000000000003131134695670819061760 +[7, 2, 8, 5, 0, 9, 1, 2, 9, 5, 3, 6, 6, 7, 3, 2, 8, 6, 8, 7, 5, 1, 1, 7, 0, 4, 2, 9, 0, 1, 8, 1, 7, 0, 8, 9, 6, 5, 5] + + +___________________ + + +Using ```pow(x,y)``` + +0 38 0 6 1 6 +6 37 1 0 10 0 +6 36 2 0 100 0 +6 35 3 4 1000 4000 +4006 34 4 7 10000 70000 +74006 33 5 1 100000 100000 +174006 32 6 1 1000000 1000000 +1174006 31 7 1 10000000 10000000 +11174006 30 8 0 100000000 0 +11174006 29 9 7 1000000000 7000000000 +7011174006 28 10 4 10000000000 40000000000 +47011174006 27 11 9 100000000000 900000000000 +947011174006 26 12 4 1000000000000 4000000000000 +4947011174006 25 13 7 10000000000000 70000000000000 +74947011174006 24 14 4 100000000000000 400000000000000 +474947011174006 23 15 7 1000000000000000 7000000000000000 +7474947011174006 22 16 7 10000000000000000 70000000000000000 +77474947011174006 21 17 5 100000000000000000 500000000000000000 +577474947011174006 20 18 9 1000000000000000000 9000000000000000000 +9577474947011174006 19 19 7 10000000000000000000 70000000000000000000 +79577474947011174006 18 20 3 100000000000000000000 300000000000000000000 +379577474947011174006 17 21 4 1000000000000000000000 4000000000000000000000 +4379577474947011174006 16 22 8 10000000000000000000000 80000000000000000000000 +84379577474947011174006 15 23 2 100000000000000000000000 200000000000000000000000 +284379577474947011174006 14 24 3 1000000000000000000000000 3000000000000000000000000 +3284379577474947011174006 13 25 7 10000000000000000000000000 70000000000000000000000000 +73284379577474947011174006 12 26 6 100000000000000000000000000 600000000000000000000000000 +673284379577474947011174006 11 27 6 1000000000000000000000000000 6000000000000000000000000000 +6673284379577474947011174006 10 28 3 10000000000000000000000000000 30000000000000000000000000000 +36673284379577474947011174006 9 29 5 100000000000000000000000000000 500000000000000000000000000000 +536673284379577474947011174006 8 30 9 1000000000000000000000000000000 9000000000000000000000000000000 +9536673284379577474947011174006 7 31 2 10000000000000000000000000000000 20000000000000000000000000000000 +29536673284379577474947011174006 6 32 1 100000000000000000000000000000000 100000000000000000000000000000000 +129536673284379577474947011174006 5 33 9 1000000000000000000000000000000000 9000000000000000000000000000000000 +9129536673284379577474947011174006 4 34 0 10000000000000000000000000000000000 0 +9129536673284379577474947011174006 3 35 5 100000000000000000000000000000000000 500000000000000000000000000000000000 +509129536673284379577474947011174006 2 36 8 1000000000000000000000000000000000000 8000000000000000000000000000000000000 +8509129536673284379577474947011174006 1 37 2 10000000000000000000000000000000000000 20000000000000000000000000000000000000 +28509129536673284379577474947011174006 0 38 7 100000000000000000000000000000000000000 700000000000000000000000000000000000000 +[7, 2, 8, 5, 0, 9, 1, 2, 9, 5, 3, 6, 6, 7, 3, 2, 8, 4, 3, 7, 9, 5, 7, 7, 4, 7, 4, 9, 4, 7, 0, 1, 1, 1, 7, 4, 0, 0, 7] + +``` + +____________ + +Another way is to cast it: + +{% highlight python %} + +print( [str(d) for d in digits] ) # cast every int to string in list ["1", "2", "3"] + +str1 = "".join([str(d) for d in digits]) # string join to get "123" +print( str1 ) + +plusOne = int(str1)+1 # cast it to an int and add 1 +print( plusOne ) + + +# back to digit array +return [int(d) for d in str(plusOne)] # cast every char in string to an int and return as list + + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/powerOfFour.md b/_problems/powerOfFour.md new file mode 100644 index 0000000..504dd4b --- /dev/null +++ b/_problems/powerOfFour.md @@ -0,0 +1,56 @@ +--- +layout: page +title: Power of Four +last_solved: 2020-08-04 +category: bit manipulation +leetcode_url: https://leetcode.com/problems/power-of-four/ +status: Solved +--- + +Problem +------- + +``` +Given an integer (signed 32 bits), write a function to check whether it is a power of 4. + +Example 1: + +Input: 16 +Output: true +Example 2: + +Input: 5 +Output: false +Follow up: Could you solve it without loops/recursion? + +``` + +Solution +---------- + +{% highlight python %} + +def isPowerOfFour(self, num: int) -> bool: + + numOnes = 0 + numZerosBeforeOne = 0 + + while num>0: + + if num&1: + numOnes+=1 + else: + numZerosBeforeOne+=1 + + num>>=1 + + if numOnes==1 and numZerosBeforeOne%2==0: + return True + else: + return False + + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/powx-n.md b/_problems/powx-n.md new file mode 100644 index 0000000..1b6eee2 --- /dev/null +++ b/_problems/powx-n.md @@ -0,0 +1,58 @@ +--- +layout: page +title: Pow(x, n) +last_solved: 2020-07-16 +category: bit manipulation +leetcode_url: https://leetcode.com/problems/powx-n/ +status: Attempted +--- + +Problem +------- + +``` +Implement pow(x, n), which calculates x raised to the power n (xn). + +Example 1: + +Input: 2.00000, 10 +Output: 1024.00000 +Example 2: + +Input: 2.10000, 3 +Output: 9.26100 +Example 3: + +Input: 2.00000, -2 +Output: 0.25000 +Explanation: 2-2 = 1/22 = 1/4 = 0.25 + +``` + +Solution +---------- + +Didn't quite get it to work. Do check out [Timonthy's explanation](https://www.youtube.com/watch?v=Twr5TD8Fvbo) + + +{% highlight python %} + +def myPow(self, x: float, n: int) -> float: + + if n<0: + x = 1/x + n = n*-1 + + output = 1 + while n>0: + if n&1: + print(n, x, output) + output *= x + n>>=1 + x=x*x + return output + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/printKdistanceFromRoot.md b/_problems/printKdistanceFromRoot.md new file mode 100644 index 0000000..bd98527 --- /dev/null +++ b/_problems/printKdistanceFromRoot.md @@ -0,0 +1,41 @@ +--- +layout: page +title: Print K distance from Root +--- + + + + +{% highlight python %} + + + +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + + +def printKdistance(root, k): + + if k==0: + print( root.val ) + return + + printKdistance(root.left, k-1) + printKdistance(root.right, k-1) + + +root = TreeNode(1) +root.left = TreeNode(2) +root.right = TreeNode(3) + +printKdistance(root, 1) + + + + +{% endhighlight %} diff --git a/_problems/prisonCellsAfterNDays.md b/_problems/prisonCellsAfterNDays.md new file mode 100644 index 0000000..6bf11dd --- /dev/null +++ b/_problems/prisonCellsAfterNDays.md @@ -0,0 +1,178 @@ +--- +layout: page +title: Prison cells after n days +last_solved: 2020-07-01 +category: arrays +leetcode_url: https://leetcode.com/problems/prison-cells-after-n-days/ +status: Semi-Solved +--- + +Problem +------- + +``` +There are 8 prison cells in a row, and each cell is either occupied or vacant. + +Each day, whether the cell is occupied or vacant changes according to the following rules: + +If a cell has two adjacent neighbors that are both occupied or both vacant, then the cell becomes occupied. +Otherwise, it becomes vacant. +(Note that because the prison is a row, the first and the last cells in the row can't have two adjacent neighbors.) + +We describe the current state of the prison in the following way: cells[i] == 1 if the i-th cell is occupied, else cells[i] == 0. + +Given the initial state of the prison, return the state of the prison after N days (and N such changes described above.) + + + +Example 1: + +Input: cells = [0,1,0,1,1,0,0,1], N = 7 +Output: [0,0,1,1,0,0,0,0] +Explanation: +The following table summarizes the state of the prison on each day: +Day 0: [0, 1, 0, 1, 1, 0, 0, 1] +Day 1: [0, 1, 1, 0, 0, 0, 0, 0] +Day 2: [0, 0, 0, 0, 1, 1, 1, 0] +Day 3: [0, 1, 1, 0, 0, 1, 0, 0] +Day 4: [0, 0, 0, 0, 0, 1, 0, 0] +Day 5: [0, 1, 1, 1, 0, 1, 0, 0] +Day 6: [0, 0, 1, 0, 1, 1, 0, 0] +Day 7: [0, 0, 1, 1, 0, 0, 0, 0] + +Example 2: + +Input: cells = [1,0,0,1,0,0,1,0], N = 1000000000 +Output: [0,0,1,1,1,1,1,0] + +``` + +Solution +---------- + +My solution that worked for small test cases but reached TLE when N=1000000000 + +{% highlight python %} + +arr = [0,1,0,1,1,0,0,1] +N=7 + + +def prisonAfterNDays(arr, N): + + arr2 = [0]*len(arr) + + for i in range(N): + + for i in range(1, len(arr)-1): + + # not xor the middle + arr2[i] = int(not arr[i-1] ^ arr[i+1]) + + # make ends zero + arr2[0], arr2[len(arr)-1] = 0,0 + + # copy arr2 to arr + arr = arr2.copy() + + return arr + +print(prisonAfterNDays(arr, N)) + + +{% endhighlight %} + +__________________ + +Even adding a memo didn't help. N=1 000 000 000 took a while and didnt complete. + +{% highlight python %} + +arr = [0,1,0,1,1,0,0,1] +N=1000000000 + +def prisonAfterNDays(arr, N): + + def computeNext(arr): + + arr2 = [0]*len(arr) + + for i in range(1, len(arr)-1): + + # not xor the middle + arr2[i] = int(not arr[i-1] ^ arr[i+1]) + + # make ends zero + arr2[0], arr2[len(arr)-1] = 0,0 + + # copy arr2 to arr + return arr2.copy() + + + memo = {} + + for i in range(N): + + if tuple(arr) not in memo: + old_arr = arr + new_arr = computeNext(arr) + + memo[tuple(old_arr)] = new_arr + arr = new_arr + else: + arr = memo[tuple(arr)] + + print(memo) + return arr + +print( prisonAfterNDays(arr, N) ) + +{% endhighlight %} + +_____________________ + + +After failing to get the hashmap solution to run in time. I checked out [how other ppl did it](https://leetcode.com/problems/prison-cells-after-n-days/discuss/205684/JavaPython-Find-the-Loop-or-Mod-14)] and their solution ran in time. Will revisit this. + +{% highlight python %} + +arr = [0,1,0,1,1,0,0,1] +N=1000000000 +# N=7 + +def prisonAfterNDays(arr, N): + + def computeNext(arr): + + arr2 = [0]*len(arr) + + for i in range(1, len(arr)-1): + + # not xor the middle + arr2[i] = int(not arr[i-1] ^ arr[i+1]) + + # make ends zero + arr2[0], arr2[len(arr)-1] = 0,0 + + # copy arr2 to arr + return arr2.copy() + + + + seen = {str(arr): N} + while N: + seen.setdefault(str(arr), N) + N -= 1 + # arr = [0] + [arr[i - 1] ^ arr[i + 1] ^ 1 for i in range(1, 7)] + [0] + arr = computeNext(arr) + if str(arr) in seen: + N %= seen[str(arr)] - N + + return arr + + +print( prisonAfterNDays(arr, N) ) + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/productOfArrayExceptSelf.md b/_problems/productOfArrayExceptSelf.md new file mode 100644 index 0000000..7ed0ce3 --- /dev/null +++ b/_problems/productOfArrayExceptSelf.md @@ -0,0 +1,63 @@ +--- +layout: page +title: Product of Array Except Self +last_solved: +category: +leetcode_url: https://leetcode.com/problems/product-of-array-except-self +status: Attempted +--- + +Problem +------- + +``` +Given an array nums of n integers where n > 1, return an array output such that output[i] is equal to the product of all the elements of nums except nums[i]. + +Example: + +Input: [1,2,3,4] +Output: [24,12,8,6] +Constraint: It's guaranteed that the product of the elements of any prefix or suffix of the array (including the whole array) fits in a 32 bit integer. + +Note: Please solve it without division and in O(n). + +Follow up: +Could you solve it with constant space complexity? (The output array does not count as extra space for the purpose of space complexity analysis.) + +``` + +Solution +---------- + +Make Left and Right Array, then multiply together. + +- Left Array consist of product of all elements to the left of i +- Right Array consist of product of all elements to the right of i + +{% highlight python %} + + def productExceptSelf(self, nums: List[int]) -> List[int]: + + length = len(nums) + + L, R, ans = [0]*length, [0]*length, [0]*length + + L[0]=1 + for i in range(1, length): + L[i] = nums[i-1]*L[i-1] + + R[length-1]=1 + for i in range(length-2, -1, -1): + # for i in reversed(range(length-1)): + R[i] = nums[i+1] * R[i+1] + + + for i in range(length): + ans[i] = L[i]*R[i] + + return ans + +{% endhighlight %} + + +![image1](https://4lscea.dm.files.1drv.com/y4moZDY--zQtyjchZihDibspJtcXS7g6gp9nWktB3lpAu_lE0U1QuUB3wEuIN_1VH2sqosjTpLDY0JCULp5OAzQIMvSy5tmHTpoL5IWDyl9_-dPMiRhe5wLGjhspxmUIVkPDS1Z4-4r4FGhZA0r4nXT9RThzOFWR-jtJCTL-SCxKUP3g9dUsOn0EJc0edUV4HYDZ4gfRbfhEQsXOEdLWKRu9w?width=1810&height=2243&cropmode=none) \ No newline at end of file diff --git a/_problems/queueReconstructionByHeight.md b/_problems/queueReconstructionByHeight.md new file mode 100644 index 0000000..e83a3ab --- /dev/null +++ b/_problems/queueReconstructionByHeight.md @@ -0,0 +1,64 @@ +--- +layout: page +title: Queue Reconstruction By Height +last_solved: 2020-06-06 +category: greedy +leetcode_url: https://leetcode.com/problems/queue-reconstruction-by-height/ +status: Attempted +--- + +Problem +------- + +``` + +Suppose you have a random list of people standing in a queue. Each person is described by a pair of integers (h, k), where h is the height of the person and k is the number of people in front of this person who have a height greater than or equal to h. Write an algorithm to reconstruct the queue. + +Note: +The number of people is less than 1,100. + + +Example + +Input: +[[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]] + +Output: +[[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]] + +``` + +Solution +---------- + +{% highlight python %} + +def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]: + + print(people) + + # sort ppl by decending height first and k second + people.sort(key=lambda x: (-x[0], x[1])) + + print(people) + + ans = [] + for person, num in people: + + if num >= len(ans): + ans.append([person, num]) + else: + ans.insert(num, [person, num]) + return ans + +{% endhighlight %} + +After the initial sort, it looks like this: +``` +[[7, 0], [4, 4], [7, 1], [5, 0], [6, 1], [5, 2]] +[[7, 0], [7, 1], [6, 1], [5, 0], [5, 2], [4, 4]] +[[5, 0], [7, 0], [5, 2], [6, 1], [4, 4], [7, 1]] +``` + + +![image1]() \ No newline at end of file diff --git a/_problems/ransomNote.md b/_problems/ransomNote.md new file mode 100644 index 0000000..ff04e54 --- /dev/null +++ b/_problems/ransomNote.md @@ -0,0 +1,60 @@ +--- +layout: page +title: Ransom Note +last_solved: +category: string +leetcode_url: https://leetcode.com/problems/ransom-note +status: Attempted +--- + +Problem +------- + +``` +Given an arbitrary ransom note string and another string containing letters from all the magazines, write a function that will return true if the ransom note can be constructed from the magazines ; otherwise, it will return false. + +Each letter in the magazine string can only be used once in your ransom note. + + + +Example 1: + +Input: ransomNote = "a", magazine = "b" +Output: false +Example 2: + +Input: ransomNote = "aa", magazine = "ab" +Output: false +Example 3: + +Input: ransomNote = "aa", magazine = "aab" +Output: true + +``` + +Solution +---------- + +{% highlight python %} + + def canConstruct(self, ransomNote: str, magazine: str) -> bool: + + letterCounts = Counter(magazine) + + print(letterCounts) + + for c in ransomNote: + + if c in letterCounts and letterCounts[c]>0: + letterCounts[c]-=1 + print(letterCounts) + + else: + return False + + return True + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/reconstructIternary.md b/_problems/reconstructIternary.md new file mode 100644 index 0000000..296f195 --- /dev/null +++ b/_problems/reconstructIternary.md @@ -0,0 +1,105 @@ +--- +layout: page +title: Reconstruct Iternary +last_solved: +category: dfs, graph +leetcode_url: https://leetcode.com/problems/reconstruct-itinerary +status: Not Solved +--- + +Problem +------- + +``` +Given a list of airline tickets represented by pairs of departure and arrival airports [from, to], reconstruct the itinerary in order. All of the tickets belong to a man who departs from JFK. Thus, the itinerary must begin with JFK. + +Note: + +If there are multiple valid itineraries, you should return the itinerary that has the smallest lexical order when read as a single string. For example, the itinerary ["JFK", "LGA"] has a smaller lexical order than ["JFK", "LGB"]. +All airports are represented by three capital letters (IATA code). +You may assume all tickets form at least one valid itinerary. +One must use all the tickets once and only once. +Example 1: + +Input: [["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]] +Output: ["JFK", "MUC", "LHR", "SFO", "SJC"] +Example 2: + +Input: [["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]] +Output: ["JFK","ATL","JFK","SFO","ATL","SFO"] +Explanation: Another possible reconstruction is ["JFK","SFO","ATL","JFK","ATL","SFO"]. + But it is larger in lexical order. + + +``` + + + +Solution +---------- + +Solution that I came up with myself. It works for the first test case but doesn't handle the lexical duplicate tickets. + +{% highlight python %} + +tickets = [["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]] +tickets = [["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]] + +def findTicketIndForStartCity(startCity): + + # TODO: store all ticket indexes that have the same start city + sameStartCityIndex = {} + + for ticketInd, cities in enumerate(tickets): + if cities[0]==startCity: + return ticketInd + + +output = ['JFK'] +for i in range(0, len(tickets)): + + currTicketIndex = findTicketIndForStartCity( output[-1] ) + nextCity = tickets[currTicketIndex][1] + output.append(nextCity) + +print(output) + +{% endhighlight %} + +_________________ + + +Here is the solution in Python using DFS and a stack. The solution is explained in [this video](https://www.youtube.com/watch?v=WYqsg5dziaQ). + +Visualization [here](https://leetcode.com/problems/reconstruct-itinerary/discuss/709699/Python-by-DFS-and-stack-w-Visualization) + +I don't fully get why it's DFS but you can revisit it. For now, just take a few things as a lesson like how they use a hashmap to build an adjacency list (as seen in other similar graph problems). + +{% highlight python %} + +def findItinerary(self, tickets: List[List[str]]) -> List[str]: + graph = {} + + tickets.sort(key=lambda x: x[1]) + + # build graph as adjacency list + for u, v in tickets: + if u in graph: + graph[u].append(v) + else: + graph[u] = [v] + + itinerary, stack = [], [("JFK")] + + while stack: + curr = stack[-1] + + if curr in graph and len(graph[curr]) > 0: + stack.append(graph[curr].pop(0)) + else: + itinerary.append(stack.pop()) + return itinerary[::-1] + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/removeDupFromSortedArray.md b/_problems/removeDupFromSortedArray.md new file mode 100644 index 0000000..bab805f --- /dev/null +++ b/_problems/removeDupFromSortedArray.md @@ -0,0 +1,65 @@ +--- +layout: page +title: Remove Duplicate from Sorted Array +last_solved: 2020-06-03 +category: array, 2ptr +leetcode_url: https://leetcode.com/problems/remove-duplicates-from-sorted-array +status: Solved +--- + +Problem +------- + +``` +Given a sorted array nums, 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 by modifying the input array in-place with O(1) extra memory. + +Example 1: + +Given 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 returned length. +Example 2: + +Given nums = [0,0,1,1,1,2,2,3,3,4], + +Your function should return length = 5, with the first five elements of nums being modified to 0, 1, 2, 3, and 4 respectively. + +It doesn't matter what values are set beyond the returned length. + +``` + +Solution +---------- + +{% highlight python %} + +def removeDuplicates(self, nums: List[int]) -> int: + + if not nums: return 0 + + # [1,1,2] + # [0,0,1,1,1,2,2,3,3,4], + + slow, fast = 0, 0 + + while fast2->6->3->4->5->6, val = 6 +Output: 1->2->3->4->5 + +``` + +Solution +---------- + +I wasn't able to solve this, despite it being easy. +There were tricks that I didn't utilized like dummy and previous pointers. +Also, my problem with linked list problems have always been edge cases. + +The only way to fix this is to solve more linked list problems. + +{% highlight python %} + +def removeElements(self, head: ListNode, val: int) -> ListNode: + + dummy = ListNode(0) + dummy.next = head + curr, prev = head, dummy + + while curr: + + if curr.val==val: # if what happens to curr pointer + prev.next = curr.next # then what happens to prev pointer + else: # if what happens to curr pointer + prev = curr # then what happens to prev pointer + curr = curr.next # always move up curr + + return dummy.next + + + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/removeNthNodeFromEndOfList.md b/_problems/removeNthNodeFromEndOfList.md new file mode 100644 index 0000000..dbd7209 --- /dev/null +++ b/_problems/removeNthNodeFromEndOfList.md @@ -0,0 +1,90 @@ +--- +layout: page +title: Remove Nth Node from End of List +last_solved: 2020-06-06 +category: linked list +leetcode_url: https://leetcode.com/problems/remove-nth-node-from-end-of-list +status: Solved +--- + +Problem +------- + +``` +Given a linked list, remove the n-th node from the end of list and return its head. + +Example: + +Given linked list: 1->2->3->4->5, and n = 2. + +After removing the second node from the end, the linked list becomes 1->2->3->5. + +``` + +Solution +---------- + +{% highlight python %} + +def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode: + + if not head: return None + if head.next is None: return None + + slow = head + fast = head + + # move fast up n times + for _ in range(n): + fast = fast.next + + + # This situation would happen when we are required to del the first node (n = len(List)) + # Also, it can handle the [] case + if not fast: + return slow.next + + # move fast to the last node + while fast.next: + slow = slow.next + fast = fast.next + + # do removal + slow.next = slow.next.next + + return head + +{% endhighlight %} + +______________ + +With dummy node. Dummy node helps with edge case where you want to remove the first element. + +{% highlight python %} + +def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode: + + dummy = ListNode(0) + dummy.next = head + + slow, fast = dummy, dummy + + # advance fast pointer so gap between slow and fast are n apart + for _ in range(n+1): + fast = fast.next + + + # advance both pointers, maintain gap + while fast: + slow = slow.next + fast = fast.next + + + # remove the nth node + slow.next = slow.next.next + + return dummy.next + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/reorder_list.md b/_problems/reorder_list.md new file mode 100644 index 0000000..b5aea7c --- /dev/null +++ b/_problems/reorder_list.md @@ -0,0 +1,161 @@ +--- +layout: page +title: Reorder List +last_solved: +category: linked list +leetcode_url: https://leetcode.com/problems/reorder-list/ +status: Attempted +--- + +Problem +------- + +``` +Given a singly linked list L: L0→L1→…→Ln-1→Ln, +reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→… + +You may not modify the values in the list's nodes, only nodes itself may be changed. + +Example 1: + +Given 1->2->3->4, reorder it to 1->4->2->3. +Example 2: + +Given 1->2->3->4->5, reorder it to 1->5->2->4->3. +``` + +Solution +---------- + +With Stack: + +- make a queue(), push all nodes to it +- pop off left and right side of q, alternating each time +- as you pop off, rebuild linked list (make sure to set node.next to None) + + +{% highlight python %} + + def reorderList(self, head: ListNode) -> None: + + # push all into list + q = deque() + while head: + q.append(head) + head = head.next + + + dummy = ListNode(0) + cur = dummy + even = False + + while q: + + node = q.pop() if even else q.popleft() + node.next = None + + cur.next = node + cur = cur.next + + even ^= True + + return dummy.next + + +{% endhighlight %} + +____________ + +Without Stack + +- split list in half +- reverse second half +- merge lists + +{% highlight python %} + + def reorderList(self, head: ListNode) -> None: + + if not head: return None + + # 1 2 3 4 + # 8 7 6 5 + + + # 1) split list in half + prev, slow, fast = None, head, head + + + + while fast and fast.next: + + prev = slow # prev is "tail" of slow + slow = slow.next + fast = fast.next.next + + # print(prev.val, slow.val, fast) + + # current state + # 1 2 3 4 + # p s f + + + prev.next = None + + l1 = head + + # 1 2 + # l p + # + # 3 4 + # s f + + # 2) reverse second list + def reverse(head): + + prev, curr, next = None, head, None + + while curr: + next = curr.next + curr.next = prev + prev = curr + curr = next + + return prev + + + l1 = head + l2 = reverse(slow) + print(l1.val, l2.val) + + # 1 2 + # 4 3 + + # 3) time to merge + dummy = ListNode(0) + curr = dummy + + while l1 and l2: + + if l1: + curr.next = l1 + l1 = l1.next + curr = curr.next + if l2: + curr.next = l2 + l2 = l2.next + curr = curr.next + + if l1: + curr.next = l1 + + if l2: + curr.next = l2 + + return dummy.next + + + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/restoreIpAddresses.md b/_problems/restoreIpAddresses.md new file mode 100644 index 0000000..bb87516 --- /dev/null +++ b/_problems/restoreIpAddresses.md @@ -0,0 +1,90 @@ +--- +layout: page +title: Restore IP Addresses +last_solved: +category: backtracking +leetcode_url: https://leetcode.com/problems/restore-ip-addresses/ +status: Not Solved +--- + +Problem +------- + +``` +Given a string s containing only digits. Return all possible valid IP addresses that can be obtained from s. You can return them in any order. + +A valid IP address consists of exactly four integers, each integer is between 0 and 255, separated by single points and cannot have leading zeros. For example, "0.1.2.201" and "192.168.1.1" are valid IP addresses and "0.011.255.245", "192.168.1.312" and "192.168@1.1" are invalid IP addresses. + + + +Example 1: + +Input: s = "25525511135" +Output: ["255.255.11.135","255.255.111.35"] +Example 2: + +Input: s = "0000" +Output: ["0.0.0.0"] +Example 3: + +Input: s = "1111" +Output: ["1.1.1.1"] +Example 4: + +Input: s = "010010" +Output: ["0.10.0.10","0.100.1.0"] +Example 5: + +Input: s = "101023" +Output: ["1.0.10.23","1.0.102.3","10.1.0.23","10.10.2.3","101.0.2.3"] +``` + +Solution +---------- + + + +{% highlight python %} + + def restoreIpAddresses(self, s: str) -> List[str]: + + def dfs(s, index, path, res): + + if index==4: + if not s: # why is this here? + res.append( path[:-1] ) + return + + + + for i in range(1,4): + + if i<=len(s): + + if i==1: + dfs(s[1:], index+1, path+s[:i]+".", res) + + elif i==2 and s[0]!="0": + dfs(s[i:], index+1, path+s[:i]+".", res) + + elif i==3 and s[0]!="0" and int(s[:3]) <= 255: + dfs(s[i:], index+1, path+s[:i]+".", res) + + + res = [] + dfs(s, 0, "", res) + return res + + +{% endhighlight %} + +______________ + + + +{% highlight python %} + + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/reverseBits.md b/_problems/reverseBits.md new file mode 100644 index 0000000..5b1e46f --- /dev/null +++ b/_problems/reverseBits.md @@ -0,0 +1,52 @@ +--- +layout: page +title: Reverse Bits +last_solved: Solved +category: Bits +leetcode_url: https://leetcode.com/problems/reverse-bits +status: Solved +--- + +Problem +------- + +``` +Reverse bits of a given 32 bits unsigned integer. + + + +Example 1: + +Input: 00000010100101000001111010011100 +Output: 00111001011110000010100101000000 +Explanation: The input binary string 00000010100101000001111010011100 represents the unsigned integer 43261596, so return 964176192 which its binary representation is 00111001011110000010100101000000. +Example 2: + +Input: 11111111111111111111111111111101 +Output: 10111111111111111111111111111111 +Explanation: The input binary string 11111111111111111111111111111101 represents the unsigned integer 4294967293, so return 3221225471 which its binary representation is 10111111111111111111111111111111. + +``` + +Solution +---------- + +Try doing it by hand for a small test case like a number with 4 bits (see image). + +{% highlight python %} + +def reverseBits(self, n: int) -> int: + + output, power = 0, 31 + + while n: + output += (n&1) << power + n>>=1 + power-=1 + + return output + +{% endhighlight %} + + +![image1](https://5wizmw.dm.files.1drv.com/y4mU0kKdlap0lTnvFuIlluTwIYshPYaprTkHKJLryfgid6p0j5D9rNwGI7j-QbfbVWZin0j6QstrypxExk0g8t9rrKpBL1XGemV7OLVw9nyJNcbPI-5Cn_NNqTSR4UEfUe5uMePXSkTkz8QC0IuOl8WS1vyNMj6c9nHVv4daJn7TKBtZ5L4g5LtyU1oMP0jz42RO9FcIhcIexp0jaazW9F4Wg?width=2710&height=1085&cropmode=none) \ No newline at end of file diff --git a/_problems/reverseInteger.md b/_problems/reverseInteger.md new file mode 100644 index 0000000..f49c8fa --- /dev/null +++ b/_problems/reverseInteger.md @@ -0,0 +1,101 @@ +--- +layout: page +title: Reverse Integer +last_solved: 2020-06-02 +category: math +leetcode_url: https://leetcode.com/problems/reverse-integer +status: Solved +--- + +##### Problem + +Given a 32-bit signed integer, reverse digits of an integer. + +Example 1: +Input: 123 +Output: 321 + +Example 2: +Input: -123 +Output: -321 + +Example 3: +Input: 120 +Output: 21 + +##### Solution + +The tricky part of this question is handling the overflows. Check out [this](https://www.youtube.com/watch?v=ThdOYKsFSK0) video: + +{% highlight python %} + +def reverse(self, num: int) -> int: + + # handle negative case + neg = False + if num<0: + neg = True + num = abs(num) + + rev = 0 + + while num>0: + + # pop last digit + popped = num % 10 + num = math.floor(num / 10) + + # handle overflow + # if (rev > 2**31 / 10) or (rev == 2**31 / 10 and popped>7): return 0 + # if (rev < -2**31 / 10) or (rev == -2**31 / 10 and popped<-8): return 0 + + # this is good enough + if (rev >= 2**31 / 10) : return 0 + if (rev <= -2**31 / 10) : return 0 + + rev = rev * 10 + popped + + print(num, popped, rev) + + + return rev*-1 if neg else rev + +{% endhighlight %} + + +```2**31 = 2147483648``` +```-2**31 = -2147483648``` + +-2147483648 to 2147483647 Because of the range see thee last digit + +This is what happens when it overflows + +{% highlight text %} +153423646 9 9 +15342364 6 96 +1534236 4 964 +153423 6 9646 +15342 3 96463 +1534 2 964632 +153 4 9646324 +15 3 96463243 +1 5 964632435 +0 1 9646324351 +9646324351 +{% endhighlight %} + +This is what happens when we prevent the overflow +{% highlight text %} +153423646 9 9 +15342364 6 96 +1534236 4 964 +153423 6 9646 +15342 3 96463 +1534 2 964632 +153 4 9646324 +15 3 96463243 +1 5 964632435 +0 +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/reverseLLiterative.md b/_problems/reverseLLiterative.md new file mode 100644 index 0000000..709ffdf --- /dev/null +++ b/_problems/reverseLLiterative.md @@ -0,0 +1,35 @@ +--- +layout: page +title: Reverse Linked List Iteratively +last_solved: 2020-07-10 +category: linked list +leetcode_url: https://leetcode.com/problems/reverse-linked-list/ +status: Solved +--- + + + + +{% highlight python %} + +def reverseList(self, head: ListNode) -> ListNode: + + prev = None + curr = head + next = None + + while curr: + + next = curr.next # save next + + curr.next = prev # do reversal + + prev = curr + curr = next + + return prev + + +{% endhighlight %} + + diff --git a/_problems/reverseString.md b/_problems/reverseString.md new file mode 100644 index 0000000..cd0a87b --- /dev/null +++ b/_problems/reverseString.md @@ -0,0 +1,49 @@ +--- +layout: page +title: Reverse String +last_solved: 2020-06-01 +category: string +leetcode_url: https://leetcode.com/problems/reverse-string/ +status: Solved +--- + +##### Problem + +{% highlight text %} + +Example 1: + +Input: ["h","e","l","l","o"] +Output: ["o","l","l","e","h"] + +{% endhighlight %} + +##### Solution + +{% highlight python %} + +def reverseString(self, s: List[str]) -> None: + """ + Do not return anything, modify s in-place instead. + """ + + if not s: return + + start = 0 + end = len(s)-1 + + while start str: + + lst = list(s) + + def isVowel(c): + if c in "AEIOUaeiou": + return True + return False + + def swap(x,y,lst): + tmp = lst[x] + lst[x]=s[y] + lst[y]=tmp + + + left, right = 0, len(lst)-1 + + + while left str: + + letters = list(s) + + def reverse(letters, startIndex, endIndex): + + left, right = 0, endIndex + + while left None: + + if not nums: return + if len(nums)==1: return + + # in case k>len(nums) + if k>len(nums): + k = k%len(nums) + + def reverse(nums, start, end): + + while start0: + + minutes_passed+=1 + + # process orange at the current level + for i in range(len(rottonQueue)): + + # get rotton + x, y = rottonQueue.pop(0) + + # visit neighbours + for dx, dy in [(1,0), (-1,0), (0,1), (0,-1)]: + + # calculate coordinates of adjacent cells + xx, yy = x+dx, y+dy + + # ignore cell if it's out of boundary + if xx<0 or xx==R or yy<0 or yy==C: + continue + + # ignore cell if it is empty '0' or visited before '2' + if grid[xx][yy]==0 or grid[xx][yy]==2: + continue + + # update fresh count + fresh_count-=1 + + # mark current cell as rotton + grid[xx][yy]=2 + + # add to queue + rottonQueue.append((xx,yy)) + + return minutes_passed if fresh_count==0 else -1 + +print( orangesRotting(grid) ) + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/searchForARange.md b/_problems/searchForARange.md new file mode 100644 index 0000000..18098f9 --- /dev/null +++ b/_problems/searchForARange.md @@ -0,0 +1,94 @@ +--- +layout: page +title: Find First and Last Position of Element in Sorted Array +last_solved: +category: binary search +leetcode_url: https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/ +status: Attempted +--- + +Problem +------- + +``` +Given an array of integers nums sorted in ascending order, find the starting and ending position of a given target value. + +Your algorithm's runtime complexity must be in the order of O(log n). + +If the target is not found in the array, return [-1, -1]. + +Example 1: + +Input: nums = [5,7,7,8,8,10], target = 8 +Output: [3,4] +Example 2: + +Input: nums = [5,7,7,8,8,10], target = 6 +Output: [-1,-1] + +``` + +Solution +---------- + +[nick white](https://www.youtube.com/watch?v=bU-q1OJ0KWw) + +Run binary search twice: +- find the starting position +- find the ending position + +Take note of boundary conditions and termination conditions when implementing binary search. + +{% highlight python %} + +def searchRange(self, nums: List[int], target: int) -> List[int]: + + def findStartIndex(nums, target): + + index = -1 + + left, right = 0, len(nums)-1 + + while left<=right: + + mid = left + (right-left) // 2 + if nums[mid]>=target: # >= becuz we want to find teh first occurance of the duplicates + right = mid-1 + else: + left = mid+1 + + if nums[mid]==target: + index = mid + + return index + + + + def findEndIndex(nums, target): + + index = -1 + + left, right = 0, len(nums)-1 + + while left<=right: + + mid = left + (right-left) // 2 + if nums[mid]<=target: + left = mid+1 + else: + right = mid-1 + + if nums[mid]==target: + index = mid + + return index + + start = findStartIndex(nums, target) + end = findEndIndex(nums, target) + + return [start,end] + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/searchInRotatedSortedArray.md b/_problems/searchInRotatedSortedArray.md new file mode 100644 index 0000000..0e7bd7b --- /dev/null +++ b/_problems/searchInRotatedSortedArray.md @@ -0,0 +1,93 @@ +--- +layout: page +title: Search in Rotated Sorted Array +last_solved: +category: binary search +leetcode_url: https://leetcode.com/problems/search-in-rotated-sorted-array +status: Attempted +--- + +Problem +------- + +``` +Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. + +(i.e., [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2]). + +You are given a target value to search. If found in the array return its index, otherwise return -1. + +You may assume no duplicate exists in the array. + +Your algorithm's runtime complexity must be in the order of O(log n). + +Example 1: + +Input: nums = [4,5,6,7,0,1,2], target = 0 +Output: 4 +Example 2: + +Input: nums = [4,5,6,7,0,1,2], target = 3 +Output: -1 + +``` + +Solution +---------- + +Do it in two parts: +- first find pivot (similar to find min in rotated sorted array) +- then reset boundaries to do a regular binary search + +{% highlight python %} + +def search(self, nums: List[int], target: int) -> int: + + if not nums: return -1 + + left, right = 0, len(nums)-1 + + # get left to the pivot + while left=nums[start] and target<=nums[right]: + left = start + else: # target is on left side + right = start + + + # do binary search + while left<=right: + + mid = (left+right)//2 + + if nums[mid]==target: + return mid + elif nums[mid]=nums[left] and target<=nums[right]: + return left+1 + + # target is outside of array (to the right) + elif target>nums[right]: + return right+1 + + # target is outside of array (to the left) + elif targetnums[mid]: + left = mid+1 + elif target=nums[left] and target<=nums[right]: + # return left+1 + + # # target is outside of array (to the right) + # elif target>nums[right]: + # return right+1 + + # # target is outside of array (to the left) + # elif targetnums[mid]: + left = mid+1 + elif target int: + + left, right = 0, len(nums) + + while left=target: + right = mid + else: + left = mid+1 + + return left + + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/searchRotatedArray.md b/_problems/searchRotatedArray.md new file mode 100644 index 0000000..b46e1a8 --- /dev/null +++ b/_problems/searchRotatedArray.md @@ -0,0 +1,72 @@ +--- +layout: page +title: Search in Rotated Sorted Array +last_solved: 2020-06-07 +category: binary search +leetcode_url: https://leetcode.com/problems/search-in-rotated-sorted-array +status: Attempted +--- + +Problem +------- + +``` +Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. + +(i.e., [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2]). + +You are given a target value to search. If found in the array return its index, otherwise return -1. + +You may assume no duplicate exists in the array. + +Your algorithm's runtime complexity must be in the order of O(log n). + +Example 1: + +Input: nums = [4,5,6,7,0,1,2], target = 0 +Output: 4 +Example 2: + +Input: nums = [4,5,6,7,0,1,2], target = 3 +Output: -1 + + +``` + +Solution +---------- + +Check Nick White's video on this question. it's also 2-pass binary search + +{% highlight python %} + +def search(self, nums, target): + if not nums: + return -1 + l,r=0,len(nums)-1 + while l<=r: + m=(l+r)/2 + if nums[m]target: + r=len(nums)-1 + else: + l=0 + + while l<=r: + m=(l+r)/2 + if nums[m]==target: + return m + if nums[m]=rows: return + else: + mat[i][j]=0 + zeroDownward(i+1,j) + + def zeroLeft(i,j): + + if j<0: return + else: + mat[i][j]=0 + zeroLeft(i,j-1) + + def zeroRight(i,j): + + if j>=cols: return + else: + mat[i][j]=0 + zeroRight(i,j+1) + + for i in range(0, rows): + for j in range(0, cols): + if mat[i][j]==0: + zeroUpward(i,j) + print("after up", mat) + + zeroDownward(i,j) + print("after down", mat) + + zeroLeft(i,j) + print("after left", mat) + + zeroRight(i,j) + print("after right", mat) + + return mat + +setZeroes(mat) + +print(mat) + + +{% endhighlight %} + +A solution to this problem is instead of modifying the matrix right away, save the row and columns that need to be zeroed into two sets. Then zero it the rows and columns in the second pass. + +The time complexity is O(m*n) + +The space complexity is O(m+n) + +{% highlight python %} + +def setZeroes(self, mat: List[List[int]]) -> None: + + if not mat: return None + + R = len(mat) + C = len(mat[0]) + + zero_rows = set() + zero_cols = set() + + # iterate over matrix once to add row and column that needs to be zeroed (without modifying it in place yet) + for i in range(0, R): + for j in range(0, C): + if mat[i][j]==0: + zero_rows.add(i) + zero_cols.add(j) + + # go over second time to actually zero out rows and columns + for i in range(0, R): + for j in range(0, C): + if i in zero_rows: + mat[i][j]=0 + if j in zero_cols: + mat[i][j]=0 + +{% endhighlight %} + +_______________ + + +Using itertools.product + +{% highlight python %} + +def setZeroes(self, mat: List[List[int]]) -> None: + + if not mat: return None + + R = len(mat) + C = len(mat[0]) + + zero_rows = set() + zero_cols = set() + + # iterate over matrix once to add row and column that needs to be zeroed (without modifying it in place yet) + for i, j in product(range(R), range(C)): + if mat[i][j]==0: + zero_rows.add(i) + zero_cols.add(j) + + # go over second time to actually zero out rows and columns + for i, j in product(range(R), range(C)): + if i in zero_rows: + mat[i][j]=0 + if j in zero_cols: + mat[i][j]=0 + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/shortestPathCells.md b/_problems/shortestPathCells.md new file mode 100644 index 0000000..edd01ed --- /dev/null +++ b/_problems/shortestPathCells.md @@ -0,0 +1,111 @@ +--- +layout: page +title: Shortest Cell Path +last_solved: +category: +leetcode_url: https://www.pramp.com/challenge/Y56aZmaj9Ptmd9wV9xvL +status: Attempted +--- + +Problem +------- + +``` +Shortest Cell Path +In a given grid of 0s and 1s, we have some starting row and column sr, sc and a target row and column tr, tc. Return the length of the shortest path from sr, sc to tr, tc that walks along 1 values only. + +Each location in the path, including the start and the end, must be a 1. Each subsequent location in the path must be 4-directionally adjacent to the previous location. + +It is guaranteed that grid[sr][sc] = grid[tr][tc] = 1, and the starting and target positions are different. + +If the task is impossible, return -1. + +Examples: + +input: +grid = [[1, 1, 1, 1], [0, 0, 0, 1], [1, 1, 1, 1]] +sr = 0, sc = 0, tr = 2, tc = 0 +output: 8 +(The lines below represent this grid:) +1111 +0001 +1111 + +grid = [[1, 1, 1, 1], [0, 0, 0, 1], [1, 0, 1, 1]] +sr = 0, sc = 0, tr = 2, tc = 0 +output: -1 +(The lines below represent this grid:) +1111 +0001 +1011 + +``` + +Solution +---------- + + + +Have to use BFS because BFS finds the shortest path. DFS doesn't + +None of the solutions below returns the correct result. + +{% highlight python %} + +def shortestCellPath(grid, sr, sc, tr, tc): + + q = [(sr, sc, 0)] + + seen = set() + seen.add((sr,sc)) + + + #[[1, 1, 1, 1] + # [0, 0, 0, 1] + # [1, 1, 1, 1]] + + while q: + + r,c,depth = q.pop(0) + + if r==tr and c==tc: return depth + + for (nr, nc) in ((r-1,c), (r+1,c), (r,c-1), (r,c+1)): + + # check within bounardies and check if not visited before + if 0<=nr=len(grid) or j>=len(grid[0]): + return + if grid[i][j]==0: + return + if i==i1 and j==j1: + Min[0]=min(Min[0],depth) + return + grid[i][j]=0 + + for paths in [i+1,j],[i-1,j],[i,j-1],[i,j+1]: + traverse(paths,end,Min,grid,depth+1) + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/singleNumber.md b/_problems/singleNumber.md new file mode 100644 index 0000000..096f83b --- /dev/null +++ b/_problems/singleNumber.md @@ -0,0 +1,86 @@ +--- +layout: page +title: Single Number +last_solved: 2020-06-02 +category: array, bit manipulation +leetcode_url: https://leetcode.com/problems/single-number/ +status: Solved +--- + +Problem +------------ + +{% highlight text %} + +Given a non-empty array of integers, every element appears twice except for one. Find that single one. + +Note: + +Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? + +Example 1: + +Input: [2,2,1] +Output: 1 +Example 2: + +Input: [4,1,2,1,2] +Output: 4 + +{% endhighlight %} + +Solution +--------- + + +### Add to List and Remove if duplicated + +{% highlight python %} + +def singleNumber(self, nums: List[int]) -> int: + + dupList = [] + + for n in nums: + if n in dupList: + dupList.remove(n) + else: + dupList.append(n) + + return dupList[0] + +{% endhighlight %} + +- Time: O(n^2) because O(n) to look thru list once, and since search is in loop, it's another O(n) +- Space: O(n) + + +### Hashtable + +Add to hash table with count and return count=1. + +- O(n) time and space + +### XOR Solution (Best Solution) + + +Since XOR is commutative and any number XOR'ed with itself is 0, it will cancel out all the duplicate numbers, leaving the single number by itself + +- O(n) time +- O(1) space + +{% highlight python %} + +def singleNumber(self, nums: List[int]) -> int: + + res=0 + for n in nums: + res = res^n + print(res) + + return res + +{% endhighlight python %} + + +![image1]() \ No newline at end of file diff --git a/_problems/singleNumber3.md b/_problems/singleNumber3.md new file mode 100644 index 0000000..1e28a1b --- /dev/null +++ b/_problems/singleNumber3.md @@ -0,0 +1,77 @@ +--- +layout: page +title: Single Number III +last_solved: 2020-07-23 +category: bit manipulation +leetcode_url: https://leetcode.com/problems/single-number-iii +status: Attempted +--- + +Problem +------- + +``` + +Given an array of numbers nums, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once. + +Example: + +Input: [1,2,1,3,2,5] +Output: [3,5] +Note: + +The order of the result is not important. So in the above example, [5, 3] is also correct. +Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity? +``` + +Solution +---------- + +Solution 1: you could always add it to a hashmap or set and if the count==1, add it to the result + +{% highlight python %} + +counter = Counter(nums) + +ans = [] +for k,v in counter.items(): + if v==1: + ans.append(k) + +return ans + +{% endhighlight %} + + +Solution 2 uses bit manipulation: + +There's two tricks you need to be aware of. + +- xor by itself cancels/zeros itself out (you know this already) +- to find the last bit set: + - `firstbit = xor & (xor-1) ^ xor` +- xor is: + - `a^b=c, a^c=b, b^c=a` + +The code and explaination are [here](https://www.youtube.com/watch?v=B7rhKt77fbw) + +{% highlight python %} + +def singleNumber(self, nums: List[int]) -> List[int]: + + xor = 0 + for n in nums: + xor ^= n + + # xor = num1 ^ num2 + firstbit = xor & (xor-1) ^ xor + num1 = 0 + for n in nums: + if n & firstbit: + num1 ^= n + + return [num1, num1^xor] + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/singleNumberii.md b/_problems/singleNumberii.md new file mode 100644 index 0000000..82fcb9b --- /dev/null +++ b/_problems/singleNumberii.md @@ -0,0 +1,62 @@ +--- +layout: page +title: Single Number II +last_solved: 2020-06-22 +category: bit manipulation +leetcode_url: https://leetcode.com/problems/single-number-ii +status: Attempted +--- + +Problem +------- + +``` +Given a non-empty array of integers, every element appears three times except for one, which appears exactly once. Find that single one. + +Note: + +Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? + +Example 1: + +Input: [2,2,3,2] +Output: 3 +Example 2: + +Input: [0,1,0,1,0,1,99] +Output: 99 + +``` + +Solution +---------- + +If a number appears 3 times, then its sum of bits will be of the form ```3 * n```. +But if it only appears once, then it's sum of bits will be ```n```. + +So iterate thru all 32 bits of integers, adding their sums, mod it by 3 and the remaining will be the answer. + +Let's take [2,2,3,2] for example. + +``` +0 1 0 | 2 +0 1 0 | 2 +0 1 0 | 2 +1 0 0 | 3 +--------------- +1 3 0 sum of each digit column + + +1 % 3 => 1 +3 % 3 => 0 +0 % 0 => 0 + +The answer is 3 +``` + +{% highlight python %} + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/sortColors.md b/_problems/sortColors.md new file mode 100644 index 0000000..4d5b64a --- /dev/null +++ b/_problems/sortColors.md @@ -0,0 +1,138 @@ +--- +layout: page +title: Sort Colors +last_solved: 2020-08-04 +category: arrays, sorting +leetcode_url: https://leetcode.com/problems/sort-colors/ +status: Solved +--- + +Problem +------- + +``` +Given an array with n objects colored red, white or blue, sort them in-place 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. + +Example: + +Input: [2,0,2,1,1,0] +Output: [0,0,1,1,2,2] +Follow up: + +A rather straight forward solution is a two-pass algorithm using counting sort. +First, iterate the array counting number of 0's, 1's, and 2's, then overwrite array with total number of 0's, then 1's and followed by 2's. +Could you come up with a one-pass algorithm using only constant space? + +``` + +Solution +---------- + +{% highlight python %} + +nums = [2,0,2,1,1,0] + +def sortColors(nums): + + start = 0 + end = len(nums)-1 + index = 0 + + # 2 0 2 1 1 0 i=0 s=0 e=5 + # 0 0 2 1 1 2 i=1 s=0 e=4 + + while index<=end and start None: + + start = 0 + end = len(nums)-1 + index = 0 + + def swap(nums, i, j): + tmp = nums[i] + nums[i] = nums[j] + nums[j] = tmp + + while start None: + + s = 0 + e = len(nums)-1 + p = 0 + + def swap(nums,x,y): + tmp = nums[x] + nums[x] = nums[y] + nums[y] = tmp + + while p<=e: + + if nums[p]==2: + swap(nums, p, e) + e-=1 + elif nums[p]==0: + swap(nums, p, s) + s+=1 + p+=1 + else: + p+=1 + + return nums + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/spiralMatrix.md b/_problems/spiralMatrix.md new file mode 100644 index 0000000..cfe7cf9 --- /dev/null +++ b/_problems/spiralMatrix.md @@ -0,0 +1,162 @@ +--- +layout: page +title: Spiral Matrix +last_solved: 2020-07-16 +category: matrix +leetcode_url: https://leetcode.com/problems/spiral-matrix/ +status: Attempted +--- + +Problem +------- + +``` +Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order. + +Example 1: + +Input: +[ + [ 1, 2, 3 ], + [ 4, 5, 6 ], + [ 7, 8, 9 ] +] +Output: [1,2,3,6,9,8,7,4,5] +Example 2: + +Input: +[ + [1, 2, 3, 4], + [5, 6, 7, 8], + [9,10,11,12] +] +Output: [1,2,3,4,8,12,11,10,9,5,6,7] + +``` + +Solution +---------- + +This is a really good problem to practice reverse for loops and matrix traversal + +{% highlight python %} + + +matrix = [ + [ 1, 2, 3 ], + [ 4, 5, 6 ], + [ 7, 8, 9 ] +] + +def spiralMatrix(matrix): + + start_row = 0 + end_row = len(matrix) + start_col = 0 + end_col = len(matrix) + + output = [] + while start_row b.id + +{% endhighlight %} + +{% highlight sql %} + +delete a +from person a join person b on a.email=b.email +where a.id > b.id + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/sql_department_highest_salary.md b/_problems/sql_department_highest_salary.md new file mode 100644 index 0000000..0a84219 --- /dev/null +++ b/_problems/sql_department_highest_salary.md @@ -0,0 +1,89 @@ +--- +layout: page +title: department highest salary +last_solved: +category: sql +leetcode_url: https://leetcode.com/problems/department-highest-salary/ +status: solved +--- + +Problem +------- + +``` +The Employee table holds all employees. Every employee has an Id, a salary, and there is also a column for the department Id. + ++----+-------+--------+--------------+ +| Id | Name | Salary | DepartmentId | ++----+-------+--------+--------------+ +| 1 | Joe | 70000 | 1 | +| 2 | Jim | 90000 | 1 | +| 3 | Henry | 80000 | 2 | +| 4 | Sam | 60000 | 2 | +| 5 | Max | 90000 | 1 | ++----+-------+--------+--------------+ +The Department table holds all departments of the company. + ++----+----------+ +| Id | Name | ++----+----------+ +| 1 | IT | +| 2 | Sales | ++----+----------+ +Write a SQL query to find employees who have the highest salary in each of the departments. For the above tables, your SQL query should return the following rows (order of rows does not matter). + ++------------+----------+--------+ +| Department | Employee | Salary | ++------------+----------+--------+ +| IT | Max | 90000 | +| IT | Jim | 90000 | +| Sales | Henry | 80000 | ++------------+----------+--------+ +Explanation: + +Max and Jim both have the highest salary in the IT department and Henry has the highest salary in the Sales department. +``` + +Solution +---------- + + +- First, just make the inner query to get departmentid and highest salary. + +{% highlight sql %} + +# get highest salary per department group +select departmentid, max(salary) +from employee +group by departmentid + +{% endhighlight %} + + +It will look like: + +``` +deptid | max(salary) +1 | 90000 +2 | 80000 +``` + +Then join tables and do a `where ... in` with results from inner query. + +{% highlight sql %} + +select d.name as 'Department', e.name as 'Employee', e.salary as 'Salary' +from Employee e join Department d on e.departmentid=d.id +where (e.departmentid, salary) in +( + # get highest salary per department group + select departmentid, max(salary) + from employee + group by departmentid +) + + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/sql_dupicate_emails.md b/_problems/sql_dupicate_emails.md new file mode 100644 index 0000000..aaaaad4 --- /dev/null +++ b/_problems/sql_dupicate_emails.md @@ -0,0 +1,46 @@ +--- +layout: page +title: Duplicate Emails +last_solved: +category: sql +leetcode_url: https://leetcode.com/problems/duplicate-emails/ +status: Attempted +--- + +Problem +------- + +``` +Write a SQL query to find all duplicate emails in a table named Person. + ++----+---------+ +| Id | Email | ++----+---------+ +| 1 | a@b.com | +| 2 | c@d.com | +| 3 | a@b.com | ++----+---------+ +For example, your query should return the following for the above table: + ++---------+ +| Email | ++---------+ +| a@b.com | ++---------+ + +``` + +Solution +---------- + +{% highlight sql %} + +select Email +from person +group by email +having count(*)>1 + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/sql_employees_earning_more_than_managers.md b/_problems/sql_employees_earning_more_than_managers.md new file mode 100644 index 0000000..4882c21 --- /dev/null +++ b/_problems/sql_employees_earning_more_than_managers.md @@ -0,0 +1,49 @@ +--- +layout: page +title: Employees Earning More Than Their Managers +last_solved: +category: sql +leetcode_url: https://leetcode.com/problems/employees-earning-more-than-their-managers +status: solved +--- + +Problem +------- + +``` +The Employee table holds all employees including their managers. Every employee has an Id, and there is also a column for the manager Id. + ++----+-------+--------+-----------+ +| Id | Name | Salary | ManagerId | ++----+-------+--------+-----------+ +| 1 | Joe | 70000 | 3 | +| 2 | Henry | 80000 | 4 | +| 3 | Sam | 60000 | NULL | +| 4 | Max | 90000 | NULL | ++----+-------+--------+-----------+ +Given the Employee table, write a SQL query that finds out employees who earn more than their managers. For the above table, Joe is the only employee who earns more than his manager. + ++----------+ +| Employee | ++----------+ +| Joe | ++----------+ + +``` + +Solution +---------- + +use an self join + +{% highlight sql %} + +select a.name as 'Employee' +from Employee a join Employee b +on a.managerid=b.id +where a.salary > b.salary + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/sql_facebook_practice.md b/_problems/sql_facebook_practice.md new file mode 100644 index 0000000..e24c4ae --- /dev/null +++ b/_problems/sql_facebook_practice.md @@ -0,0 +1,144 @@ +--- +layout: page +title: SQL Facebook Practice Questions +last_solved: +category: sql +leetcode_url: +status: Attempted +--- + +[sql fiddle](http://sqlfiddle.com/#!15/8a51c/1) + +Problem +------- + +{% highlight sql %} + +create table salesperson ( + id int, + name varchar, + age int, + salary int +); + +create table customer ( + id int, + name varchar, + city varchar, + industrytype varchar + ); + + create table orders ( + number int, + order_date date, + cust_id int, + salesperson_id int, + amount int + ); + +insert into salesperson values (1, 'Abe', 61, 140000); +insert into salesperson values (2, 'Bob', 34, 44000); +insert into salesperson values (5, 'Chris', 34, 40000); +insert into salesperson values (7, 'Dan', 41, 52000); +insert into salesperson values (8, 'Ken', 57, 115000); +insert into salesperson values (11, 'Joe', 38, 38000); + + +insert into customer values (4, 'Samsonic', 'pleasant', 'J'); +insert into customer values (6, 'Panusung', 'oaktown', 'J'); +insert into customer values (7, 'Samony', 'jackson', 'B'); +insert into customer values (9, 'Orange', 'jackson', 'B'); + + +insert into orders values (10, '1996-8-2', 4, 2, 540); +insert into orders values (20, '1999-1-30', 4, 8, 1800); +insert into orders values (30, '1995-7-14', 9, 1, 460 ); +insert into orders values (40, '1998-1-29', 7, 2, 2400 ); +insert into orders values (50, '1998-2-3', 6, 7, 600 ); +insert into orders values (60, '1998-3-2', 6, 7, 720 ); +insert into orders values (70, '1992-5-6', 9, 7, 150 ); + + + +{% endhighlight %} + +Solution +---------- + +{% highlight sql %} + +-- a. The names of all salespeople that have an order with Samsonic. +select name +from salesperson +where id in ( + select o.salesperson_id + from orders o join customer c on o.cust_id=c.id + where c.name='Samsonic' +) + + + +-- b. The names of all salespeople that do not have any order with Samsonic. +select distinct s.name +from orders o join salesperson s on o.salesperson_id=s.id +where cust_id not in ( + select id + from customer + where name='Samsonic' +) + +-- c. The names of salespeople that have 2 or more orders. +select name +from salesperson +where id in ( +-- use group/having to get ids of salespeople with count>=2 +select o.salesperson_id +from salesperson s join orders o on s.id=o.salesperson_id +group by o.salesperson_id +having count(*)>=2 + ); + +-- d. The names and ages of all salespersons must having a salary of 100,000 or greater. +select name, age +from salesperson +where salary>100000; + + + +-- e. What sales people have sold more than 1400 total units? +select distinct s.name +from salesperson s join orders o on s.id=o.salesperson_id +where o.salesperson_id in +( + select salesperson_id + from orders + group by salesperson_id + having sum(amount) > 1400 + ); + + +-- f. When was the earliest and latest order made to Samsonite? + +select number +from orders +where cust_id=4 -- join and get customer name if you have to +and order_date in ( + + -- earliest order + select min(order_date) + from orders o join customer c on c.id=o.cust_id + where c.name='Samsonic' + + union + + -- latest order + select max(order_date) + from orders o join customer c on c.id=o.cust_id + where c.name='Samsonic' + ) + + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/sql_reformat_department.md b/_problems/sql_reformat_department.md new file mode 100644 index 0000000..095fd42 --- /dev/null +++ b/_problems/sql_reformat_department.md @@ -0,0 +1,140 @@ +--- +layout: page +title: Reformat Department table (if and case statements) +last_solved: +category: sql +leetcode_url: https://leetcode.com/problems/reformat-department-table/ +status: Attempted +--- + +Problem +------- + +``` +Table: Department + ++---------------+---------+ +| Column Name | Type | ++---------------+---------+ +| id | int | +| revenue | int | +| month | varchar | ++---------------+---------+ +(id, month) is the primary key of this table. +The table has information about the revenue of each department per month. +The month has values in ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]. + + +Write an SQL query to reformat the table such that there is a department id column and a revenue column for each month. + +The query result format is in the following example: + +Department table: ++------+---------+-------+ +| id | revenue | month | ++------+---------+-------+ +| 1 | 8000 | Jan | +| 2 | 9000 | Jan | +| 3 | 10000 | Feb | +| 1 | 7000 | Feb | +| 1 | 6000 | Mar | ++------+---------+-------+ + +Result table: ++------+-------------+-------------+-------------+-----+-------------+ +| id | Jan_Revenue | Feb_Revenue | Mar_Revenue | ... | Dec_Revenue | ++------+-------------+-------------+-------------+-----+-------------+ +| 1 | 8000 | 7000 | 6000 | ... | null | +| 2 | 9000 | null | null | ... | null | +| 3 | null | 10000 | null | ... | null | ++------+-------------+-------------+-------------+-----+-------------+ + +Note that the result table has 13 columns (1 for the department id + 12 for the months). + +``` + +Solution +---------- + +Using MySQL if statement + +`if ( condition , return_value_if_true , return_value_if_false )` + +{% highlight sql %} + +select + id, + sum( if(month = 'Jan', revenue, null) ) as "Jan_Revenue", + sum( if(month = 'Feb', revenue, null) ) as "Feb_Revenue", + sum( if(month = 'Mar', revenue, null) ) as "Mar_Revenue", + sum( if(month = 'Apr', revenue, null) ) as "Apr_Revenue", + sum( if(month = 'May', revenue, null) ) as "May_Revenue", + sum( if(month = 'Jun', revenue, null) ) as "Jun_Revenue", + sum( if(month = 'Jul', revenue, null) ) as "Jul_Revenue", + sum( if(month = 'Aug', revenue, null) ) as "Aug_Revenue", + sum( if(month = 'Sep', revenue, null) ) as "Sep_Revenue", + sum( if(month = 'Oct', revenue, null) ) as "Oct_Revenue", + sum( if(month = 'Nov', revenue, null) ) as "Nov_Revenue", + sum( if(month = 'Dec', revenue, null) ) as "Dec_Revenue" + from Department + group by id + +{% endhighlight %} + +Using Case Statement + +`case when condition then ret_val_if_true else ret_val_if_false end` + +{% highlight sql %} + +select + + id, + sum(case when month='Jan' then revenue else null end) as 'Jan_Revenue', + sum(case when month='Feb' then revenue else null end) as 'Feb_Revenue', + sum(case when month='Mar' then revenue else null end) as 'Mar_Revenue', + sum(case when month='Apr' then revenue else null end) as 'Apr_Revenue', + sum(case when month='May' then revenue else null end) as 'May_Revenue', + sum(case when month='Jun' then revenue else null end) as 'Jun_Revenue', + sum(case when month='Jul' then revenue else null end) as 'Jul_Revenue', + sum(case when month='Aug' then revenue else null end) as 'Aug_Revenue', + sum(case when month='Sep' then revenue else null end) as 'Sep_Revenue', + sum(case when month='Oct' then revenue else null end) as 'Oct_Revenue', + sum(case when month='Nov' then revenue else null end) as 'Nov_Revenue', + sum(case when month='Dec' then revenue else null end) as 'Dec_Revenue' + +from department +group by id + + +{% endhighlight %} + +Note: if you don't have the `sum()`, the result will look like this and your Jan_Rev will be + +`[1, 8000, 7000, 6000, null, null, null, null, null, null, null, null, null]` + +or + +``` ++----+-------------+-------------+ +| id | Jan_Revenue | Feb_Revenue | ++----+-------------+-------------+ +| 1 | NULL | 7000 | +| 1 | 8000 | NULL | +| 1 | NULL | NULL | +| 2 | 9000 | NULL | +| 3 | NULL | 10000 | ++----+-------------+-------------+ +``` + +- So that's why you need to `sum()` or `max()` as an aggregate to "merge them all". +- [This is why we need either SUM (NULL+8000+NULL) or MAX, in both cases 8000 will be used. Actually from MySQL version 5.7.5 you would get an error if you didn't use an aggregation method:](https://leetcode.com/problems/reformat-department-table/discuss/376357/MySQLPostgreSQL-solutions/471453) + +``` + +{"headers": ["id", "Jan_Revenue", "Feb_Revenue", "Mar_Revenue", "Apr_Revenue", "May_Revenue", "Jun_Revenue", "Jul_Revenue", "Aug_Revenue", "Sep_Revenue", "Oct_Revenue", "Nov_Revenue", "Dec_Revenue"], "values": [[1, 8000, 7000, 6000, null, null, null, null, null, null, null, null, null], [2, 9000, null, null, null, null, null, null, null, null, null, null, null], [3, null, 10000, null, null, null, null, null, null, null, null, null, null]]} +``` + + + +![image1]() \ No newline at end of file diff --git a/_problems/sql_second_highest_salary.md b/_problems/sql_second_highest_salary.md new file mode 100644 index 0000000..f538cee --- /dev/null +++ b/_problems/sql_second_highest_salary.md @@ -0,0 +1,77 @@ +--- +layout: page +title: SQL - Second Highest Salary (limit/offset + ifnull) +last_solved: +category: sql +leetcode_url: https://leetcode.com/problems/second-highest-salary +status: Attempted +--- + +Problem +------- + +``` +Write a SQL query to get the second highest salary from the Employee table. + ++----+--------+ +| Id | Salary | ++----+--------+ +| 1 | 100 | +| 2 | 200 | +| 3 | 300 | ++----+--------+ +For example, given the above Employee table, the query should return 200 as the second highest salary. If there is no second highest salary, then the query should return null. + ++---------------------+ +| SecondHighestSalary | ++---------------------+ +| 200 | ++---------------------+ + +``` + +Solution +---------- + +Normally something like this is sufficient if you just use the limit and offset clause. + +{% highlight sql %} + +select distinct salary as SecondHighestSalary + from employee + order by salary desc + limit 1 offset 1 + +{% endhighlight %} + +Without limit, the resultset is +``` +300 +200 +100 +``` + +- offset chooses the one you want and puts it on the top +- limit just selects the top one + +But we also have to use the ifnull( if this is null , return this value ) clause + +{% highlight sql %} + +select ifnull( + + (select distinct salary as SecondHighestSalary + from employee + order by salary desc + limit 1 offset 1) + +, + null +) as SecondHighestSalary + +{% endhighlight %} + + + + +![image1]() \ No newline at end of file diff --git a/_problems/sql_thepads.md b/_problems/sql_thepads.md new file mode 100644 index 0000000..07a927f --- /dev/null +++ b/_problems/sql_thepads.md @@ -0,0 +1,71 @@ +--- +layout: page +title: The PADS +last_solved: +category: sql +leetcode_url: https://www.hackerrank.com/challenges/the-pads/problem +status: Attempted +--- + +Problem +------- + +``` +Generate the following two result sets: + +Query an alphabetically ordered list of all names in OCCUPATIONS, immediately followed by the first letter of each profession as a parenthetical (i.e.: enclosed in parentheses). For example: AnActorName(A), ADoctorName(D), AProfessorName(P), and ASingerName(S). +Query the number of ocurrences of each occupation in OCCUPATIONS. Sort the occurrences in ascending order, and output them in the following format: + +There are a total of [occupation_count] [occupation]s. +where [occupation_count] is the number of occurrences of an occupation in OCCUPATIONS and [occupation] is the lowercase occupation name. If more than one Occupation has the same [occupation_count], they should be ordered alphabetically. + +Note: There will be at least two entries in the table for each type of occupation. + +Input Format + +The OCCUPATIONS table is described as follows: Occupation will only contain one of the following values: Doctor, Professor, Singer or Actor. + +Sample Input + +An OCCUPATIONS table that contains the following records: + + + +Sample Output + +Ashely(P) +Christeen(P) +Jane(A) +Jenny(D) +Julia(A) +Ketty(P) +Maria(A) +Meera(S) +Priya(S) +Samantha(D) +There are a total of 2 doctors. +There are a total of 2 singers. +There are a total of 3 actors. +There are a total of 3 professors. + +``` + +Solution +---------- + +{% highlight sql %} + +select concat(name, "(", substring(occupation, 1,1), ")") +from occupations +order by name; + + +select concat("There are a total of ", count(*), " ", lower(occupation), "s.") +from occupations +group by occupation +order by count(*), occupation; + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/sql_triangles.md b/_problems/sql_triangles.md new file mode 100644 index 0000000..4c25e22 --- /dev/null +++ b/_problems/sql_triangles.md @@ -0,0 +1,86 @@ +--- +layout: page +title: Triangles (SQL Case Statements) +last_solved: +category: sql +leetcode_url: https://www.hackerrank.com/challenges/what-type-of-triangle/problem +status: Attempted +--- + +Problem +------- + +``` +Write a query identifying the type of each record in the TRIANGLES table using its three side lengths. Output one of the following statements for each record in the table: + +Equilateral: It's a triangle with sides of equal length. +Isosceles: It's a triangle with sides of equal length. +Scalene: It's a triangle with sides of differing lengths. +Not A Triangle: The given values of A, B, and C don't form a triangle. +Input Format + +The TRIANGLES table is described as follows: + + + +Each row in the table denotes the lengths of each of a triangle's three sides. + +Sample Input + + + +Sample Output + +Isosceles +Equilateral +Scalene +Not A Triangle +Explanation + +Values in the tuple form an Isosceles triangle, because . +Values in the tuple form an Equilateral triangle, because . Values in the tuple form a Scalene triangle, because . +Values in the tuple cannot form a triangle because the combined value of sides and is not larger than that of side . + +``` + +Solution +---------- + +{% highlight sql %} + +select A,B,C, + +case when A=B and B=C and C=A then 'Equilateral' + when A=B or B=C or C=A then 'Isosceles' + when A!=B and B!=C and C!=A and (A+B>C and B+C>A and A+C>A) then 'Scalene' +else 'Not A Triangle' +end + +from triangles + +{% endhighlight %} + +___________ + +This is the right answer (just take away the A,B,C) + +{% highlight sql %} + +select A,B,C, + +case when A+B>C and B+C>A and A+C>A then + + case when A=B and B=C and C=A then 'Equilateral' + when A=B or B=C or C=A then 'Isosceles' + else 'Scalene' + end + +else 'Not A Triangle' +end + +from triangles + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/sqrtx.md b/_problems/sqrtx.md new file mode 100644 index 0000000..d165817 --- /dev/null +++ b/_problems/sqrtx.md @@ -0,0 +1,135 @@ +--- +layout: page +title: Sqrt(x) +last_solved: 2020-07-24 +category: Binary Search +leetcode_url: https://leetcode.com/problems/sqrtx +status: Attempted +--- + +Problem +------- + +``` +Implement int sqrt(int x). + +Compute and return the square root of x, where x is guaranteed to be a non-negative integer. + +Since the return type is an integer, the decimal digits are truncated and only the integer part of the result is returned. + +Example 1: + +Input: 4 +Output: 2 +Example 2: + +Input: 8 +Output: 2 +Explanation: The square root of 8 is 2.82842..., and since + the decimal part is truncated, 2 is returned. + +``` + +Solution +---------- + +Binary search, where if the (current value)^2 is greater than x, than it can't be in second half. + +- [Terrible Whiteboard](https://www.youtube.com/watch?v=VYtEKhxKd1Q&feature=emb_logo) + +My first attempt with memory limit exceeded. + +{% highlight python %} + +def mySqrt(self, x: int) -> int: + + nums = [i for i in range(x+1)] + + low, high = 0, len(nums) + + while low<=high: + + mid = (low+high)//2 + + square = nums[mid]**2 + + if square == x: + print("found at %s" % mid) + return mid + elif square > x: + print(low, high) + high = mid-1 # ignore right half + else: + print(low, high) + low = mid+1 # ignore left half + + return high # low and high will converge to [3] which is index 2 + +{% endhighlight %} + +_________________ + +Without "number line array" + + +{% highlight python %} + +def mySqrt(self, x: int) -> int: + + low, high = 0, x + + while low<=high: + + mid = (low+high)//2 + + square = mid**2 + + if square == x: + print("found at %s" % mid) + return mid + elif square > x: + print(low, high) + high = mid-1 # ignore right half + else: + print(low, high) + low = mid+1 # ignore left half + + return high # low and high will converge to [3] which is index 2 + +{% endhighlight %} + +____________- + +using powerful binary search template + +{% highlight python %} + + def mySqrt(self, x: int) -> int: + + # 1 2 3 4 x=4 sqrt=16 + + left, right = 0, x+1 + + while leftx: # condition is k**2 > x + right = mid + else: + left = mid+1 + + return left-1 # left is minimum k value satisfying condition, k-1 is answer + + + # k^2 x=8 condition + # 4^2>8 true + # 3^2>8 true left is this k, the minimum k satisfying the condition + # 2^2>8 false the answer is this, so use left-1 + # 1^2>8 false + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/subsets.md b/_problems/subsets.md new file mode 100644 index 0000000..0380d9d --- /dev/null +++ b/_problems/subsets.md @@ -0,0 +1,211 @@ +--- +layout: page +title: Subsets (Backtracking) +last_solved: 2020-06-22 +category: recursion, backtracking +leetcode_url: https://leetcode.com/problems/subsets/ +status: Solved +--- + +Problem +------- + +``` +Given a set of distinct integers, nums, return all possible subsets (the power set). + +Note: The solution set must not contain duplicate subsets. + +Example: + +Input: nums = [1,2,3] +Output: +[ + [3], + [1], + [2], + [1,2,3], + [1,3], + [2,3], + [1,2], + [] +] + +``` + +Solution +---------- + +All backtracking problems have this structure, just memorize it. + +Still not sure why we +1 to index and why that is different from Permutation. This series of articles tries to explain it. + +[part 1](https://medium.com/algorithms-and-leetcode/backtracking-e001561b9f28) +[part 2](https://medium.com/algorithms-and-leetcode/backtracking-with-leetcode-problems-part-2-705c9cc70e52) +[part 3](https://medium.com/algorithms-and-leetcode/in-depth-backtracking-with-leetcode-problems-part-3-b225f19e0d51) + + +{% highlight python %} + +def subsets3(nums): + + def backtrack(currentSubset, allSubsets, nums, index): + + allSubsets.append( currentSubset.copy() ) + + for i in range(index, len(nums)): + + currentSubset.append(nums[i]) + print(currentSubset) + + backtrack( currentSubset, allSubsets, nums, i+1 ) + currentSubset.pop() + print(currentSubset) + + + ans = [] + backtrack([], ans, nums, 0) + return ans + +{% endhighlight %} + + +printing the currentSubset at each iteration looks like this: +``` +[1] +[1, 2] +[1, 2, 3] +[1, 2] +[1] +[1, 3] +[1] +[] +[2] +[2, 3] +[2] +[] +[3] +[] +[[], [1], [1, 2], [1, 2, 3], [1, 3], [2], [2, 3], [3]] +``` + +![image1](https://miro.medium.com/max/1400/1*xrjS6JIZ5f7wFCNBDPrr0g.png) + +![image1](https://miro.medium.com/max/1400/1*_s5iiwdZXbg1OFWO9YDjng@2x.jpeg) + + + +______________ + + +Compare these two solutions: + +{% highlight python %} + +def subsets5(nums): + + def helper(start, currentSubset, allSubsets): + + output.append( currentSubset.copy() ) + + for i in range(start, len(nums) ): + + currentSubset.append( nums[i] ) + helper(i+1, currentSubset, output) + currentSubset.pop() + + output = [] + helper(0, [], output) + return output + + + +''' + recursion without backtracking from timonthy chang + https://www.youtube.com/watch?v=Mi_C_CMW7vQ +''' +def subsets4(nums): + + output = [] + + def helper(start, currentSubset, output): + # output += [tmp] + output.append(currentSubset) + for i in range(start, len(nums)): + print( (i+1, currentSubset+[nums[i]]) ) + helper( i+1, currentSubset+[nums[i]], output ) + + helper(0, [], output) + + return output + +{% endhighlight %} + +The output is like this: +``` +(1, [1]) +(2, [1, 2]) +(3, [1, 2, 3]) +(3, [1, 3]) +(2, [2]) +(3, [2, 3]) +(3, [3]) +[[], [1], [1, 2], [1, 2, 3], [1, 3], [2], [2, 3], [3]] +[[], [1], [1, 2], [1, 2, 3], [1, 3], [2], [2, 3], [3]] +``` + +____________ + + +![image1](https://miro.medium.com/max/1050/1*ddhF2JWfmEl8yLwjx5vt7Q.jpeg) + +______________ + + +![image1](https://5wlqpa.dm.files.1drv.com/y4mWw6FM6vfQ2uGgQLZVTXK03b2a4oZzG94ARUypRFP8T48s5todh08mGzzH5CVx79cVUGI-lKe00r0vgEJt0PlTTYmYze-M_EXdkfEaUTggaMMsCwXXKXHUC3ko0ITL_jl14nHjNEXlI5I3kh3AnD98MerAvWU3GuICbnIDQETihjZo-F86GzUuLYTn-2Q-ZoddrY1zu3b6rchFalBW9mJEQ?width=2425&height=1523&cropmode=none) +![image1](https://5wjpha.dm.files.1drv.com/y4mECUr_-JYl8Sn_JLbFcKa5QKYMklb32Cht5rZj3MsoCjcLrnWDDaxHqFCOwIh2VD5UT5xoy2xcKKpoMAvYe4-kH0xVw8vdaEkGRva0OF1WdfmvoPifSLQLOK4RAGPO72WQifQ87qsF8APOnzvPA3M5LAhp7wvYU8X7f__vZO7Oae4ZVj0dARrF8fms6KVQ__ect74q1YyqECYIjJci7DQkQ?width=2041&height=1334&cropmode=none) + + + + +_______________ + + +Another way is the BFS approach from [educative](https://www.educative.io/courses/grokking-the-coding-interview/gx2OqlvEnWG) + + + + +``` + +Given set: [1, 5, 3] + +Start with an empty set: [[]] +Add the first number (1) to all the existing subsets to create new subsets: [[], [1]]; +Add the second number (5) to all the existing subsets: [[], [1], [5], [1,5]]; +Add the third number (3) to all the existing subsets: [[], [1], [5], [1,5], [3], [1,3], [5,3], [1,5,3]]. + +``` + + +{% highlight python %} + +def find_subsets(nums): + subsets = [] + # start by adding the empty subset + subsets.append([]) + for currentNumber in nums: + # we will take all existing subsets and insert the current number in them to create new subsets + n = len(subsets) + for i in range(n): + # create a new subset from the existing subset and insert the current element to it + set = list(subsets[i]) + set.append(currentNumber) + subsets.append(set) + + return subsets + +{% endhighlight %} + + +Time and space complexity is O(2^n) because we will have 2^n items + diff --git a/_problems/subsetsCascading.md b/_problems/subsetsCascading.md new file mode 100644 index 0000000..e7c2abe --- /dev/null +++ b/_problems/subsetsCascading.md @@ -0,0 +1,121 @@ +--- +layout: page +title: Subsets (Cascading) +last_solved: 2020-06-22 +category: cascading +leetcode_url: https://leetcode.com/problems/subsets/ +status: Solved +--- + +Problem +------- + +``` +Given a set of distinct integers, nums, return all possible subsets (the power set). + +Note: The solution set must not contain duplicate subsets. + +Example: + +Input: nums = [1,2,3] +Output: +[ + [3], + [1], + [2], + [1,2,3], + [1,3], + [2,3], + [1,2], + [] +] + +``` + +Solution +---------- + + + +Another way is the BFS approach from [educative](https://www.educative.io/courses/grokking-the-coding-interview/gx2OqlvEnWG) + + + + +``` + +Given set: [1, 5, 3] + +Start with an empty set: [[]] +Add the first number (1) to all the existing subsets to create new subsets: [[], [1]]; +Add the second number (5) to all the existing subsets: [[], [1], [5], [1,5]]; +Add the third number (3) to all the existing subsets: [[], [1], [5], [1,5], [3], [1,3], [5,3], [1,5,3]]. + +``` + + +{% highlight python %} + +def find_subsets(nums): + subsets = [] + # start by adding the empty subset + subsets.append([]) + for currentNumber in nums: + # we will take all existing subsets and insert the current number in them to create new subsets + n = len(subsets) + for i in range(n): + # create a new subset from the existing subset and insert the current element to it + set = list(subsets[i]) + set.append(currentNumber) + subsets.append(set) + + return subsets + +{% endhighlight %} + + +Time and space complexity is O(2^n) because we will have 2^n items + + + +________________ + + +{% highlight python %} + + def subsets(self, nums: List[int]) -> List[List[int]]: + +# start with empty set +# [] + +# make a copy of all existing subsets and add 1 to them +# [] [1] + +# make a copy of all existing subsets and add 2 to them +# [] [1] [2,][1,2] + +# make a copy of all existing subsets and add 3 to them +# [] [1] [2][1,2] [3] [1,3] [2,3][1,2,3] + + + subsets = [[]] + + for n in nums: + + # make a copy of all existing subsets + size = len(subsets) + + existingSubsets = [] + for i in range(size): + existingSubsets.append( subsets[i].copy() ) + + # add n to all existing subsets + for existSubset in existingSubsets: + existSubset.append(n) + + # add existing subset list into master subset list + subsets.extend( existingSubsets ) + + return subsets + +{% endhighlight %} \ No newline at end of file diff --git a/_problems/sumRootToLeaf.md b/_problems/sumRootToLeaf.md new file mode 100644 index 0000000..ad90c9a --- /dev/null +++ b/_problems/sumRootToLeaf.md @@ -0,0 +1,105 @@ +--- +layout: page +title: Sum Root to Leaf Numbers +last_solved: 2020-06-26 +category: trees +leetcode_url: https://leetcode.com/problems/sum-root-to-leaf-numbers +status: Attempted +--- + +Problem +------- + +``` +Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number. + +An example is the root-to-leaf path 1->2->3 which represents the number 123. + +Find the total sum of all root-to-leaf numbers. + +Note: A leaf is a node with no children. + +Example: + +Input: [1,2,3] + 1 + / \ + 2 3 +Output: 25 +Explanation: +The root-to-leaf path 1->2 represents the number 12. +The root-to-leaf path 1->3 represents the number 13. +Therefore, sum = 12 + 13 = 25. +Example 2: + +Input: [4,9,0,5,1] + 4 + / \ + 9 0 + / \ +5 1 +Output: 1026 +Explanation: +The root-to-leaf path 4->9->5 represents the number 495. +The root-to-leaf path 4->9->1 represents the number 491. +The root-to-leaf path 4->0 represents the number 40. +Therefore, sum = 495 + 491 + 40 = 1026. + +``` + +Solution +---------- + +{% highlight python %} + +def sumNumbers(root): + + if not root: return 0 + + output = [] # list of strings of each path: ["12", "13"] + + def dfs(root, sofar): # sofar is list of integers as we recurse down the tree + + if root.left is None and root.right is None: + output.append("".join(sofar+[str(root.val)])) + + if root.left: + # sofar.append(str(root.val)) + dfs(root.left, sofar+[str(root.val)]) + + if root.right: + # sofar.append(str(root.val)) + dfs(root.right, sofar+[str(root.val)]) + + dfs(root, []) + + return sum([ int(x) for x in output ]) + +{% endhighlight %} + + +_____________ + + +Anotehr solution + + +{% highlight python %} + +def sumNumbers(self, root: TreeNode) -> int: + + def dfs(root, n): + if not root: + return 0 + n = n*10 + root.val + if not root.left and not root.right: + return n + else: + return dfs(root.left, n) + dfs(root.right, n) + return dfs(root, 0) + + +{% endhighlight %} + + +![image1](https://5wjpjg.dm.files.1drv.com/y4mQXn_k4mYsnwW7OsyfFTgPp4V0-G1X9AvuveNRV_HZ72gpClN9TsNQGqUSULWOT_SKWwlYsXBCT6U117kb5dUfFA7AljA3iQiTDr2F_1d7jWuXB1vSz7Pa6B1NgFvapoHBQ48y1F5-_sBTG7O1ZIjo9g3xc8-suiyyCTjaMKYL5x-jCLtp9LvCHGTW9s9LzreX4okmXD7StEu6vDLbF4DYw?width=1400&height=2901&cropmode=none) \ No newline at end of file diff --git a/_problems/surroundedRegion.md b/_problems/surroundedRegion.md new file mode 100644 index 0000000..b734953 --- /dev/null +++ b/_problems/surroundedRegion.md @@ -0,0 +1,101 @@ +--- +layout: page +title: Surrounded Region +last_solved: 2020-06-16 +category: union find +leetcode_url: https://leetcode.com/problems/surrounded-regions +status: Attempted +--- + +Problem +------- + +``` +Given a 2D board containing 'X' and 'O' (the letter O), capture all regions surrounded by 'X'. + +A region is captured by flipping all 'O's into 'X's in that surrounded region. + +Example: + +X X X X +X O O X +X X O X +X O X X +After running your function, the board should be: + +X X X X +X X X X +X X X X +X O X X +Explanation: + +Surrounded regions shouldn’t be on the border, which means that any 'O' on the border of the board are not flipped to 'X'. Any 'O' that is not on the border and it is not connected to an 'O' on the border will be flipped to 'X'. Two cells are connected if they are adjacent cells connected horizontally or vertically. + +``` + +Solution +---------- + +We need to have some way to figure out which cells are "surrounded" by X. If they are surrounded, we don't flip them. To do this: + +- First, go thru border cells and run DFS on them, temporarily turning them to another color 'T'. +- Then iterate thru matrix (use `itertools.product()`) and change to 'X' if not 'T', else 'O + + + +{% highlight python %} + +from itertools import product + +''' + https://leetcode.com/problems/surrounded-regions/discuss/691646/Python-O(mn)-3-colors-dfs-explained +''' + +board = [ + ["X","X","X","X"], + ["X","O","O","X"], + ["X","X","O","X"], + ["X","O","X","X"] +] + + +class Solution: + + def dfs(self, i, j): + + if i<0 or j<0 or i>=self.M or j>=self.N or self.board[i][j] != "O": + return + self.board[i][j] = 'T' + neib_list = [[i+1,j],[i-1,j],[i,j-1],[i,j+1]] + for x, y in neib_list: + self.dfs(x, y) + + def solve(self, board): + if not board: return 0 + self.board, self.M, self.N = board, len(board), len(board[0]) + + # run dfs on sides + for i in range(0, self.M): + self.dfs(i,0) # left side + self.dfs(i,self.N-1) # right side + + # run dfs on top and bottom + for j in range(0, self.N): + self.dfs(0,j) # top + self.dfs(self.M-1,j) # bottom + + print(board) + + # itertools.product() is equivalent to nested forloop + for i,j in product(range(self.M), range(self.N)): + board[i][j] = "X" if board[i][j] != "T" else "O" + +sol = Solution() +sol.solve(board) + +print(board) + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/task_scheduler.md b/_problems/task_scheduler.md new file mode 100644 index 0000000..183a398 --- /dev/null +++ b/_problems/task_scheduler.md @@ -0,0 +1,87 @@ +--- +layout: page +title: Task Scheduler +last_solved: +category: heap, greedy +leetcode_url: https://leetcode.com/problems/task-scheduler/ +status: Attempted +--- + +Problem +------- + +``` +You are given a char array representing tasks CPU need to do. It contains capital letters A to Z where each letter represents a different task. Tasks could be done without the original order of the array. Each task is done in one unit of time. For each unit of time, the CPU could complete either one task or just be idle. + +However, there is a non-negative integer n that represents the cooldown period between two same tasks (the same letter in the array), that is that there must be at least n units of time between any two same tasks. + +You need to return the least number of units of times that the CPU will take to finish all the given tasks. + + + +Example 1: + +Input: tasks = ["A","A","A","B","B","B"], n = 2 +Output: 8 +Explanation: +A -> B -> idle -> A -> B -> idle -> A -> B +There is at least 2 units of time between any two same tasks. +Example 2: + +Input: tasks = ["A","A","A","B","B","B"], n = 0 +Output: 6 +Explanation: On this case any permutation of size 6 would work since n = 0. +["A","A","A","B","B","B"] +["A","B","A","B","A","B"] +["B","B","B","A","A","A"] +... +And so on. +Example 3: + +Input: tasks = ["A","A","A","A","A","A","B","C","D","E","F","G"], n = 2 +Output: 16 +Explanation: +One possible solution is +A -> B -> C -> A -> D -> E -> A -> F -> G -> A -> idle -> idle -> A -> idle -> idle -> A + +``` + +Solution +---------- + +[timothy h chang](https://www.youtube.com/watch?v=wTUsb3nuOCQ) + +{% highlight python %} + +def leastInterval(self, tasks: List[str], n: int) -> int: + + output, h = 0, [] + + c = Counter(tasks) + for k,v in c.items(): + heapq.heappush(h, (-v, k)) # (numTimes, char) # the neg is for Max heap + + while h: + i, temp = 0, [] + + while i<=n: + + output +=1 + if h: + nums,key = heapq.heappop(h) + nums +=1 + if nums<0: temp.append((nums,key)) + if not h and not temp: break + i+=1 + + for k,v in temp: + heapq.heappush(h,(k,v)) + + return output + + print(h) + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/threeSum.md b/_problems/threeSum.md new file mode 100644 index 0000000..67dda04 --- /dev/null +++ b/_problems/threeSum.md @@ -0,0 +1,105 @@ +--- +layout: page +title: Three Sum +last_solved: 2020-07-08 +category: array +leetcode_url: https://leetcode.com/problems/3sum +status: Attempted +--- + +Problem +------- + +``` +Given an array nums of n integers, are there elements a, b, c in nums 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. + +Example: + +Given array nums = [-1, 0, 1, 2, -1, -4], + +A solution set is: +[ + [-1, 0, 1], + [-1, -1, 2] +] + +``` + +Solution +---------- + +__________ + +This triple loop solution will cause duplicates sets. + +{% highlight python %} + +ans = [] +for i in range(len(nums)): + for j in range(i, len(nums)): + for k in range(j, len(nums)): + if nums[i] + nums[j] + nums[k] == 0: + ans.append([nums[i], nums[j], nums[k]]) + +{% endhighlight %} + +__________ + + +Check out [dicussion](https://leetcode.com/problems/3sum/discuss/232712/Best-Python-Solution-(Explained)) and [timonthy's video](https://www.youtube.com/watch?v=LBOAVbEqOTQ) + +When I tried to mimic that solution on my own: + + +{% highlight python %} + +def threeSum(nums): + + nums.sort() + output = [] + + print(nums) + + index = 0 + while index List[int]: + + minHeap=[] + c = Counter(nums) + + for n in c.values(): + + heapq.heappush(minHeap, n) + + if len(minHeap)>k: + heapq.heappop(minHeap) + + + out = [] + for k,v in c.items(): + if v in minHeap: + out.append(k) + + return out + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/twoCityScheduling.md b/_problems/twoCityScheduling.md new file mode 100644 index 0000000..87e5691 --- /dev/null +++ b/_problems/twoCityScheduling.md @@ -0,0 +1,85 @@ +--- +layout: page +title: Two City Scheduling +last_solved: 2020-06-03 +category: greedy +leetcode_url: https://leetcode.com/problems/two-city-scheduling +status: Attempted +--- + +Problem +------- + +{% highlight text %} + +There are 2N people a company is planning to interview. The cost of flying the i-th person to city A is costs[i][0], and the cost of flying the i-th person to city B is costs[i][1]. + +Return the minimum cost to fly every person to a city such that exactly N people arrive in each city. + + + +Example 1: + +Input: [[10,20],[30,200],[400,50],[30,20]] +Output: 110 +Explanation: +The first person goes to city A for a cost of 10. +The second person goes to city A for a cost of 30. +The third person goes to city B for a cost of 50. +The fourth person goes to city B for a cost of 20. + +The total minimum cost is 10 + 30 + 50 + 20 = 110 to have half the people interviewing in each city. + +{% endhighlight %} + +Solution +---------- + +{% highlight python %} + +costs = [ + [10,20], + [30,200], + [400,50], + [30,20] +] + +def minCosts(costs): + + n = len(costs)//2 + + # calculate the difference between city A and city B for each person + delta = [(a - b) for a, b in costs] + print( "delta: ", delta ) + + # get the ordered difference + ordered_delta = sorted((value, i) for (i, value) in enumerate(delta)) + print( "ordered delta:", ordered_delta ) + + minimum_cost = 0 + + # for the n smallest cost_A - cost_B, it costs a lot to fly to B, + # so we send them to city A + print( "ordered_delta[:n] ", ordered_delta[:n] ) + for value, i in ordered_delta[:n]: + minimum_cost += costs[i][0] + + # for the n greatest cost_A - cost_B, it costs a lot to fly to A, + # so we send them to city B + for value, i in ordered_delta[n:]: + minimum_cost += costs[i][1] + return minimum_cost + +print( minCosts(costs) ) + +{% endhighlight %} + +``` +delta: [-10, -170, 350, 10] +ordered delta: [(-170, 1), (-10, 0), (10, 3), (350, 2)] +ordered_delta[:n] [(-170, 1), (-10, 0)] +110 +``` + + +![image1](https://gnfhha.dm.files.1drv.com/y4muHXtqyUxi04APXeMASIp-yHG57ZaQjRlTKOSEZKuTP093gr_IpctxKHrhcC_w5Dzj7GjGOia0S0fzqFCQEz4yVcm_3f0UP9NtsNzDCAU51qivDcj1tmMKDm1QAQNtdEOfxjQpmxE3uGQtsQRVjcwv5NX9dhqis6gkW1_MkABagijSZSmRh6Tpe5a3aMOtLvkGib3dWO9QvYuDPpBBgsDxA?width=2245&height=1049&cropmode=none) \ No newline at end of file diff --git a/_problems/twoSum.md b/_problems/twoSum.md new file mode 100644 index 0000000..42d4b1a --- /dev/null +++ b/_problems/twoSum.md @@ -0,0 +1,118 @@ +--- +layout: page +title: Two Sum +last_solved: 2020-08-04 +category: array, hashtable +leetcode_url: https://https://leetcode.com/problems/two-sum +status: Solved +--- + +### Problem + +Given an array of integers, return indices of the two numbers such that they add up to a specific target. + +You may assume that each input would have exactly one solution, and you may not use the same element twice. + +{% highlight text %} + +Example: + +Given nums = [2, 7, 11, 15], target = 9, + +Because nums[0] + nums[1] = 2 + 7 = 9, +return [0, 1]. + +{% endhighlight %} + +### Brute Force Solution + +{% highlight python %} + +nums = [2, 7, 11, 15] +target = 26 + + +def twoSum(nums, target): + + length = len(nums) + for i in range(0, length): + for j in range(i+1, length): + + if nums[i] + nums[j] == target: + + return (i, j) + break + + j=j+1 + + +res = twoSum(nums, target) +print res + + +{% endhighlight %} + +### OnePass HashTable SOlution + +This is a common interview problem. Just memorize the technique. + +{% highlight python %} + +def twoSum(nums, target): + + seen = {} + + for i, v in enumerate(nums): + + remaining = target - v + + # if seen, return indexes + if remaining in seen: + return [seen[remaining], i] + + # else, add it to seen hashtable + else: + seen[v] = i + + + return [] +{% endhighlight %} + +____________ + +Another way of writing it, not as nice. Use enumerate. + +{% highlight python %} + +# not using enumerate +def twoSum(self, nums: List[int], target: int) -> List[int]: + + seen = {} + + for i in range(len(nums)): + + remaining = target-nums[i] + + if nums[i] in seen: + return [i, seen[nums[i]]] + else: + seen[remaining] = i + +# using enumerate +def twoSum(self, nums: List[int], target: int) -> List[int]: + + seen = {} + + for i, v in enumerate(nums): + + remaining = target-v + + if nums[i] in seen: + return [i, seen[v]] + else: + seen[remaining] = i + + +{% endhighlight %} + + diff --git a/_problems/uglyNum2.md b/_problems/uglyNum2.md new file mode 100644 index 0000000..e0612fc --- /dev/null +++ b/_problems/uglyNum2.md @@ -0,0 +1,59 @@ +--- +layout: page +title: Ugly Num II +last_solved: Attempted +category: math +leetcode_url: https://leetcode.com/problems/ugly-number-ii +status: Attempted +--- + +Problem +------- + +``` +Write a program to find the n-th ugly number. + +Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. + +Example: + +Input: n = 10 +Output: 12 +Explanation: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 is the sequence of the first 10 ugly numbers. + +``` + +Solution +---------- + +Works for small cases but not large cases. TLE + +{% highlight python %} + +def nthUglyNumber(self, n: int) -> int: + + uglyNums = [1] + + curr = 2 + while len(uglyNums) int: + + @lru_cache(None) + def helper(left, right): + + # base case, g(1) + if left>=right: + return 1 + + count = 0 + for i in range(left, right+1): + l_tree = helper(left, i-1) + r_tree = helper(i+1, right) + count += l_tree * r_tree + + return count + + return helper(1, n) + +{% endhighlight %} + + +_________ + +{% highlight python %} + +def numTrees(self, n: int) -> int: + + memo = {} + + def helper(left, right): + + # base case, g(1) + if left>=right: + return 1 + + count = 0 + if (left,right) in memo: + return memo[(left,right)] + else: + for i in range(left, right+1): + l_tree = helper(left, i-1) + r_tree = helper(i+1, right) + count += l_tree * r_tree + + memo[(left,right)] = count + + return count + + return helper(1, n) + +{% endhighlight %} + +![image1](https://5wjipq.dm.files.1drv.com/y4mGWZgxXlcbqWkME_TAbhQzZc-tKLBlnAh21XzispT5JT2OU_vNPssOHuz51hmmaf7NJhJEchJ0E-6gXneLg7vFcp783yACPjsuAwjg44yGWFV92KTS1ufbI3KzxvrfJJhdRUN1gDBbZOwG_Z5t8UV3cDUgKmnzI2RLLnqVIk7urmVbwBtv3R5mr-OmbxQurUisD-__JYMfpAMMslDZPSYHA?width=2401&height=1691&cropmode=none) + +![image1](https://5wktya.dm.files.1drv.com/y4mQEUskkqKpyjuYSH8VnOR0_hhpyHmKPYTDI8SrRQ_UnGtNEfG0V7P1ldz_cNzVvPHyBddKspB0Y44HApuSSblU8YPZfAeCiOrUFto_CvQjx6h3SSCi0rRDNlagtQp7nramCIJz4vt8RbKHO0Bfmmw-EP9VegfuKC9BlkYrLPb2z-ujsI1gp2Ufy15Geje0H3qQGHnnB2G17EoRnEmT_a4NQ?width=1525&height=1196&cropmode=none) \ No newline at end of file diff --git a/_problems/uniquePaths.md b/_problems/uniquePaths.md new file mode 100644 index 0000000..d1c123a --- /dev/null +++ b/_problems/uniquePaths.md @@ -0,0 +1,60 @@ +--- +layout: page +title: Unique Paths +last_solved: 2020-06-29 +category: dp +leetcode_url: https://leetcode.com/problems/unique-paths/submissions/ +status: Solved +--- + +Problem +------- + +``` +A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). + +The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below). + +How many possible unique paths are there? + + +Above is a 7 x 3 grid. How many possible unique paths are there? + + + +Example 1: + +Input: m = 3, n = 2 +Output: 3 +Explanation: +From the top-left corner, there are a total of 3 ways to reach the bottom-right corner: +1. Right -> Right -> Down +2. Right -> Down -> Right +3. Down -> Right -> Right +Example 2: + +Input: m = 7, n = 3 +Output: 28 + +``` + +Solution +---------- + +{% highlight python %} + +def uniquePaths(self, m: int, n: int) -> int: + + dp = [[1]*(n) for x in range(m)] + + for i in range(1, m): + for j in range(1, n): + dp[i][j] = dp[i][j-1] + dp[i-1][j] + + print(dp) + return dp[-1][-1] + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/validParenthesis.md b/_problems/validParenthesis.md new file mode 100644 index 0000000..b037ebf --- /dev/null +++ b/_problems/validParenthesis.md @@ -0,0 +1,78 @@ +--- +layout: page +title: Valid Parenthesis +last_solved: +category: stack +leetcode_url: https://leetcode.com/problems/valid-parentheses +status: Attempted +--- + +Problem +------- + +``` +Given a string s containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. + +An input string is valid if: + +Open brackets must be closed by the same type of brackets. +Open brackets must be closed in the correct order. + + +Example 1: + +Input: s = "()" +Output: true +Example 2: + +Input: s = "()[]{}" +Output: true +Example 3: + +Input: s = "(]" +Output: false +Example 4: + +Input: s = "([)]" +Output: false +Example 5: + +Input: s = "{[]}" +Output: true +``` + +Solution +---------- + + + +{% highlight python %} + + def isValid(self, s: str) -> bool: + + stack = [] + + for c in s: + if c=='(': + stack.append(')') + elif c=='[': + stack.append(']') + elif c=='{': + stack.append('}') + elif not stack or stack.pop()!=c: + return False + + return not stack + +{% endhighlight %} + +______________ + + + +{% highlight python %} + + +{% endhighlight %} + +![image1]() \ No newline at end of file diff --git a/_problems/validateBST.md b/_problems/validateBST.md new file mode 100644 index 0000000..bfdfad0 --- /dev/null +++ b/_problems/validateBST.md @@ -0,0 +1,127 @@ +--- +layout: page +title: Validate BST +last_solved: 2020-07-29, 2020-08-25 +category: dfs +leetcode_url: https://leetcode.com/problems/validate-binary-search-tree/ +status: Solved +--- + + +Unfortunately, we can't just check BST conditions for current node and dfs recurse downward. In the following example, node 15 satisfies the condition locally in its subtree (15,6,20) but it has a '6' that is in the root's right subtree (violates the right subtree condition). + +{% highlight text %} +# # 10 +# # 5 15 +# # X X 6 20 +{% endhighlight %} + +Wrong way to do it: + +{% highlight python %} + +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + + + +def isValidBST(self, root): + + if not root: + return True + + # check BST conditions for current node + validBST = True + + if root.left and root.left.val >= root.val: + validBST = False + + if root.right and root.right.val <= root.val: + validBST = False + + leftRes = self.isValidBST(root.left) + rightRes = self.isValidBST(root.right) + + return validBST and leftRes and rightRes + +# # 5 +# # 3 7 +# # 2 4 6 8 + +# root = TreeNode(5) +# root.left = TreeNode(3) +# root.right = TreeNode(7) +# root.left.left = TreeNode(2) +# root.left.right = TreeNode(4) +# root.right.left = TreeNode(6) +# root.right.right = TreeNode(8) + + + +print(validateBST(root)) + +{% endhighlight %} + +______________ + + +The solution to this is to pass down lower and upper limits with each recursive call. + +![image1](https://gnduaw.dm.files.1drv.com/y4mPUcMxE9-yS-JjLSg4TK9uqG0PXbZGv9tB9KoZeeYNmqnvyeJB55bC4sJDHpvEBJiPnfe5J_VdAUOQBem8F70r1wBITqdYz5MgpIM9ZjllCk9D6A_MZb42JGNPXeg_WPFAvr0LiVdDzLDafRPD6ndE3gcftog3YZEmJ8HeNvoK0bCCOFBpU__K9ogsBtL6qh9c6pAAJLs4GdR1gxHehvYgw?width=1518&height=1137&cropmode=none) + +{% highlight python %} + +class TreeNode: + + def __init__(self, val): + + self.val = val + self.left = None + self.right = None + + + +def validateBST(root): + + if not root: + return True + + def helper(node, lower, upper): + + if not node: + return True + + if node.val<=lower or node.val>=upper: # current node violates left and right conditions + return False + + leftValid = helper(node.left, lower, node.val) + rightValid = helper(node.right, node.val, upper) + + return leftValid and rightValid + + return helper(root, float('-inf'), float('inf')) + + +# [10,5,15,null,null,6,20] + +# 10 +# 5 15 +# X X 6 20 + +root = TreeNode(10) +root.left = TreeNode(5) +root.right = TreeNode(15) +root.right.left = TreeNode(6) +root.right.right = TreeNode(20) + + +print(validateBST(root)) + +{% endhighlight %} + + diff --git a/_problems/validateSudoku.md b/_problems/validateSudoku.md new file mode 100644 index 0000000..fc6ba54 --- /dev/null +++ b/_problems/validateSudoku.md @@ -0,0 +1,79 @@ +--- +layout: page +title: Validate Sudoku +last_solved: 2020-06-10 +category: matrix +leetcode_url: https://leetcode.com/problems/valid-sudoku/ +status: Solved +--- + +Problem +------- + +``` +Input: +[ + ["5","3",".",".","7",".",".",".","."], + ["6",".",".","1","9","5",".",".","."], + [".","9","8",".",".",".",".","6","."], + ["8",".",".",".","6",".",".",".","3"], + ["4",".",".","8",".","3",".",".","1"], + ["7",".",".",".","2",".",".",".","6"], + [".","6",".",".",".",".","2","8","."], + [".",".",".","4","1","9",".",".","5"], + [".",".",".",".","8",".",".","7","9"] +] +Output: true + +``` + +Solution +---------- + +{% highlight python %} + +def validateBoard(bo): + + rows = [ set() for i in range(9) ] + cols = [ set() for i in range(9) ] + boxes = [ set() for i in range(9) ] + + for i in range(9): + for j in range(9): + + val = bo[i][j] + if val==".": + continue + + + # validate row + if val in rows[i]: + + print( val + "already in row %s" % i ) + return False + else: + rows[i].add( val ) + + # validate col + if val in cols[j]: + + print( val + "already in col %s" % j ) + return False + else: + cols[j].add( val ) + + # validate box + k = (i//3)*3 + (j//3) + if val in boxes[k]: + + print( val + "already in box %s" % k ) + return False + else: + boxes[k].add( val ) + + return True + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/waterWithMostWater.md b/_problems/waterWithMostWater.md new file mode 100644 index 0000000..b353ef8 --- /dev/null +++ b/_problems/waterWithMostWater.md @@ -0,0 +1,80 @@ +--- +layout: page +title: Water with Most Water +last_solved: 2020-08-04 +category: array, 2ptr +leetcode_url: https://leetcode.com/problems/container-with-most-water/ +status: Solved +--- + + + +##### Problem + +The above vertical lines are represented by array [1,8,6,2,5,4,8,3,7]. In this case, the max area of water (blue section) the container can contain is 49. + +![water](https://s3-lc-upload.s3.amazonaws.com/uploads/2018/07/17/question_11.jpg) + + + +#### Solution + +Since the area is limited to the shorter of the two lines, use 2 pointers and move the closer one inwards. + + +{% highlight python %} + +def maxArea(height): + + left = 0 + right = len(height)-1 + + maxArea = 0 + + while left int: + + s = 0 + e = len(height)-1 + + maxArea = 0 + + while smaxArea: + maxArea = area + + if height[s]>height[e]: + e-=1 + else: + s+=1 + + return maxArea + +{% endhighlight %} + diff --git a/_problems/wordLadder.md b/_problems/wordLadder.md new file mode 100644 index 0000000..b77bb88 --- /dev/null +++ b/_problems/wordLadder.md @@ -0,0 +1,118 @@ +--- +layout: page +title: Word Ladder +last_solved: 2020-07-23 +category: bfs +leetcode_url: https://leetcode.com/problems/word-ladder +status: Attempted +--- + +Problem +------- + +``` +Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that: + +Only one letter can be changed at a time. +Each transformed word must exist in the word list. +Note: + +Return 0 if there is no such transformation sequence. +All words have the same length. +All words contain only lowercase alphabetic characters. +You may assume no duplicates in the word list. +You may assume beginWord and endWord are non-empty and are not the same. +Example 1: + +Input: +beginWord = "hit", +endWord = "cog", +wordList = ["hot","dot","dog","lot","log","cog"] + +Output: 5 + +Explanation: As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog", +return its length 5. +Example 2: + +Input: +beginWord = "hit" +endWord = "cog" +wordList = ["hot","dot","dog","lot","log"] + +Output: 0 + +Explanation: The endWord "cog" is not in wordList, therefore no possible transformation. + +``` + +Solution +---------- + +I did not solve this myself yet. Just got it from solutions tab and tried to analyse it. + +{% highlight python %} + +def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int: + + # {'*og': ['dog', 'log', 'cog'], + # '*ot': ['hot', 'dot', 'lot'], + # 'c*g': ['cog'], + # 'co*': ['cog'], + # 'd*g': ['dog'], + # 'd*t': ['dot'], + # 'do*': ['dot', 'dog'], + # 'h*t': ['hot'], + # 'ho*': ['hot'], + # 'l*g': ['log'], + # 'l*t': ['lot'], + # 'lo*': ['lot', 'log']}) + + + if endWord not in wordList or not endWord or not beginWord or not wordList: + return 0 + + L = len(beginWord) + + # make adjacency list + all_combo_dict = defaultdict(list) + for word in wordList: + for i in range(L): + # key is the generic word + # value is a list of words which have the same intermediate generic word + all_combo_dict[word[:i] + "*" + word[i+1:]].append(word) + + #pp.pprint(all_combo_dict) + + # Queue for BFS + queue = collections.deque([(beginWord, 1)]) # (word, level) + + # Visited to make sure we don't repeat processing same word. + visited = {beginWord: True} + + while queue: + current_word, level = queue.popleft() + + for i in range(L): + + # intermediate words for current word + intermediate_word = current_word[:i] + "*" + current_word[i+1:] + + # next states are all the words which share the same intermediate state + for word in all_combo_dict[intermediate_word]: + + if word==endWord: + return level+1 + + if word not in visited: + visited[word] = True + queue.append((word, level+1) ) + + all_combo_dict[intermediate_word] = [] + + return 0 + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/_problems/wordSearch.md b/_problems/wordSearch.md new file mode 100644 index 0000000..4f8d3fc --- /dev/null +++ b/_problems/wordSearch.md @@ -0,0 +1,67 @@ +--- +layout: page +title: Word Search +last_solved: 2020-06-01 +category: matrix +leetcode_url: https://leetcode.com/problems/word-search/ +status: Attempted +--- + +##### Problem + +{% highlight text %} + +board = +[ + ['A','B','C','E'], + ['S','F','C','S'], + ['A','D','E','E'] +] + +Given word = "ABCCED", return true. +Given word = "SEE", return true. +Given word = "ABCB", return false. + +{% endhighlight %} + +##### Solution + +tmp is to prevent going back and visiting an already visited cell + +{% highlight python %} + +def exist(board, word): + + R = len(board) + C = len(board[0]) + + def searchWord(i, j, word, index): + + if index==len(word): + return True + + if i<0 or i>=R or j<0 or j>=C or board[i][j]!=word[index]: + return False + + tmp = board[i][j] + board[i][j] = ' ' + # found = searchWord(i+1,j,word,index+1) + found = searchWord(i-1,j,word,index+1) or \ + searchWord(i+1,j,word,index+1) or \ + searchWord(i,j-1,word,index+1) or \ + searchWord(i,j+1,word,index + 1) + + board[i][j] = tmp + return found + + for i in range(R): + for j in range(C): + if board[i][j]==word[0] and searchWord(i,j,word,0): + return True + + return False + +{% endhighlight %} + + +![image1]() \ No newline at end of file diff --git a/about.markdown b/about.markdown new file mode 100644 index 0000000..8b4e0b2 --- /dev/null +++ b/about.markdown @@ -0,0 +1,18 @@ +--- +layout: page +title: About +permalink: /about/ +--- + +This is the base Jekyll theme. You can find out more info about customizing your Jekyll theme, as well as basic Jekyll usage documentation at [jekyllrb.com](https://jekyllrb.com/) + +You can find the source code for Minima at GitHub: +[jekyll][jekyll-organization] / +[minima](https://github.com/jekyll/minima) + +You can find the source code for Jekyll at GitHub: +[jekyll][jekyll-organization] / +[jekyll](https://github.com/jekyll/jekyll) + + +[jekyll-organization]: https://github.com/jekyll diff --git a/index.md b/index.md new file mode 100644 index 0000000..13384b3 --- /dev/null +++ b/index.md @@ -0,0 +1,27 @@ +--- +# Feel free to add content and custom Front Matter to this file. +# To modify the layout, see https://jekyllrb.com/docs/themes/#overriding-theme-defaults + +layout: home +--- + + +Coding +------------ +- [Solved](pages/lists/solved.html) +- [Solved - Last Modified](pages/lists/solvedLastModified.html) +- [Blind 100](pages/lists/blind100.html) +- [EPI](pages/lists/epi.html) +- [Amazon Top 50](/pages/lists/amazonTop50) + +- [Review Problems](pages/lists/reviewProblems) +- [Bookmarked Sites](/pages/bookmarkedSites) + +System Design +-------------- + +- [System Design](pages/system_design/link_shortener) + + +To start: +``` bundle exec jekyll serve ``` diff --git a/pages/_behavior_interview/behavior.md b/pages/_behavior_interview/behavior.md new file mode 100644 index 0000000..209f203 --- /dev/null +++ b/pages/_behavior_interview/behavior.md @@ -0,0 +1,12 @@ +- [educative](https://www.educative.io/courses/grokking-the-behavioral-interview/xo8w4prlYyJ) +- [jackson gabbard](https://www.youtube.com/watch?v=PJKYqLP6MRE) + + + +- premature optimization + + +Common hangups +Behavioral questions can sometimes include additional words that cause interviewees to hesitate. Some such words are: + +“Greatest”, “proudest”, “worst”, “best”, “biggest”, “most significant”, “fastest” \ No newline at end of file diff --git a/pages/_system_design/concepts.md b/pages/_system_design/concepts.md new file mode 100644 index 0000000..18a0655 --- /dev/null +++ b/pages/_system_design/concepts.md @@ -0,0 +1,51 @@ +--- +layout: page +title: System Design - Concepts +--- + + + +other system design resources +---------- +- [reddit udacity architecture course](https://www.youtube.com/watch?v=pjNTgULVVf4&list=PLVi1LmRuKQ0NINQfjKLVen7J2lZFL35wP) +- [harvard scalabilty course](https://www.youtube.com/watch?v=-W9F__D3oY4) + +- [grokking system design interviews](https://www.youtube.com/watch?v=ZgdS0EUmn70&list=PL73KFetZlkJSZ9vTDSJ1swZhe6CIYkqTL) +- https://github.com/donnemartin/system-design-primer + +[back of the envelope calculations](https://www.reddit.com/r/cscareerquestions/comments/6c3x0h/for_system_design_interview_questions_are_back_of/) +[back of the envelope](https://itsallbinary.com/system-design-back-of-envelop-calculations-for-storage-size-bandwidth-traffic-etc-estimates/) + +___________________ + + + +[architecting systems for scale](https://lethain.com/introduction-to-architecting-systems-for-scale/) +[github - system design premier](https://github.com/donnemartin/system-design-primer#system-design-topics-start-here) + +- Message Queues (RabbitMQ and kafka) + - buffer where producers add expensive workload tasks + - worker consumers take and process tasks + +- Periodic Tasks + - Like 'link cleanup service' in link shortener + +- Map-Reduce + - once you start sharding your DB and SQL queries don't work + - distributed data processing + +- Platform Layer + - an interface for other microservices to interact with a 3rd party + + + + +- long polling vs websockets vs server-sent events + - ajax polling + - many http reqs and responses + - http long-polling (hanging GET) + - client expects the server to not respond immediately + - web-sockets + - full deplex communication over tcp connection + - server sent events + diff --git a/pages/_system_design/instagram.md b/pages/_system_design/instagram.md new file mode 100644 index 0000000..724e22a --- /dev/null +++ b/pages/_system_design/instagram.md @@ -0,0 +1,72 @@ +--- +layout: page +title: System Design - instagram +--- + +[educative.io](https://www.educative.io/courses/grokking-the-system-design-interview/m2yDVZnQ8lG) + +1. What is Instagram? +2. Requirements and Goals of the System +3. Some Design Considerations +4. Capacity Estimation and Constraints +5. High Level System Design +6. Database Schema +7. Data Size Estimation +8. Component Design +9. Reliability and Redundancy +10. Data Sharding +11. Ranking and News Feed Generation +12. News Feed Creation with Sharded Data +13. Cache and Load balancing + + +1-3. requirements + +upload, view news feed, follow other users +tags not in scope + + + +4. capacity estimates + +2M new photos per day +avg photo size = 200KB +1 day of photos = 2M * 200KB = 400GB +10 years = 400GB * 265 * 10 = 1425TB + + +5. high level design + - image hosting system needs two parts + - object storage for storing photos + - DB for storing image metadta + +8. component design + - since upload image is slow, split upload service and download service to different services + + +6. db schema + +tables: +- photo +- user +- userFollow +- user photo cross reference + + +10. db sharing + +partition based on userid +if we do 10 shards, then userid%10 + +considerations +- hot users, ppl with lots of followers +- some ppl have lots of photos + - if we shard a single user's photos on multiple servers, will there be high latency? + - storing all of a user's data in one shard could make it unavailable if it fails + + + + + +other things to consider +- redundency - losing photos is not an option diff --git a/pages/_system_design/link_shortener.md b/pages/_system_design/link_shortener.md new file mode 100644 index 0000000..f151507 --- /dev/null +++ b/pages/_system_design/link_shortener.md @@ -0,0 +1,87 @@ +--- +layout: page +title: System Design - link shortener +--- + +[educative.io](https://www.educative.io/courses/grokking-the-system-design-interview/m2ygV4E81AR) + + +7. data partitioning and replication +----------------------- +- range based partitioning: + - all URL's starting with 'A' goes into this bucket + - can store less frequently used letters in one bucket/node + - could become unblanced +- hash-based partitioning + - use a key hash to map to one of 1-256 servers + - could still lead to overloaded partitions? can be solved by consistent hashing? + + + +8. caching +------------ + +- app level cache +- CDN +- cache invalidation +- cache evictin polices + +- to reduce DB load, can check cache before hitting the DB +- can precompute frequently used data and store in cache + +- consider cache eviction policies like LRU +- what happens in a cache miss? + -> fetch from backend DB + -> update all cache replicas + +- memcache + - stores in memory to avoid giong to external disks + - large distributed hashtable + - reduces DB load + - client server app over tcp/udp + - NOT persistent + +- redit + - get/set operations + - supports richer data types including string, hash, list + + + + +9. load balancers +---------------- + + + +- add LB at 3 layers + - between users and app servers + - between app servers and DB + - between servers and cache servers + +- round robin approach to distribute incoming requests + +- algorithms + - round robin + - ip hash + - least connections/response time/bandwidth + + + +10. purging or DB cleanup (expired urls) +---------------------- + +Approaches +- active search for exipred links could put pressure on DB +- lazy cleanup could delete links as user requests them and delete if expired +- cleanup service to be schduled to run at low usage hours + + + +11 and 12. analytics and security +-------------------- + +otehr requirements that needs to be considered +- + + + diff --git a/pages/_system_design/system_design_notes b/pages/_system_design/system_design_notes new file mode 100644 index 0000000..c981795 --- /dev/null +++ b/pages/_system_design/system_design_notes @@ -0,0 +1,3 @@ + + +- [leetcode coupon management system](https://leetcode.com/discuss/interview-question/system-design/786972/coupon-management-system-system-design-interview) diff --git a/pages/bookmarkedSites.md b/pages/bookmarkedSites.md new file mode 100644 index 0000000..2123dc2 --- /dev/null +++ b/pages/bookmarkedSites.md @@ -0,0 +1,96 @@ +--- +layout: page +title: Bookmarked Sites +--- + + +- [leetcode](leetcode.com) +- [interviewing.io](interviewing.io) + + +- [coding bat](https://codingbat.com/python) +- [check.io](https://checkio.org/) + +- [grokking system design]() +- [Techinical Interview Handbook](https://yangshun.github.io/tech-interview-handbook/best-practice-questions) +- [amazon prep](https://www.amazon.jobs/en/landing_pages/software-development-topics) +- [career advice](https://www.teamblind.com/post/advice-for-younger-folks-WzpcU2oi) +- [Jouney](https://leetcode.com/discuss/interview-experience/716202/amz-google-facebook-offer-reject-reject-my-journey-from-failure-to-offer-at-faang) +- [System Design Github](https://github.com/prasadgujar/low-level-design-primer) + +Interview Whiteboards +------------------------ +- http://collabedit.com/gbv3p +- https://start.interviewing.io/interview/playground + + + +Other worthwile leetcode sites +- [github book](https://github.com/liyin2015/Algorithms-and-Coding-Interviews) +- [TechGig algorithm practice](https://www.techgig.com/practice/algorithms/implementation) + +Leetcode post for writing concise Python code: +- https://leetcode.com/discuss/general-discussion/459791/Special-data-structures-in-Python + +Another list of leetcode questions: +- https://yangshun.github.io/tech-interview-handbook/best-practice-questions +- https://leetcode.com/discuss/interview-question/344650/Amazon-Online-Assessment-Questions + + +Behaviour Interview +--------------------- +[Amazon LP](https://medium.com/@scarletinked/are-you-the-leader-were-looking-for-interviewing-at-amazon-8301d787815d) +[Behaviour Interview](https://www.youtube.com/c/DanCroitor/videos) -> youtube-dl and listen to mp3 + + + + + +Youtubers +------- +- Nick White +- Kevin Naughton +- BackToBackSWE +- Timothy H Chang +- Terrible Whiteboard +- [good teacher](https://goodtecher.com/page/18/) +- [time infinity complex](https://www.youtube.com/channel/UCf9ywn38ypqEIC6McbwH9sQ/videos) + +Mock Interviews +----------------- +- interviewing.io sandbox + + + +Facebook questions +----------------- +[facebook phone interview questions](https://leetcode.com/discuss/interview-question/790428/facebook-phone-interview-questions) +[fb interviews jun 2020](https://leetcode.com/discuss/general-discussion/675445/facebook-interview-experiences-all-combined-from-lc-till-date-07-jun-2020) + +[mega leetcode post](https://leetcode.com/discuss/general-discussion/665604/important-and-useful-links-from-all-over-the-leetcode) + +[Must Do Easy and Medium Problems](https://leetcode.com/discuss/career/449135/How-to-effectively-use-LeetCode-to-prepare-for-interviews) + +Good leetcode grouped problems (from user wh0ami/whoami): +- [Graphs](https://leetcode.com/discuss/general-discussion/655708/graph-problems-for-beginners-practice-problems-and-sample-solutions) +- [Sliding Windows](https://leetcode.com/discuss/general-discussion/657507/sliding-window-for-beginners-problems-template-sample-solutions) +- [DP](https://leetcode.com/discuss/general-discussion/662866/dp-for-beginners-problems-patterns-sample-solutions) +- [Greedy](https://leetcode.com/discuss/general-discussion/669996/greedy-for-beginners-problems-sample-solutions) +- [Binary Search](https://leetcode.com/discuss/general-discussion/691825/binary-search-for-beginners-problems-patterns-sample-solutions) +- [Binary Search ZhiJun_liao](https://leetcode.com/discuss/general-discussion/786126/python-powerful-ultimate-binary-search-template-solved-many-problems) +- [Binary Search 101](https://leetcode.com/problems/binary-search/discuss/423162/Binary-Search-101-The-Ultimate-Binary-Search-Handbook) + + +Dynamic Programming Links +------------ +- [dynamic programming patterns](https://leetcode.com/discuss/interview-question/778035/dynamic-programming-patterns) +- [list of dp problems](https://leetcode.com/discuss/general-discussion/458695/Dynamic-Programming-Patterns) +- [algo monster](https://algo.monster/problems/dynamic_programming_intro) +- [dp](https://leetcode.com/discuss/general-discussion/868902/dynamic-programming) + + + +Why you're doing all this +------------ + +- [engineering levels](https://engineerseekingfire.com/how-to-prepare-for-software-engineering-interviews/) \ No newline at end of file diff --git a/pages/failureAttempts.md b/pages/failureAttempts.md new file mode 100644 index 0000000..9666b75 --- /dev/null +++ b/pages/failureAttempts.md @@ -0,0 +1,10 @@ +--- +layout: page +title: Failure Attempts +--- + +2020 +------ + +Amazon - Online Coding Assessment Failed +Facebook - Phone Screen - easy questions but failed due to not solving enough questions in the 1 hr diff --git a/pages/lists/amazonTop50.md b/pages/lists/amazonTop50.md new file mode 100644 index 0000000..c85fede --- /dev/null +++ b/pages/lists/amazonTop50.md @@ -0,0 +1,57 @@ +--- +layout: page +title: Amazon Top 50 +--- + +##Top 50 amazon Tagged questions +Also prepared a list which only contains non premium questions but this post contains both premium and non premium questions. + +- [Two Sum](https://leetcode.com/problems/two-sum) +- [Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring) +- [3Sum](https://leetcode.com/problems/3sum) +- [Merge Two Sorted Lists](https://leetcode.com/problems/merge-two-sorted-lists) +- [Merge k Sorted Lists](https://leetcode.com/problems/merge-k-sorted-lists) +- [Trapping Rain Water](https://leetcode.com/problems/trapping-rain-water) +- [Group Anagrams](https://leetcode.com/problems/group-anagrams) +- [Maximum Subarray](https://leetcode.com/problems/maximum-subarray) +- [Word Search](https://leetcode.com/problems/word-search) +- [Binary Tree Zigzag Level Order Traversal](https://leetcode.com/problems/binary-treezigzag-level-order-traversal) +- [Best Time to Buy and Sell Stock](https://leetcode.com/problems/best-time-to-buy-and-sell-stock) +- [Word Ladder II](https://leetcode.com/problems/word-ladder-ii) +- [Word Ladder](https://leetcode.com/problems/word-ladder) +- [Copy List with Random Pointer](https://leetcode.com/problems/copy-list-with-random-pointer) +- [Word Break](https://leetcode.com/problems/word-break) +- [Word Break II](https://leetcode.com/problems/word-break-ii) +- [LRU Cache](https://leetcode.com/problems/lru-cache) +- [Min Stack](https://leetcode.com/problems/min-stack) +- [Number of Islands](https://leetcode.com/problems/number-of-islands) +- [Course Schedule II](https://leetcode.com/problems/course-schedule-ii) +- [Word Search II](https://leetcode.com/problems/word-search-ii) +- [Basic Calculator II](https://leetcode.com/problems/basic-calculator-ii) +- [Sliding Window Maximum](https://leetcode.com/problems/sliding-window-maximum) +- [Search a 2D Matrix II](https://leetcode.com/problems/search-a-2d-matrix-ii) +- [Meeting Rooms II](https://leetcode.com/problems/meeting-rooms-ii) +- [Alien Dictionary](https://leetcode.com/problems/alien-dictionary) +- [Integer to English Words](https://leetcode.com/problems/integer-to-english-words) +- [Find Median from Data Stream](https://leetcode.com/problems/find-median-from-datastream) +- [Serialize and Deserialize Binary Tree](https://leetcode.com/problems/serialize-and-deserialize-binary-tree) +- [Design Snake Game](https://leetcode.com/problems/design-snake-game) +- [Insert Delete GetRandom O(1)](https://leetcode.com/problems/insert-delete-getrandom-o1) +- [LFU Cache](https://leetcode.com/problems/lfu-cache) +- [Concatenated Words](https://leetcode.com/problems/concatenated-words) +- [Subtree of Another Tree](https://leetcode.com/problems/subtree-of-another-tree) +- [Design In-Memory File System](https://leetcode.com/problems/design-in-memory-file-system) +- [Design Search Autocomplete System](https://leetcode.com/problems/design-search-autocomplete-system) +- [Top K Frequent Words](https://leetcode.com/problems/top-k-frequent-words) +- [Number of Distinct Islands](https://leetcode.com/problems/number-of-distinct-islands) +- [Partition Labels](https://leetcode.com/problems/partition-labels) +- [Most Common Word](https://leetcode.com/problems/most-common-word) +- [All Nodes Distance K in Binary Tree](https://leetcode.com/problems/all-nodes-distance-k-in-binary-tree) +- [Snakes and Ladders](https://leetcode.com/problems/snakes-and-ladders) +- [Reorder Data in Log Files](https://leetcode.com/problems/reorder-data-in-log-files) +- [Prison Cells After N Days](https://leetcode.com/problems/prison-cells-after-n-days) +- [K Closest Points to Origin](https://leetcode.com/problems/k-closest-points-to-origin) +- [Rotting Oranges](https://leetcode.com/problems/rotting-oranges) +- [Analyze User Website Visit Pattern](https://leetcode.com/problems/analyze-user-website-visit-pattern) +- [Minimum Cost to Connect Sticks](https://leetcode.com/problems/minimum-cost-to-connect-sticks) +- [Critical Connections in a Network](https://leetcode.com/problems/critical-connections-in-a-network) \ No newline at end of file diff --git a/pages/lists/blind100.md b/pages/lists/blind100.md new file mode 100644 index 0000000..48ef046 --- /dev/null +++ b/pages/lists/blind100.md @@ -0,0 +1,166 @@ +--- +layout: page +title: Blind 100 +--- + +Array +------- + +| Problem | Solved | Time To Solve | Solutions | Last Attempted | Comments +|-----------|:------------:|:-------:| +| [Two Sum ](https://leetcode.com/problems/two-sum/) | Solved | n/a | [brute force + one pass](/problems/twoSum.html) | | +| [Best Time to Buy and Sell Stock ](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/) | Solved | 10 min to code | [1 pass solution](/problems/buyAndSellStock.html) | May17 | +| [Contains Duplicate ](https://leetcode.com/problems/contains-duplicate/) | Solved | 5min | [hashset/sorting](/problems/containsDuplicates) | | +| [Product of Array Except Self ](https://leetcode.com/problems/product-of-array-except-self/) | | | | | +| [Maximum Subarray ](https://leetcode.com/problems/maximum-subarray/) | Solved | 15 min to code | [kadane's algo](/problems/maxSubarray.html) | May 26 | +| [Maximum Product Subarray ](https://leetcode.com/problems/maximum-product-subarray/) | Attempted | n/a | [variation of kadane's algo](/problems/maxProductSubarray.html) | | +| [Find Minimum in Rotated Sorted Array ](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/) | Attempted | n/a | [binary search](/problems/findMinInSortedArray.html) | | +| [Search in Rotated Sorted Array ](https://leetcode.com/problems/search-in-rotated-sorted-array/) | | | | | +| [3Sum ](https://leetcode.com/problems/3sum/) | | | | | +| [Container With Most Water ](https://leetcode.com/problems/container-with-most-water/) | Solved | 25min | [2 pointer](/problems/waterWithMostWater) | may27 | + +--- + +Binary +------- + +| Problem | Solved | Time To Solve | Solutions | Last Attempted | Comments +|-----------|:------------:|:-------:| +| [Sum of Two Integers ](https://leetcode.com/problems/sum-of-two-integers/) | | | | | +| [Number of 1 Bits ](https://leetcode.com/problems/number-of-1-bits/) | Solved | 5min | [loop and bit mask](/problems/numOnes) | may14 | try approach #2 in LC next time +| [Counting Bits ](https://leetcode.com/problems/counting-bits/) | Attempted | n/a | [dp](/problems/countOnesInArray) | may14 | +| [Missing Number ](https://leetcode.com/problems/missing-number/) | Solved | 5min | [sort/hashmap/xor/gauss](/problems/missingNumber) | | +| [Reverse Bits ](https://leetcode.com/problems/reverse-bits/) | | | | | + +--- + +Dynamic Programming +------- + +| Problem | Solved | Time To Solve | Solutions | Last Attempted | Comments +|-----------|:------------:|:-------:| +| [Climbing Stairs ](https://leetcode.com/problems/climbing-stairs/) | Solved | 1hr | [fib](/problems/climbingStairs) | may16 | +| [Coin Change ](https://leetcode.com/problems/coin-change/) | Attempted | 1hr | [dp](/problems/coinChange) | may19 | +| [Longest Increasing Subsequence ](https://leetcode.com/problems/longest-increasing-subsequence/) | | | | | +| [Longest Common Subsequence ](https://leetcode.com/problems/longest-common-subsequence/) | Attemped | may25 | [dp](/problems/longestCommonSubsequence) | | +| [Word Break Problem ](https://leetcode.com/problems/word-break/) | | | | | +| [Combination Sum ](https://leetcode.com/problems/combination-sum-iv/) | | | | | +| [House Robber ](https://leetcode.com/problems/house-robber/) | Solved | 20min | [dp](/problems/houseRobber) | may26 | +| [House Robber II ](https://leetcode.com/problems/house-robber-ii/) | Solved | 20m | [extention of hourse robber 1](/problems/houseRobber2) | may27 | +| [Decode Ways ](https://leetcode.com/problems/decode-ways/) | | | | | +| [Unique Paths ](https://leetcode.com/problems/unique-paths/) | | | | | +| [Jump Game ](https://leetcode.com/problems/jump-game/) | | | | | + +--- + +Graph +------- + +| Problem | Solved | Time To Solve | Solutions | Last Attempted | Comments +|-----------|:------------:|:-------:| +| [Clone Graph ](https://leetcode.com/problems/clone-graph/) | | | | | +| [Course Schedule ](https://leetcode.com/problems/course-schedule/) | | | | | +| [Pacific Atlantic Water Flow ](https://leetcode.com/problems/pacific-atlantic-water-flow/) | | | | | +| [Number of Islands ](https://leetcode.com/problems/number-of-islands/) | Solved | 15m | [flood fill](/problems/numIslands) | may28 | +| [Longest Consecutive Sequence ](https://leetcode.com/problems/longest-consecutive-sequence/) | | | | | +| [Alien Dictionary (Leetcode Premium) ](https://leetcode.com/problems/alien-dictionary/) | | | | | +| [Graph Valid Tree (Leetcode Premium) ](https://leetcode.com/problems/graph-valid-tree/) | | | | | +| [Number of Connected Components in an Undirected Graph (Leetcode Premium) ](https://leetcode.com/problems/number-of-connected-components-in-an-undirected-graph/) | | | | | + +--- + +Interval +------- + +| Problem | Solved | Time To Solve | Solutions | Last Attempted | Comments +|-----------|:------------:|:-------:| +| [Insert Interval ](https://leetcode.com/problems/insert-interval/) | | | | | +| [Merge Intervals ](https://leetcode.com/problems/merge-intervals/) | Solved | half day | [solution](/problems/mergeIntervals) | | +| [Non Overlapping Intervals](https://leetcode.com/problems/non-overlapping-intervals/) | | | | | +| [Meeting Rooms (Leetcode Premium) ](https://leetcode.com/problems/meeting-rooms/) | | | | | +| [Meeting Rooms II (Leetcode Premium) ](https://leetcode.com/problems/meeting-rooms-ii/) | | | | | + +--- + +Linked List +------- + +| Problem | Solved | Time To Solve | Solutions | Last Attempted | Comments +|-----------|:------------:|:-------:| +| [Reverse a Linked List ](https://leetcode.com/problems/reverse-linked-list/) | Solved | 10min | [iteratively](/problems/reverseLLiterative) | may13 | try recursive +| [Detect Cycle in a Linked List ](https://leetcode.com/problems/linked-list-cycle/) | Solved | 10min | [hashmap](/problems/llcycle)
[floyd](/problems/llcycle) | may13 | +| [Merge Two Sorted Lists ](https://leetcode.com/problems/merge-two-sorted-lists/) | Solved | 30m | [iteratively](/problems/mergeSortedLLiter)
[recur](/problems/mergeSortedLLrecur) | iter-may22
recur-may14 | +| [Merge K Sorted Lists ](https://leetcode.com/problems/merge-k-sorted-lists/) | | | | | +| [Remove Nth Node From End Of List ](https://leetcode.com/problems/remove-nth-node-from-end-of-list/) | | | | | +| [Reorder List ](https://leetcode.com/problems/reorder-list/) | | | | | + +--- + +Matrix +------- + +| Problem | Solved | Time To Solve | Solutions | Last Attempted | Comments +|-----------|:------------:|:-------:| +| [Set Matrix Zeroes ](https://leetcode.com/problems/set-matrix-zeroes/) | attempted | 2hrs | [solution](/problems/setMatrixZeros) | may29 | there are other more efficient sols in leetcode solutions artc le page +| [Spiral Matrix ](https://leetcode.com/problems/spiral-matrix/) | | | | | +| [Rotate Image ](https://leetcode.com/problems/rotate-image/) | Solved | 2hrs | [transpose and flip horizontally](/problems/rotateImage.html) | Apr29 | fav problem +| [Word Search ](https://leetcode.com/problems/word-search/) | Attempted | n/a | [solution](/problems/wordSearch) | | +| [Matrix Search ](https://leetcode.com/problems/search-a-2d-matrix/) | Attempted | n/a | [binary search](/problems/matrixSearch) | | + +--- + +String +------- + +| Problem | Solved | Time To Solve | Solutions | Last Attempted | Comments +|-----------|:------------:|:-------:| +| [Longest Substring Without Repeating Characters ](https://leetcode.com/problems/longest-substring-without-repeating-characters/) | Attempted | n/a | [sliding window](/problems/longestSubstringWithoutRepeatingChars) | may14 | +| [Longest Repeating Character Replacement ](https://leetcode.com/problems/longest-repeating-character-replacement/) | | | | | +| [Minimum Window Substring ](https://leetcode.com/problems/minimum-window-substring/) | | | | | +| [Valid Anagram ](https://leetcode.com/problems/valid-anagram/) | | | | | +| [Group Anagrams ](https://leetcode.com/problems/group-anagrams/) | | | | | +| [Valid Parentheses ](https://leetcode.com/problems/valid-parentheses/) | | | | | +| [Valid Palindrome ](https://leetcode.com/problems/valid-palindrome/) | | | | | +| [Longest Palindromic Substring ](https://leetcode.com/problems/longest-palindromic-substring/) | | | | | +| [Palindromic Substrings ](https://leetcode.com/problems/palindromic-substrings/) | | | | | +| [Encode and Decode Strings (Leetcode Premium) ](https://leetcode.com/problems/encode-and-decode-strings/) | | | | | + +--- + +Tree +------- + +| Problem | Solved | Time To Solve | Solutions | Last Attempted | Comments +|-----------|:------------:|:-------:| +| [Maximum Depth of Binary Tree ](https://leetcode.com/problems/maximum-depth-of-binary-tree/) | Solved | n/a | [recursion](/problems/maxDepth.html) | | +| [Same Tree ](https://leetcode.com/problems/same-tree/) | Solved | n/a | [recursion](/problems/isSameTree) | may12 | +| [Invert/Flip Binary Tree ](https://leetcode.com/problems/invert-binary-tree/) | Solved | 10min | [recursion](/problems/invertTree) | | +| [Binary Tree Maximum Path Sum ](https://leetcode.com/problems/binary-tree-maximum-path-sum/) | | | | | +| [Binary Tree Level Order Traversal ](https://leetcode.com/problems/binary-tree-level-order-traversal/) | Solved | n/a | [bfs](/problems/bfs.html) | may12 | +| [Serialize and Deserialize Binary Tree ](https://leetcode.com/problems/serialize-and-deserialize-binary-tree/) | Attemped | n/a | [solution](/problems/serializeTree) | | +| [Subtree of Another Tree ](https://leetcode.com/problems/subtree-of-another-tree/) | Solved | n/a | [recursion](/problems/isSubtree.html) | | +| [Construct Binary Tree from Preorder and Inorder Traversal ](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/) | | | | | +| [Validate BST ](https://leetcode.com/problems/validate-binary-search-tree/) | Attempted | n/a | [recursion and pass limits](/problems/validateBST) | | +| [Kth Smallest Element in a BST ](https://leetcode.com/problems/kth-smallest-element-in-a-bst/) | | | | | +| [Lowest Common Ancestor of BST ](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/) | Solved | 45min | [Recursion](/problems/lcaBinaryTree) | Mar27,May1 | +| [Implement Trie (Prefix Tree) ](https://leetcode.com/problems/implement-trie-prefix-tree/) | | | | | +| [Add and Search Word ](https://leetcode.com/problems/add-and-search-word-data-structure-design/) | | | | | +| [Word Search II ](https://leetcode.com/problems/word-search-ii/) | | | | | +[Symmetric Tree]() | Solved | n/a | [recursion](/problems/symmetricTree.html) | +[Balanced Tree]() | Solved | n/a | [recursion](/problems/isTreeBalanced.html) | +[Deepest Leaves Sum]() | Solved | n/a | [dfs](/problems/deepestLeavesSumDFS.html)
[bfs](/problems/deepestLeavesSumBFS.html) | may12 | +[Print K distance from root]() | Solved | n/a | [dfs](/problems/printKdistanceFromRoot.html) | n/a | also could've used bfs approach + +--- + +Heap +------- + +| Problem | Solved | Time To Solve | Solutions | Last Attempted | Comments +|-----------|:------------:|:-------:| +| [Merge K Sorted Lists ](https://leetcode.com/problems/merge-k-sorted-lists/) | | | | | +| [Top K Frequent Elements ](https://leetcode.com/problems/top-k-frequent-elements/) | | | | | +| [Find Median from Data Stream ](https://leetcode.com/problems/find-median-from-data-stream/) | | | | | + + +from https://www.teamblind.com/post/New-Year-Gift---Curated-List-of-Top-100-LeetCode-Questions-to-Save-Your-Time-OaM1orEU diff --git a/pages/lists/epi.md b/pages/lists/epi.md new file mode 100644 index 0000000..75601fb --- /dev/null +++ b/pages/lists/epi.md @@ -0,0 +1,430 @@ +--- +layout: page +title: EPI +--- + +Legend +====== + - Solved + + - Attempted + + - Needs Revisit + + +Solutions +========= + +Primitive Types +--------------- + +| Problem | Solved | Time To Solve | Solved Multiple Ways | Last Attempted | Comments +|--------------------------------------------------------------------------|:------------:|:-------:| +| Computing the parity of a word | a | b | c | d +| Swap bits | | | +| Reverse bits | | | +| Find a closest integer with the same weight | | | +| Compute *x × y* without arithmetical operators | | | +| Compute *x/y* | | | +| Compute *x^y* | | | +| Reverse digits | | | +| Check if a decimal integer is a palindrome | | | +| Generate uniform random numbers | | | +| Rectangle intersection | | | + +Arrays +------ + +| Problem | Solved | Time To Solve | Solved Multiple Ways | Last Attempted | Comments +|--------------------------------------------------------------------------|:------------:|:-------:| +| The Dutch national flag problem | | | +| Increment an arbitrary-precision integer | | | +| Multiply two arbitrary-precision integers | | | +| Advancing through an array | | | +| Delete a key from an array | | | +| Delete duplicates from a sorted array | | | +| Buy and sell a stock once | | | +| Buy and sell a stock twice | | | +| Enumerate all primes to *n* | | | +| Permute the elements of an array | | | +| Compute the next permutation | | | +| Sample offline data | | | +| Sample online data | | | +| Compute a random permutation | | | +| Compute a random subset | | | +| Generate nonuniform random numbers | | | +| The Sudoku checker problem | Solved | 3-4 hrs | n/a | apr 29 | Spent 1 hr just on row and col check, looked up box validation +| Compute the spiral ordering of a 2D array | Attempted | n/a | solve by simulation | +| Rotate a 2D array | Solved | 2hrs | transpose and flip horizontally | apr 29 | fav problems +| Compute rows in Pascal’s Triangle | | | + +Strings +------- + +| Problem | Solved | Time To Solve | Solved Multiple Ways | Last Attempted | Comments +|--------------------------------------------------------------------------|:------------:|:-------:| +| Interconvert strings and integers | | | +| Base conversion | | | +| Compute the spreadsheet column encoding | | | +| Replace and remove | | | +| Solved palindromicity | | | +| Reverse all the words in a sentence | | | +| Compute all mnemonics for a phone number | | | +| The look-and-say problem | | | +| Convert from Roman to decimal | | | +| Compute all valid IP addresses | | | +| Write a string sinusoidally | | | +| Implement run-length encoding | | | +| Implement the UNIX `tail` command | | | +| Find the first occurrence of a substring | | | + +Linked List +----------- + +| Problem | Solved | Time To Solve | Solved Multiple Ways | Last Attempted | Comments +|--------------------------------------------------------------------------|:------------:|:-------:| +| Merge two sorted lists | Solved | 1hr | iteratively, recursively | Apr 28 | deep dive on recursive solution +| Reverse a singly linked list | Solved | 30m | Iteratively | May1 | solve with recursion +| Reverse a single sublist | Attempted | n/a | n/a | May 2 | don't quite get the connection and tail variable +| Solved for cyclicity | | | +| Solved for overlapping lists—lists are cycle-free | | | | | +| Solved for overlapping lists—lists may have cycles | | | | | +| Delete a node from a singly linked list | | | +| Remove the *k*th last element from a list | | | +| Remove duplicates from a sorted list | | | | | +| Implement cyclic right shift for singly linked lists | | | | | +| Implement even-odd merge | | | | | +| Solved whether a singly linked list is palindromic | | | | | +| Implement list pivoting | | | | | +| Add list-based integers | | | | | + +Stacks and Queues +----------------- + +### Stacks + +| Problem | Solved | Time To Solve | Solved Multiple Ways | Last Attempted | Comments +|--------------------------------------------------------------------------|:------------:|:-------:| +| Implement a stack with max API | | | | | +| Evaluate RPN expressions | | | | | +| Solved a string over “{,},(,),[,]” for well-formedness | | | | | +| Normalize pathnames | | | | | +| BST keys in sort order | | | | | +| Search a postings list | | | | | +| Compute buildings with a sunset view | | | | | +| Sort a stack | | | | | + +### Queues + +| Problem | Solved | Time To Solve | Solved Multiple Ways | Last Attempted | Comments +|--------------------------------------------------------------------------|:------------:|:-------:| +| Compute binary tree nodes in order of increasing depth | | | | | +| Implement a circular queue | | | | | +| Implement a queue using stacks | | | | | +| Implement a queue with max API | | | | | + +Binary Trees +------------ + +| Problem | Solved | Time To Solve | Solved Multiple Ways | Last Attempted | Comments +|--------------------------------------------------------------------------|:------------:|:-------:| +| Solved if a binary tree is balanced | Solved | 20min | Recursion | Apr30 +| Solved if a binary tree is symmetric | Solved | 1hr | Recursion | May1 | If you need to compare 2 subtrees, use helper(left, right) +| Compute the lowest common ancestor in a binary tree | Solved | 45min | Recursion | Mar27, May1 | +| Compute the LCA when nodes have parent pointers | | | | | +| Sum the root-to-leaf paths in a binary tree | | | | | +| Find a root to leaf path with specified sum | | | | | +| Compute the *k*th node in an inorder traversal | | | | | +| Compute the successor | | | | | +| Implement an inorder traversal with *O(1)* space | | | | | +| Reconstruct a binary tree from traversal data | | | | | +| Reconstruct a binary tree from a preorder traversal with markers | | | | | +| Form a linked list from the leaves of a binary tree | | | | | +| Compute the exterior of a binary tree | | | | | +| Compute the right sibling tree | | | | | +| Implement locking in a binary tree | | | | | + +Heaps +----- + +| Problem | Solved | Time To Solve | Solved Multiple Ways | Last Attempted | Comments +|--------------------------------------------------------------------------|:------------:|:-------:| +| Merge sorted files | | | | | +| Sort an increasing-decreasing array | | | | | +| Sort an almost-sorted array | | | | | +| Compute the *k* closest stars | | | | | +| Compute the median of online data | | | | | +| Compute the *k* largest elements in a max-heap | | | | | +| Implement a stack API using a heap | | | | | + +Searching +--------- + +### Binary Search + +| Problem | Solved | Time To Solve | Solved Multiple Ways | Last Attempted | Comments +|--------------------------------------------------------------------------|:------------:|:-------:| +| Search a sorted array for first occurrence of *k* | | | | | +| Search a sorted array for the first element greater than *k* | | | | | +| Search a sorted array for entry equal to its index | | | | | +| Search a cyclically sorted array | | | | | +| Compute the integer square root | | | | | +| Compute the real square root | | | | | + +### Generalized Search + +| Problem | Solved | Time To Solve | Solved Multiple Ways | Last Attempted | Comments +|--------------------------------------------------------------------------|:------------:|:-------:| +| Search in a 2D sorted array | Solved | 1hr | Binary Search | Apr 30 | +| Find the min and max simultaneously | | | | | +| Find the *k*th largest element | | | | | +| Compute the optimum mailbox placement | | | | | +| Find the missing IP address | | | | | +| Find the duplicate and missing elements | | | | | + +Hash Tables +----------- + +| Problem | Solved | Time To Solve | Solved Multiple Ways | Last Attempted | Comments +|--------------------------------------------------------------------------|:------------:|:-------:| +| Partition into anagrams | | | | | +| Solved for palindromic permutations | | | | | +| Is an anonymous letter constructible? | | | | | +| Implement an ISBN cache | | | | | +| Compute the LCA, optimizing for close ancestors | | | | | +| Compute the *k* most frequent queries | | | | | +| Find the nearest repeated entries in an array | | | | | +| Find the smallest subarray covering all values | | | | | +| Find smallest subarray sequentially covering all values | | | | | +| Find the longest subarray with distinct entries | | | | | +| Find the length of a longest contained range | | | | | +| Compute the average of the top three scores | | | | | +| Compute all string decompositions | | | | | +| Find a highest affinity pair | | | | | +| Solved the Collatz conjecture | | | | | +| Implement a hash function for chess | | | | | + +Sorting +------- + +| Problem | Solved | Time To Solve | Solved Multiple Ways | Last Attempted | Comments +|--------------------------------------------------------------------------|:------------:|:-------:| +| Compute the intersection of two sorted arrays | | | | | +| Implement mergesort in-place | | | | | +| Count the frequencies of characters in a sentence | | | | | +| Find unique elements | | | | | +| Render a calendar | | | | | +| Sets of disjoint intervals | | | | | +| Compute the union of intervals | | | | | +| Partitioning and sorting an array with many repeated entries | | | | | +| Team photo day—1 | | | | | +| Implement a fast sorting algorithm for lists | | | | | +| Compute a salary threshold | | | | | + +Binary Search Trees +------------------- + +| Problem | Solved | Time To Solve | Solved Multiple Ways | Last Attempted | Comments +|--------------------------------------------------------------------------|:------------:|:-------:| +| Solved if a binary tree satisfies the BST property | | | | | +| Find the first occurrence of a key in a BST | | | | | +| Find the first key larger than a given value in a BST | | | | | +| Find the *k* largest elements in a BST | | | | | +| Compute the LCA in a BST | | | | | +| Reconstruct a BST from traversal data | | | | | +| Find the closest entries in three sorted arrays | | | | | +| Enumerate numbers of the form *a + b√2* | | | | | +| The most visited pages problem | | | | | +| Build a minimum height BST from a sorted array | | | | | +| Insertion and deletion in a BST | | | | | +| Solved if three BST nodes are totally ordered | | | | | +| The range lookup problem | | | | | +| Add credits | | | | | +| Count the number of entries in an interval | | | | | + +Recursion +--------- + +| Problem | Solved | Time To Solve | Solved Multiple Ways | Last Attempted | Comments +|--------------------------------------------------------------------------|:------------:|:-------:| +| The Tower of Hanoi problem | | | | | +| Generate all nonattacking placements of *n*-Queens | | | | | +| Generate permutations | | | | | +| Generate the power set | | | | | +| Generate all subsets of size *k* | | | | | +| Generate strings of matched parens | | | | | +| Generate palindromic decompositions | | | | | +| Generate binary trees | | | | | +| Implement a Sudoku solver | | | | | +| Compute a Gray code | | | | | +| Compute the diameter of a tree | | | | | + +Dynamic Programming +------------------- + +| Problem | Solved | Time To Solve | Solved Multiple Ways | Last Attempted | Comments +|--------------------------------------------------------------------------|:------------:|:-------:| +| Count the number of score combinations | | | | | +| Compute the Levenshtein distance | | | | | +| Count the number of ways to traverse a 2D array | | | | | +| Plan a fishing trip | | | | | +| Search for a sequence in a 2D array | | | | | +| The knapsack problem | | | | | +| Divide the spoils fairly | | | | | +| The **bedbathandbeyond.com** problem | | | | | +| Find the minimum weight path in a triangle | | | | | +| Pick up coins for maximum gain | | | | | +| Count the number of moves to climb stairs | | | | | +| Compute the probability of a Republican majority | | | | | +| The pretty printing problem | | | | | +| Find the longest nondecreasing subsequence | | | | | + +Greedy Algorithms and Invariants +-------------------------------- + +| Problem | Solved | Time To Solve | Solved Multiple Ways | Last Attempted | Comments +|--------------------------------------------------------------------------|:------------:|:-------:| +| Implement Huffman coding | | | | | +| Compute an optimum assignment of tasks | | | | | +| Implement a schedule which minimizes waiting time | | | | | +| The interval covering problem | | | | | +| The 3-sum problem | | | | | +| Find the majority element | | | | | +| The gasup problem | | | | | +| Compute the maximum water trapped by a pair of vertical lines | | | | | +| Compute the largest rectangle under the skyline | | | | | + +Graphs +------ + +| Problem | Solved | Time To Solve | Solved Multiple Ways | Last Attempted | Comments +|--------------------------------------------------------------------------|:------------:|:-------:| +| Identify the celebrity | | | | | +| Search a maze | | | +| Paint a Boolean matrix | | | | | +| Compute enclosed regions | | | | | +| Degrees of connectedness—1 | | | | | +| Clone a graph | | | | | +| Making wired connections | | | | | +| Transform one string to another | | | | | +| The shorSolved straight-line program for *x^n* | | | | | +| Team photo day—2 | | | | | +| Compute a shorSolved path with fewest edges | | | | | + +Parallel Computing +------------------ + +| Problem | Solved | Time To Solve | Solved Multiple Ways | Last Attempted | Comments +|--------------------------------------------------------------------------|:------------:|:-------:| +| Implement caching for a multithreaded dictionary | | | | | +| Analyze two unsynchronized interleaved threads | | | | | +| Implement synchronization for two interleaving threads | | | | | +| Implement a thread pool | | | | | +| Implement asynchronous callbacks | | | | | +| Implement a Timer class | | | | | +| The readers-writers problem | | | | | +| The readers-writers problem with write preference | | | | | +| Solved the Collatz conjecture in parallel | | | | | +| Design TeraSort and PetaSort | | | | | +| Implement distributed throttling | | | | | + +Design Problems +--------------- + +| Problem | Solved | Time To Solve | Solved Multiple Ways | Last Attempted | Comments +|--------------------------------------------------------------------------|:------------:|:-------:| +| Design a spell checker | | | | | +| Design a solution to the stemming problem | | | | | +| Plagiarism detector | | | | | +| Pair users by attributes | | | | | +| Design a system for detecting copyright infringement | | | | | +| Design *TEX* | | | | | +| Design a search engine | | | | | +| Implement PageRank | | | | | +| Design a scalable priority system | | | | | +| Create photomosaics | | | | | +| Implement Mileage Run | | | | | +| Implement Connexus | | | | | +| Design an online advertising system | | | | | +| Design a recommendation system | | | | | +| Design an optimized way of distributing large files | | | | | +| Design the World Wide Web | | | | | +| Estimate the hardware cost of a photo sharing app | | | | | + +Honors Class +------------ + +| Problem | Solved | Time To Solve | Solved Multiple Ways | Last Attempted | Comments +|--------------------------------------------------------------------------|:------------:|:-------:| +| Compute the greaSolved common divisor | | | | | +| Find the first missing positive entry | | | | | +| Buy and sell a stock *k* times | | | | | +| Compute the maximum product of all entries but one | | | | | +| Compute the longest contiguous increasing subarray | | | | | +| Rotate an array | | | | | +| Identify positions attacked by rooks | | | | | +| Justify text | | | | | +| Reverse sublists *k* at a time | | | | | +| Implement list zipping | | | | | +| Copy a postings list | | | | | +| Compute the median of a sorted circular linked list | | | | | +| Compute the longest substring with matching parens | | | | | +| Compute the maximum of a sliding window | | | | | +| Implement preorder and postorder traversals without recursion | | | | | +| Compute fair bonuses | | | | | +| Find *k* elements closest to the median | | | | | +| Search a sorted array of unknown length | | | | | +| Search in two sorted arrays | | | | | +| Find the *k*th largest element—large *n*, small *k* | | | | | +| Find an element that appears only once | | | | | +| Find the line through the most points | | | | | +| Find the shorSolved unique prefix | | | | | +| Compute the smallest nonconstructible change | | | | | +| Find the most visited pages in a window | | | | | +| Convert a sorted doubly linked list into a BST | | | | | +| Convert a BST to a sorted doubly linked list | | | | | +| Merge two BSTs | | | | | +| Solved if a binary tree is an almost BST | | | | | +| The view from above | | | | | +| Searching a min-first BST | | | | | +| Implement regular expression matching | | | | | +| Synthesize an expression | | | | | +| Count inversions | | | | | +| Draw the skyline | | | | | +| Find the two closest points | | | | | +| Measure with defective jugs | | | | | +| Compute the maximum subarray sum in a circular array | | | | | +| Determine the critical height | | | | | +| Voltage selection in a logic circuit | | | | | +| Find the maximum 2D subarray | | | | | +| Trapping water | | | | | +| Load balancing | | | | | +| Search for a pair-sum in an abs-sorted array | | | | | +| The heavy hitter problem | | | | | +| Find the longest subarray whose sum ≤ *k* | | | | | +| Degrees of connectedness—2 | | | | | +| Compute a minimum delay schedule, unlimited resources | | | | | +| Road network | | | | | +| Solved if arbitrage is possible | | | | | +| The readers-writers problem with fairness | | | | | +| Implement a producer-consumer queue | | | | | + + +------------------------ + +**Want to Revisit** + +- binary search +- longest common subsequence + + +------------------------ + +**Classic Problems** + +- lowest common ancestor +- is same tree +- is subtree +- invert binary tree + + diff --git a/pages/lists/reviewProblems.md b/pages/lists/reviewProblems.md new file mode 100644 index 0000000..cbd8a65 --- /dev/null +++ b/pages/lists/reviewProblems.md @@ -0,0 +1,205 @@ +--- +layout: page +title: Review Problems +--- + +Let this be the list that you go thru for your review right before an upcoming interview. These problems provide the most bang for your buck. + +It is sorted by category. This list will continually change as your skill level progresses. + +#### Arrays (Two Pointers/Sliding Window) + +- [Sort Colors](/problems/sortColors) +- [Water with Most Water](/problems/waterWithMostWater) +- [Intersection of Two Arrays](/problems/intersectionOfTwoArrays2) +- [Move Zeros](/problems/moveZeros) +- [Remove Duplicates From Sorted Array](/problems/removeDupFromSortedArray) +- [Three Sum](/problems/threeSum) + +#### HashTables + +- [Two Sum](/problems/twoSum) +- [Group Isomorphic Strings](/problems/groupIsomorphicStrings) +- [Isomorphic Strings](/problems/isomorphicStrings) + + + +#### Stacks + +Need more practice with stacks, don't assume they're easy + +- [Minimum Add to Make Parentheses Valid](/problems/minimumAddToMakeValidParenthesis) +- [Valid Parenthesis]() + +#### Heap + +Whenever problem asks for kth largest or kth smallest. Think heap. + +- [Kth Largest Element in an Array](/problems/kthlargestElementInAnArray) +- [Kth Largest Element in a Stream](/problems/kthlargestElementInAStream) +- [Top Frequent K Elements](/problems/topFrequentKElements) + +#### Strings + +- [Longest Common Prefix](/problems/longestCommonPrefix) +- [Longest Substring without Repeating Characters](/problems/longestSubstringWithoutRepeatingChars) +- [Reverse Vowels from a String](/problems/reverseVowelsFromAString) +- [Is Subsequence](/problems/isSubSequence) +- [Longest Palindromic Substring](/problems/longestPalindromicSubstring) +- [implement strstr](implement_strstr) + + +#### Math + +- Reverse Integer + + + + +#### Trees + +- [Deepest Leaves Sum BFS](/problems/deepestLeavesSumBFS) +- [Deepest Leaves Sum DFS](/problems/deepestLeavesSumDFS) +- [Validate BST](/problems/validateBST) +- [LCA Binary Tree (No parent pointers)](/problems/lcaBinaryTree) +- Easy Tree Problems + - [Max Depth](/problems/maxDepth) + - [Is Tree Balanced](/problems/isTreeBalanced) + - [Is Same Tree](/problems/isSameTree) + - [Is Symmetric Tree?](/problems/isSymmetricTree) + - [Is Sub Tree](/problems/isSubtree) + - [Invert/Reverse Tree](/problems/invertTree) + + +#### Path Sums +- [Path Sum](/problems/pathSum) +- [Path Sum 2](/problems/pathSum2) +- [Path Sum 3](/problems/pathSum3) + +#### BFS (Trees) + +- [Binary Tree Zig Zag](/problems/binaryTreeZigZag) +- [Cousins in Binary Tree](/problems/cousinsInBinaryTree) + +#### DFS (Trees) + +- [Binary Tree Zig Zag](/problems/binaryTreeZigZagDfs) + +#### Binary Search + +Need to get way better at identifying and applying these. +[Leetcode List](https://leetcode.com/tag/binary-search/) + +- [Binary Search](/problems/binarySearch) +- [Guess Number Higher or Lower](/problems/guessNumberHigherOrLower) +- [Find First and Last Position of Element in Sorted Array](/problems/searchForARange) + +- [Search Matrix](/problems/matrixSearch) +- [Find Min in Sorted Array](/problems/findMinInSortedArray) +- [Search in rotated array](/problems/searchInRotatedSortedArray) +- [Search Rotated Array](/problems/searchRotatedArray) +- [Arrange Coins](/problems/arrangeCoins) + +#### Bit Manipulation + +- [Missing Number](/problems/missingNumber) +- [Single Number](/problems/singleNumber) +- [Reverse Bits](/problems/reverseBits) +- [Power(x,n)](/problems/powx-n) + +#### Interval + +- [Merge Interval](/problems/mergeIntervals) + +### Linked List + +Need to practice these. Keep messing up on edge cases. Learn when to use techniques like dummy nodes and prev pointers. + +Linked List Advice found [here](https://leetcode.com/explore/learn/card/linked-list/214/two-pointer-technique/1216/) + +- [Merge Sorted Lists](/problems/mergeSortedLLiter) +- [Remove Nth Node from End of List](/problems/removeNthNodeFromEndOfList) +- [Remove Linked List Elements](/problems/removeLinkedListElements) +- [Reverse Linked List](/problems/reverseLLiterative) +- Cycle Detection + - [Linked List Cycle I](/problems/llcycle) + - [Linked List Cycle II](/problems/llcycle2) + - [Find the Duplicate number](/problems/findTheDuplicateNumber) +- [Flatten Mutlilevel LInked List](/problems/flattenMultilevelDoublyLinkedList) +- [Reorder List - list reversal and merge as subproblems](/problems/reorder_list) + + + + + +#### Matrix + +- [Rotate Image](/problems/rotateImage) +- [Validate Sudoku](/problems/validateSudoku) +- [Spiral Matrix](/problems/spiralMatrix) + + +#### Dynamic Programming + +Can only solve these if seen before + +- [Longest Common Subsequence](/problems/longestCommonSubsequence) +- [Unique Paths](/problems/uniquePaths) +- [Coin Change](/problems/coinChange) +- [Coin Change 2](/problems/coinChange2) +- Perfect Squares +- [Unique BST](/problems/uniqueBST) +- Easy + - [Buy and sell stock i](/problems/buyAndSellStock) + - [Buy and sell stock 2](/problems/buyAndSellStock2) + - [House robber 1](/problems/houseRobber) + - [House robber 12](/problems/houseRobber2) + - [max subarray](/problems/maxSubarray) + - [max product subarray](/problems/maxProductSubarray) + +#### Recursion / Backtracking + +Solvable with backtracking template. Need to articulate them better. + +- [Permutation](/problems/permutations) +- [Permutation (cascading)](/problems/permutationsCascading) +- [Subsets](/problems/subsets) +- [Subsets (cascading)](/problems/subsetsCascading) +- [Generate Parenthesis](/problems/generateParanthesis) +- [Combination Sum](/problems/combination_sum) +- [Combination Sum II](/problems/combinationSum2) +- [Combination Sum III](/problems/combinationSum3) + +[Check this link for combo sum 1,2,3 using add/pop method](https://leetcode.com/problems/combination-sum-ii/discuss/16878/Combination-Sum-I-II-and-III-Java-solution-(see-the-similarities-yourself)) + +#### Islands + +Okay at solving these. Just need to remember pattern. + +- [Flood Fill](/problems/floodfill) +- [Num Islands](/problems/numIslands) +- [Max Area Of Islands](/problems/maxAreaOfIsland) +- [Rotten Oranges](/problems/rottenOranges) +- [Surrounded Region](/problems/surroundedRegion) +- [Word Search](/problems/wordSearch) +- [Island Perimeter](/problems/islandPerimeter) + + + + + +#### Graphs (Dijkstra) + +Just learning these. Do more of these problems to find patterns. + +- [All Paths Fro Source to Target](/problems/allPathsFromSourceToTarget) +- Cheapest Flights +- Network Delay Times +- Reconstruct Iteranary + +#### Greedy + +Just learning these. Do more of these problems to find patterns. + +- [Queue Reconstruction By Height](/problems/queueReconstructionByHeight) +- [Jump Game](/problems/jumpGame) \ No newline at end of file diff --git a/pages/lists/solved.md b/pages/lists/solved.md new file mode 100644 index 0000000..7c65391 --- /dev/null +++ b/pages/lists/solved.md @@ -0,0 +1,30 @@ +--- +layout: page +title: Solved Problems +--- + + +{% for p in site.problems %} +- [{{ p.title }}]( {{ p.url }} ) +{% endfor %} + + + + + +Problems (todo) +----------------- +- Min Stack +- LRU Cache (not complete) +- Reverse Linked List (Iterative + Recursive) +- Missing Number (Euler's formula + XOR method) +- Two Sums +- Binary to Decimal - Linked List +- Sum Even Grandparents +- Reverse Bits +- Fib Iterative Return Array +- Binary Search Iterative +- Find Min in sorted Array +- Group Anagram +- Sort Merge LInked LIst Recursive +- Symmetric Tree diff --git a/pages/lists/solvedLastModified.md b/pages/lists/solvedLastModified.md new file mode 100644 index 0000000..79c0687 --- /dev/null +++ b/pages/lists/solvedLastModified.md @@ -0,0 +1,10 @@ +--- +layout: page +title: Solved - Last Modified +--- + + +There are 0 problems solved. + +Problem | Last Modified | Status | Category +--------|---------------|--------|---------- diff --git a/pages/practiceJournal.md b/pages/practiceJournal.md new file mode 100644 index 0000000..7bb61d4 --- /dev/null +++ b/pages/practiceJournal.md @@ -0,0 +1,1568 @@ +--- +layout: page +title: Practice Log +--- + +### Sept 22 + + + +### Sept 16 + +Tmr try to grok: + +- [combo sum backtracking](https://www.youtube.com/watch?v=MTI2wc8s0BY) +- [permuation backtracking](https://www.youtube.com/watch?v=KukNnoN-SoY) + +then draw recursion tree for generate parenthesis + + +### Sept 6 + +New goal to keep up. + +- solve questions you've seen before in less time +- resolve harder questions days or a week after you've learned them +- round robin thru all types of problems +- can solve questions from daily problems, explore cards, lists, difficulty, categories, etc + + +### Sept 4 + +The last few days I've just stressing out over the Facebook phone screen. It turns out that the actual interview had pretty easy questions (even though I didn't answer all the questions). But as the days approached, I just kept thinking that I am not ready. I saw people say on Leetcode that they're phone screens are leetcode difficulty questions that I was not ready for. + +To relieve the stress, I would need to keep up my Leetcodig skills. I also need a fun project to releave myself from telus boredom and as a break from leetcoding. I think + + +### Sept 1 + +Procrastinating from solving problems with my facebook interview coming up soon. I found myself procrastinating by doing telus work. Next time, I might need to have "my own project" to keep me busy. Maybe a stock tracker or a real estate property finder. + +___________ + +Somethings to make studying easier: +- listen to something relaxing or podcast +- forest app +- keep spreadsheet of questions solved +- start by listening to something CS related (CS50 - Harvard Intro to AI) + +___________- + + + +### Aug 31 + +After taking the weekend off from studying, it's now Monday and I need to get back to the mindset of solving problems for my Facebook phone screen on Thursday. To relief the stress, I've opened Spotify to some relaxing music and I'm going thru my "Review List". + + + +### Aug 27 + +Got the question [Find Right Interval]() today for the daily challenge and it seems doable. However, I messed up the initial implementation and had to spend a bit of time debugging. This debugging time should be factored into solving the problem so now I should work on speed of implementation and debugging. + + +So leetcode time should be split between: + +- doing new medium or hard problems (from daily challenge or from lists) (work on learning new techniques) +- interview.io or pramp (video conference practice) +- on meh days + - solve easy questions for motivation + - reviewing old problems in a round robin fashion (work on speed and recall) + +I may need to have another system for tracking leetcode problems. I'm outgrowing jekyll, probably need to keep track of revisits and timing. Outsource solutions database to a blog or something (substack?). + + +__________ + +On the motivational and sustainable end, leetcoding could be very dry (it's a grind afterall), so intermix it with rental reseach and life planning. Like what you would do in a regular work day anyways. + +__________ + +On real estate investing, [this video on bigger pockets](https://www.youtube.com/watch?v=u83O2l1QEj4) has first steps on what you need to do to start your rental business career. It boils down to get good at the math. + +You can start by doing the math on your current property. + + + +### Aug 25 + +[programmer coach](https://www.programmercoach.com/)https://www.programmercoach.com/ + +___________ + +SQL Practice, take the "practice sql questions.doc" from facebook and try them in sql fiddle. + + + +### Aug 24 + +Sometimes on your meh days, you just have to warm up with easy questions. + +[interview experience post](https://leetcode.com/discuss/interview-experience/808191/google-l3-mountain-view-august-2020-offer) + +On your days when you're very productive and solving random problems, take some time to look over life stuff like real estate and future planning. + + +### Aug 23 + +try [this](https://leetcode.com/problems/heaters/) problem. it should be easy + +just do a bunch of easy problems to see if you can get brute force solution on your meh days + + +round robin thru each type of problems in last 2 weeks before interview: +- 1-2 sql questions +- 1-2 string/array problems +- 1-2 matrix q +- 1-2 island +- 1-2 binary search +- 1-2 trees +- 1-2 bfs +- etc + + +### Aug 20 + +Getting very burnt out but my facebook interview phone screen is coming up in 2 weeks. + +I'm just going to have to find the build a curriculum and follow thru. Leetcoding is something that I'm not going to enjoy and never will but I will have to do it to continue living a better life. Much like going on a run or exercising. + + +Things are getting busier at work. Not caring and doing the minimum has been working and it helps my sanity. + +As for leetcode and studying for interviews when your interview is coming up. +=> admit that you wont be able to remember all your problems so just make it a plan to study all the ones that you have reviewed +=> focus on quantity than quality + + +___________- + + +Today, I'm feeling kinda meh but I've gotten in the zone by doing random questions and SQL problems. Sometimes it's nice to just do random problems and figure it out as you go along without any pressure. Focus on quantity>quality on these meh days. Aim to increase submission count in leetcode profile. Keep doing it until you get tired. You got the time, now you just need to keep up the motivation. The interview is partly luck based so you're just increasing your chances. + + +Another thing on can do on my "meh days" is just to randomly pick medium problems and practice them. + +Can also do hackerrank practice on my meh days. + + + +### Aug 18 + +Got [Product of Array Except Self](https://leetcode.com/problems/product-of-array-except-self/) problem on pramp. I saw it before, got the algorithm with help but couldn't write code for it. + +[company specific questions list](https://github.com/MysteryVaibhav/leetcode_company_wise_questions) + + +Do this pattern: + +``` +LeetCode Studying Approach + +1. Do Breadth-First Scan of “Easy” questions from each Topic on Leetcode + 1. Try to get it right on the first try + 2. Should be finishing these in < 10 minutes + 3. Take note of which sections you struggled at (the following was for me) + 1. Trees + 2. Dynamic Programming +2. Do more “Easy” questions from the topics you struggled at +3. Shuffle “Medium” problems + 1. Only do the problems you are not 100% sure how to do + 2. Start a 25 minute pomodoro timer and attempt to solve it + 3. If the problem isn’t solved in 25 minutes, take a look at the discussion section but do NOT look at code just yet + 1. Reset the timer and do another pomodoro + 2. Once the problem is done, look at the discussion section and understand how other people solved it + 3. Write this problem down in your notes as a problem you need to revisit +4. Do the popular “Hard” problems from each Topic + 1. Try to finish these within 45 minutes +5. Do a mock interview AT LEAST once a week +6. Towards the last month of interview prep, do the 1-month term plan in EPI on PAPER +``` + + +### Aug 17 + +Topics from groking +-------------------- +Pattern: Sliding Window +Pattern: Two Pointers +Pattern: Fast & Slow pointers +Pattern: Merge Intervals +Pattern: Cyclic Sort +Pattern: In-place Reversal of a LinkedList +Pattern: Tree Breadth First Search +Pattern: Tree Depth First Search +Pattern: Two Heaps +Pattern: Subsets +Pattern: Modified Binary Search +Pattern: Bitwise XOR +Pattern: Top 'K' Elements +Pattern: K-way merge +Pattern : 0/1 Knapsack (Dynamic Programming) +Pattern: Topological Sort (Graph) + + +### Aug 14 + +[back2backswe course](https://backtobackswe.com/pricing?utm_source=facebook&utm_medium=cpm&utm_campaign=23844860978500459&utm_content=23844860982700459&fbclid=IwAR3YvZ76JBQ2Mg_By8XxRbNMPH-wfkFOSMFs3dVSQTCi9Rpj7jgKVou3eTY) + + +Worked on: +- top k frequent elements +- k most frequent elements +- move zeros +- reverse vowels of a string + +### Aug 13 + +[my youtube channel](https://www.youtube.com/channel/UC_2uIVR51P4EuccbJOJvcQA/videos) +[youtube studio dashboard](https://studio.youtube.com/channel) + + +### Aug 11 + +Interviews +- Amazon - Missy is contact, need to complete coding assessment +- Facebook - Shone is contact, need to complete 1 hr phone screen with data engineer + +1 hr on coder pad +25 min questions on sql, 5 max +25 min questions on coding, 5 max +5 min for Q's + +the bar is 3-4 questions on each one, it gets progressively harder + +best way is to hit up leetcode and hackerrank and practice those on medium +if you can do 3-4 of them in 25 min, you're ready + +__________- + +sql resources + +- [coderpad.io sandbox](https://coderpad.io/launch-sandbox) +- [summary of sql qustions on leetcode](https://byrony.github.io/summary-of-sql-questions-on-leetcode.html) +- [What I realized after solving 100 leetcode SQL questions…](https://towardsdatascience.com/sql-questions-summary-df90bfe4c9c) +- [hackerrank](https://www.hackerrank.com/domains/sql) +- [advanced sql q&a](https://www.programmerinterview.com/database-sql/advanced-sql-interview-questions-and-answers/) +- [sql zoo](https://sqlzoo.net/) +__________ + +[facebook recruiting link](https://www.facebookrecruiting.com/portal/home) +[fb data engineer prep](https://www.facebook.com/careers/DE-prep-initial) +- material in /home/steve/tmp/facebook_interview_prep + + + + + +### Aug 9 + +Educative.io is good for knowing which problems to work on and sometimes have decent explanatinos. +Just use educative.io as a list to get thru and feel free to use the explaination in conjunction with youtube to understand the problem. + + +### Aug 8 + +I just learned that there's another more intuitive way to do the subset/permutation problem without backtracking +[subset - duplicate and add next item](https://www.educative.io/courses/grokking-the-coding-interview/gx2OqlvEnWG) + + +It's much more about how you articulate the problem than knowing the problem. Recording yourself should help with this. + +______________ + +Strategy for interview prep: +- review leetcode questions on jekyll +- hackerrank interview prep +- educative.io - groking coding patterns + +System +- educative.io - groking system design + +Behavior +- educative.io - groking behavior + + +You can even use educative.io to teach for passive income: +https://www.educative.io/authors + + +### Aug 7 + +educative.io +---------------- + + + +just search for all "groking" + + +[groking coding interview patterns](https://www.educative.io/courses/grokking-the-coding-interview) +[groking dynamic programming](https://www.educative.io/courses/grokking-dynamic-programming-patterns-for-coding-interviews) +[grok behavior interview](https://www.educative.io/courses/grokking-the-behavioral-interview) + +get 1 month subscription and download using [scraper](https://anotherdev.xyz/educative-io-course-downloader/) +- [downloader](https://github.com/shihabmridha/educative.io-downloader) + +[top educative courses](https://medium.com/double-pointer/top-courses-on-educative-io-aa8179682a2d) + + + + +try hackerrank as well +- interview prep kit +- tries +- topological sort -> educative.io has one too + +nick white has 300 problems solved as of dec 2019 + + + + + + + +### Jul 30 + +I've been falling off the behind on my practice. In the last few days, I've solved many problems and practiced many types of problems inlcuding: +- various types of binary searches problems +- dfs technique in level order problems +- heap based problems (kth most frequent elements) + +I think taking a step back from doing new problems and reviewing older problems that you've attempted is good once in a while. There are a couple of study habits that I've found effective while studying algos: + +- need to dedicate at least a few hours per day every day +- don't spend too long on a problem if you can't figure it out +- space repetition, review all types of problems occasionally + +This falls within the "Principles of Life" that I've been building up slowly throughout the past couple years: + +- Do not worry about your stock portfolio, just buy and hold +- Do not waste time on Telus work, just use that time on getting better at leetcode. But do not stress out over not working for Big4. +- Use other time to get better at cooking/chinese/fitness/photography/business/etc? + + + +### Jul 28 + +[Julia Zines](https://wizardzines.com/) +[Leetcode Behaviroal Interview](https://leetcode.com/explore/interview/) + +### Jul 24 + +[Amazon Behaviroual Interview](https://www.1point3acres.com/bbs/thread-307462-1-1.html) +[space repetition advice](https://leetcode.com/discuss/interview-experience/426561/amazon-sde2-jul-2019-reject-lesson-learned-to-never-fail-again) + +### Jul 23 + +I was able to solve Max Depth of Nary Tree by myself today on my first try. I remembered the solution from max depth of binary tree and just modified it from 2 left and right children to iterate thru all children. + +Understanding the concept and being able to modify the code is what I needed to do. + +Kevin Naughton Jr. +[Getting Laid Off](https://www.youtube.com/watch?v=tAQ-s90eaKQ) +[Dealing With Failure](https://www.youtube.com/watch?v=sWfTIQ2wX_0) + +### Jul 22 + +I did a few linked list problems but even though I was able to do those at an earlier point in time, I still write buggy code. Been trying to do a few more. Learned a few techniques like dummy nodes and prev pointers. + + +### Jul 21 + +[Anxiety During Interviews](https://leetcode.com/discuss/interview-question/746391/my-faang-interview-experience) + + +### Jul 20 + +Wasn't able to solve the Remove Linked List Elements problem, even though it was an easy problem. +I should start solving a bunch of linked list problems one after the other. Kinda like how I gotten "comfortable" with tree problems. + +Also, should start publishing to leetcodegym.substack.com + +Btw, it seems like I am the owner of both substacks: +https://bootstrapersjourney.substack.com/publish/settings +https://leetcodegym.substack.com/publish/settings + + + +### Jul 19 + +Okay, it's been a couple days where I've taken a break from the daily challenge and gone to "think of a business idea" but now I'm back. Both are painful to do but are necessary. I can use one to motivate myself to do the other when I get sick of one of them. + +The leetcoding one should be my 40hr per week job where 20% is used to do my side hustle (business). + +### Jul 17 + +Aside from playing around with Anki, I've started just reviewing some of the problems that I've done in the past and it's a nice refreshing feeling. It lets me know that I'm actually improving. + + + +### Jul 15 + +Thinking about moving some Leetcode Gym jekyll articles over to Anki for studying. + +### Jul 11 + +[Recursive backtracking](https://medium.com/leetcode-patterns/leetcode-pattern-3-backtracking-5d9e5a03dc26) + + +### Jul 8 + +[Leetcode Patterns](https://medium.com/leetcode-patterns) +[Backtracking Standford](https://see.stanford.edu/materials/icspacs106b/H19-RecBacktrackExamples.pdf) + +### Jul 4 + +Coded July Leetcode Challange (Ugly Num 2), got it working but TLE for large N. +Then did longest padlindromic substring, can get it working for odd palindrome but not even. + +Sometimes, you just have to work on your coding ability and translating ideas to code. Even if solution doens't work out. + +Focus on getting more practice in. Especially coding pratice. + + +### Jul 3 + +Another day, another battle to decide whether to continue working on leetcoding or work on business/self improvement. + +Today, I attempted the July Challenge "Prison Cells after N days", I got most of it and was able to code up solutions for small cases of N, but was not able to get the optimized solution for N=1 billion. + +Eventually, I ran to my 2hr limit and just wrapped it up. + +One area where I have gotten better is reading solutions and understanding the idea behind the code. Just need to increase speed now. + + +[Python Visualizer](http://pythontutor.com/visualize.html#mode=display) + +___________ + +Morning - Solve Daily Challenge +Afternoon - Work on Business Project? +Evening - Review old Leetcode problems + +___________ + +When it's time for an upcoming interview: +- review "Review Problems" +- create a "algorithm cheat sheet" + +___________ + +Focus on communicating / explaining a problem: +- Answer on Leetcode discussion board +- Post a blog post +- Etc + + +### Jul 2 + +I've learned enough to self-correct. Time for retrospective. + +Things you could start doing differently to improve your studying: + +- build a personal curriculum (graphs, backtracking, binary search, etc) +- mark similar questions together +- revisit old problems regularly (whether solved or unsolved) +- unsolved problems should be visited sooner +- upvote problems that you want to focus on +- interactive way to mix running code with flashcards? + - multiple choice: fill in this "block of code" +- take pictures of notes and upload them with whiteboard filter +- turn some problems that you've worked on into blog articles +- have some sort of version control so you can see your solutions evolve +- differentiate different types of solutions for the same problem (ie: recursive vs iteration vs xor) +- time your exercises +- allow input for space and time complexity +- how fast can you review all your solutions if you had an interview in a week? +- round robin thru each type of category +- have 2 types of study session: broad or by category +- show some type of visible progress +- make it easy to create leetcode flashcards +- make it easy to convert some of these articles into blog articles +- have flashcards link to jekyll blog + +Instead of making an app, create a study schedule: + +- week 1: + + + +Make Review Cheat Sheet: +- Dynamic Programming +- Backtracking (Permutations, Subsets) +- Flood Fill +- Reverse Linked List +- Merge Intervals +- Binary Search + +Easy +- BFS / DFS +- Trees + - LCA +- Hashtables (Two Sum, Isomorphic Strings) + + +1) + + + +### Jun 30 + +I realized I can't even work with Steve and Mayuresh on a project where there is no communication or leadership/accountability. Fuck those guys too. + +They are finally asking question in the 11th hour and I have lost all my willpower to care. Just going to keep leetcoding and deflecting their questions. + + + +### Jun 29 + +Did the June Daily Challenge all by myself on a brand new problem. It was the Unique Paths Problem and I solved it using the bottom up dynamics programming approach. Practicing all those similar dp problems have really paid off. + +____________ + +Rant: + +Johnson, Gus and Yvonne asked for an update on SMS Whitelisting and CPG. Eventhough nothing was done, just lie to their fucking faces about it being wrapped up. Tell them what they want to hear and get them off my back. + +_________ + +I've built the habit of leetcoding in my free time. This has become the norm and it requires less will power to keep up. Just like running daily now, whenever it's a "normal" day, I am growing. + + + + +### Jun 28 + +I did the REconstructIternary problem almost all by myself. At least the first example works. + +Mark down questions that you could do and ones that you have no idea how to start. +- count and say +- reconstruct iternary + +__________ + +Today, upon working on the Perfect Square problem, I went back to visit the Coin Change problem (change making problem) because Timonthy H Chang said it was similar. After watching Back2BackSWE video, I finally understand how the problem is solved. Sometimes, you just need to come back to a problem after gaining more insight. + + + +### Jun 27 + +Working on the Perfect Squares problem and I'm starting to identify subproblems by myself. + +Also, in the last couple days, I've been working on backtracking problems. Should work on "similar types of questions" at the same time so I can identify patterns. Maybe make a study curriculum. + + +_________ + +Time to add a new habit? + +- chinese / cooking +- writing / blogging / tweeting and building audience + + +Start building these small habits slowly. And be realistic. + +Got the leetcoding habit down. +Should expand and do blogging habit next. + + +### Jun 25 + +Today, I just spent 2 hours trying to get DS to run my CommandLineRunner after Andrei's changes. FUCK!!!!! +After that, I just into issues because teh Auth.net prod credentials were incorrect. Stupid problems. In comparison, leetcoding is easy shit. + + +### Jun 24 + +I just watched David V's course on "Everybody can build a Twitter Audience" and it convinced me that I need to gain credibility before I can start any entrepreneurial adventure. Since I'm already working on leetcoding, I can start small and tweet/post my leetcode solutions on medium/leetcode/twitter, etc. + +It's better to look at solution, learn it and move on than to get stuck and waste hours on a single problem. You can always return to it later or turn it into a blog article to cement your learning. + +The key thing is that you want to gain credibility and have something to promote later on. + + + +### Jun 23 + +Need to do telus work first. Then go back to Complete Binary Tree Node problem. + +I think I've successfully built the habit of leetcoding a little bit every day. + +### Jun 22 + +Make a timeline for reaching milestones. (IE: by August, start applying to tier B companies) + +Do June Challenge, then work on permutation problems. Do not spend more than 30 min figuring out a solution and not more than an hour coding it. + +Another list of questions: https://docs.google.com/document/d/1wUCqhVHydWiDk6FJdFLSMpgigNrGcs4OFZg0Wa7JGEw/preview?pru=AAABcwEKa6A*jTAyJNFMW1ButNqUo_V6zA + + +When a problem is really hard to understand, try debugging, putting print statements or finding a solution to a similar problem. + +### Jun 21 + +I have definately stopped consistently doing the June challenge. I should get back into the habit of doing it. It's about how you recover after getting off the wagon. + + + + +### Jun 20 + +I tried the weekly contest. The time pressure is there. There are also virtual contests where rank will not be affected. + +When the contest is finished, you see your rank amongst other ppl. For my first one, I got 1/4 question correct with a rank of 9316/13807. + + + + +### Jun 19 + +Other than doing problems from a problems list, can also go thru youtube video playlists of known leetcode youtubers. + +Add due dates to learn certain tasks: +- 1 night to learn dijkstra and bfs +- 1 week to learn dp + + +Been learning some advanced algos recently: +- Dijkstra +- Rabin Carp +- KMP substring matching + +Practice whiteboard/paper space management + +Do this graph problem, it has every graph algorithm below: +https://leetcode.com/problems/network-delay-time/discuss/471164/Python-DFS-BFS-Dijkstra-Bellman-Ford-Floyd-Warshall + + +### Jun 18 + +Time to do some retrospective: + +----- + +Doing daily problems have been slowing down the past week. Need to keep monitor burnout/stress level. + +Now that I've worked on over a hundred problems on leetcode. It's time to go back and review some of the ones that I didn't get (or do some faster and more concisely) + + +Things that have worked: + +- this journal +- this jekyll blog for easy tracking of problems +- this site doesn't actually make me review questions, but it does have my old solutions and some notes so I can reference them in similar problems +- try to gather a bunch of similar type problems and do them in batches + + +---- + + +Get to the point where the skill of doing coding interviews is a science. Create your own list of "must review" problems before an interview. Have those problems be ones that you have worked on before because you will never be able to do all the leetcode problems ever. + +--- + + + + +### Jun 17 + +Today, do cheapest flight problem (dijkstra) and leetcode daily problem (union find). + +Get used to tryign out solutions and being wrong in leetcode. It's better than being wrong in the actual interview. + +---------------- + +Try rewriting Num Islands solution more concisely from techniques learned from Surrounded Region (for x,y in neib_list) and itertools.product() +Maybe instead of going thru new problems, go thru the ones that you have done before and make sure you can write them concisely and can communicate them well. + +-------------- + + +Leetcode post for writing concise Python code: +- https://leetcode.com/discuss/general-discussion/459791/Special-data-structures-in-Python +- https://yangshun.github.io/tech-interview-handbook/landscape + +Another list of leetcode questions: +- https://yangshun.github.io/tech-interview-handbook/best-practice-questions + + +### Jun 16 + +Spent the morning working on telus shit. what a waste of time. + +Today, I went thru the BFS and Dijkstra chapters in Grokking Algorithms book. It does a very good job at explaining for visual learners. Tmr will attempt some dijkstra problems. + + + +### Jun 15 + + +Today, I spent most of the day with the Cheapest Flight problem. I didn't quite get it even after looking at the code so tomorrow, I will focus on understand Dijkstra at a deep level before going back to the problem. + +Check groking algorithms ebook for dijkstra chapter. +Can also read "competitive programming" ebook. + + +----------------- + +I read somewhere that Leetcoding is like going to the gym for your coding skills. It's a slow marathon. That falls in line with my experience that you can't cram for an interview. I will just have to incorporate it into my daily routine or work routine. + +Since you value your time, your 9-5 is when you should be leetcoding. Treat it like a job and don't bother leetcoding outside office hours. + + + +### Jun 12 + +Start using interview.io sandbox to practice, they have Python autocomplete and executes code on save. (Much nicer than VS Code). + + + + +### Jun 11 + +Just finished the practice interview. I got this question in the interview: +https://leetcode.com/discuss/interview-question/368038/Amazon-or-Onsite-or-Group-Isomorphic-Strings + + + + +It went okay. I surprised myself when I actually came up with a solution myself in the allotted time, even though it wasn't optimal. For your practice, allocate some time to problems where you just figure it out yourself and don't stop unless you've tried for over an hour. Probably best done in some of the easier types of questions (ie: arrays, strings, hashmap). + + + +Some other feedback has been left here: +https://start.interviewing.io/feedback/J2aykIDapnWN + +Key points were: +- ask clarifying questions +- always review space and time complexity (i got space complexity wrong) + + +In every interview, you will always feel unprepared and you will even stress out DURING the interview. You will want to give up. Need to find some way to handle the stress and keep tackling the problem. + + +-------------------- + +Have a practice interview today at 3pm. Should start practicing using the online environment: +https://start.interviewing.io/interview/playground?tutorial=true + + +It also helps you with your walk-thru dry debugging. When you're doing a dry walk-thru online, type out the array in its current state along with all tracker variables. For example: + +``` + # 2 0 2 1 1 0 i=0 s=0 e=5 + # 0 0 2 1 1 2 i=1 s=0 e=4 +``` + +When you run the code, you can print(num, trackerVars...) at the end of the loop and verify what you get when you execute matches what you think you should get. + +Getting prep'ed for my practice interview. Just reviewing all the different "bag of tricks" by going thru jekyll blog. +I should make my own list of problems to "review before an interview". Should be a handful of problems that I can review in a short amount of time. + +After your interview, you should go and find it in the showcase and see where you can improve. So give it all you got. + + +### Jun 10 + + +Search Insert Position +---------------------- + +I did the problem "Search INsert Position" all by myself. It was an easy binary search question, but it's usually one of the ones that I always failed at. + +I started with what I know about binary search and modified it by thinking of all the edge cases and eventually wound up at an acceptable solution. + +Looking back at some of the LC discussions, I may have over-complicated it and wrote more than I need to. The classical binary search would have suffice with a single line modification (return left if none found). + +I posted my solution in the discussions for feedback. + + + +Validate Sudoku +---------------------- + +Also did validate sudoku problem. I did it within a reasonable amount of time. The debugger helped with finding bugs such as ignoring ".". +It wasn't a logic problem. Just a trivial mistake. + + +Rotate Image +----------------------- + +Transpose and Flip. This is the second time that I'm seeing this and I really worked hard to understand it the first time. + +The second time, I was able to: +- recall "the solution" +- code up the solution and get the array indexes and loop ranges correct (things I usually mess up on) + +It turns out these problems are actually easier if you solve them a few times before. So it really is all just about practice and not purely talent. + +------------------ + + +Did the Hackerrank Data Engineer BS assessment yesterday. It was pretty BS. It's a good reminder that these algo questions are the easiest way to go if you get good at them. + +P.S. need to categorize binary search as its own categories and practice a bunch of those questions, just like strings + + + + +### Jun 7 + +Booked a peer interview for Thursday @ 3pm. Should start watching other interviews from the showcase. +https://start.interviewing.io/showcase + +----------------- + +Teck mining company, who has no business giving technical interviews, are also giving out hacker ranks assessments now. +This whole industry has gone to shit. + + +### Jun 6 + +Goal: finish easy collection by wednesday. + +Get to the point where you can read solution and understand/code it. If you don't get a solution, keep using other resources until you can understand it. You will eventually reach a eureka moment. + +At least be able to comment on the code. Just find the systematic approach to get the best bang for your buck for each hour of studying. + +Don't compare your ability with anyone else, just compare to your past self. + + + +### Jun 5 + +Did the problem "Plus One" all by myself without reference. Sure, I took a bit longer with some corner cases but it's definately a confidence booster. + +------------- + +Use the Python debugger in VS Code. F5 to debug, F10 to step over. + +------------ + +Going thru some of the SQL problems in preparation for the SQL online assessment. I'm realizin it's not just about knowing algorithms. Getting good at interviews is just about getting good at the skill of being tested. It's not about being a good engineer and completing projects, it's about being good at leetcode problems and hackerrank shit. + +https://www.hackerrank.com/dashboard + +------------ + +Spent longer than I should have on Longest Common Prefix. It should've been an easy String problem but I'm not familiar with the basic String functions (ie: index() vs find()). + +I need to spend more time on String problems too. Thinking they're too easy and avoiding them is a mistake. + + +------------- + +Leetcoding is now full-time job. Business ideas/Real Estate are side hustles. No time for real work. + +If you can't understand a problem. Try to understand as much of it and revisit it the next day. Mark it down as "Attempted" in the Solved Problems page. + +After a while, you should go back and "revisit" all the ones you marked as Attempted. + +Don't get stuck on any one problem. Your goal is to move ahead and do as many problems as possible with deliberate practice. + + +### Jun 4 + +I'm starting to realize there's no way I'm going to memorize the solution to all these problems. But I'm starting to feel like it's actually possible to "recite" these solutions in an interview if I do enough of them. It's just going to take a lot of time and practice. + +So I would still have to spend all my available time on it for a chance to get lucky in an interview. Still, it's something that I should do if I have a pointless job. But I should still work on other stuff in life if I can make the time for it. + + + +### Jun 3 + +I studied one new type of problem (two city scheduling). It's a greedy problem that I probably wouldn't have encountered but I did it because it was the June challenge. + +That also brought me to redo (Merge Intervals) because of the foreign Python syntax to sort by first element. I need to practice python fundamentals instead of doing my Java style habits. + +Python practices here: +- https://www.hackerrank.com/domains/python +- https://learnxinyminutes.com/docs/python/ + + + +### Jun 2 + +Today I've done 6 problems. 5 were easy and 1 (reversing integer), I had to analyze how they handled overflow. + +Something that I'm realizing is that even if I have a bunch of easy questions, it still takes a long time to do a bunch of them. And the "harder" questions could be solved in the same amount of time if you've memorized them. + +Your willpower to keep doing another easy question will also be drained. At most, you might be able to get through 5-6 easy problems per day. + +So the only way to do good on interviews is to do a bunch of problems, memorize them and find ways to practice more problems right before your interview. + +Also, read this: +https://leetcode.com/explore/interview/card/coding-interview-strategy + + + +----------- + +Also found this other youtube channel for coding interviews: +https://www.youtube.com/channel/UCpLC2ohmappF2iUsWYRnsxg + +So we have "Terrible Whiteboard", nick white and backtobackswe. + + + +### Jun 1 + +Doing the list Leetcode Top Interview Questions Easy List: +https://leetcode.com/explore/interview/card/top-interview-questions-easy/ + +Just want to see if I can do all the easy ones now that I had 3 months to practice. + + + +### May 30 + +Made a python script that generates "Solved Problems" listed by last modified date. Hopefully this will help with space repetition. + + + +### May 29 + +Studied +- Set Matrix Zeros + +I attempted Set Matrix Zeros but ran into gotcha. When you modify the matrix in place, it will screw over teh zeroing logic. This is like a gotcha that I found when validating BST. It seems pretty simple but there's a gotcha. The only way is to just do this algorithms and remember the gotchas. + +I swear these problems really make you feel stupid and the only way to overcome them is to play the stupid game and memorize the problems and solutions. + + + +### May 28 + +Reviewed: +- num islands + +Found [this](https://leetcode.com/discuss/general-discussion/655708/graph-problems-for-beginners-practice-problems-and-sample-solutions) great list of graph problems. + +Use the forest app to focus and not get distracted. Remember, leetcode first priority, shopify is a side hustle. + +### May 27 + +Review: +- search matrix + +Studied: +- Water with most water +- house robber 2 + +Today, I did a brand new problem "Water with Most water". I jumped straight to the solution, read the optimum approach and was able to code up the solution myself within 25 min. + + +- The more I'm working on leetcoding/app dev/spending time with loved ones, the more i'm realizing that time management is key. +- Think of leetcoding as full time job and dropshipping/app development as side hustle +- I think last time I wasted time on Project Euler and UVA Online Judge but they were not tailered towards interviewing enough. + +### May 26 + +Reviewed: +- house robber +- max sub array + + +I just reviewed house robber and max sub array today. Seems like even if I think I know the appraoch, there's lots of things coding-wise that trip me up. Definately need to review old problems from time to time. + + +Also, I only have a certain level of WILLPOWER everyday. It's best to split it between working on my business and leetcode. But I cannot neglect either one. + + +Todo: +matrix binary search: +https://www.youtube.com/watch?v=41ON2EghJi0 + +Try geometric problems: +https://leetcode.com/problems/generate-random-point-in-a-circle +https://www.youtube.com/watch?v=pvimAM_SLic + + +I swear memorizing these intereview problems is as dumb as memorizing prayers when I was a kid. + + +### May 25 + +Reviewed +- Longest Common Subsequence (25 min to reviewed approach, another 30 to code with minor mistakes) + +### May 22 + +Reviewed +- Merge Sorted List (Iterative) +- Reverse LL (Iter) + +Back from a 2-day break. Been thinking entrepreneurally since was getting burnt out from leetcoding. +I should balance out business and leetcode. + +Tips for leetcoding: +- Use Forest app for timeboxing leetcode. +- Use space repetition to rework old problems in leetcode. + + +Other ideas: +- keep track of submission by problems +- track myshopify stores and copy products + + +### May 19 + +Studied +- Coin Change +- House Robber + +Just looked at solutions and memorized/learned from them. Will review in a few days. + + +### May 16 + +Tomorrow or next week, need to review a few problems that I've "forgotten" +- Find Min in Sorted Array +- missing number +- reverse bits +- remove nth node from end of list + + + +### May 15 + +Studied +- flood fill / num islands + + +Just finished studying the Flood Fill problem. I think I found a pattern/routine that works. + +1) Find a new problem. + +2) Understand the problem and think of initial solution for 5 minutes. + +3) Look at discussion solutions + +4) Implement the discussion solutions yourself without looking (you'll catch some small errors) + +5) Redo problem a few days later. + + + +### May 14 + +Studied (new problem or new algo) +- longest substring without repeating chars +- count ones in array + +Reviewed +- numOnes +- merge sorted linked lists (recursive) + + +Tip from Nick White: don’t sit there and try and solve it. Just look at the solutions and learn +Let's see how many new problems I can "study" using this method. I can always go back to "review" the problems. +Quantity over Quality! FTW + +Once you learn it, write it down in notes (ie: blog) and keep looking over it. Who cares if you're "memoroziing it". Just do whatever works. + +Found this article on bit manipulation: +https://leetcode.com/problems/sum-of-two-integers/discuss/84278/A-summary%3A-how-to-use-bit-manipulation-to-solve-problems-easily-and-efficiently/207733/ + + + +Looking at a new algorithm (union find), from problem "number of islands". Time to add this to your "algo toolbelt" +https://leetcode.com/problems/number-of-islands/discuss/583483/Summarize-of-3-Types-of-solution-methods +Do these next: +- https://leetcode.com/problems/flood-fill/ +- https://leetcode.com/problems/number-of-islands/ + +Found a backtracking algo: +https://www.thecshandbook.com/Backtracking + +Leetcoding is starting to become fun. Considering the alternative is doing telus work. Both type of work is pointless but there's at least a greater chance of being rewarded with leetcode. + + +### May 13 + +Studied +- merge intervals + + +Reviewed +- reverse linked list (iterative) +- link list cycle (hashmap and floyd) + +Today, had a lack of motivation. Did a new hard problem instead (merge intervals). +Should do 1-2 "hard" problems that will require studying and "review" the rest. + +Also found out about https://interviewing.io/. It's free so try it out when you're more comfortable. + + + + + +### May 12 + +today is pop quiz time + +- BFS +- buy and sell stock +- deepest leaves sum (dfs) +- same tree +- symmetric tree +- invert tree +- validate bst (studied) + +keep track of which problem is "studied" vs "reviewed" + + +### May 6 + +- Max Subarray +- Max Product Subarray + +Having problem with product subarray, will do a dry run later +https://stackoverflow.com/questions/19148539/getting-range-of-max-product-subarray-using-kadanes-algorithm + +Getting good at leetcode article: +https://heidi-newton.com/blog/getting-good-at-leetcode + + + +### May 5 + +Setup algo blog at stevenc49.github.io to keep track of blind 100 curated questions and keep solutions to problems. + +Also found out about https://learnxinyminutes.com/docs/python/ + + + +### May 1 + +- LCA binary tree +- symmetric tree + +I am definately getting better at solving and reasoning thru tree problems. Sometimes you just need to work on other types of problems and come back to them later. + +use multiple resources while studying answers: +- youtube +- LC discussions +- EPI + +Goal right now is to try to understand and do as many questions as possible per day (increase learning rate) +Trying to take frequent breaks (playing / watching games between questions) + +from blind: +"I'll give you a hint on career success: politics and expectations management." +"SAT tests get you into a good college, whiteboard tests get you a good job. Unfortunately that’s just how things work today" +Ref: https://www.teamblind.com/post/To-all-the-good-students-who-are-now-good-at-Leetcode-EraCXo5R + + +### Apr 30 + +- rotate matrix +- is tree balanced +- search sorted matrix + + +rotate matrix is turning into one of the more interesting and one of my fav problems, since transposing/flipping and for loop arguments are non-trivial + +for array problems, stick to medium difficulty problems + + +### Apr 29 +- validate sudoku box (validate box can be reduced to 1-d array with formula k = (i//3) * 3 + (j//3) +- spiral matrix +- rotate matrix (transpose and flip method) https://www.youtube.com/watch?v=SA867FvqHrM + + + +watched nick white youtube on how he got into google: https://www.youtube.com/watch?v=nmf-oObylnk +- he said he grind pramp interviews, 8 per day for a month +- try to solve medium problems +- found a python concept tutorial list - https://www.hackerrank.com/domains/python + + +### Apr 29 + +- merge-two-sorted-lists (took a little more than an hour and had to rework it for edge cases) (ie: empty list) +- merge two sorted list recursive + +Revisit Later: + + + +### Apr 27 + +- group anagrams (solved in 15 minutes) + +also can work on problems from app "Data Structures & Algorithms" + + +### Apr 24 + +- binary search +- + +yesterday, i couldn't even write a binary search. it's embarassing for a software engineer. i need to get to a level that even i would approve of. + +do quantity practice over quality, do as many varied types of questions and just look over solutions + +try to replicate solving after even are seen + +maybe make a space repetition app to redo problems that you were struggling with: + +ie: had trouble doing "find min in sorted array but eventually understood the solution, next couple days, come back to it and redo it" + +it's good to take a break and reflect on how you can improve your practice. today, after finishing binary search and search min in sorted array, i reflected on how i can "remember" these solutions and the idea of spaced repetition came in + +also useful to reflect on problems that you wanted to solve, understood but didn't and want to retry + +P.S. officially today, i've been practicing consistently for 3 weeks + + + +### Apr 23 + +Retrospective +--------------- +The goods / What has been working: +- stop working on Telus work and only focus on interviewing +- having a system / scheduled time / routine to work on it is key (get more hours in) +- posting to blog kinda helps +- journaling definately helps +- make studying convenient by making it easy to solve simple problems while watching TV + +The Bads / What I need to work on +------------ +- In addition to leetcoding questions, also need to: + - know python trivial concepts (list comprehension, lambda) + - geekforgeek problems (min and missing #) (not in leetcode) + - system design problems + - regex +- Need to know many different ways to solve problem + - recursion vs iteration + - xor in array/math problems + - different data structures/ time vs space complexicity +- keep log book and have a list of key interview problems to do before an interview (organized way to do long term studying) + +Takeaways +------------- +- Don't complain about work +- Keep the leetcoding momentum going and refine study methods after this one bad interview +- Can think about introducing system for new goal (Chinese, Business, Cooking) + + + + + + +### Apr 22 + +I bombed the 1 hr coding interview at Softmax Data. + +some questions were: +1) ways to reverse string (iterative, swap, recursive) +2) are two strings anagrams +2) [ i/2 if i>3 else 0] +3) lambda function to increase every elem in array +4 regex "vowels" | "come" +5) fib(3) giving [0,1,1] +6) +a = [6, 5, 4, 2, 6] +1 . continuous integers randomly sorted +2. min, max +3. missing -> 3 +4. duplicate -> 6 + +#### Takeaways + +- need to stop doing telus work and only focus on interviewing +- practice python syntax/concepts as well as algorithms + + + + + +### Apr 21 + +Merge 2 sorted list is suppose to be easy but it's hard, come back to it later + + +#### Cramming Retrospective: + +#### Good Parts +- you can get in the mindset of it and it will boost confidence + +#### Bad Parts +- you'll forget how you solved a problem a week later +- Need to keep these skills sharp for lifetime and practice regularly. +- It's not possible to cram the learning into a few days or a week + + + +### Apr 20 + +Studying in on hyperdrive now that I have a coding interview in 2 days. + +I actually solved the hamming distance problem by myself (bitwise problem). new achivement + + +https://www.teamblind.com/post/New-Year-Gift---Curated-List-of-Top-100-LeetCode-Questions-to-Save-Your-Time-OaM1orEU + + +### Apr 15 + +- LCS +- BFS + +Completely wrote a working BFS from scratch by myself. I have it memorized and ingrained from thinking about it for so long. Need to get as familiar as this with other classic problems (ie: longest common subsequence). Despite how non-intuitive it is. + +got a bit complicated when i had to start keeping track of levels. apparently the technique i used to keep track is the same technique i used in java 4 years ago, it's just much more verbose. fuck java + +--- + +The language matters, python has list comprehension which will make writing out the algo easier/faster. + + +### Apr 14 + +- longest common subsequence (DP) + +If you need data to flow up, need to make use of return value. And usually post order (after null check) + +Just watched the LCS solution [here](https://www.youtube.com/watch?v=ASoaQq66foQ). Will implement tmr. + +### Apr 13 + +- deepest leaves sum (LC1302) (solve time about 1 hour with help) +- spent afternoon trying to figure out wrong error problem on sum even grandparents problem + +Compare your python solution to [this](https://leetcode.com/problems/sum-of-nodes-with-even-valued-grandparent/discuss/562939/Simple-recursive-python-solution) solution tomorrow. + +find out why making it postorder instead of preorder made it work. + + +Work days should consist of 1-2 hours of applying to jobs, and 3-4 hours of leetcoding. + +Leetcoding should focus on quantity vs quality so you can identify patterns. Don't be afraid to look up solutions. Like studying for linear algebra exam. + +Ultimate goal is to get comfortable with classic questions in the shortest amount of time. + +Looked at some solutions on leetcode and found some python best practices and shorcuts to make code look more clean. + +An idea I got from a leetcode article is to start recording practice time in a spreadsheet like in [here](https://leetcode.com/discuss/general-discussion/571805/600-problems-in-one-year). + +The columns are: +- problem topic +- problem difficulty +- time to find a solution +- time for implementation +- status (solved, not solved, solved with hints + + +### Apr 9 + +- missingNumber (XOR solution) +- twoSum ( O(n^2 solution) +- LC #1290 - binary to dec, linked list + +I feel like the daily practice is showing some signs of improvement. I just attempted the twoSum problem (which is suppose to be a super easy problem), and I was able to get the Python solution on the first try. 4 years ago, I attempted the Java solution and got a wrong ansewr. + +I also intuitively understood the XOR solution for the missing numbers problem. + +Did the binary to integer linked list problem. It's an easy problem that made me think of fundamental binary properties and I had some small coding errors. But I was able to do it in about an hour. Not great but it's still in an afternoon. P.S. I checked the forums after I thought my initial process was non-ideal (using library methods). + + +Also read some reddit comments about leetcoding. TDLR: leetcode or die. + + + +### Apr 8 + +Did leetcode #268: Missing number. + +If it's an easy one, try to get it right and compilable on the first try. I did not because I made a small mistake, the for range loop is exclusive of the final number. It screwed up my calculations. + +My new strategy now is to sort leet codes by acceptance and tags (ie: arrays, hash tables, trees, etc) + +Just reviewed the solution for missing number and encountered the XOR solution. I still don't fully understand it intuitively but it's good to review other solutions and learn something new. + +I'm feeling much more comfortable about doing these everyday. Maybe I won't feel comfortable going for an interview tmr but I am able to work on these regularly now. I've started building up that habit and ignoring Telus. + + + +### Apr 7 + +Uploaded [Reverse Linked Listed Iterative Method](https://bubblesortblog.wordpress.com/2020/04/08/reverse-linked-list-iterative-method/) + +If it's pointer heavy with lots of iterations, it's better to draw it out and redraw each iteration. + + +### Apr 6 + +Just do lots of problems, easy or not. + +Do Reverse linked list today. You're bound to run into "end of list error" + +Need to also be able to do easy questions when feeling tired. + +### Apr 5 + +I was going entering some of my solutions into leetcode, specificailly the valid parenthesis problem and I realized my solution is just entirely wrong and does not solve the min stack problem correctly. + +It doesn't even give the correct solution for "(]". My solution gives true and the answer is obviously false but I didn't see it. +I need to read the question more closely. Entering these into leetcode will help me know what to test for. + + + +### Apr 3 + +New strategy - do lots of problems, quantity over quality + +I've forgotten the general solution to problems I've done exactly a week ago. Need to review bubblesort.blog periodically. + +Let's do LRU question today. +Been doing the LRU question and creating a doubly linked list. I definatley need to work on managinging my double pointers without having to check with the compiler and running it. + +In a doubly linked list, always keep track of head and tail pointers +I managed to keep track of head and tail nodes after realizing I forgotten about them but it took me a lot of time. And I still didn't get to work on the eviction policy. + +### Apr 2 + +- max depth of binary tree +- is tree balaned + +After checking on the deepest node code, I should do this easy balanced binary tree checker question: + +- https://leetcode.com/problems/balanced-binary-tree/ +- https://leetcode.com/problems/maximum-depth-of-binary-tree/ + +I'm not sure why [this](https://leetcode.com/submissions/detail/318802426/) submission failed, but [this](https://leetcode.com/submissions/detail/318803393/) one passed. + +Some tipes from reading interviewing articles: +"I found that it is extremely helpful for me to read solutions before attempting to solve the problems all by myself. " + +------------- + +I also just did the isTreeBalanced() problem but I really just rewrote a java solution that i rewrote 4 years ago. +I will need to actually drill down and run it step by step to really understand it and fully grasp it. + + +### Apr 1 + +I inputted the deepest node code into leetcode but I'm getting wrong answer. I'll have to look into this. + + + +### Mar 31 + +- [Print Nodes K Distance from Root](https://bubblesortblog.wordpress.com/2020/03/31/print-k-distance-from-root/) +- [Deepest Node/Get Height of Tree](https://bubblesortblog.wordpress.com/2020/03/31/get-deepest-node-get-height-of-binary-tree/) + +Tried the k distance from tree node problem. It involves a hashtable to go up the tree. I watched Back2BackSWE video but it doesn't make sense without code. + +So I'm going to try a simpler version first where we get nodes at k distance from the root. +https://www.geeksforgeeks.org/print-nodes-at-k-distance-from-root/ + +------ + +I did the deepest node by myself and got it right after some debugging. Next time will work on leftmost deepest node. + + + + +### Mar 27 + +- LCA of binary tree +- serialize/deserilize binary tree + +Today, I've added a blog post on LCA of binary tree nodes (without parent pointers or BST) + +For the next few days, I should try out the other similar problems: + +- 10.3) LCA of binary tree (done) +- 10.4) LCA with parent pointers +- 15.4) LCA of BST + +Also watched a video on serializing/deserilizing a binary tree on Back2BackSWE. Will try to implement this. + +Today, I actually implemented serialize and deserialize binary tree: + +- [Serialize Binary Tree](https://bubblesortblog.wordpress.com/2020/03/27/serializing-a-binary-tree/) +- [Deserialize Binary Tree](https://bubblesortblog.wordpress.com/2020/03/28/deserialize-tree/) + +### Mar 26 + +- validate sudoku +- LCA of binary tree nodes + + +Yesterday, I spent so much time trying to understand the sudoku solver. I think I should take a break from it. Maybe implement a sudoku validator first. The video from [Tech with Time](https://www.youtube.com/watch?v=lK4N8E6uNr4&list=TLPQMjUwMzIwMjBh1WFA0aDQLg&index=1) is actually very useful. + +What I did learn was the x,y coordinate with col,row intuition. + +Did LCA of binary tree node. Best explaination was from BackToBackSWE [here](https://www.youtube.com/watch?v=py3R23aAPCA). +The insight from this video is **"when dealing with tree recursion problems, always think of it from the point of view of a single node"** + + +### Mar 25 + +- sudoku solver + +My goal today is to solve the sudoku problem with backtracking. + +It's 2:30pm and I'm not making a lot of head way into this sudoku backtracking problem. Maybe I'll work on an easier tree problem for the rest of today. +This sudoku problem is helping me get 2d rays with row and columns straight though. + +[This](https://www.youtube.com/watch?v=lK4N8E6uNr4&list=TLPQMjUwMzIwMjBh1WFA0aDQLg&index=1) guy does a good job at explaining how to implement a sudoku solver. + + +### Mar 24 + +Today, I tried implementing the solution for Min Stack and I wrote a blog post for it [here](https://bubblesortblog.wordpress.com/2020/03/24/min-stack/) + +Writing the blog post is really just as hard because you will have to communicate clearly to the reader your logic. You'll also need to provide an example test scenario. + +This is a good practice for communicating to the interviewer and I should do this with every problem I solve. I should get to the point where I can communicate the problem like this guy [here](https://www.youtube.com/watch?v=nGwn8_-6e7w). + +As a side note, the explaination in EPI is exactly to what the BacktoBackSWE guy describes. So I should probably understand the solution before checking with EPI for the "cononical" solution. + +The good news is that I'm building up the habit of practicing algorithms every day now. I should keep it up and pick another problem to work tmr. + +I definately need to give studying algorithms as much attention as I've given work and studying investing as in the past. The key to this might be continous deliverate practice. + +I need to remember that habit + deliberate practice = Mastery. + +Same thing for Chinese. + + +### Mar 23 + +- Valid Parenthesis +- Min Stack + +Solved Valid Parenthesis Problem by myself. My solution is posted on my new blog [here](https://bubblesortblog.wordpress.com/2020/03/23/64/). +However, the solution I came up with involves 3 stacks, each keeping track of a type of brace. + +This can be improved with a single stack and detecing if it's an opening or closing brace. If it's an opening brace, we push to the stack, and if it's a closing brace, we pop from the stack. Try this solution tomorrow. + +Today, we will try to get another problem in. + +I also found this great youtube channel with a teaching style that I like: +[Back to Back SWE](https://www.youtube.com/channel/UCmJz2DV1a3yfgrR7GqRtUUA/videos) + +Next question that I will attempt is the Min Stack problem. The min stack problem will run into the problem when you pop from a stack and you have to update the global minimum, the solution is to store the global minimum for each element in the stack. We can use another structure to do that, like another stack. + +This solution is outlined [here](https://www.youtube.com/watch?v=nGwn8_-6e7w) + + + + +### Mar 20 + +- found [Techinical Interview Handbook](https://yangshun.github.io/tech-interview-handbook/best-practice-questions) +- read groking algorithms - chapter 3 recursion + + + +### Mar 9 +- reverse string using recursion +- reversed stack using recursion diff --git a/site-management/fileutils.py b/site-management/fileutils.py new file mode 100644 index 0000000..e2f659f --- /dev/null +++ b/site-management/fileutils.py @@ -0,0 +1,24 @@ +class FileUtil: + + @staticmethod + def saveToFile(string, filepath): + + with open(filepath, "w") as f: + f.write(string) + + + + @staticmethod + def appendToFile(string, filepath): + + with open(filepath, "a") as f: + f.write(string) + + + @staticmethod + def readFromFile(filepath): + + file = open(filepath, 'r') + text = file.read() + file.close() + return text \ No newline at end of file diff --git a/site-management/generateSolvedModified.py b/site-management/generateSolvedModified.py new file mode 100644 index 0000000..132fb04 --- /dev/null +++ b/site-management/generateSolvedModified.py @@ -0,0 +1,82 @@ +import pprint +import os, subprocess +import re +from fileutils import FileUtil + +''' + This script takes all the markdown pages and creates a solved page sorted by last modified date. +''' + +ROOT_DIR = "/Users/steve/workspace/stevenc49.github.io/" +PROBLEMS_DIR = ROOT_DIR + "_problems" +LIST_DIR = ROOT_DIR + "pages/lists" + + +def main(): + + print('> generating solved modified page') + + os.chdir( PROBLEMS_DIR ) + + ll_result = os.popen('ls -lt --time-style=long-iso').read() + ll_result = ll_result.split('\n') + ll_result = filter(None, ll_result) # remove empty element + + # got list of filenames/dates + list_filenames_dates = [] + for line in ll_result: + filename, last_modified = line[47:], line[30:40] + list_filenames_dates.append( (filename, last_modified) ) + + + # generate markdown list content + sb = """ +--- +layout: page +title: Solved - Last Modified +--- + """.strip() + "\n\n\n" + + sb += "There are %s problems solved.\n\n" % len(list_filenames_dates) + + # generate table header + sb += "Problem | Last Modified | Status | Category \n" + sb += "--------|---------------|--------|----------\n" + + # generate table rows + for prob in list_filenames_dates: + filename = prob[0] + + if filename and filename!="1template.md": + sb += "[%s](%s) | %s | %s | %s \n" % \ + (getAttribute(filename, "title"), \ + "/problems/"+filename[:-3], \ + prob[1], \ + getAttribute(filename, "status"), \ + getAttribute(filename, "category") \ + ) + + + # write to solved list markdown page + FileUtil.saveToFile(sb, LIST_DIR + "/solvedLastModified.md") + + + +def getAttribute(filename, attribute): + content = FileUtil.readFromFile( PROBLEMS_DIR + "/" + filename ) + attributeLen = len(attribute)+1 + + lines = content.split('\n') + filterObject = list(filter( lambda x: attribute + ": " in x, lines )) + + if filterObject: + lineWithAttribute = filterObject[0] + return lineWithAttribute[attributeLen:].strip() + else: + return "" + + + +if __name__ == '__main__': + + main() \ No newline at end of file