├── .babelrc
├── .eslintrc
├── .gitignore
├── .npmignore
├── .prettierrc
├── README.md
├── cover.jpg
├── package.json
├── src
├── algo
│ ├── bfs
│ │ └── level-order-traversal.js
│ ├── binary-search
│ │ ├── v1
│ │ │ ├── README.md
│ │ │ ├── binary-search.js
│ │ │ ├── binary-search.spec.js
│ │ │ ├── ceil.js
│ │ │ ├── ceil.spec.js
│ │ │ ├── docs
│ │ │ │ └── lower-bound-upper-bound.png
│ │ │ ├── floor.js
│ │ │ ├── floor.spec.js
│ │ │ ├── lower-bound.js
│ │ │ ├── lower-bound.spec.js
│ │ │ ├── upper-bound.js
│ │ │ └── upper-bound.spec.js
│ │ └── v2
│ │ │ ├── index.js
│ │ │ └── index.spec.js
│ ├── gcd
│ │ └── index.js
│ ├── graph
│ │ └── articulation-point
│ │ │ ├── articulation-point.pdf
│ │ │ └── index.js
│ ├── heap
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── merge-sort
│ │ ├── index.js
│ │ ├── index.spec.js
│ │ └── v1.js
│ ├── numbers
│ │ ├── README.md
│ │ ├── to-binary.js
│ │ ├── to-binary.spec.js
│ │ ├── to-hex.js
│ │ └── to-hex.spec.js
│ ├── quick-select
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── quick-sort
│ │ ├── index.js
│ │ ├── index.spec.js
│ │ └── v1.js
│ └── topological-sort
│ │ ├── index.js
│ │ └── index.spec.js
├── data-structure
│ ├── binary-indexed-tree-2d
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── binary-indexed-tree
│ │ ├── Binary Indexed Tree.pdf
│ │ ├── README.md
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── bst
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── priority-queue
│ │ ├── v1
│ │ │ ├── __tests__
│ │ │ │ └── index.js
│ │ │ ├── bubbleDown.js
│ │ │ ├── bubbleUp.js
│ │ │ ├── defaultComparator.js
│ │ │ ├── index.js
│ │ │ └── swap.js
│ │ ├── v2
│ │ │ └── index.js
│ │ ├── v3
│ │ │ ├── index.js
│ │ │ └── index.spec.js
│ │ └── v4
│ │ │ ├── index.js
│ │ │ └── index.spec.js
│ ├── sorted-map
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── trie
│ │ ├── index.js
│ │ └── index.spec.js
│ └── union-find
│ │ ├── index.js
│ │ └── index.spec.js
├── interviews
│ └── facebook
│ │ └── 2020-03-20
│ │ └── index.js
├── leetcode
│ ├── 01-matrix
│ │ └── index.js
│ ├── 24-game
│ │ └── index.js
│ ├── 3sum-closest
│ │ ├── index.js
│ │ └── no-sorting.js
│ ├── 3sum-smaller
│ │ └── index.js
│ ├── 3sum-with-multiplicity
│ │ └── index.js
│ ├── 3sum
│ │ ├── hash.js
│ │ └── index.js
│ ├── 4-keys-keyboard
│ │ ├── README.md
│ │ └── index.js
│ ├── 4sum-ii
│ │ └── index.js
│ ├── 4sum
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── README.md
│ ├── accounts-merge
│ │ ├── 721. Accounts Merge.pdf
│ │ ├── index.error.js
│ │ └── index.js
│ ├── add-and-search-word-data-structure-design
│ │ ├── Add and Search Word - Data structure design.pdf
│ │ └── index.js
│ ├── add-binary
│ │ └── index.js
│ ├── add-bold-tag-in-string
│ │ └── index.js
│ ├── add-digits
│ │ └── index.js
│ ├── add-strings
│ │ └── index.js
│ ├── add-two-numbers-ii
│ │ └── index.js
│ ├── add-two-numbers
│ │ ├── 2. Add Two Numbers.pdf
│ │ └── index.js
│ ├── adding-two-negabinary-numbers
│ │ ├── 1073. Adding Two Negabinary Numbers 2019-08-04.pdf
│ │ ├── README.md
│ │ └── index.js
│ ├── alien-dictionary
│ │ ├── 2019-02-17.js
│ │ ├── Alien Dictionary.pdf
│ │ ├── README.md
│ │ └── index.js
│ ├── all-nodes-distance-k-in-binary-tree
│ │ ├── bfs.js
│ │ └── index.js
│ ├── all-oone-data-structure
│ │ ├── IMG_3581.JPG
│ │ ├── README.md
│ │ └── index.js
│ ├── all-paths-from-source-lead-to-destination
│ │ └── index.js
│ ├── all-paths-from-source-to-target
│ │ └── index.js
│ ├── all-possible-full-binary-trees
│ │ ├── dp.js
│ │ └── index.js
│ ├── alphabet-board-path
│ │ └── index.js
│ ├── as-far-from-land-as-possible
│ │ ├── README.md
│ │ └── index.js
│ ├── average-of-levels-in-binary-tree
│ │ └── index.js
│ ├── backspace-string-compare
│ │ └── index.js
│ ├── balance-a-binary-search-tree
│ │ └── index.js
│ ├── balanced-binary-tree
│ │ └── index.js
│ ├── basic-calculator-ii
│ │ ├── 227. Basic Calculator II.pdf
│ │ └── index.js
│ ├── basic-calculator-iii
│ │ ├── index.js
│ │ └── submit.png
│ ├── basic-calculator
│ │ ├── README.md
│ │ └── index.js
│ ├── battleships-in-a-board
│ │ └── index.js
│ ├── best-meeting-point
│ │ └── index.js
│ ├── best-time-to-buy-and-sell-stock-ii
│ │ └── index.js
│ ├── best-time-to-buy-and-sell-stock-iii
│ │ ├── 123. Best Time to Buy and Sell Stock III.pdf
│ │ ├── 2019-11-14-v2.js
│ │ ├── 2019-11-14-v3.js
│ │ ├── 2019-11-14.js
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── k.js
│ │ ├── left-right.js
│ │ └── space-O(m).js
│ ├── best-time-to-buy-and-sell-stock-iv
│ │ ├── 188. Best Time to Buy and Sell Stock IV.pdf
│ │ ├── README.md
│ │ └── index.js
│ ├── best-time-to-buy-and-sell-stock-with-cooldown
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── time-n.js
│ │ └── time-n2.js
│ ├── best-time-to-buy-and-sell-stock
│ │ └── index.js
│ ├── binary-search-tree-iterator
│ │ └── index.js
│ ├── binary-search
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── binary-subarrays-with-sum
│ │ └── index.js
│ ├── binary-tree-coloring-game
│ │ └── index.js
│ ├── binary-tree-inorder-traversal
│ │ └── index.js
│ ├── binary-tree-level-order-traversal-ii
│ │ ├── Binary Tree Level Order Traversal II.pdf
│ │ └── index.js
│ ├── binary-tree-level-order-traversal
│ │ └── index.js
│ ├── binary-tree-longest-consecutive-sequence-ii
│ │ ├── index.js
│ │ └── submit.png
│ ├── binary-tree-longest-consecutive-sequence
│ │ └── index.js
│ ├── binary-tree-maximum-path-sum
│ │ ├── 124. Binary Tree Maximum Path Sum.pdf
│ │ ├── README.md
│ │ └── index.js
│ ├── binary-tree-paths
│ │ └── index.js
│ ├── binary-tree-postorder-traversal
│ │ └── index.js
│ ├── binary-tree-preorder-traversal
│ │ └── index.js
│ ├── binary-tree-right-side-view
│ │ └── index.js
│ ├── binary-tree-upside-down
│ │ └── index.js
│ ├── binary-tree-vertical-order-traversal
│ │ └── index.js
│ ├── binary-tree-zigzag-level-order-traversal
│ │ └── index.js
│ ├── bomb-enemy
│ │ ├── index.js
│ │ └── v1.js
│ ├── boundary-of-binary-tree
│ │ └── index.js
│ ├── brace-expansion-ii
│ │ ├── README.md
│ │ └── index.js
│ ├── brace-expansion
│ │ ├── README.md
│ │ └── index.js
│ ├── bulb-switcher-ii
│ │ └── index.js
│ ├── bulb-switcher
│ │ └── index.js
│ ├── bulls-and-cows
│ │ └── index.js
│ ├── bus-routes
│ │ ├── README.md
│ │ └── index.js
│ ├── campus-bikes-ii
│ │ ├── README.md
│ │ ├── index.js
│ │ └── submit.png
│ ├── campus-bikes
│ │ └── index.js
│ ├── can-make-palindrome-from-substring
│ │ └── index.js
│ ├── candy
│ │ └── index.js
│ ├── capacity-to-ship-packages-within-d-days
│ │ ├── README.md
│ │ └── index.js
│ ├── car-pooling
│ │ └── index.js
│ ├── cells-with-odd-values-in-a-matrix
│ │ └── index.js
│ ├── cheapest-flights-within-k-stops
│ │ ├── README.md
│ │ └── index.js
│ ├── check-completeness-of-a-binary-tree
│ │ ├── README.md
│ │ └── index.js
│ ├── check-if-it-is-a-good-array
│ │ ├── README.md
│ │ └── index.js
│ ├── check-if-it-is-a-straight-line
│ │ └── index.js
│ ├── check-if-n-and-its-double-exist
│ │ └── index.js
│ ├── cherry-pickup
│ │ ├── README.md
│ │ └── index.js
│ ├── circular-permutation-in-binary-representation
│ │ └── index.js
│ ├── climbing-stairs
│ │ └── index.js
│ ├── clone-graph
│ │ └── index.js
│ ├── closest-binary-search-tree-value-ii
│ │ ├── 272. Closest Binary Search Tree Value II.pdf
│ │ └── index.js
│ ├── closest-binary-search-tree-value
│ │ └── index.js
│ ├── closest-divisors
│ │ └── index.js
│ ├── coin-change-2
│ │ ├── 518. Coin Change 2.pdf
│ │ └── index.js
│ ├── coin-change
│ │ ├── README.md
│ │ └── index.js
│ ├── combination-sum-ii
│ │ └── index.js
│ ├── combination-sum-iii
│ │ └── index.js
│ ├── combination-sum
│ │ └── index.js
│ ├── combinations
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── compare-strings-by-frequency-of-the-smallest-character
│ │ └── index.js
│ ├── compare-version-numbers
│ │ └── index.js
│ ├── concatenated-words
│ │ └── index.js
│ ├── confusing-number
│ │ └── index.js
│ ├── connecting-cities-with-minimum-cost
│ │ ├── README.md
│ │ └── index.js
│ ├── construct-binary-search-tree-from-preorder-traversal
│ │ └── index.js
│ ├── construct-binary-tree-from-inorder-and-postorder-traversal
│ │ └── index.js
│ ├── construct-binary-tree-from-preorder-and-inorder-traversal
│ │ └── index.js
│ ├── construct-binary-tree-from-preorder-and-postorder-traversal
│ │ ├── README.md
│ │ ├── index.js
│ │ └── submit.png
│ ├── construct-binary-tree-from-string
│ │ └── index.js
│ ├── construct-quad-tree
│ │ └── index.js
│ ├── construct-string-from-binary-tree
│ │ └── index.js
│ ├── container-with-most-water
│ │ ├── 11. Container With Most Water.pdf
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── contains-duplicate
│ │ └── index.js
│ ├── contiguous-array
│ │ └── index.js
│ ├── continuous-subarray-sum
│ │ ├── README.md
│ │ ├── index.js
│ │ └── note.pdf
│ ├── convert-a-number-to-hexadecimal
│ │ ├── README.md
│ │ └── index.js
│ ├── convert-binary-number-in-a-linked-list-to-integer
│ │ └── index.js
│ ├── convert-binary-search-tree-to-sorted-doubly-linked-list
│ │ └── index.js
│ ├── convert-sorted-array-to-binary-search-tree
│ │ └── index.js
│ ├── convert-sorted-list-to-binary-search-tree
│ │ └── index.js
│ ├── convert-to-base-2
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── to base -2.pdf
│ │ ├── to base -8.pdf
│ │ └── what happens to 9 >> 1.pdf
│ ├── copy-list-with-random-pointer
│ │ ├── 138. Copy List with Random Pointer.pdf
│ │ └── index.js
│ ├── count-and-say
│ │ └── index.js
│ ├── count-complete-tree-nodes
│ │ └── index.js
│ ├── count-negative-numbers-in-a-sorted-matrix
│ │ └── index.js
│ ├── count-number-of-nice-subarrays
│ │ └── index.js
│ ├── count-of-range-sum
│ │ ├── README.md
│ │ └── index.js
│ ├── count-of-smaller-numbers-after-self
│ │ └── binary-search.js
│ ├── count-primes
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── count-servers-that-communicate
│ │ └── index.js
│ ├── count-square-submatrices-with-all-ones
│ │ ├── README.md
│ │ └── index.js
│ ├── course-schedule-ii
│ │ └── index.js
│ ├── course-schedule-iii
│ │ └── index.js
│ ├── course-schedule
│ │ ├── README.md
│ │ └── index.js
│ ├── cracking-the-safe
│ │ └── index.js
│ ├── critical-connections-in-a-network
│ │ ├── 1192. Critical Connections in a Network.pdf
│ │ ├── README.md
│ │ ├── index.js
│ │ └── v1.js
│ ├── custom-sort-string
│ │ └── index.js
│ ├── cut-off-trees-for-golf-event
│ │ ├── README.md
│ │ └── index.js
│ ├── daily-temperatures
│ │ └── index.js
│ ├── data-stream-as-disjoint-intervals
│ │ └── index.js
│ ├── decode-string
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── recursive.js
│ │ └── stack.js
│ ├── decode-ways-ii
│ │ └── index.js
│ ├── decode-ways
│ │ ├── Decode ways.pdf
│ │ ├── README.md
│ │ └── index.js
│ ├── decrypt-string-from-alphabet-to-integer-mapping
│ │ └── index.js
│ ├── defanging-an-ip-address
│ │ └── index.js
│ ├── delete-and-earn
│ │ ├── README.md
│ │ └── index.js
│ ├── delete-leaves-with-a-given-value
│ │ └── index.js
│ ├── delete-node-in-a-bst
│ │ └── index.js
│ ├── delete-nodes-and-return-forest
│ │ └── index.js
│ ├── delete-operation-for-two-strings
│ │ ├── README.md
│ │ └── index.js
│ ├── design-a-leaderboard
│ │ ├── README.md
│ │ └── index.js
│ ├── design-add-and-search-words-data-structure
│ │ └── index.js
│ ├── design-circular-deque
│ │ └── index.js
│ ├── design-circular-queue
│ │ └── index.js
│ ├── design-hashmap
│ │ └── index.js
│ ├── design-hit-counter
│ │ └── index.js
│ ├── design-linked-list
│ │ └── inedx.js
│ ├── design-search-autocomplete-system
│ │ ├── README.md
│ │ ├── index.js
│ │ └── trie.js
│ ├── design-tic-tac-toe
│ │ └── index.js
│ ├── design-twitter
│ │ └── index.js
│ ├── diagonal-traverse
│ │ ├── 498. Diagonal Traverse.pdf
│ │ └── index.js
│ ├── diameter-of-binary-tree
│ │ └── index.js
│ ├── diet-plan-performance
│ │ └── index.js
│ ├── different-ways-to-add-parentheses
│ │ └── index.js
│ ├── distance-between-bus-stops
│ │ └── index.js
│ ├── distinct-subsequences
│ │ └── index.js
│ ├── distribute-coins-in-binary-tree
│ │ ├── README.md
│ │ └── index.js
│ ├── divide-array-in-sets-of-k-consecutive-numbers
│ │ └── index.js
│ ├── divide-two-integers
│ │ ├── 29. Divide Two Integers.pdf
│ │ ├── index.js
│ │ ├── index.spec.js
│ │ └── screencapture-leetcode-submissions-detail-179251987-2018-09-29-20_31_17.png
│ ├── dot-product-of-two-sparse-vectors
│ │ └── index.js
│ ├── duplicate-zeros
│ │ ├── index.js
│ │ └── v2.js
│ ├── edit-distance
│ │ ├── README.md
│ │ ├── index.js
│ │ └── v1.js
│ ├── employee-free-time
│ │ └── index.js
│ ├── encode-and-decode-strings
│ │ └── index.js
│ ├── encode-and-decode-tinyurl
│ │ └── index.js
│ ├── equal-tree-partition
│ │ └── index.js
│ ├── evaluate-division
│ │ ├── README.md
│ │ └── index.js
│ ├── evaluate-reverse-polish-notation
│ │ └── index.js
│ ├── exam-room
│ │ └── index.js
│ ├── excel-sheet-column-number
│ │ └── index.js
│ ├── excel-sheet-column-title
│ │ ├── README.md
│ │ └── index.js
│ ├── exclusive-time-of-functions
│ │ ├── 636. Exclusive Time of Functions.pdf
│ │ └── index.js
│ ├── expression-add-operators
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── v1.js
│ │ └── v2.js
│ ├── expressive-words
│ │ └── index.js
│ ├── factor-combinations
│ │ └── index.js
│ ├── falling-squares
│ │ └── index.js
│ ├── fibonacci-number
│ │ └── index.js
│ ├── find-all-anagrams-in-a-string
│ │ ├── index.js
│ │ └── index.tle.js
│ ├── find-all-duplicates-in-an-array
│ │ └── index.js
│ ├── find-and-replace-in-string
│ │ └── index.js
│ ├── find-bottom-left-tree-value
│ │ └── index.js
│ ├── find-duplicate-subtrees
│ │ └── index.js
│ ├── find-first-and-last-position-of-element-in-sorted-array
│ │ └── index.js
│ ├── find-in-mountain-array
│ │ └── index.js
│ ├── find-k-closest-elements
│ │ ├── README.md
│ │ └── index.js
│ ├── find-k-length-substrings-with-no-repeated-characters
│ │ └── index.js
│ ├── find-k-pairs-with-smallest-sums
│ │ ├── README.md
│ │ └── index.js
│ ├── find-k-th-smallest-pair-distance
│ │ └── index.js
│ ├── find-largest-value-in-each-tree-row
│ │ └── index.js
│ ├── find-leaves-of-binary-tree
│ │ ├── README.md
│ │ └── index.js
│ ├── find-median-from-data-stream
│ │ ├── 295. Find Median from Data Stream 2.pdf
│ │ ├── 295. Find Median from Data Stream.pdf
│ │ └── index.js
│ ├── find-minimum-in-rotated-sorted-array-ii
│ │ ├── README.md
│ │ └── index.js
│ ├── find-minimum-in-rotated-sorted-array
│ │ ├── README.md
│ │ └── index.js
│ ├── find-peak-element
│ │ ├── README.md
│ │ └── index.js
│ ├── find-pivot-index
│ │ └── index.js
│ ├── find-right-interval
│ │ └── index.js
│ ├── find-smallest-common-element-in-all-rows
│ │ └── index.js
│ ├── find-the-celebrity
│ │ └── index.js
│ ├── find-the-closest-palindrome
│ │ ├── README.md
│ │ └── index.js
│ ├── find-the-duplicate-number
│ │ └── index.js
│ ├── find-the-shortest-superstring
│ │ ├── README.md
│ │ ├── index.js
│ │ └── tle.js
│ ├── find-the-smallest-divisor-given-a-threshold
│ │ └── index.js
│ ├── find-words-that-can-be-formed-by-characters
│ │ └── index.js
│ ├── first-bad-version
│ │ ├── 278. First Bad Version.pdf
│ │ └── index.js
│ ├── first-missing-positive
│ │ └── index.js
│ ├── first-unique-character-in-a-string
│ │ └── index.js
│ ├── fixed-point
│ │ └── index.js
│ ├── flatten-2d-vector
│ │ └── index.js
│ ├── flatten-a-multilevel-doubly-linked-list
│ │ ├── index.js
│ │ └── recursive.js
│ ├── flatten-binary-tree-to-linked-list
│ │ ├── index.js
│ │ └── v1.js
│ ├── flatten-nested-list-iterator
│ │ └── index.js
│ ├── flip-equivalent-binary-trees
│ │ └── index.js
│ ├── flood-fill
│ │ └── index.js
│ ├── four-divisors
│ │ └── index.js
│ ├── fraction-to-recurring-decimal
│ │ ├── README.md
│ │ ├── index.js
│ │ └── submit.png
│ ├── friend-circles
│ │ └── index.js
│ ├── friends-of-appropriate-ages
│ │ ├── README.md
│ │ └── index.js
│ ├── fruit-into-baskets
│ │ └── index.js
│ ├── game-of-life
│ │ └── index.js
│ ├── gas-station
│ │ └── index.js
│ ├── generalized-abbreviation
│ │ └── index.js
│ ├── generate-parentheses
│ │ ├── README.md
│ │ └── index.js
│ ├── get-equal-substrings-within-budget
│ │ └── index.js
│ ├── get-watched-videos-by-your-friends
│ │ └── index.js
│ ├── goat-latin
│ │ ├── Goat Latin.pdf
│ │ └── index.js
│ ├── graph-valid-tree
│ │ ├── README.md
│ │ └── index.js
│ ├── gray-code
│ │ ├── README.md
│ │ └── idnex.js
│ ├── greatest-common-divisor-of-strings
│ │ └── index.js
│ ├── greatest-sum-divisible-by-three
│ │ ├── README.md
│ │ └── index.js
│ ├── group-anagrams
│ │ └── index.js
│ ├── group-shifted-strings
│ │ └── index.js
│ ├── group-the-people-given-the-group-size-they-belong-to
│ │ └── index.js
│ ├── guess-the-word
│ │ └── index.js
│ ├── h-index-ii
│ │ └── index.js
│ ├── h-index
│ │ └── index.js
│ ├── hamming-distance
│ │ └── index.js
│ ├── happy-number
│ │ ├── README.md
│ │ └── index.js
│ ├── high-five
│ │ └── index.js
│ ├── house-robber-ii
│ │ └── index.js
│ ├── house-robber-iii
│ │ ├── FireShot_Capture_2_-__1__House_Robber_III_-_Su__-_https___leetcode_com_submissions_detail_174593214_.png
│ │ └── index.js
│ ├── house-robber
│ │ └── index.js
│ ├── how-many-numbers-are-smaller-than-the-current-number
│ │ └── index.js
│ ├── image-overlap
│ │ └── index.js
│ ├── implement-magic-dictionary
│ │ ├── README.md
│ │ └── index.js
│ ├── implement-strstr
│ │ ├── index.js
│ │ └── kmp.js
│ ├── implement-trie-prefix-tree
│ │ └── index.js
│ ├── increasing-subsequences
│ │ ├── index.js
│ │ └── submit.png
│ ├── increasing-triplet-subsequence
│ │ ├── README.md
│ │ └── index.js
│ ├── inorder-successor-in-bst-ii
│ │ └── index.js
│ ├── inorder-successor-in-bst
│ │ └── index.js
│ ├── insert-delete-getrandom-o1-duplicates-allowed
│ │ ├── 381. Insert Delete GetRandom O(1) - Duplicates allowed.pdf
│ │ └── index.js
│ ├── insert-delete-getrandom-o1
│ │ └── index.js
│ ├── insert-interval
│ │ ├── 57. Insert Interval.pdf
│ │ └── index.js
│ ├── insert-into-a-binary-search-tree
│ │ └── index.js
│ ├── insert-into-a-cyclic-sorted-list
│ │ ├── README.md
│ │ └── index.js
│ ├── insertion-sort-list
│ │ ├── 147. Insertion Sort List.pdf
│ │ └── index.js
│ ├── insufficient-nodes-in-root-to-leaf-paths
│ │ └── index.js
│ ├── integer-to-english-words
│ │ ├── index.js
│ │ ├── index.spec.js
│ │ ├── v2.js
│ │ └── v3.js
│ ├── integer-to-roman
│ │ ├── README.md
│ │ └── index.js
│ ├── interleaving-string
│ │ ├── README.md
│ │ └── index.js
│ ├── intersection-of-three-sorted-arrays
│ │ └── index.js
│ ├── intersection-of-two-arrays-ii
│ │ └── index.js
│ ├── intersection-of-two-arrays
│ │ └── index.js
│ ├── intersection-of-two-linked-lists
│ │ └── index.js
│ ├── interval-list-intersections
│ │ └── index.js
│ ├── invert-binary-tree
│ │ └── index.js
│ ├── is-graph-bipartite
│ │ ├── Is graph bipartite.pdf
│ │ └── index.js
│ ├── is-subsequence
│ │ ├── index.js
│ │ ├── recursive.js
│ │ └── two-ptrs.js
│ ├── island-perimeter
│ │ └── index.js
│ ├── isomorphic-strings
│ │ └── index.js
│ ├── jewels-and-stones
│ │ └── index.js
│ ├── jump-game-ii
│ │ ├── 45. Jump Game II.pdf
│ │ └── index.js
│ ├── jump-game-iii
│ │ └── index.js
│ ├── jump-game-v
│ │ └── index.js
│ ├── jump-game
│ │ ├── 55. Jump Game.pdf
│ │ └── index.js
│ ├── k-closest-points-to-origin
│ │ ├── 973. K Closest Points to Origin.pdf
│ │ ├── index.js
│ │ ├── recursive.js
│ │ └── topk.pdf
│ ├── k-concatenation-maximum-sum
│ │ └── index.js
│ ├── knight-dialer
│ │ ├── README.md
│ │ └── index.js
│ ├── knight-probability-in-chessboard
│ │ ├── README.md
│ │ └── index.js
│ ├── koko-eating-bananas
│ │ └── index.js
│ ├── kth-largest-element-in-a-stream
│ │ ├── index.bst.js
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── kth-largest-element-in-an-array
│ │ ├── README.md
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── kth-smallest-element-in-a-bst
│ │ └── index.js
│ ├── kth-smallest-element-in-a-sorted-matrix
│ │ ├── 378. Kth Smallest Element in a Sorted Matrix.pdf
│ │ └── index.js
│ ├── kth-smallest-number-in-multiplication-table
│ │ └── index.js
│ ├── largest-divisible-subset
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── largest-plus-sign
│ │ └── index.js
│ ├── largest-rectangle-in-histogram
│ │ ├── Largest Rectangle in Histogram 3.pdf
│ │ └── index.js
│ ├── last-substring-in-lexicographical-order
│ │ └── index.js
│ ├── leftmost-column-with-at-least-a-one
│ │ ├── binary-search.js
│ │ └── index.js
│ ├── length-of-last-word
│ │ └── index.js
│ ├── length-of-longest-fibonacci-subsequence
│ │ └── index.js
│ ├── letter-combinations-of-a-phone-number
│ │ └── index.js
│ ├── license-key-formatting
│ │ └── index.js
│ ├── linked-list-components
│ │ └── index.js
│ ├── linked-list-cycle-ii
│ │ └── index.js
│ ├── linked-list-cycle
│ │ └── index.js
│ ├── linked-list-in-binary-tree
│ │ └── index.js
│ ├── linked-list-random-node
│ │ └── index.js
│ ├── logger-rate-limiter
│ │ └── index.js
│ ├── lonely-pixel-i
│ │ └── index.js
│ ├── longest-absolute-file-path
│ │ ├── README.md
│ │ └── index.js
│ ├── longest-arithmetic-sequence
│ │ ├── README.md
│ │ └── index.js
│ ├── longest-common-prefix
│ │ └── index.js
│ ├── longest-common-subsequence
│ │ ├── README.md
│ │ └── index.js
│ ├── longest-consecutive-sequence
│ │ └── index.js
│ ├── longest-continuous-increasing-subsequence
│ │ └── index.js
│ ├── longest-duplicate-substring
│ │ └── index.js
│ ├── longest-increasing-path-in-a-matrix
│ │ └── index.js
│ ├── longest-increasing-subsequence
│ │ └── index.js
│ ├── longest-line-of-consecutive-one-in-matrix
│ │ └── index.js
│ ├── longest-mountain-in-array
│ │ └── index.js
│ ├── longest-palindrome
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── longest-palindromic-subsequence
│ │ ├── README.md
│ │ └── index.js
│ ├── longest-palindromic-substring
│ │ ├── README.md
│ │ ├── dp.js
│ │ └── index.js
│ ├── longest-repeating-character-replacement
│ │ ├── README.md
│ │ └── index.js
│ ├── longest-string-chain
│ │ ├── README.md
│ │ ├── index.js
│ │ └── v1.js
│ ├── longest-substring-with-at-least-k-repeating-characters
│ │ └── index.js
│ ├── longest-substring-with-at-most-k-distinct-characters
│ │ └── index.js
│ ├── longest-substring-with-at-most-two-distinct-characters
│ │ └── index.js
│ ├── longest-substring-without-repeating-characters
│ │ └── index.js
│ ├── longest-valid-parentheses
│ │ ├── 32. Longest Valid Parentheses.pdf
│ │ └── index.js
│ ├── longest-word-in-dictionary-through-deleting
│ │ └── index.js
│ ├── lowest-common-ancestor-of-a-binary-search-tree
│ │ └── index.js
│ ├── lowest-common-ancestor-of-a-binary-tree-iii
│ │ └── index.js
│ ├── lowest-common-ancestor-of-a-binary-tree
│ │ └── index.js
│ ├── lowest-common-ancestor-of-deepest-leaves
│ │ └── index.js
│ ├── lru-cache
│ │ ├── index.js
│ │ └── map.js
│ ├── lucky-numbers-in-a-matrix
│ │ └── index.js
│ ├── majority-element-ii
│ │ └── index.js
│ ├── majority-element
│ │ ├── bit.js
│ │ ├── index.js
│ │ └── v1.js
│ ├── making-a-large-island
│ │ └── index.js
│ ├── max-area-of-island
│ │ └── index.js
│ ├── max-chunks-to-make-sorted
│ │ └── index.js
│ ├── max-consecutive-ones-ii
│ │ ├── README.md
│ │ └── index.js
│ ├── max-consecutive-ones-iii
│ │ ├── dp.js
│ │ └── index.js
│ ├── max-consecutive-ones
│ │ └── index.js
│ ├── max-increase-to-keep-city-skyline
│ │ └── index.js
│ ├── max-points-on-a-line
│ │ ├── README.md
│ │ ├── index.js
│ │ └── submit.png
│ ├── max-stack
│ │ └── index.js
│ ├── max-sum-of-rectangle-no-larger-than-k
│ │ ├── README.md
│ │ └── index.js
│ ├── maximal-rectangle
│ │ └── index.js
│ ├── maximal-square
│ │ ├── README.md
│ │ └── index.js
│ ├── maximize-distance-to-closest-person
│ │ └── index.js
│ ├── maximum-69-number
│ │ └── index.js
│ ├── maximum-binary-tree
│ │ └── index.js
│ ├── maximum-depth-of-binary-tree
│ │ └── index.js
│ ├── maximum-difference-between-node-and-ancestor
│ │ └── index.js
│ ├── maximum-frequency-stack
│ │ └── index.js
│ ├── maximum-length-of-a-concatenated-string-with-unique-characters
│ │ ├── README.md
│ │ └── index.js
│ ├── maximum-length-of-repeated-subarray
│ │ ├── README.md
│ │ └── index.js
│ ├── maximum-level-sum-of-a-binary-tree
│ │ └── index.js
│ ├── maximum-number-of-balloons
│ │ └── index.js
│ ├── maximum-number-of-events-that-can-be-attended
│ │ └── index.js
│ ├── maximum-performance-of-a-team
│ │ ├── README.md
│ │ └── index.js
│ ├── maximum-product-of-splitted-binary-tree
│ │ └── index.js
│ ├── maximum-product-of-three-numbers
│ │ └── index.js
│ ├── maximum-product-subarray
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── maximum-side-length-of-a-square-with-sum-less-than-or-equal-to-threshold
│ │ ├── README.md
│ │ └── index.js
│ ├── maximum-size-subarray-sum-equals-k
│ │ └── index.js
│ ├── maximum-students-taking-exam
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── v1.js
│ │ ├── v2.js
│ │ └── v3.js
│ ├── maximum-subarray-sum-with-one-deletion
│ │ ├── 1186. Maximum Subarray Sum with One Deletion.pdf
│ │ ├── README.md
│ │ └── index.js
│ ├── maximum-subarray
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── maximum-sum-circular-subarray
│ │ ├── 918. Maximum Sum Circular Subarray.pdf
│ │ └── index.js
│ ├── maximum-sum-of-3-non-overlapping-subarrays
│ │ ├── 689. Maximum Sum of 3 Non-Overlapping Subarrays.pdf
│ │ ├── README.md
│ │ └── index.js
│ ├── maximum-sum-of-two-non-overlapping-subarrays
│ │ └── index.js
│ ├── maximum-swap
│ │ ├── README.md
│ │ └── index.js
│ ├── maximum-vacation-days
│ │ ├── README.md
│ │ ├── index.js
│ │ └── v1.js
│ ├── maximum-width-of-binary-tree
│ │ └── index.js
│ ├── median-of-two-sorted-arrays
│ │ ├── IMG_1777.JPG
│ │ ├── index.js
│ │ └── readme.md
│ ├── meeting-rooms-ii
│ │ └── index.js
│ ├── meeting-rooms
│ │ └── index.js
│ ├── meeting-scheduler
│ │ └── index.js
│ ├── merge-intervals
│ │ └── index.js
│ ├── merge-k-sorted-lists
│ │ ├── index.js
│ │ └── screencapture-leetcode-submissions-detail-191108256-2018-11-23-01_51_44.png
│ ├── merge-sorted-array
│ │ └── index.js
│ ├── merge-two-binary-trees
│ │ └── index.js
│ ├── merge-two-sorted-lists
│ │ └── index.js
│ ├── min-cost-climbing-stairs
│ │ └── index.js
│ ├── min-stack
│ │ └── index.js
│ ├── minesweeper
│ │ └── index.js
│ ├── minimize-malware-spread
│ │ ├── 924. Minimize Malware Spread.pdf
│ │ └── index.js
│ ├── minimize-max-distance-to-gas-station
│ │ ├── README.md
│ │ └── index.js
│ ├── minimum-add-to-make-parentheses-valid
│ │ └── index.js
│ ├── minimum-area-rectangle
│ │ ├── README.md
│ │ └── index.js
│ ├── minimum-cost-for-tickets
│ │ ├── README.md
│ │ ├── index.js
│ │ └── v1.js
│ ├── minimum-cost-to-connect-sticks
│ │ ├── index.js
│ │ └── priority-queue.js
│ ├── minimum-cost-to-make-at-least-one-valid-path-in-a-grid
│ │ └── index.js
│ ├── minimum-cost-tree-from-leaf-values
│ │ └── index.js
│ ├── minimum-depth-of-binary-tree
│ │ └── index.js
│ ├── minimum-domino-rotations-for-equal-row
│ │ ├── README.md
│ │ └── index.js
│ ├── minimum-falling-path-sum
│ │ ├── README.md
│ │ └── index.js
│ ├── minimum-height-trees
│ │ ├── README.md
│ │ ├── dfs-tls.js
│ │ └── index.js
│ ├── minimum-insertion-steps-to-make-a-string-palindrome
│ │ ├── README.md
│ │ └── index.js
│ ├── minimum-knight-moves
│ │ ├── README.md
│ │ └── index.js
│ ├── minimum-number-of-arrows-to-burst-balloons
│ │ └── index.js
│ ├── minimum-number-of-flips-to-convert-binary-matrix-to-zero-matrix
│ │ ├── bit.js
│ │ └── index.js
│ ├── minimum-number-of-refueling-stops
│ │ ├── README.md
│ │ ├── index.js
│ │ └── recursive.js
│ ├── minimum-number-of-steps-to-make-two-strings-anagram
│ │ └── index.js
│ ├── minimum-number-of-taps-to-open-to-water-a-garden
│ │ └── index.js
│ ├── minimum-path-sum
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── minimum-remove-to-make-valid-parentheses
│ │ └── index.js
│ ├── minimum-size-subarray-sum
│ │ └── index.js
│ ├── minimum-swaps-to-make-sequences-increasing
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── space-2.js
│ │ └── space-2n.js
│ ├── minimum-time-visiting-all-points
│ │ └── index.js
│ ├── minimum-window-subsequence
│ │ ├── 727. Minimum Window Subsequence.pdf
│ │ ├── README.md
│ │ └── index.js
│ ├── minimum-window-substring
│ │ ├── README.md
│ │ └── index.js
│ ├── missing-element-in-sorted-array
│ │ ├── README.md
│ │ └── index.js
│ ├── missing-number-in-arithmetic-progression
│ │ └── index.js
│ ├── missing-number
│ │ └── index.js
│ ├── missing-ranges
│ │ └── index.js
│ ├── monotonic-array
│ │ └── index.js
│ ├── most-common-word
│ │ └── index.js
│ ├── most-frequent-subtree-sum
│ │ └── index.js
│ ├── most-stones-removed-with-same-row-or-column
│ │ ├── 947. Most Stones Removed with Same Row or Column.pdf
│ │ └── index.js
│ ├── move-zeroes
│ │ └── index.js
│ ├── moving-average-from-data-stream
│ │ └── index.js
│ ├── multiply-strings
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── my-calendar-i
│ │ ├── README.md
│ │ └── index.js
│ ├── my-calendar-ii
│ │ ├── index.js
│ │ ├── v2.js
│ │ └── wrong-answer.js
│ ├── n-queens-ii
│ │ └── index.js
│ ├── n-queens
│ │ ├── N-Queens.pdf
│ │ └── index.js
│ ├── nested-list-weight-sum-ii
│ │ └── index.js
│ ├── nested-list-weight-sum
│ │ └── index.js
│ ├── network-delay-time
│ │ └── index.js
│ ├── new-21-game
│ │ └── index.js
│ ├── next-closest-time
│ │ └── index.js
│ ├── next-greater-element-i
│ │ ├── 496. Next Greater Element I.pdf
│ │ └── index.js
│ ├── next-greater-element-ii
│ │ └── index.js
│ ├── next-greater-node-in-linked-list
│ │ ├── README.md
│ │ └── index.js
│ ├── next-permutation
│ │ ├── Next Permutation.pdf
│ │ └── index.js
│ ├── non-overlapping-intervals
│ │ ├── README.md
│ │ └── index.js
│ ├── number-of-burgers-with-no-waste-of-ingredients
│ │ ├── README.md
│ │ └── index.js
│ ├── number-of-closed-islands
│ │ └── index.js
│ ├── number-of-connected-components-in-an-undirected-graph
│ │ ├── index.js
│ │ └── union-find.js
│ ├── number-of-days-between-two-dates
│ │ └── index.js
│ ├── number-of-distinct-islands-ii
│ │ ├── README.md
│ │ └── index.js
│ ├── number-of-distinct-islands
│ │ └── index.js
│ ├── number-of-islands-ii
│ │ ├── index.js
│ │ └── submit.png
│ ├── number-of-islands
│ │ └── index.js
│ ├── number-of-longest-increasing-subsequence
│ │ ├── README.md
│ │ └── index.js
│ ├── number-of-matching-subsequences
│ │ └── index.js
│ ├── number-of-operations-to-make-network-connected
│ │ ├── README.md
│ │ └── index.js
│ ├── number-of-subarrays-with-bounded-maximum
│ │ ├── README.md
│ │ └── index.js
│ ├── number-of-submatrices-that-sum-to-target
│ │ ├── README.md
│ │ ├── index.js
│ │ └── space-n**2.js
│ ├── number-of-valid-subarrays
│ │ └── index.js
│ ├── number-of-ways-to-stay-in-the-same-place-after-some-steps
│ │ ├── README.md
│ │ ├── dp-space-n2.js
│ │ └── index.js
│ ├── odd-even-linked-list
│ │ └── index.js
│ ├── one-edit-distance
│ │ ├── README.md
│ │ └── index.js
│ ├── online-election
│ │ └── index.js
│ ├── open-the-lock
│ │ ├── README.md
│ │ ├── bfs.js
│ │ └── index.js
│ ├── optimal-account-balancing
│ │ ├── README.md
│ │ ├── index.js
│ │ └── v1.js
│ ├── pacific-atlantic-water-flow
│ │ └── index.js
│ ├── paint-fence
│ │ └── index.js
│ ├── paint-house-ii
│ │ └── index.js
│ ├── paint-house
│ │ └── index.js
│ ├── palindrome-linked-list
│ │ ├── README.md
│ │ └── index.js
│ ├── palindrome-number
│ │ ├── 9. Palindrome Number.pdf
│ │ └── index.js
│ ├── palindrome-pairs
│ │ ├── README.md
│ │ ├── index.js
│ │ └── tle.js
│ ├── palindrome-partitioning-ii
│ │ └── index.js
│ ├── palindrome-partitioning-iii
│ │ ├── README.md
│ │ └── index.js
│ ├── palindrome-partitioning
│ │ └── index.js
│ ├── palindrome-permutation-ii
│ │ └── index.js
│ ├── palindrome-permutation
│ │ └── index.js
│ ├── palindromic-substrings
│ │ └── index.js
│ ├── pancake-sorting
│ │ ├── README.md
│ │ └── index.js
│ ├── partition-array-into-disjoint-intervals
│ │ ├── index.js
│ │ └── v1.js
│ ├── partition-equal-subset-sum
│ │ ├── README.md
│ │ ├── dp-v1.js
│ │ ├── dp.js
│ │ └── index.js
│ ├── partition-labels
│ │ └── index.js
│ ├── partition-list
│ │ └── index.js
│ ├── partition-to-k-equal-sum-subsets
│ │ └── index.js
│ ├── pascals-triangle-ii
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── pascals-triangle
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── path-sum-ii
│ │ └── index.js
│ ├── path-sum-iii
│ │ └── index.js
│ ├── path-sum-iv
│ │ └── index.js
│ ├── path-sum
│ │ └── index.js
│ ├── path-with-maximum-gold
│ │ └── index.js
│ ├── path-with-maximum-minimum-value
│ │ ├── README.md
│ │ └── index.js
│ ├── peak-index-in-a-mountain-array
│ │ └── index.js
│ ├── perfect-squares
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── permutation-in-string
│ │ └── index.js
│ ├── permutation-sequence
│ │ └── index.js
│ ├── permutations-ii
│ │ └── index.js
│ ├── permutations
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── plus-one-linked-list
│ │ └── idnex.js
│ ├── plus-one
│ │ └── index.js
│ ├── populating-next-right-pointers-in-each-node-ii
│ │ ├── 117. Populating Next Right Pointers in Each Node II.pdf
│ │ └── index.js
│ ├── populating-next-right-pointers-in-each-node
│ │ ├── 116. Populating Next Right Pointers in Each Node.pdf
│ │ └── index.js
│ ├── power-of-two
│ │ └── index.js
│ ├── powerful-integers
│ │ └── index.js
│ ├── powx-n
│ │ ├── 50. Pow(x, n).pdf
│ │ ├── index.js
│ │ └── recursive.js
│ ├── predict-the-winner
│ │ ├── READMD.md
│ │ └── index.js
│ ├── print-binary-tree
│ │ └── index.js
│ ├── print-words-vertically
│ │ └── index.js
│ ├── prison-cells-after-n-days
│ │ └── index.js
│ ├── product-of-array-except-self
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── product-of-the-last-k-numbers
│ │ └── index.js
│ ├── queens-that-can-attack-the-king
│ │ ├── README.md
│ │ └── index.js
│ ├── random-pick-index
│ │ ├── README.md
│ │ ├── index.js
│ │ └── reservoir_sampling.png
│ ├── random-pick-with-blacklist
│ │ └── index.js
│ ├── random-pick-with-weight
│ │ ├── README.md
│ │ └── index.js
│ ├── range-sum-of-bst
│ │ └── index.js
│ ├── range-sum-query-2d-immutable
│ │ ├── 304. Range Sum Query 2D - Immutable.pdf
│ │ └── index.js
│ ├── range-sum-query-2d-mutable
│ │ ├── README.md
│ │ ├── index.js
│ │ └── v1.js
│ ├── range-sum-query-immutable
│ │ └── index.js
│ ├── range-sum-query-mutable
│ │ ├── index.js
│ │ └── segment-tree.js
│ ├── rank-teams-by-votes
│ │ └── index.js
│ ├── reaching-points
│ │ ├── 780. Reaching Points.pdf
│ │ └── index.js
│ ├── read-n-characters-given-read4-ii-call-multiple-times
│ │ └── index.js
│ ├── read-n-characters-given-read4
│ │ └── index.js
│ ├── rearrange-string-k-distance-apart
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── reconstruct-a-2-row-binary-matrix
│ │ └── index.js
│ ├── reconstruct-itinerary
│ │ ├── 332. Reconstruct Itinerary.pdf
│ │ └── index.js
│ ├── recover-a-tree-from-preorder-traversal
│ │ └── index.js
│ ├── recover-binary-search-tree
│ │ └── index.js
│ ├── rectangle-area-ii
│ │ ├── bfs.js
│ │ ├── index.js
│ │ └── v1.js
│ ├── rectangle-area
│ │ └── index.js
│ ├── rectangle-overlap
│ │ └── index.js
│ ├── reduce-array-size-to-the-half
│ │ └── index.js
│ ├── redundant-connection
│ │ └── index.js
│ ├── regular-expression-matching
│ │ ├── 10. Regular Expression Matching.pdf
│ │ ├── README.md
│ │ ├── RECURSIVE.md
│ │ ├── constant-space.js
│ │ ├── dp-2d.js
│ │ ├── index.js
│ │ └── recursive.js
│ ├── remove-all-adjacent-duplicates-in-string-ii
│ │ └── index.js
│ ├── remove-duplicates-from-sorted-array-ii
│ │ └── index.js
│ ├── remove-duplicates-from-sorted-array
│ │ └── index.js
│ ├── remove-duplicates-from-sorted-list-ii
│ │ └── index.js
│ ├── remove-duplicates-from-sorted-list
│ │ └── index.js
│ ├── remove-element
│ │ └── index.js
│ ├── remove-interval
│ │ └── index.js
│ ├── remove-invalid-parentheses
│ │ ├── README.md
│ │ ├── bfs.js
│ │ └── index.js
│ ├── remove-linked-list-elements
│ │ ├── index.js
│ │ ├── recursive.js
│ │ └── screencapture-leetcode-submissions-detail-192938904-2018-12-02-23_17_08.png
│ ├── remove-nth-node-from-end-of-list
│ │ └── index.js
│ ├── remove-outermost-parentheses
│ │ └── index.js
│ ├── remove-sub-folders-from-the-filesystem
│ │ └── index.js
│ ├── reorder-data-in-log-files
│ │ └── index.js
│ ├── reorder-list
│ │ └── index.js
│ ├── reorganize-string
│ │ └── index.js
│ ├── repeated-substring-pattern
│ │ └── index.js
│ ├── replace-words
│ │ └── index.js
│ ├── restore-ip-addresses
│ │ ├── 93. Restore IP Addresses.pdf
│ │ └── index.js
│ ├── reverse-integer
│ │ └── index.js
│ ├── reverse-linked-list-ii
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── submission-screenshot.png
│ │ └── v2.js
│ ├── reverse-linked-list
│ │ ├── iterative.js
│ │ └── recursive.js
│ ├── reverse-nodes-in-k-group
│ │ ├── index.js
│ │ └── screencapture-leetcode-submissions-detail-192938162-2018-12-02-23_09_39.png
│ ├── reverse-only-letters
│ │ └── index.js
│ ├── reverse-string
│ │ └── index.js
│ ├── reverse-substrings-between-each-pair-of-parentheses
│ │ └── index.js
│ ├── reverse-vowels-of-a-string
│ │ └── index.js
│ ├── reverse-words-in-a-string-ii
│ │ └── index.js
│ ├── reverse-words-in-a-string-iii
│ │ └── index.js
│ ├── reverse-words-in-a-string
│ │ └── index.js
│ ├── robot-room-cleaner
│ │ ├── 489. Robot Room Cleaner.pdf
│ │ └── index.js
│ ├── roman-to-integer
│ │ └── index.js
│ ├── rotate-array
│ │ └── index.js
│ ├── rotate-image
│ │ └── index.js
│ ├── rotate-list
│ │ ├── 61. Rotate List.pdf
│ │ └── index.js
│ ├── rotated-digits
│ │ └── index.js
│ ├── rotting-oranges
│ │ └── index.js
│ ├── russian-doll-envelopes
│ │ ├── README.md
│ │ └── index.js
│ ├── scramble-string
│ │ └── index.js
│ ├── search-a-2d-matrix-ii
│ │ ├── 240. Search a 2D Matrix II.pdf
│ │ └── index.js
│ ├── search-a-2d-matrix
│ │ └── index.js
│ ├── search-in-rotated-sorted-array-ii
│ │ ├── 81. Search in Rotated Sorted Array II.pdf
│ │ ├── README.md
│ │ └── index.js
│ ├── search-in-rotated-sorted-array
│ │ ├── 33. Search in Rotated Sorted Array.pdf
│ │ ├── README.md
│ │ └── index.js
│ ├── search-insert-position
│ │ └── index.js
│ ├── search-suggestions-system
│ │ └── index.js
│ ├── second-minimum-node-in-a-binary-tree
│ │ └── index.js
│ ├── sentence-similarity-ii
│ │ └── index.js
│ ├── sentence-similarity
│ │ └── index.js
│ ├── sequence-reconstruction
│ │ ├── README.md
│ │ └── index.js
│ ├── sequential-digits
│ │ ├── README.md
│ │ └── index.js
│ ├── serialize-and-deserialize-binary-tree
│ │ ├── bfs.js
│ │ ├── dfs.js
│ │ └── index.js
│ ├── serialize-and-deserialize-bst
│ │ ├── README.md
│ │ └── index.js
│ ├── serialize-and-deserialize-n-ary-tree
│ │ └── index.js
│ ├── set-matrix-zeroes
│ │ ├── 73. Set Matrix Zeroes.pdf
│ │ └── index.js
│ ├── shortest-distance-from-all-buildings
│ │ ├── index.js
│ │ └── v1.js
│ ├── shortest-distance-to-a-character
│ │ └── index.js
│ ├── shortest-palindrome
│ │ ├── README.md
│ │ └── index.js
│ ├── shortest-path-in-a-grid-with-obstacles-elimination
│ │ └── index.js
│ ├── shortest-path-in-binary-matrix
│ │ ├── index.js
│ │ └── v1.js
│ ├── shortest-path-to-get-all-keys
│ │ ├── README.md
│ │ └── index.js
│ ├── shortest-path-visiting-all-nodes
│ │ ├── README.md
│ │ ├── index.js
│ │ └── tle.js
│ ├── shortest-subarray-with-sum-at-least-k
│ │ ├── README.md
│ │ ├── algo.jpg
│ │ └── index.js
│ ├── shortest-way-to-form-string
│ │ ├── README.md
│ │ ├── binary-search.js
│ │ ├── brute-force.js
│ │ └── inedx.js
│ ├── shortest-word-distance-ii
│ │ └── index.js
│ ├── shortest-word-distance
│ │ └── index.js
│ ├── simplify-path
│ │ ├── 71. Simplify Path.pdf
│ │ └── index.js
│ ├── single-element-in-a-sorted-array
│ │ ├── README.md
│ │ ├── index.js
│ │ └── submit.png
│ ├── single-number-ii
│ │ └── index.js
│ ├── single-number-iii
│ │ ├── 260. Single Number III.pdf
│ │ └── index.js
│ ├── single-number
│ │ └── index.js
│ ├── sliding-puzzle
│ │ ├── README.md
│ │ └── index.js
│ ├── sliding-window-maximum
│ │ └── index.js
│ ├── sliding-window-median
│ │ └── index.js
│ ├── smallest-common-region
│ │ ├── 1257. Smallest Common Region.pdf
│ │ ├── README.md
│ │ ├── index.js
│ │ └── v1.js
│ ├── smallest-range-covering-elements-from-k-lists
│ │ ├── README.md
│ │ ├── index.js
│ │ └── iterator-priority-queue-and-sliding-window.js
│ ├── smallest-range-i
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── smallest-range
│ │ ├── index.js
│ │ └── sliding-window.js
│ ├── smallest-string-with-swaps
│ │ ├── README.md
│ │ └── index.js
│ ├── smallest-subtree-with-all-the-deepest-nodes
│ │ └── index.js
│ ├── snapshot-array
│ │ ├── README.md
│ │ └── index.js
│ ├── sort-array-by-parity-ii
│ │ └── index.js
│ ├── sort-array-by-parity
│ │ └── index.js
│ ├── sort-characters-by-frequency
│ │ └── index.js
│ ├── sort-colors
│ │ └── index.js
│ ├── sort-items-by-groups-respecting-dependencies
│ │ └── index.js
│ ├── sort-list
│ │ └── index.js
│ ├── sparse-matrix-multiplication
│ │ └── index.js
│ ├── spiral-matrix-ii
│ │ └── index.js
│ ├── spiral-matrix-iii
│ │ └── index.js
│ ├── spiral-matrix
│ │ ├── 54. Spiral Matrix.pdf
│ │ └── index.js
│ ├── split-array-into-consecutive-subsequences
│ │ ├── README.md
│ │ └── index.js
│ ├── split-array-into-fibonacci-sequence
│ │ └── index.js
│ ├── split-array-largest-sum
│ │ ├── README.md
│ │ ├── dp-space-n.js
│ │ ├── dp.js
│ │ └── index.js
│ ├── split-array-with-equal-sum
│ │ ├── README.md
│ │ ├── dfs-lte.js
│ │ └── index.js
│ ├── split-array-with-same-average
│ │ ├── README.md
│ │ ├── dfs.js
│ │ ├── index.js
│ │ └── n**2.js
│ ├── split-bst
│ │ └── index.js
│ ├── sqrtx
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── squares-of-a-sorted-array
│ │ └── index.js
│ ├── statistics-from-a-large-sample
│ │ └── index.js
│ ├── stepping-numbers
│ │ └── index.js
│ ├── stickers-to-spell-word
│ │ ├── index.js
│ │ └── submit.png
│ ├── stream-of-characters
│ │ ├── README.md
│ │ └── index.js
│ ├── string-to-integer-atoi
│ │ └── index.js
│ ├── string-transforms-into-another-string
│ │ ├── README.md
│ │ └── index.js
│ ├── strobogrammatic-number-ii
│ │ ├── index.js
│ │ └── index.mle.js
│ ├── strobogrammatic-number-iii
│ │ └── index.js
│ ├── strobogrammatic-number
│ │ └── index.js
│ ├── student-attendance-record-i
│ │ └── index.js
│ ├── student-attendance-record-ii
│ │ ├── README.md
│ │ ├── dfs.js
│ │ ├── dp-n**2.js
│ │ └── index.js
│ ├── subarray-product-less-than-k
│ │ ├── README.md
│ │ └── index.js
│ ├── subarray-sum-equals-k
│ │ └── index.js
│ ├── subarray-sums-divisible-by-k
│ │ ├── README.md
│ │ └── index.js
│ ├── subarrays-with-k-different-integers
│ │ └── index.js
│ ├── subdomain-visit-count
│ │ └── index.js
│ ├── subsets-ii
│ │ └── index.js
│ ├── subsets
│ │ └── index.js
│ ├── substring-with-concatenation-of-all-words
│ │ ├── index.js
│ │ └── tle.js
│ ├── subtract-the-product-and-sum-of-digits-of-an-integer
│ │ └── index.js
│ ├── subtree-of-another-tree
│ │ └── index.js
│ ├── sudoku-solver
│ │ └── index.js
│ ├── sum-of-distances-in-tree
│ │ ├── 834. Sum of Distances in Tree.pdf
│ │ └── index.js
│ ├── sum-of-left-leaves
│ │ └── index.js
│ ├── sum-of-subarray-minimums
│ │ └── index.js
│ ├── sum-root-to-leaf-numbers
│ │ └── index.js
│ ├── summary-ranges
│ │ └── index.js
│ ├── surrounded-regions
│ │ └── index.js
│ ├── swap-nodes-in-pairs
│ │ └── index.js
│ ├── swim-in-rising-water
│ │ ├── README.md
│ │ └── index.js
│ ├── symmetric-tree
│ │ └── index.js
│ ├── tag-validator
│ │ └── index.js
│ ├── target-sum
│ │ ├── index.js
│ │ ├── recursive.js
│ │ └── v1.js
│ ├── task-scheduler
│ │ └── index.js
│ ├── text-justification
│ │ └── index.js
│ ├── the-k-weakest-rows-in-a-matrix
│ │ └── index.js
│ ├── the-maze-ii
│ │ └── index.js
│ ├── the-maze-iii
│ │ ├── index.js
│ │ └── submit.png
│ ├── the-maze
│ │ └── index.js
│ ├── the-skyline-problem
│ │ ├── index.js
│ │ └── readme.md
│ ├── third-maximum-number
│ │ └── index.js
│ ├── tiling-a-rectangle-with-the-fewest-squares
│ │ ├── README.md
│ │ └── index.js
│ ├── time-based-key-value-store
│ │ └── index.js
│ ├── toeplitz-matrix
│ │ └── index.js
│ ├── top-k-frequent-elements
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── top-k-frequent-words
│ │ ├── README.md
│ │ ├── index.js
│ │ └── quick-select.js
│ ├── toss-strange-coins
│ │ ├── README.md
│ │ ├── index.js
│ │ └── space-n**2.js
│ ├── total-hamming-distance
│ │ ├── 477. Total Hamming Distance.pdf
│ │ └── index.js
│ ├── trapping-rain-water-ii
│ │ ├── index.js
│ │ └── index.wrong-answer.js
│ ├── trapping-rain-water
│ │ ├── dp.js
│ │ └── index.js
│ ├── tree-diameter
│ │ ├── README.md
│ │ └── index.js
│ ├── triangle
│ │ └── index.js
│ ├── tweet-counts-per-frequency
│ │ ├── README.md
│ │ └── index.js
│ ├── two-sum-bsts
│ │ └── index.js
│ ├── two-sum-ii-input-array-is-sorted
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── two-sum-iii-data-structure-design
│ │ └── index.js
│ ├── two-sum-iv-input-is-a-bst
│ │ └── index.js
│ ├── two-sum-less-than-k
│ │ └── index.js
│ ├── two-sum
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── ugly-number-ii
│ │ └── index.js
│ ├── ugly-number
│ │ └── index.js
│ ├── unique-binary-search-trees-ii
│ │ └── index.js
│ ├── unique-binary-search-trees
│ │ └── index.js
│ ├── unique-email-addresses
│ │ └── index.js
│ ├── unique-morse-code-words
│ │ └── index.js
│ ├── unique-number-of-occurrences
│ │ └── index.js
│ ├── unique-paths-ii
│ │ └── index.js
│ ├── unique-paths-iii
│ │ └── index.js
│ ├── unique-paths
│ │ └── index.js
│ ├── utf-8-validation
│ │ └── index.js
│ ├── valid-anagram
│ │ └── index.js
│ ├── valid-mountain-array
│ │ └── index.js
│ ├── valid-number
│ │ └── index.js
│ ├── valid-palindrome-ii
│ │ └── index.js
│ ├── valid-palindrome-iii
│ │ └── index.js
│ ├── valid-palindrome
│ │ └── index.js
│ ├── valid-parentheses
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── valid-parenthesis-string
│ │ ├── README.md
│ │ └── index.js
│ ├── valid-square
│ │ └── index.js
│ ├── valid-sudoku
│ │ ├── 36. Valid Sudoku.pdf
│ │ └── index.js
│ ├── valid-tic-tac-toe-state
│ │ └── index.js
│ ├── valid-word-abbreviation
│ │ └── index.js
│ ├── validate-binary-search-tree
│ │ ├── index.js
│ │ └── recursive.js
│ ├── validate-binary-tree-nodes
│ │ └── index.js
│ ├── validate-ip-address
│ │ ├── Validate IP address.pdf
│ │ └── index.js
│ ├── verify-preorder-sequence-in-binary-search-tree
│ │ └── index.js
│ ├── verifying-an-alien-dictionary
│ │ ├── README.md
│ │ └── index.js
│ ├── vertical-order-traversal-of-a-binary-tree
│ │ └── index.js
│ ├── video-stitching
│ │ ├── README.md
│ │ └── index.js
│ ├── walls-and-gates
│ │ └── index.js
│ ├── water-and-jug-problem
│ │ └── index.js
│ ├── wildcard-matching
│ │ ├── README.md
│ │ ├── dp.js
│ │ ├── index.js
│ │ └── screenshot.png
│ ├── word-break-ii
│ │ ├── README.md
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── word-break
│ │ ├── README.md
│ │ ├── index.js
│ │ ├── index.spec.js
│ │ └── screencapture-leetcode-submissions-detail-179481115-2018-09-30-19_28_02.png
│ ├── word-ladder-ii
│ │ └── index.js
│ ├── word-ladder
│ │ └── index.js
│ ├── word-pattern-ii
│ │ └── index.js
│ ├── word-pattern
│ │ └── index.js
│ ├── word-search-ii
│ │ └── index.js
│ ├── word-search
│ │ ├── dfs-extra-spaces.js
│ │ └── index.js
│ ├── xor-queries-of-a-subarray
│ │ └── index.js
│ └── zigzag-conversion
│ │ ├── ZigZag Conversion2.pdf
│ │ └── index.js
├── notes
│ ├── README.md
│ └── assets
│ │ ├── boxmodel.gif
│ │ ├── constructor-proto-chain.png
│ │ ├── event-propagation.svg
│ │ ├── lower-bound-upper-bound.png
│ │ └── speed-metrics.png
├── practices
│ ├── 2018-11-24
│ │ └── quick-sort
│ │ │ ├── index.js
│ │ │ └── index.spec.js
│ ├── 2018-12-03
│ │ └── priority-queue
│ │ │ ├── index.js
│ │ │ └── index.spec.js
│ ├── 2019-03-25
│ │ └── bst
│ │ │ ├── index.js
│ │ │ └── index.spec.js
│ ├── 2019-06-18
│ │ └── quick-sort
│ │ │ ├── index.js
│ │ │ └── index.spec.js
│ ├── 2019-08-05
│ │ ├── merge-sort
│ │ │ └── index.js
│ │ └── quick-sort
│ │ │ └── index.js
│ ├── 2019-11-06
│ │ └── bst
│ │ │ └── index.js
│ ├── Uber-or-Phone-Screen-or-Wildcard-Pattern-Matching
│ │ ├── README.md
│ │ └── index.js
│ ├── add-hexadecimal
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── all-possible-full-binary-trees-with-n-leaves
│ │ ├── README.md
│ │ └── index.js
│ ├── count-integer-partitions
│ │ ├── README.md
│ │ ├── index.js
│ │ └── slow.js
│ ├── count-number-of-squares-in-the-matrix
│ │ ├── README.md
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── deep-filter
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── design-spreadsheet-with-adjustable-height-and-find-row
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── exclude-items
│ │ ├── exclude items.pdf
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── get-dot-product
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── loading-bar
│ │ ├── README.md
│ │ ├── index.css
│ │ ├── index.html
│ │ ├── index.js
│ │ └── screenshot.gif
│ ├── movies-on-flight
│ │ └── index.js
│ ├── number-of-ways-staying-at-zero
│ │ ├── Number of ways staying at zero.pdf
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── optimal-utilization
│ │ ├── README.md
│ │ └── index.js
│ ├── overlapped-intervals
│ │ ├── README.md
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── permutation-no-3-consecutive-same-color
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── range
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── react-timer
│ │ └── index.js
│ ├── render-template
│ │ ├── index.js
│ │ └── index.spec.js
│ ├── sort-a-with-b
│ │ └── index.js
│ ├── top-n-buzzwords
│ │ └── index.js
│ └── zombies-in-matrix
│ │ └── index.js
├── system-design
│ └── rate-limiter.md
└── utilities
│ ├── bind
│ ├── es5.js
│ ├── es5.spec.js
│ ├── es6.js
│ ├── es6.spec.js
│ ├── index.js
│ └── index.spec.js
│ ├── curried-5-sum
│ ├── index.js
│ └── index.spec.js
│ ├── curry
│ ├── index.js
│ └── index.spec.js
│ ├── curryN
│ ├── index.js
│ └── index.spec.js
│ ├── debounce
│ ├── index.js
│ └── index.spec.js
│ ├── event-emitter
│ ├── index.js
│ └── index.spec.js
│ ├── promisify
│ ├── index.js
│ └── index.spec.js
│ ├── pubsub
│ ├── index.js
│ └── index.spec.js
│ ├── rate-limiter
│ ├── index.js
│ └── index.spec.js
│ ├── reorder-array-with-given-order
│ ├── index.js
│ └── index.spec.js
│ ├── runner
│ ├── index.js
│ └── index.spec.js
│ ├── task-queue
│ ├── es6.js
│ ├── es6.spec.js
│ ├── index.js
│ └── index.spec.js
│ ├── the-promise
│ ├── index.js
│ └── index.spec.js
│ └── throttle
│ ├── index.js
│ └── index.spec.js
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@babel/preset-env"],
3 | "plugins": ["@babel/plugin-proposal-object-rest-spread", "@babel/transform-runtime"]
4 | }
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .env
3 | lib/
4 | *.dat
5 | logs/
6 | ignored-scripts/
7 | tmp/
8 | dist/
9 | .next/
10 | out/
11 | .vscode
12 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .env
3 | src/
4 |
5 | examples
6 | scripts
7 | docs
8 | .babelrc
9 | .eslint*
10 | .idea
11 | .editorconfig
12 | .npmignore
13 | .nyc_output
14 | .travis.yml
15 | webpack.*
16 | coverage
17 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 100,
3 | "semi": true,
4 | "singleQuote": true,
5 | "trailingComma": "all",
6 | "bracketSpacing": true,
7 | "arrowParens": "always"
8 | }
9 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Algorithms
2 |
3 | A study notes and solutions to algorithms using javascript.
4 |
5 | 👉 [Javascript Solutions](src/leetcode/)
6 |
7 |
8 |
--------------------------------------------------------------------------------
/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/cover.jpg
--------------------------------------------------------------------------------
/src/algo/bfs/level-order-traversal.js:
--------------------------------------------------------------------------------
1 | function bfs(root) {
2 | let queue = [root];
3 | while (queue.length) {
4 | const next = [];
5 | while (queue.length) {
6 | // add next level nodes to next queue
7 | }
8 | queue = next;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/algo/binary-search/v1/binary-search.js:
--------------------------------------------------------------------------------
1 | const fn = (arr, target) => {
2 | let left = 0;
3 | let right = arr.length;
4 | while (left < right) {
5 | const mid = Math.floor((left + right) / 2);
6 | if (target === arr[mid]) {
7 | return mid;
8 | } else if (target > arr[mid]) {
9 | left = mid + 1;
10 | } else {
11 | right = mid;
12 | }
13 | }
14 | return -1;
15 | };
16 |
17 | export default fn;
18 |
--------------------------------------------------------------------------------
/src/algo/binary-search/v1/binary-search.spec.js:
--------------------------------------------------------------------------------
1 | import binarySearch from './binary-search';
2 |
3 | test('binarySearch', () => {
4 | expect(binarySearch([1, 2, 3, 4, 5], 3)).toEqual(2);
5 | expect(binarySearch([1, 2, 3, 4, 5], 2)).toEqual(1);
6 | expect(binarySearch([1, 2, 3, 4, 5], 1)).toEqual(0);
7 | expect(binarySearch([1, 2, 3, 4, 5], 5)).toEqual(4);
8 | expect(binarySearch([1, 2, 3, 4, 5], 13)).toEqual(-1);
9 | expect(binarySearch([], 3)).toEqual(-1);
10 | });
11 |
--------------------------------------------------------------------------------
/src/algo/binary-search/v1/ceil.js:
--------------------------------------------------------------------------------
1 | function lowerBound(arr, target) {
2 | let left = 0;
3 | let right = arr.length;
4 | while (left < right) {
5 | const mid = Math.floor((left + right) / 2);
6 | if (target > arr[mid]) {
7 | left = mid + 1;
8 | } else {
9 | right = mid;
10 | }
11 | }
12 | return left;
13 | }
14 |
15 | function ceil(arr, target) {
16 | return lowerBound(arr, target);
17 | }
18 |
19 | export default ceil;
20 |
--------------------------------------------------------------------------------
/src/algo/binary-search/v1/ceil.spec.js:
--------------------------------------------------------------------------------
1 | import ceil from './ceil';
2 |
3 | test('ceil', () => {
4 | expect(ceil([1, 3, 4, 6, 7, 8, 9], 5)).toEqual(3);
5 | expect(ceil([1, 3, 4, 6, 7, 8, 9], 4)).toEqual(2);
6 | });
7 |
--------------------------------------------------------------------------------
/src/algo/binary-search/v1/docs/lower-bound-upper-bound.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/algo/binary-search/v1/docs/lower-bound-upper-bound.png
--------------------------------------------------------------------------------
/src/algo/binary-search/v1/floor.js:
--------------------------------------------------------------------------------
1 | function lowerBound(arr, target) {
2 | let left = 0;
3 | let right = arr.length;
4 | while (left < right) {
5 | const mid = Math.floor((left + right) / 2);
6 | if (target > arr[mid]) {
7 | left = mid + 1;
8 | } else {
9 | right = mid;
10 | }
11 | }
12 | return left;
13 | }
14 |
15 | function floor(arr, target) {
16 | const index = lowerBound(arr, target);
17 | return arr[index] === target ? index : index - 1;
18 | }
19 |
20 | export default floor;
21 |
--------------------------------------------------------------------------------
/src/algo/binary-search/v1/floor.spec.js:
--------------------------------------------------------------------------------
1 | import floor from './floor';
2 |
3 | test('floor', () => {
4 | expect(floor([1, 3, 4, 6, 7, 8, 9], 5)).toEqual(2);
5 | expect(floor([1, 3, 4, 6, 7, 8, 9], 2)).toEqual(0);
6 | expect(floor([1, 3, 4, 6, 7, 8, 9], 3)).toEqual(1);
7 | });
8 |
--------------------------------------------------------------------------------
/src/algo/binary-search/v1/lower-bound.js:
--------------------------------------------------------------------------------
1 | const fn = (arr, target) => {
2 | let left = 0;
3 | let right = arr.length;
4 | while (left < right) {
5 | const mid = Math.floor((left + right) / 2);
6 | if (target > arr[mid]) {
7 | left = mid + 1;
8 | } else {
9 | right = mid;
10 | }
11 | }
12 | return left;
13 | };
14 |
15 | export default fn;
16 |
--------------------------------------------------------------------------------
/src/algo/binary-search/v1/lower-bound.spec.js:
--------------------------------------------------------------------------------
1 | import lowerBound from './lower-bound';
2 |
3 | test('lowerBound', () => {
4 | expect(lowerBound([1, 3, 5, 7, 9], 3)).toEqual(1);
5 | expect(lowerBound([1, 3, 5, 7, 9], 4)).toEqual(2);
6 | expect(lowerBound([], 4)).toEqual(0);
7 | });
8 |
--------------------------------------------------------------------------------
/src/algo/binary-search/v1/upper-bound.js:
--------------------------------------------------------------------------------
1 | const fn = (arr, target) => {
2 | let left = 0;
3 | let right = arr.length;
4 | while (left < right) {
5 | const mid = Math.floor((left + right) / 2);
6 | if (target >= arr[mid]) {
7 | left = mid + 1;
8 | } else {
9 | right = mid;
10 | }
11 | }
12 | return left;
13 | };
14 |
15 | export default fn;
16 |
--------------------------------------------------------------------------------
/src/algo/binary-search/v1/upper-bound.spec.js:
--------------------------------------------------------------------------------
1 | import upperBound from './upper-bound';
2 |
3 | test('upperBound', () => {
4 | expect(upperBound([1, 3, 5, 7, 9], 3)).toEqual(2);
5 | expect(upperBound([1, 3, 5, 7, 9], 4)).toEqual(2);
6 | expect(upperBound([], 4)).toEqual(0);
7 | });
8 |
--------------------------------------------------------------------------------
/src/algo/gcd/index.js:
--------------------------------------------------------------------------------
1 | function gcd(a, b) {
2 | if (b === 0) {
3 | return a;
4 | }
5 | return gcd(b, a % b);
6 | }
7 |
8 | export default gcd;
9 |
--------------------------------------------------------------------------------
/src/algo/graph/articulation-point/articulation-point.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/algo/graph/articulation-point/articulation-point.pdf
--------------------------------------------------------------------------------
/src/algo/merge-sort/index.spec.js:
--------------------------------------------------------------------------------
1 | import sort from './index';
2 |
3 | test('sort', () => {
4 | const data = [1, 3, 6, 6, 2, 5, 8, 0, 5];
5 | const result = sort(data);
6 | const expectedResult = [0, 1, 2, 3, 5, 5, 6, 6, 8];
7 | expect(result).toEqual(expectedResult);
8 | });
9 |
10 | test('sort', () => {
11 | expect(sort([0])).toEqual([0]);
12 | expect(sort([1, 6, 3])).toEqual([1, 3, 6]);
13 | expect(sort([1, 6, 3, 4])).toEqual([1, 3, 4, 6]);
14 | expect(sort([1, 6, 0, 3])).toEqual([0, 1, 3, 6]);
15 | });
16 |
--------------------------------------------------------------------------------
/src/algo/numbers/to-binary.js:
--------------------------------------------------------------------------------
1 | const toBinary = (num, nBits = 32) => {
2 | let output = '';
3 | for (let i = 0; i < nBits; i++) {
4 | output = ((num >> i) & 1) + output;
5 | }
6 | return output;
7 | };
8 |
9 | export default toBinary;
10 |
--------------------------------------------------------------------------------
/src/algo/numbers/to-binary.spec.js:
--------------------------------------------------------------------------------
1 | import toBinary from './to-binary';
2 |
3 | test('to-binary', () => {
4 | expect(toBinary(7, 8)).toEqual('00000111');
5 | expect(toBinary(-1, 8)).toEqual('11111111');
6 | expect(toBinary(-7, 8)).toEqual('11111001');
7 | });
8 |
--------------------------------------------------------------------------------
/src/algo/numbers/to-hex.js:
--------------------------------------------------------------------------------
1 | const fn = (num, nBits = 32) => {
2 | let output = '';
3 | for (let i = 0; i < nBits / 4; i++) {
4 | output = ((num >> (i * 4)) & 15).toString(16) + output;
5 | }
6 | return '0x' + trimZero(output);
7 | };
8 |
9 | function trimZero(str) {
10 | let i = 0;
11 | while (str[i] === '0') {
12 | i += 1;
13 | }
14 | return i < str.length ? str.substring(i) : '0';
15 | }
16 |
17 | export default fn;
18 |
--------------------------------------------------------------------------------
/src/algo/numbers/to-hex.spec.js:
--------------------------------------------------------------------------------
1 | import toHex from './to-hex';
2 |
3 | test('to-hex', () => {
4 | expect(toHex(10)).toEqual('0xa');
5 | expect(toHex(123)).toEqual('0x7b');
6 | expect(toHex(456)).toEqual('0x1c8');
7 | expect(toHex(0)).toEqual('0x0');
8 | });
9 |
--------------------------------------------------------------------------------
/src/algo/quick-select/index.spec.js:
--------------------------------------------------------------------------------
1 | import quickSelect from './index';
2 |
3 | test('quickSelect', () => {
4 | const arr = [3, 5, 9, 10, 100, 50, 6, 5];
5 | expect(quickSelect(arr, 4)).toEqual([3, 5, 5, 6]);
6 | });
7 |
--------------------------------------------------------------------------------
/src/algo/quick-sort/index.spec.js:
--------------------------------------------------------------------------------
1 | import quicksort from './index';
2 |
3 | test('quicksort', () => {
4 | const arr = [1, 3, 4, 2];
5 | const result = quicksort(arr);
6 | expect(result).toEqual([1, 2, 3, 4]);
7 | });
8 |
9 | test('quicksort', () => {
10 | const arr = [1, 3, 4, 2, 5, 9, 7, 5, 8];
11 | const result = quicksort(arr);
12 | expect(result).toEqual([1, 2, 3, 4, 5, 5, 7, 8, 9]);
13 | });
14 |
--------------------------------------------------------------------------------
/src/algo/topological-sort/index.spec.js:
--------------------------------------------------------------------------------
1 | import sort from './index';
2 |
3 | test('topological-sort', () => {
4 | const graph = [[], [], [3], [1], [0, 1], [0, 2]];
5 | console.log(sort(graph));
6 | });
7 |
8 | test('topological-sort', () => {
9 | const graph = [[1], [], [1]];
10 | console.log(sort(graph));
11 | });
12 |
13 | test('topological-sort', () => {
14 | const graph = [[1], [0]];
15 | console.log(sort(graph));
16 | });
17 |
--------------------------------------------------------------------------------
/src/data-structure/binary-indexed-tree/Binary Indexed Tree.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/data-structure/binary-indexed-tree/Binary Indexed Tree.pdf
--------------------------------------------------------------------------------
/src/data-structure/binary-indexed-tree/README.md:
--------------------------------------------------------------------------------
1 | # Binary Indexed Tree
2 |
3 | ## References
4 |
5 | - (https://blog.csdn.net/Yaokai_AssultMaster/article/details/79492190)[https://blog.csdn.net/Yaokai_AssultMaster/article/details/79492190]
6 | - (https://www.geeksforgeeks.org/binary-indexed-tree-or-fenwick-tree-2/)[https://www.geeksforgeeks.org/binary-indexed-tree-or-fenwick-tree-2/]
7 |
--------------------------------------------------------------------------------
/src/data-structure/binary-indexed-tree/index.spec.js:
--------------------------------------------------------------------------------
1 | import BinaryIndexedTree from './index';
2 |
3 | test('BinaryIndexedTree', () => {
4 | const arr = [2, 1, 1, 3, 2, 3, 4, 5, 6, 7, 8, 9];
5 | const bit = new BinaryIndexedTree(arr);
6 | expect(bit.getSum(6)).toEqual(arr.slice(0, 6 + 1).reduce((acc, cur) => acc + cur, 0));
7 | expect(bit.getSum(3)).toEqual(arr.slice(0, 3 + 1).reduce((acc, cur) => acc + cur, 0));
8 | expect(bit.getSum(9)).toEqual(arr.slice(0, 9 + 1).reduce((acc, cur) => acc + cur, 0));
9 | });
10 |
--------------------------------------------------------------------------------
/src/data-structure/bst/index.spec.js:
--------------------------------------------------------------------------------
1 | import createBST, { insert, inOrder } from './index';
2 |
3 | test('bst', () => {
4 | const data = [3, 2, 1, 3, 4, 5, 6];
5 | const bst = createBST();
6 | const result = data.reduce((acc, i) => bst.insert(i), bst).inOrder();
7 | expect(result).toEqual([1, 2, 3, 3, 4, 5, 6]);
8 | const result2 = bst
9 | .remove(1)
10 | .remove(2)
11 | .remove(3)
12 | .remove(3)
13 | .inOrder();
14 | expect(result2).toEqual([4, 5, 6]);
15 | });
16 |
--------------------------------------------------------------------------------
/src/data-structure/priority-queue/v1/__tests__/index.js:
--------------------------------------------------------------------------------
1 | import PriorityQueue from '../index';
2 |
3 | test('PriorityQueue', () => {
4 | const queue = new PriorityQueue();
5 | queue
6 | .enqueue(2, 2)
7 | .enqueue(1, 1)
8 | .enqueue(3, 3)
9 | .enqueue(4, 4)
10 | .enqueue(0, 0);
11 | expect([...queue]).toEqual([0, 1, 2, 3, 4]);
12 | });
13 |
--------------------------------------------------------------------------------
/src/data-structure/priority-queue/v1/bubbleDown.js:
--------------------------------------------------------------------------------
1 | import swap from './swap';
2 |
3 | const fn = (arr, i, comparator) => {
4 | const left = 2 * i + 1;
5 | const right = 2 * i + 2;
6 | const isValid =
7 | (left >= arr.length || comparator(arr[i], arr[left]) <= 0) &&
8 | (right >= arr.length || comparator(arr[i], arr[right]) <= 0);
9 | if (!isValid) {
10 | const next = right >= arr.length || comparator(arr[left], arr[right]) <= 0 ? left : right;
11 | swap(arr, i, next);
12 | fn(arr, next, comparator);
13 | }
14 | };
15 |
16 | export default fn;
17 |
--------------------------------------------------------------------------------
/src/data-structure/priority-queue/v1/bubbleUp.js:
--------------------------------------------------------------------------------
1 | import swap from './swap';
2 |
3 | const fn = (arr, i, comparator) => {
4 | if (i <= 0) {
5 | return;
6 | }
7 | const p = Math.floor((i - 1) / 2);
8 | const isValid = comparator(arr[p], arr[i]) <= 0;
9 | if (!isValid) {
10 | swap(arr, i, p);
11 | fn(arr, p, comparator);
12 | }
13 | };
14 |
15 | export default fn;
16 |
--------------------------------------------------------------------------------
/src/data-structure/priority-queue/v1/defaultComparator.js:
--------------------------------------------------------------------------------
1 | const fn = (a, b) => a.priority - b.priority;
2 |
3 | export default fn;
4 |
--------------------------------------------------------------------------------
/src/data-structure/priority-queue/v1/swap.js:
--------------------------------------------------------------------------------
1 | const fn = (arr, i, j) => {
2 | const tmp = arr[i];
3 | arr[i] = arr[j];
4 | arr[j] = tmp;
5 | };
6 |
7 | export default fn;
8 |
--------------------------------------------------------------------------------
/src/data-structure/priority-queue/v3/index.spec.js:
--------------------------------------------------------------------------------
1 | import PriorityQueue from './index';
2 |
3 | test('PriorityQueue', () => {
4 | const pq = new PriorityQueue({
5 | comparator: (a, b) => a <= b,
6 | isEqual: (a, b) => a === b,
7 | });
8 | const data = [16, 49, 62, 58, 14, 72458777923, 3, 4, 1, 2];
9 | data.forEach((el) => pq.enqueue(el));
10 | const result = [];
11 | while (pq.length) {
12 | result.push(pq.dequeue());
13 | }
14 | const expectedResult = [1, 2, 3, 4, 14, 16, 49, 58, 62, 72458777923];
15 | expect(result).toEqual(expectedResult);
16 | });
17 |
--------------------------------------------------------------------------------
/src/data-structure/sorted-map/index.spec.js:
--------------------------------------------------------------------------------
1 | import SortedMap from './index';
2 |
3 | test('SortedMap', () => {
4 | const map = new SortedMap();
5 | expect(map.get('k1')).toEqual(null);
6 | map.set('k1', 'v1');
7 | expect(map.get('k1')).toEqual('v1');
8 | map.set('k3', 'v3');
9 | map.set('k2', 'v2');
10 | expect(map.keys()).toEqual(['k1', 'k2', 'k3']);
11 | });
12 |
--------------------------------------------------------------------------------
/src/data-structure/trie/index.spec.js:
--------------------------------------------------------------------------------
1 | import Trie from './index';
2 |
3 | test('Trie', () => {
4 | const trie = new Trie();
5 | const data = ['app', 'apple', 'applepen'];
6 | data.map((word) => trie.add(word));
7 | expect(trie.dfs()).toEqual(data);
8 | expect(trie.startsWith('app')).toEqual(true);
9 | expect(trie.startsWith('appl')).toEqual(true);
10 | expect(trie.startsWith('apple')).toEqual(true);
11 | expect(trie.search('appl')).toEqual(false);
12 | expect(trie.search('applepen')).toEqual(true);
13 | });
14 |
--------------------------------------------------------------------------------
/src/data-structure/union-find/index.spec.js:
--------------------------------------------------------------------------------
1 | import DisjointSet from './index';
2 |
3 | test('DisjointSet', () => {
4 | const set = new DisjointSet(6);
5 | set.union(0, 5);
6 | set.union(1, 2);
7 | set.union(3, 4);
8 | set.union(1, 4);
9 | expect(set.find(0)).toEqual(set.find(5));
10 | expect(set.find(1)).toEqual(set.find(2));
11 | expect(set.find(2)).toEqual(set.find(3));
12 | expect(set.find(3)).toEqual(set.find(4));
13 | });
14 |
--------------------------------------------------------------------------------
/src/leetcode/3sum-with-multiplicity/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} A
3 | * @param {number} target
4 | * @return {number}
5 | */
6 | var threeSumMulti = function(A, target) {
7 | // number of combinations of 2 numbers of certain sum
8 | const counts = {};
9 | let n = 0;
10 | for (let i = 0; i < A.length; i++) {
11 | n += counts[target - A[i]] || 0;
12 | for (let j = 0; j < i; j++) {
13 | const sum = A[i] + A[j];
14 | counts[sum] = (counts[sum] || 0) + 1;
15 | }
16 | }
17 | return n % (10 ** 9 + 7);
18 | };
19 |
--------------------------------------------------------------------------------
/src/leetcode/4-keys-keyboard/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} N
3 | * @return {number}
4 | */
5 |
6 | var maxA = function(N) {
7 | const dp = [...new Array(N + 1)].map((_, i) => i);
8 | for (let i = 4; i <= N; i++) {
9 | for (let j = 1; j <= i - 3; j++) {
10 | dp[i] = Math.max(dp[i], dp[j] * (i - j - 1));
11 | }
12 | }
13 | return dp[N];
14 | };
15 |
--------------------------------------------------------------------------------
/src/leetcode/4sum/index.spec.js:
--------------------------------------------------------------------------------
1 | import fn from './index';
2 |
3 | test('4sum', () => {
4 | expect(fn([-4, -4, -1, -1, -1, -1, 0, 0, 0, 1, 2, 2, 2], 0)).toEqual([
5 | [-4, 0, 2, 2],
6 | [-1, -1, 0, 2],
7 | [-1, 0, 0, 1],
8 | ]);
9 | });
10 |
--------------------------------------------------------------------------------
/src/leetcode/accounts-merge/721. Accounts Merge.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/accounts-merge/721. Accounts Merge.pdf
--------------------------------------------------------------------------------
/src/leetcode/add-and-search-word-data-structure-design/Add and Search Word - Data structure design.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/add-and-search-word-data-structure-design/Add and Search Word - Data structure design.pdf
--------------------------------------------------------------------------------
/src/leetcode/add-binary/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} a
3 | * @param {string} b
4 | * @return {string}
5 | */
6 | var addBinary = function(a, b) {
7 | let i = a.length - 1;
8 | let j = b.length - 1;
9 | let c = 0;
10 | let output = '';
11 | while (i >= 0 || j >= 0 || c > 0) {
12 | const sum = parseInt(a[i] || '0') + parseInt(b[j] || '0') + c;
13 | output = (sum % 2) + output;
14 | c = Math.floor(sum / 2);
15 | i -= 1;
16 | j -= 1;
17 | }
18 | return output;
19 | };
20 |
--------------------------------------------------------------------------------
/src/leetcode/add-digits/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} num
3 | * @return {number}
4 | */
5 | var addDigits = function(num) {
6 | return 1 + ((num - 1) % 9);
7 | };
8 |
--------------------------------------------------------------------------------
/src/leetcode/add-strings/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} num1
3 | * @param {string} num2
4 | * @return {string}
5 | */
6 | var addStrings = function(num1, num2) {
7 | let i = num1.length - 1;
8 | let j = num2.length - 1;
9 | let c = 0;
10 | let output = '';
11 | while (i >= 0 || j >= 0 || c > 0) {
12 | const sum = parseInt(num1[i] || '0') + parseInt(num2[j] || '0') + c;
13 | output = (sum % 10) + output;
14 | c = Math.floor(sum / 10);
15 | i -= 1;
16 | j -= 1;
17 | }
18 | return output;
19 | };
20 |
--------------------------------------------------------------------------------
/src/leetcode/add-two-numbers/2. Add Two Numbers.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/add-two-numbers/2. Add Two Numbers.pdf
--------------------------------------------------------------------------------
/src/leetcode/adding-two-negabinary-numbers/1073. Adding Two Negabinary Numbers 2019-08-04.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/adding-two-negabinary-numbers/1073. Adding Two Negabinary Numbers 2019-08-04.pdf
--------------------------------------------------------------------------------
/src/leetcode/adding-two-negabinary-numbers/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | - For each digit
6 | - Calcute sum which is equal to `arr1[i] + arr2[j] + c`
7 | - Push `sum % 2` to output
8 | - Update carry. `c = -(sum >> 1)`
9 | - Finally, trim leading zeros.
10 |
--------------------------------------------------------------------------------
/src/leetcode/alien-dictionary/Alien Dictionary.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/alien-dictionary/Alien Dictionary.pdf
--------------------------------------------------------------------------------
/src/leetcode/all-oone-data-structure/IMG_3581.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/all-oone-data-structure/IMG_3581.JPG
--------------------------------------------------------------------------------
/src/leetcode/all-paths-from-source-to-target/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[][]} graph
3 | * @return {number[][]}
4 | */
5 | var allPathsSourceTarget = function(graph, u = 0, path = [u], output = []) {
6 | if (u === graph.length - 1) {
7 | output.push([...path]);
8 | return output;
9 | }
10 | for (const v of graph[u]) {
11 | path.push(v);
12 | allPathsSourceTarget(graph, v, path, output);
13 | path.pop();
14 | }
15 | return output;
16 | };
17 |
--------------------------------------------------------------------------------
/src/leetcode/as-far-from-land-as-possible/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | To find a water cell with maximized nearest distance to any land, we need to know the nearest distance to any land for every water cell. Start from every land, do BFS to find out nearest distance to this land. In the maintime, we update the nearest distance to any land for every water cell. After traversing all lands, we know the nearest distance to any land for every water cell, we traverse all water cells to find out the maximized one.
6 |
--------------------------------------------------------------------------------
/src/leetcode/basic-calculator-ii/227. Basic Calculator II.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/basic-calculator-ii/227. Basic Calculator II.pdf
--------------------------------------------------------------------------------
/src/leetcode/basic-calculator-iii/submit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/basic-calculator-iii/submit.png
--------------------------------------------------------------------------------
/src/leetcode/best-time-to-buy-and-sell-stock-ii/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} prices
3 | * @return {number}
4 | */
5 | var maxProfit = function(prices) {
6 | let output = 0;
7 | for (let i = 1; i < prices.length; i++) {
8 | if (prices[i] > prices[i - 1]) {
9 | output += prices[i] - prices[i - 1];
10 | }
11 | }
12 | return output;
13 | };
14 |
--------------------------------------------------------------------------------
/src/leetcode/best-time-to-buy-and-sell-stock-iii/123. Best Time to Buy and Sell Stock III.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/best-time-to-buy-and-sell-stock-iii/123. Best Time to Buy and Sell Stock III.pdf
--------------------------------------------------------------------------------
/src/leetcode/best-time-to-buy-and-sell-stock-iv/188. Best Time to Buy and Sell Stock IV.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/best-time-to-buy-and-sell-stock-iv/188. Best Time to Buy and Sell Stock IV.pdf
--------------------------------------------------------------------------------
/src/leetcode/best-time-to-buy-and-sell-stock/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} prices
3 | * @return {number}
4 | */
5 | var maxProfit = function(prices) {
6 | let max = 0;
7 | let minSoFar = Infinity;
8 | for (const price of prices) {
9 | minSoFar = Math.min(minSoFar, price);
10 | max = Math.max(max, price - minSoFar);
11 | }
12 | return max;
13 | };
14 |
--------------------------------------------------------------------------------
/src/leetcode/binary-search/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @param {number} target
4 | * @return {number}
5 | */
6 | const search = function(nums, target) {
7 | let i = 0;
8 | let j = nums.length - 1;
9 | while (i <= j) {
10 | let m = Math.floor((i + j) / 2);
11 | if (target === nums[m]) {
12 | return m;
13 | } else if (target > nums[m]) {
14 | i = m + 1;
15 | } else if (target < nums[m]) {
16 | j = m - 1;
17 | }
18 | }
19 | return -1;
20 | };
21 |
22 | export default search;
23 |
--------------------------------------------------------------------------------
/src/leetcode/binary-search/index.spec.js:
--------------------------------------------------------------------------------
1 | import fn from './index';
2 |
3 | test('binary-search [-1, 0, 3, 5, 9, 12], 9', () => {
4 | expect(fn([-1, 0, 3, 5, 9, 12], 9)).toEqual(4);
5 | });
6 |
7 | test('binary-search [-1, 0, 3, 5, 9, 12], 2', () => {
8 | expect(fn([-1, 0, 3, 5, 9, 12], 2)).toEqual(-1);
9 | });
10 |
--------------------------------------------------------------------------------
/src/leetcode/binary-subarrays-with-sum/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} A
3 | * @param {number} S
4 | * @return {number}
5 | */
6 | var numSubarraysWithSum = function(A, S) {
7 | const freq = { 0: 1 };
8 | let sum = 0;
9 | let nSubarrs = 0;
10 | for (const num of A) {
11 | sum += num;
12 | nSubarrs += freq[sum - S] || 0;
13 | freq[sum] = (freq[sum] || 0) + 1;
14 | }
15 | return nSubarrs;
16 | };
17 |
--------------------------------------------------------------------------------
/src/leetcode/binary-tree-inorder-traversal/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for a binary tree node.
3 | * function TreeNode(val) {
4 | * this.val = val;
5 | * this.left = this.right = null;
6 | * }
7 | */
8 | /**
9 | * @param {TreeNode} root
10 | * @return {number[]}
11 | */
12 | var inorderTraversal = function(root, output = []) {
13 | if (!root) {
14 | return output;
15 | }
16 | inorderTraversal(root.left, output);
17 | output.push(root.val);
18 | inorderTraversal(root.right, output);
19 | return output;
20 | };
21 |
--------------------------------------------------------------------------------
/src/leetcode/binary-tree-level-order-traversal-ii/Binary Tree Level Order Traversal II.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/binary-tree-level-order-traversal-ii/Binary Tree Level Order Traversal II.pdf
--------------------------------------------------------------------------------
/src/leetcode/binary-tree-longest-consecutive-sequence-ii/submit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/binary-tree-longest-consecutive-sequence-ii/submit.png
--------------------------------------------------------------------------------
/src/leetcode/binary-tree-maximum-path-sum/124. Binary Tree Maximum Path Sum.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/binary-tree-maximum-path-sum/124. Binary Tree Maximum Path Sum.pdf
--------------------------------------------------------------------------------
/src/leetcode/binary-tree-maximum-path-sum/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | For every visited node, we calculate `localMax` and `globalMax`.
6 |
7 | `localMax`: Maximum value tnat can connect current node to its parent on the path. So it does not include this.
8 |
9 | left <- root -> right
10 |
11 | `globalMax`: Maximum value that can be formed within a tree rooted at current node.
12 |
13 | So for each node, we ask the information above from its left and right children and compute the result.
14 |
--------------------------------------------------------------------------------
/src/leetcode/brace-expansion/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | First, create array from the given input.
6 |
7 | ```js
8 | '{a,b}c{d,e}f';
9 | ```
10 |
11 | ```js
12 | [['a', 'b'], ['c'], ['d', 'e'], ['f']];
13 | ```
14 |
15 | Then use DFS to list all combinations.
16 |
--------------------------------------------------------------------------------
/src/leetcode/bulb-switcher-ii/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} n
3 | * @param {number} m
4 | * @return {number}
5 | */
6 | var flipLights = function(n, m) {
7 | if (n <= 0 || m <= 0) {
8 | return 1;
9 | }
10 | if (n <= 1) {
11 | return 2;
12 | }
13 | if (n <= 2) {
14 | return m === 1 ? 3 : 4;
15 | }
16 | if (m === 1) {
17 | return 4;
18 | }
19 | return m === 2 ? 7 : 8;
20 | };
21 |
--------------------------------------------------------------------------------
/src/leetcode/bulb-switcher/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} n
3 | * @return {number}
4 | */
5 | var bulbSwitch = function(n) {
6 | return Math.floor(Math.sqrt(n));
7 | };
8 |
--------------------------------------------------------------------------------
/src/leetcode/campus-bikes-ii/submit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/campus-bikes-ii/submit.png
--------------------------------------------------------------------------------
/src/leetcode/cheapest-flights-within-k-stops/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | Use BFS to traverse level by level. Keep going only if
6 |
7 | - `nStops + 1 <= K`
8 | - `price + prices[u][v] <= min`
9 | - If next price is going to be greater than min, no need to keep going.
10 | - Without this, it will result in Time Limit Exceeded.
11 |
--------------------------------------------------------------------------------
/src/leetcode/check-completeness-of-a-binary-tree/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | Use BFS to iterate level by level from left to right. If there exists nodes after null node, it's not a complete tree.
6 |
--------------------------------------------------------------------------------
/src/leetcode/check-if-it-is-a-good-array/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | If `a % x === 0` && `b % x === 0`, then `(a + b) % x === 0` and `(ap + bq) % x === 0`.
6 |
7 | `(ap + bq) % x === 0`
8 |
9 | If `x > 1`, then `ap + bq !== 1`.
10 |
11 | So to find `ap + bq === 1`, we need x to be 1. We are looking for if there exists some numbers that are coprime.
12 |
--------------------------------------------------------------------------------
/src/leetcode/check-if-it-is-a-good-array/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {boolean}
4 | */
5 | var isGoodArray = function(nums) {
6 | let gcd = nums[0];
7 | for (const num of nums) {
8 | gcd = findGCD(num, gcd);
9 | if (gcd === 1) {
10 | return true;
11 | }
12 | }
13 | return false;
14 | };
15 |
16 | function findGCD(a, b) {
17 | if (b === 0) {
18 | return a;
19 | }
20 | return findGCD(b, a % b);
21 | }
22 |
--------------------------------------------------------------------------------
/src/leetcode/check-if-n-and-its-double-exist/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} arr
3 | * @return {boolean}
4 | */
5 | var checkIfExist = function(arr) {
6 | const set = new Set();
7 | for (const val of arr) {
8 | if (set.has(val / 2) || set.has(2 * val)) {
9 | return true;
10 | }
11 | set.add(val);
12 | }
13 | return false;
14 | };
15 |
--------------------------------------------------------------------------------
/src/leetcode/climbing-stairs/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} n
3 | * @return {number}
4 | */
5 | var climbStairs = function(n) {
6 | if (n <= 2) {
7 | return n;
8 | }
9 | let x = 1;
10 | let y = 2;
11 | let dp = y;
12 | for (let i = 3; i <= n; i++) {
13 | dp = x + y;
14 | x = y;
15 | y = dp;
16 | }
17 | return dp;
18 | };
19 |
--------------------------------------------------------------------------------
/src/leetcode/closest-binary-search-tree-value-ii/272. Closest Binary Search Tree Value II.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/closest-binary-search-tree-value-ii/272. Closest Binary Search Tree Value II.pdf
--------------------------------------------------------------------------------
/src/leetcode/closest-divisors/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} num
3 | * @return {number[]}
4 | */
5 | var closestDivisors = function(num) {
6 | for (let i = Math.floor(Math.sqrt(num + 2)); i >= 1; i--) {
7 | if ((num + 1) % i === 0) {
8 | return [i, (num + 1) / i];
9 | }
10 | if ((num + 2) % i === 0) {
11 | return [i, (num + 2) / i];
12 | }
13 | }
14 | };
15 |
--------------------------------------------------------------------------------
/src/leetcode/coin-change-2/518. Coin Change 2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/coin-change-2/518. Coin Change 2.pdf
--------------------------------------------------------------------------------
/src/leetcode/coin-change-2/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} amount
3 | * @param {number[]} coins
4 | * @return {number}
5 | */
6 | var change = function(amount, coins) {
7 | const dp = new Array(amount + 1).fill(0);
8 | dp[0] = 1;
9 | for (const c of coins) {
10 | for (let i = 1; i <= amount; i++) {
11 | if (i - c >= 0) {
12 | dp[i] += dp[i - c];
13 | }
14 | }
15 | }
16 | return dp[amount];
17 | };
18 |
--------------------------------------------------------------------------------
/src/leetcode/coin-change/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | Define dp as minimum number of coins required to achieve `i` amount.
6 |
7 | ```js
8 | dp[i] = min { 1 + dp[i - coins[j]] } for j from 1 to coins.length - 1
9 | ```
10 |
--------------------------------------------------------------------------------
/src/leetcode/coin-change/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} coins
3 | * @param {number} amount
4 | * @return {number}
5 | */
6 | var coinChange = function(coins, amount) {
7 | const dp = new Array(amount + 1).fill(Infinity);
8 | dp[0] = 0;
9 | for (let i = 1; i <= amount; i++) {
10 | for (const coin of coins) {
11 | const value = i - coin >= 0 ? dp[i - coin] + 1 : Infinity;
12 | dp[i] = Math.min(dp[i], value);
13 | }
14 | }
15 | return dp[amount] < Infinity ? dp[amount] : -1;
16 | };
17 |
--------------------------------------------------------------------------------
/src/leetcode/combinations/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} n
3 | * @param {number} k
4 | * @return {number[][]}
5 | */
6 | const combine = function(n, k, start = 1, selected = [], output = []) {
7 | if (selected.length >= k) {
8 | output.push([...selected]);
9 | return output;
10 | }
11 | for (let i = start; i <= n; i++) {
12 | selected.push(i);
13 | combine(n, k, i + 1, selected, output);
14 | selected.pop();
15 | }
16 | return output;
17 | };
18 |
19 | export default combine;
20 |
--------------------------------------------------------------------------------
/src/leetcode/combinations/index.spec.js:
--------------------------------------------------------------------------------
1 | import fn from './index';
2 |
3 | test('combinations', () => {
4 | const result = [[1, 2], [1, 3], [1, 4], [1, 5], [2, 3], [2, 4], [2, 5], [3, 4], [3, 5], [4, 5]];
5 | expect(fn(5, 2)).toEqual(result);
6 | });
7 |
8 | test('combinations', () => {
9 | const result = [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]];
10 | expect(fn(4, 2)).toEqual(result);
11 | });
12 |
--------------------------------------------------------------------------------
/src/leetcode/confusing-number/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} N
3 | * @return {boolean}
4 | */
5 | var confusingNumber = function(N) {
6 | const map = {
7 | '0': '0',
8 | '1': '1',
9 | '6': '9',
10 | '8': '8',
11 | '9': '6',
12 | };
13 | const nStr = N + '';
14 | let num = '';
15 | for (const c of nStr) {
16 | if (!(c in map)) {
17 | return false;
18 | }
19 | num = map[c] + num;
20 | }
21 | return num !== nStr;
22 | };
23 |
--------------------------------------------------------------------------------
/src/leetcode/construct-binary-tree-from-preorder-and-postorder-traversal/submit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/construct-binary-tree-from-preorder-and-postorder-traversal/submit.png
--------------------------------------------------------------------------------
/src/leetcode/container-with-most-water/11. Container With Most Water.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/container-with-most-water/11. Container With Most Water.pdf
--------------------------------------------------------------------------------
/src/leetcode/container-with-most-water/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} height
3 | * @return {number}
4 | */
5 | var maxArea = function(height) {
6 | let left = 0;
7 | let right = height.length - 1;
8 | let max = -Infinity;
9 | while (left < right) {
10 | const area = Math.min(height[left], height[right]) * (right - left);
11 | max = Math.max(max, area);
12 | if (height[left] <= height[right]) {
13 | left += 1;
14 | } else {
15 | right -= 1;
16 | }
17 | }
18 | return max;
19 | };
20 |
--------------------------------------------------------------------------------
/src/leetcode/container-with-most-water/index.spec.js:
--------------------------------------------------------------------------------
1 | import fn from './index';
2 |
3 | test('container-with-most-water', () => {
4 | expect(fn([1, 8, 6, 2, 5, 4, 8, 3, 7])).toEqual(49);
5 | });
6 |
--------------------------------------------------------------------------------
/src/leetcode/contains-duplicate/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {boolean}
4 | */
5 | var containsDuplicate = function(nums) {
6 | const cache = {};
7 | for (let i = 0; i < nums.length; i++) {
8 | if (cache[nums[i]]) {
9 | return true;
10 | }
11 | cache[nums[i]] = true;
12 | }
13 | return false;
14 | };
15 |
--------------------------------------------------------------------------------
/src/leetcode/continuous-subarray-sum/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @param {number} k
4 | * @return {boolean}
5 | */
6 | var checkSubarraySum = function(nums, k) {
7 | const map = { 0: -1 };
8 | let sum = 0;
9 | for (let i = 0; i < nums.length; i++) {
10 | sum += nums[i];
11 | const r = sum % k;
12 | if (r in map && i - map[r] >= 2) {
13 | return true;
14 | }
15 | if (!(r in map)) {
16 | map[r] = i;
17 | }
18 | }
19 | return false;
20 | };
21 |
--------------------------------------------------------------------------------
/src/leetcode/continuous-subarray-sum/note.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/continuous-subarray-sum/note.pdf
--------------------------------------------------------------------------------
/src/leetcode/convert-a-number-to-hexadecimal/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | - For each iteration
6 | - Get reminder of `n % 16` by `&` with `15`
7 | - Divide n with 16 by right shifting without sign bits
8 | - `n = n >>> 4;`
9 | - https://stackoverflow.com/questions/10382122/what-is-operator-in-js
10 |
11 | ### Reminder of n % 16
12 |
13 | ```
14 | 1011 1101
15 | & 0000 1111
16 | -----------
17 | 0000 1101
18 | ```
19 |
20 | ### Right shifting without sign bits
21 |
22 | ```
23 | n = 1011 1101
24 | n >>> 4 = 0000 1011
25 | ```
26 |
--------------------------------------------------------------------------------
/src/leetcode/convert-a-number-to-hexadecimal/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} num
3 | * @return {string}
4 | */
5 |
6 | // prettier-ignore
7 | const map = [
8 | ...[...new Array(10)].map((_, i) => i),
9 | 'a',
10 | 'b',
11 | 'c',
12 | 'd',
13 | 'e',
14 | 'f',
15 | ];
16 |
17 | var toHex = function(num) {
18 | if (!num) {
19 | return '0';
20 | }
21 | let output = '';
22 | let n = num;
23 | while (n) {
24 | const r = n & 15;
25 | output = map[r] + output;
26 | n = n >>> 4;
27 | }
28 | return output;
29 | };
30 |
--------------------------------------------------------------------------------
/src/leetcode/convert-binary-number-in-a-linked-list-to-integer/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for singly-linked list.
3 | * function ListNode(val) {
4 | * this.val = val;
5 | * this.next = null;
6 | * }
7 | */
8 | /**
9 | * @param {ListNode} head
10 | * @return {number}
11 | */
12 | var getDecimalValue = function(head) {
13 | let ptr = head;
14 | let sum = 0;
15 | while (ptr) {
16 | sum = sum * 2 + ptr.val;
17 | ptr = ptr.next;
18 | }
19 | return sum;
20 | };
21 |
--------------------------------------------------------------------------------
/src/leetcode/convert-to-base-2/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | -9 to base -2
6 |
7 | ```
8 | -9 = -2 * 5 + 1
9 | 5 = -2 * -2 + 1
10 | -2 = -2 * 1 + 0
11 | 1 = -2 * 0 + 1
12 | ```
13 |
14 | Every time we take reminder to the output. Then we shift right `num` for 1 time and take negative sign. Repeat this process until `num` is equal to zero.
15 |
16 | Noted that reminder is always positive.
17 |
--------------------------------------------------------------------------------
/src/leetcode/convert-to-base-2/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} N
3 | * @return {string}
4 | */
5 | var baseNeg2 = function(N) {
6 | if (N === 0) {
7 | return '0';
8 | }
9 | let num = N;
10 | let output = '';
11 | while (num) {
12 | output = (num & 1) + output;
13 | num = -(num >> 1);
14 | }
15 | return output;
16 | };
17 |
--------------------------------------------------------------------------------
/src/leetcode/convert-to-base-2/to base -2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/convert-to-base-2/to base -2.pdf
--------------------------------------------------------------------------------
/src/leetcode/convert-to-base-2/to base -8.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/convert-to-base-2/to base -8.pdf
--------------------------------------------------------------------------------
/src/leetcode/convert-to-base-2/what happens to 9 >> 1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/convert-to-base-2/what happens to 9 >> 1.pdf
--------------------------------------------------------------------------------
/src/leetcode/copy-list-with-random-pointer/138. Copy List with Random Pointer.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/copy-list-with-random-pointer/138. Copy List with Random Pointer.pdf
--------------------------------------------------------------------------------
/src/leetcode/count-negative-numbers-in-a-sorted-matrix/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[][]} grid
3 | * @return {number}
4 | */
5 | var countNegatives = function(grid) {
6 | const m = grid.length;
7 | const n = grid[0].length;
8 | let i = 0;
9 | let j = n;
10 | let nNegatives = 0;
11 | while (i < m && j >= 0) {
12 | while (grid[i][j - 1] < 0) {
13 | j -= 1;
14 | }
15 | nNegatives += n - j;
16 | i += 1;
17 | }
18 | return nNegatives;
19 | };
20 |
--------------------------------------------------------------------------------
/src/leetcode/count-of-range-sum/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | ```
6 | S(i, j) = sum[i] - sum[j - 1]
7 | lower <= sum[i] - sum[j - 1] <= upper
8 |
9 | looking for some `sum` in the interval of [sum[i] - upper, sum[i] - lower]
10 | sum[i] - upper <= sum[j - 1] <= sum[i] - lower
11 |
12 | example prefixSum:
13 |
14 | const prefixSum = [1,2,2,3,3,4]
15 | assume:
16 | sum[i] - upper = 2
17 | sum[i] - lower = 3
18 | count of range sum = upperBound(prefixSum, 3) - lowerBound(prefixSum, 2) = 5 - 1 = 4
19 | ```
20 |
--------------------------------------------------------------------------------
/src/leetcode/count-primes/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} n
3 | * @return {number}
4 | */
5 | var countPrimes = function(n) {
6 | if (n < 3) {
7 | return 0;
8 | }
9 | const isPrime = new Array(n).fill(false);
10 | let count = 0;
11 | for (let i = 2; i < n; i++) {
12 | if (!isPrime[i]) {
13 | count += 1;
14 | for (let j = 2; i * j < n; j++) {
15 | isPrime[i * j] = true;
16 | }
17 | }
18 | }
19 | return count;
20 | };
21 |
--------------------------------------------------------------------------------
/src/leetcode/count-primes/index.spec.js:
--------------------------------------------------------------------------------
1 | import fn from './index';
2 |
3 | test('count-primes', () => {
4 | expect(fn(100)).toEqual(25);
5 | });
6 |
7 | test('count-primes', () => {
8 | expect(fn(1)).toEqual(0);
9 | });
10 |
--------------------------------------------------------------------------------
/src/leetcode/cracking-the-safe/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} n
3 | * @param {number} k
4 | * @return {string}
5 | */
6 | var crackSafe = function(n, k) {
7 | let pwd = '0'.repeat(n);
8 | const visited = new Set([pwd]);
9 | const nTotal = k ** n;
10 | while (visited.size < nTotal) {
11 | for (let i = k - 1; i >= 0; i--) {
12 | const word = pwd.substring(pwd.length - (n - 1)) + i;
13 | if (!visited.has(word)) {
14 | visited.add(word);
15 | pwd += i;
16 | break;
17 | }
18 | }
19 | }
20 | return pwd;
21 | };
22 |
--------------------------------------------------------------------------------
/src/leetcode/critical-connections-in-a-network/1192. Critical Connections in a Network.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/critical-connections-in-a-network/1192. Critical Connections in a Network.pdf
--------------------------------------------------------------------------------
/src/leetcode/daily-temperatures/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} T
3 | * @return {number[]}
4 | */
5 | var dailyTemperatures = function(T) {
6 | const output = new Array(T.length).fill(0);
7 | const stack = [];
8 | for (let i = 0; i < T.length; i++) {
9 | while (stack.length && T[i] > T[stack[stack.length - 1]]) {
10 | const j = stack.pop();
11 | output[j] = i - j;
12 | }
13 | stack.push(i);
14 | }
15 | return output;
16 | };
17 |
--------------------------------------------------------------------------------
/src/leetcode/decode-string/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | Use a stack to store `[nRepeats, str]`.
6 |
7 | Iterate over str.
8 |
9 | - if encounter a number, update `nRepeats` in the top of stack.
10 | - if encounter `[`, continue.
11 | - if encounter `]`, compute the result of top of stack and append result to top of remaining stack.
12 | - otherwise, append character to top of stack.
13 |
--------------------------------------------------------------------------------
/src/leetcode/decode-ways/Decode ways.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/decode-ways/Decode ways.pdf
--------------------------------------------------------------------------------
/src/leetcode/decode-ways/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | ```js
6 | dp(n) = (if last two characters is decodable ? dp(n - 2) : 0) +
7 | (if last characters is decodable ? dp(n - 1) : 0)
8 | ```
9 |
10 | ```js
11 | dp = x + y;
12 | // x = dp[n - 2]
13 | // y = dp[n - 1]
14 | ```
15 |
--------------------------------------------------------------------------------
/src/leetcode/defanging-an-ip-address/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} address
3 | * @return {string}
4 | */
5 | var defangIPaddr = function(address) {
6 | return address.replace(/\./g, '[.]');
7 | };
8 |
--------------------------------------------------------------------------------
/src/leetcode/delete-and-earn/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | It's similar to house robber question. Because delete `n`, it will delete both `n - 1` and `n + 1`. It means `n` and `n - 1` can't be selected at the same time.
6 |
7 | Define `dp[i]` as maximum value at `i`.
8 |
9 | ```js
10 | dp[i] = Math.max(dp[i - 1], freq[i] * i + dp[i - 2]);
11 | ```
12 |
--------------------------------------------------------------------------------
/src/leetcode/delete-operation-for-two-strings/README.md:
--------------------------------------------------------------------------------
1 | ## README
2 |
3 | ## Algorithm
4 |
5 | Find out the LCS of two words. To minimize delete operations, we just delete words that are not LCS. So our goal becomes finding LCS of two words.
6 |
7 | ```js
8 | // dp[i][j] represents LCS of word1 with string length i and word2 with string length j.
9 | dp[i][j] = (() => {
10 | if (word1[i - 1] === word2[j - 1]) {
11 | return dp[i - 1][j - 1] + 1;
12 | }
13 | return Math.max(dp[i][j - 1], dp[i - 1][j]);
14 | })();
15 | ```
16 |
--------------------------------------------------------------------------------
/src/leetcode/diagonal-traverse/498. Diagonal Traverse.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/diagonal-traverse/498. Diagonal Traverse.pdf
--------------------------------------------------------------------------------
/src/leetcode/distribute-coins-in-binary-tree/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | For each subtree,
6 |
7 | ```
8 | number of moves required = Math.abs(number of coins - number of nodes)
9 | ```
10 |
11 | It means number of moves required to make this subtree balanced. So the total number of moves is equal to `number of moves required` for each subtree.
12 |
13 | So given a root, we ask its children recursively for number of nodes, number of coins and number of moves, then we can compose result for the given root.
14 |
--------------------------------------------------------------------------------
/src/leetcode/divide-two-integers/29. Divide Two Integers.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/divide-two-integers/29. Divide Two Integers.pdf
--------------------------------------------------------------------------------
/src/leetcode/divide-two-integers/index.spec.js:
--------------------------------------------------------------------------------
1 | import fn from './index';
2 |
3 | test('divide-two-integers', () => {
4 | expect(fn(-2147483648, 2)).toEqual(-1073741824);
5 | });
6 |
7 | test('divide-two-integers', () => {
8 | expect(fn(-2147483648, -1)).toEqual(2147483647);
9 | });
10 |
11 | test('divide-two-integers', () => {
12 | expect(fn(-2147483648, 1)).toEqual(-2147483648);
13 | });
14 |
15 | test('divide-two-integers', () => {
16 | expect(fn(30, 5)).toEqual(6);
17 | });
18 |
19 | test('divide-two-integers', () => {
20 | expect(fn(10, 3)).toEqual(3);
21 | });
22 |
--------------------------------------------------------------------------------
/src/leetcode/divide-two-integers/screencapture-leetcode-submissions-detail-179251987-2018-09-29-20_31_17.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/divide-two-integers/screencapture-leetcode-submissions-detail-179251987-2018-09-29-20_31_17.png
--------------------------------------------------------------------------------
/src/leetcode/duplicate-zeros/v2.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} arr
3 | * @return {void} Do not return anything, modify arr in-place instead.
4 | */
5 | var duplicateZeros = function(arr) {
6 | const m = arr.length;
7 | for (let i = 0; i < arr.length; i++) {
8 | if (arr[i] === 0) {
9 | arr.splice(i, 0, 0);
10 | i += 1;
11 | }
12 | }
13 | arr.splice(m, arr.length - m);
14 | };
15 |
--------------------------------------------------------------------------------
/src/leetcode/evaluate-division/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | - Create a graph with given equations. So that given a number, we can know which numbers are linked to this number and the value of A / B.
6 | - Then we use this graph with DFS to create all possible relations.
7 | - Finally we can map each query to the result of all possible relations.
8 |
--------------------------------------------------------------------------------
/src/leetcode/excel-sheet-column-number/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} s
3 | * @return {number}
4 | */
5 | var titleToNumber = function(s) {
6 | const m = s.length;
7 | let sum = 0;
8 | for (let i = 0; i < m; i++) {
9 | sum += getCode(s[i]) * 26 ** (m - i - 1);
10 | }
11 | return sum;
12 | };
13 |
14 | function getCode(c) {
15 | return c.charCodeAt(0) - 'A'.charCodeAt(0) + 1;
16 | }
17 |
--------------------------------------------------------------------------------
/src/leetcode/excel-sheet-column-title/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} n
3 | * @return {string}
4 | */
5 | var convertToTitle = function(n) {
6 | const m = 26;
7 | let output = '';
8 | let num = n;
9 | while (num >= 1) {
10 | // prettier-ignore
11 | const r = num % m > 0
12 | ? num % m
13 | : 26;
14 | output = getChar(r - 1) + output;
15 | num = Math.floor((num - r) / m);
16 | }
17 | return output;
18 | };
19 |
20 | function getChar(i) {
21 | const base = 'A'.charCodeAt(0);
22 | return String.fromCharCode(base + i);
23 | }
24 |
--------------------------------------------------------------------------------
/src/leetcode/exclusive-time-of-functions/636. Exclusive Time of Functions.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/exclusive-time-of-functions/636. Exclusive Time of Functions.pdf
--------------------------------------------------------------------------------
/src/leetcode/fibonacci-number/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} N
3 | * @return {number}
4 | */
5 | var fib = function(N) {
6 | if (N <= 1) {
7 | return N;
8 | }
9 | let x = 0;
10 | let y = 1;
11 | let dp;
12 | for (let i = 2; i <= N; i++) {
13 | dp = x + y;
14 | x = y;
15 | y = dp;
16 | }
17 | return dp;
18 | };
19 |
--------------------------------------------------------------------------------
/src/leetcode/find-all-duplicates-in-an-array/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number[]}
4 | */
5 | var findDuplicates = function(nums) {
6 | const output = [];
7 | for (let i = 0; i < nums.length; i++) {
8 | const index = Math.abs(nums[i]);
9 | if (nums[index - 1] < 0) {
10 | output.push(index);
11 | } else {
12 | nums[index - 1] *= -1;
13 | }
14 | }
15 | return output;
16 | };
17 |
--------------------------------------------------------------------------------
/src/leetcode/find-k-pairs-with-smallest-sums/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | - Use a priority queue to get the pair with smallest sum from pairs
6 | - We start from the first element of each array. `[0, 0]`
7 | - For each iteration,
8 | - Dequeue from the queue to get the smallest one.
9 | - Next smallest could be either `[i + 1, j]` or `[i, j + 1]`.
10 | - So push those candidates to the queue.
11 | - To prevent visiting duplicated pairs, we have `visited` set to check duplication.
12 |
--------------------------------------------------------------------------------
/src/leetcode/find-leaves-of-binary-tree/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | Use DFS to find out the maximum depth to leaves for each node. And put the value of this node to its corresponding maximum depth.
6 |
--------------------------------------------------------------------------------
/src/leetcode/find-median-from-data-stream/295. Find Median from Data Stream 2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/find-median-from-data-stream/295. Find Median from Data Stream 2.pdf
--------------------------------------------------------------------------------
/src/leetcode/find-median-from-data-stream/295. Find Median from Data Stream.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/find-median-from-data-stream/295. Find Median from Data Stream.pdf
--------------------------------------------------------------------------------
/src/leetcode/find-minimum-in-rotated-sorted-array/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number}
4 | */
5 |
6 | var findMin = function(nums) {
7 | let left = 0;
8 | let right = nums.length - 1;
9 | while (left < right) {
10 | const mid = Math.floor((left + right) / 2);
11 | if (nums[right] >= nums[left]) {
12 | right = left;
13 | } else if (nums[mid] >= nums[left]) {
14 | left = mid + 1;
15 | } else {
16 | right = mid;
17 | }
18 | }
19 | return nums[left];
20 | };
21 |
--------------------------------------------------------------------------------
/src/leetcode/find-peak-element/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | Peak element is defined as the element that is greater than its neighbors. And also define that element is greater than boundary.
6 |
7 | `[1,3,1]`
8 | `[1,2,3]`
9 |
10 | `3` in both arrays are defined as a peak element.
11 |
12 | So we can use binary search to always search in the range that contains a greater element than `arr[mid]`.
13 |
--------------------------------------------------------------------------------
/src/leetcode/find-pivot-index/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number}
4 | */
5 | var pivotIndex = function(nums) {
6 | let right = nums.reduce((a, b) => a + b, 0);
7 | let left = 0;
8 | for (let i = 0; i < nums.length; i++) {
9 | right -= nums[i];
10 | if (left === right) {
11 | return i;
12 | }
13 | left += nums[i];
14 | }
15 | return -1;
16 | };
17 |
--------------------------------------------------------------------------------
/src/leetcode/find-the-duplicate-number/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number}
4 | */
5 | var findDuplicate = function(nums) {
6 | const head = nums[0];
7 | let slow = nums[head];
8 | let fast = nums[nums[head]];
9 | while (slow !== fast) {
10 | slow = nums[slow];
11 | fast = nums[nums[fast]];
12 | }
13 | fast = head;
14 | while (slow !== fast) {
15 | slow = nums[slow];
16 | fast = nums[fast];
17 | }
18 | return slow || -1;
19 | };
20 |
--------------------------------------------------------------------------------
/src/leetcode/first-bad-version/278. First Bad Version.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/first-bad-version/278. First Bad Version.pdf
--------------------------------------------------------------------------------
/src/leetcode/first-unique-character-in-a-string/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} s
3 | * @return {number}
4 | */
5 | var firstUniqChar = function(s) {
6 | const freq = {};
7 | for (const c of s) {
8 | freq[c] = (freq[c] || 0) + 1;
9 | }
10 | for (let i = 0; i < s.length; i++) {
11 | if (freq[s[i]] === 1) {
12 | return i;
13 | }
14 | }
15 | return -1;
16 | };
17 |
--------------------------------------------------------------------------------
/src/leetcode/fixed-point/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} A
3 | * @return {number}
4 | */
5 | var fixedPoint = function(A) {
6 | let left = 0;
7 | let right = A.length;
8 | while (left < right) {
9 | const mid = Math.floor((left + right) / 2);
10 | if (mid > A[mid]) {
11 | left = mid + 1;
12 | } else {
13 | right = mid;
14 | }
15 | }
16 | const mid = Math.floor((left + right) / 2);
17 | return mid === A[mid] ? left : -1;
18 | };
19 |
--------------------------------------------------------------------------------
/src/leetcode/fraction-to-recurring-decimal/submit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/fraction-to-recurring-decimal/submit.png
--------------------------------------------------------------------------------
/src/leetcode/friends-of-appropriate-ages/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | - Count number of people for each age.
6 | - Pair each ages to see if they should send request to each other.
7 | - People don't send request to themselves. `If A === B, n += freq[A] * (freq[B] - 1)`
8 | - For javascript, every key in object will be transform to string. To store key with its original type, we should use `Map`.
9 |
--------------------------------------------------------------------------------
/src/leetcode/gas-station/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} gas
3 | * @param {number[]} cost
4 | * @return {number}
5 | */
6 | var canCompleteCircuit = function(gas, cost) {
7 | const n = gas.length;
8 | let total = 0;
9 | let sum = 0;
10 | let start = 0;
11 | for (let i = 0; i < n; i++) {
12 | total += gas[i] - cost[i];
13 | sum += gas[i] - cost[i];
14 | if (sum < 0) {
15 | start = i + 1;
16 | sum = 0;
17 | }
18 | }
19 | return total >= 0 ? start : -1;
20 | };
21 |
--------------------------------------------------------------------------------
/src/leetcode/generate-parentheses/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | - Backtracking
6 | - For each run, push left '(' first then push right ')'
7 | - It's faster to use string concatenation in javascript than joining string.
8 |
--------------------------------------------------------------------------------
/src/leetcode/generate-parentheses/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} n
3 | * @return {string[]}
4 | */
5 | var generateParenthesis = function(n, left = 0, right = 0, selected = '', output = []) {
6 | if (selected.length >= n * 2) {
7 | output.push(selected);
8 | return output;
9 | }
10 | if (left < n) {
11 | generateParenthesis(n, left + 1, right, selected + '(', output);
12 | }
13 | if (left > right) {
14 | generateParenthesis(n, left, right + 1, selected + ')', output);
15 | }
16 | return output;
17 | };
18 |
--------------------------------------------------------------------------------
/src/leetcode/goat-latin/Goat Latin.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/goat-latin/Goat Latin.pdf
--------------------------------------------------------------------------------
/src/leetcode/goat-latin/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} S
3 | * @return {string}
4 | */
5 | var toGoatLatin = function(S) {
6 | return S.split(' ')
7 | .map(mapper)
8 | .join(' ');
9 | };
10 |
11 | function mapper(word, i) {
12 | if (isVowel(word[0])) {
13 | return word + 'ma' + 'a'.repeat(i + 1);
14 | }
15 | const [first, ...rest] = word;
16 | return rest.join('') + first + 'ma' + 'a'.repeat(i + 1);
17 | }
18 |
19 | function isVowel(c) {
20 | const set = new Set(['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']);
21 | return set.has(c);
22 | }
23 |
--------------------------------------------------------------------------------
/src/leetcode/graph-valid-tree/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | A graph is a tree if:
6 |
7 | - No cycle
8 | - Connected
9 |
10 | So we are going to check no cycle and all nodes have been visited.
11 |
12 | We can test `hasCycle` from any node since any node in a tree can be the root. So we can start from any node.
13 |
--------------------------------------------------------------------------------
/src/leetcode/gray-code/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | ```
6 | n = 2 | 00,01,11,10
7 | n = 3 | 000,001,011,010,110,111,101,100
8 | ```
9 |
10 | to get gray code for n = 3, just copy the array, reverse it and add 2 \*\* i to the array for each value.
11 |
--------------------------------------------------------------------------------
/src/leetcode/gray-code/idnex.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} n
3 | * @return {number[]}
4 | */
5 | var grayCode = function(n) {
6 | const dp = [0];
7 | for (let i = 0; i < n; i++) {
8 | const next = dp.slice().reverse();
9 | for (let j = 0; j < next.length; j++) {
10 | next[j] += 2 ** i;
11 | }
12 | dp.push(...next);
13 | }
14 | return dp;
15 | };
16 |
--------------------------------------------------------------------------------
/src/leetcode/greatest-common-divisor-of-strings/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} str1
3 | * @param {string} str2
4 | * @return {string}
5 | */
6 | var gcdOfStrings = function(str1, str2) {
7 | if (str1 + str2 !== str2 + str1) {
8 | return '';
9 | }
10 | const length = gcd(str1.length, str2.length);
11 | return str1.substring(0, length);
12 | };
13 |
14 | function gcd(a, b) {
15 | if (b === 0) {
16 | return a;
17 | }
18 | return gcd(b, a % b);
19 | }
20 |
--------------------------------------------------------------------------------
/src/leetcode/greatest-sum-divisible-by-three/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | Define `dp[i][r]` as maximum sum with reminder r and with array ending at i
6 |
7 | ```js
8 | const r = (nums[i] + dp[i - 1][j]) % m;
9 | dp[i][r] = Math.max(dp[i][r], nums[i] + dp[i - 1][j]);
10 | ```
11 |
12 | ```js
13 | next[r] = Math.max(next[r], nums[i] + dp[j]);
14 | ```
15 |
--------------------------------------------------------------------------------
/src/leetcode/greatest-sum-divisible-by-three/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number}
4 | */
5 | var maxSumDivThree = function(nums) {
6 | const m = 3;
7 | let dp = new Array(m).fill(0);
8 | for (let i = 0; i < nums.length; i++) {
9 | const next = [...dp];
10 | for (let j = 0; j < m; j++) {
11 | const r = (nums[i] + dp[j]) % m;
12 | next[r] = Math.max(next[r], nums[i] + dp[j]);
13 | }
14 | dp = next;
15 | }
16 | return dp[0];
17 | };
18 |
--------------------------------------------------------------------------------
/src/leetcode/group-anagrams/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string[]} strs
3 | * @return {string[][]}
4 | */
5 | var groupAnagrams = function(strs) {
6 | const map = {};
7 | for (const str of strs) {
8 | // prettier-ignore
9 | const key = str.split('').sort().join('');
10 | if (!(key in map)) map[key] = [];
11 | map[key].push(str);
12 | }
13 | return Object.values(map);
14 | };
15 |
--------------------------------------------------------------------------------
/src/leetcode/group-the-people-given-the-group-size-they-belong-to/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} groupSizes
3 | * @return {number[][]}
4 | */
5 | var groupThePeople = function(groupSizes) {
6 | const map = {};
7 | const output = [];
8 | for (let i = 0; i < groupSizes.length; i++) {
9 | const size = groupSizes[i];
10 | if (!(size in map)) map[size] = [];
11 | map[size].push(i);
12 | if (map[size].length >= size) {
13 | output.push(map[size].splice(0, size));
14 | }
15 | }
16 | return output;
17 | };
18 |
--------------------------------------------------------------------------------
/src/leetcode/h-index-ii/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} citations
3 | * @return {number}
4 | */
5 | var hIndex = function(citations) {
6 | const n = citations.length;
7 | let left = 0;
8 | let right = n + 1;
9 | let max = 0;
10 | while (left < right) {
11 | const mid = Math.floor((left + right) / 2);
12 | if (citations[n - mid] >= mid) {
13 | max = Math.max(max, mid);
14 | left = mid + 1;
15 | } else {
16 | right = mid;
17 | }
18 | }
19 | return max;
20 | };
21 |
--------------------------------------------------------------------------------
/src/leetcode/hamming-distance/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} x
3 | * @param {number} y
4 | * @return {number}
5 | */
6 | var hammingDistance = function(x, y) {
7 | let n = x ^ y;
8 | let output = 0;
9 | while (n) {
10 | output += n % 2;
11 | n >>= 1;
12 | }
13 | return output;
14 | };
15 |
--------------------------------------------------------------------------------
/src/leetcode/happy-number/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Example
4 |
5 | ```js
6 | 20
7 | 2 ** 2 + 0 ** 2 = 4
8 | 4 ** 2 = 16
9 | 1 ** 2 + 6 ** 2 = 37
10 | 3 ** 2 + 7 ** 2 = 58
11 | 5 ** 2 + 8 ** 2 = 89
12 | 8 ** 2 + 9 ** 2 = 145
13 | 1 ** 2 + 4 ** 2 + 5 ** 2 = 42
14 | 4 ** 2 + 2 ** 2 = 20
15 | ```
16 |
--------------------------------------------------------------------------------
/src/leetcode/happy-number/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} n
3 | * @return {boolean}
4 | */
5 | var isHappy = function(n) {
6 | let slow = next(n);
7 | let fast = next(slow);
8 | while (slow !== fast) {
9 | slow = next(slow);
10 | fast = next(next(fast));
11 | }
12 | if (slow === 1) {
13 | return true;
14 | }
15 | return false;
16 | };
17 |
18 | function next(n) {
19 | let num = n;
20 | let output = 0;
21 | while (num > 0) {
22 | output += (num % 10) ** 2;
23 | num = Math.floor(num / 10);
24 | }
25 | return output;
26 | }
27 |
--------------------------------------------------------------------------------
/src/leetcode/house-robber-iii/FireShot_Capture_2_-__1__House_Robber_III_-_Su__-_https___leetcode_com_submissions_detail_174593214_.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/house-robber-iii/FireShot_Capture_2_-__1__House_Robber_III_-_Su__-_https___leetcode_com_submissions_detail_174593214_.png
--------------------------------------------------------------------------------
/src/leetcode/house-robber/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number}
4 | */
5 | var rob = function(nums) {
6 | if (nums.length <= 2) {
7 | return Math.max(...nums, 0);
8 | }
9 | let x = nums[0];
10 | let y = Math.max(x, nums[1]);
11 | let dp = y;
12 | for (let i = 2; i < nums.length; i++) {
13 | dp = Math.max(y, x + nums[i]);
14 | x = y;
15 | y = dp;
16 | }
17 | return dp;
18 | };
19 |
--------------------------------------------------------------------------------
/src/leetcode/implement-strstr/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} haystack
3 | * @param {string} needle
4 | * @return {number}
5 | */
6 | var strStr = function(haystack, needle) {
7 | if (!needle.length) {
8 | return 0;
9 | }
10 | for (let i = 0; i < haystack.length; i++) {
11 | let j = 0;
12 | while (i + j < haystack.length && haystack[i + j] === needle[j]) {
13 | j += 1;
14 | }
15 | if (j === needle.length) return i;
16 | }
17 | return -1;
18 | };
19 |
--------------------------------------------------------------------------------
/src/leetcode/increasing-subsequences/submit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/increasing-subsequences/submit.png
--------------------------------------------------------------------------------
/src/leetcode/increasing-triplet-subsequence/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | Similar to longest increasing subsequence. Maintain an array during iteration.
6 |
7 | If num is greater than the last element, push it to last.
8 | If num is smaller or equal to the first element, replace the first.
9 | If num is smaller or equal to the second element, replace the second.
10 |
--------------------------------------------------------------------------------
/src/leetcode/increasing-triplet-subsequence/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {boolean}
4 | */
5 | var increasingTriplet = function(nums) {
6 | const arr = [];
7 | for (const num of nums) {
8 | if (!arr.length || num > arr[arr.length - 1]) {
9 | arr.push(num);
10 | } else if (num <= arr[0]) {
11 | arr[0] = num;
12 | } else if (num <= arr[1]) {
13 | arr[1] = num;
14 | }
15 | if (arr.length >= 3) {
16 | return true;
17 | }
18 | }
19 | return false;
20 | };
21 |
--------------------------------------------------------------------------------
/src/leetcode/insert-delete-getrandom-o1-duplicates-allowed/381. Insert Delete GetRandom O(1) - Duplicates allowed.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/insert-delete-getrandom-o1-duplicates-allowed/381. Insert Delete GetRandom O(1) - Duplicates allowed.pdf
--------------------------------------------------------------------------------
/src/leetcode/insert-interval/57. Insert Interval.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/insert-interval/57. Insert Interval.pdf
--------------------------------------------------------------------------------
/src/leetcode/insertion-sort-list/147. Insertion Sort List.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/insertion-sort-list/147. Insertion Sort List.pdf
--------------------------------------------------------------------------------
/src/leetcode/integer-to-roman/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | Create a map sorted from greatest to least. Also need to include edge cases.
6 |
7 | ex:
8 |
9 | ```
10 | I can be placed before V (5) and X (10) to make 4 and 9.
11 | ```
12 |
13 | ```js
14 | ['IX', 9];
15 | ```
16 |
17 | ```js
18 | ['IV', 4],
19 | ```
20 |
21 | Iterate over map. For each iteration, we try to use the current value as much as possible. For each usage, we append the corresponding symbol to the output.
22 |
--------------------------------------------------------------------------------
/src/leetcode/interleaving-string/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ```
4 | aa bc c
5 | d bbc a
6 | aad bbc bc a c
7 | ```
8 |
9 | ```js
10 | dp[i][j] =
11 | (s1[i - 1] === s3[i + j - 1] && dp[i - 1][j]) || (s2[j - 1] === s3[i + j - 1] && dp[i][j - 1]);
12 | dp[0][j] = s2.substring(0, j) === s3.substring(0, j);
13 | dp[i][0] = s1.substring(0, i) === s3.substring(0, i);
14 | ```
15 |
--------------------------------------------------------------------------------
/src/leetcode/intersection-of-two-linked-lists/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for singly-linked list.
3 | * function ListNode(val) {
4 | * this.val = val;
5 | * this.next = null;
6 | * }
7 | */
8 |
9 | /**
10 | * @param {ListNode} headA
11 | * @param {ListNode} headB
12 | * @return {ListNode}
13 | */
14 | var getIntersectionNode = function(headA, headB) {
15 | let ptr1 = headA;
16 | let ptr2 = headB;
17 | while (ptr1 !== ptr2) {
18 | ptr1 = ptr1 ? ptr1.next : headB;
19 | ptr2 = ptr2 ? ptr2.next : headA;
20 | }
21 | return ptr1;
22 | };
23 |
--------------------------------------------------------------------------------
/src/leetcode/invert-binary-tree/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for a binary tree node.
3 | * function TreeNode(val) {
4 | * this.val = val;
5 | * this.left = this.right = null;
6 | * }
7 | */
8 | /**
9 | * @param {TreeNode} root
10 | * @return {TreeNode}
11 | */
12 | var invertTree = function(root) {
13 | if (!root) {
14 | return root;
15 | }
16 | [root.left, root.right] = [root.right, root.left];
17 | invertTree(root.left);
18 | invertTree(root.right);
19 | return root;
20 | };
21 |
--------------------------------------------------------------------------------
/src/leetcode/is-graph-bipartite/Is graph bipartite.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/is-graph-bipartite/Is graph bipartite.pdf
--------------------------------------------------------------------------------
/src/leetcode/is-subsequence/recursive.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} s
3 | * @param {string} t
4 | * @return {boolean}
5 | */
6 | var isSubsequence = function(s, t, sStart = 0, tStart = 0) {
7 | for (let i = tStart; i < t.length; i++) {
8 | if (s[sStart] === t[i]) {
9 | return isSubsequence(s, t, sStart + 1, i + 1);
10 | }
11 | }
12 | return sStart >= s.length;
13 | };
14 |
--------------------------------------------------------------------------------
/src/leetcode/is-subsequence/two-ptrs.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} s
3 | * @param {string} t
4 | * @return {boolean}
5 | */
6 | var isSubsequence = function(s, t) {
7 | let i = 0;
8 | for (let j = 0; j < t.length; j++) {
9 | if (s[i] === t[j]) {
10 | i += 1;
11 | }
12 | }
13 | return i >= s.length;
14 | };
15 |
--------------------------------------------------------------------------------
/src/leetcode/isomorphic-strings/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} s
3 | * @param {string} t
4 | * @return {boolean}
5 | */
6 | var isIsomorphic = function(s, t) {
7 | const map = {};
8 | const visited = new Set();
9 | for (let i = 0; i < s.length; i++) {
10 | if ((!(s[i] in map) && visited.has(t[i])) || (s[i] in map && map[s[i]] !== t[i])) {
11 | return false;
12 | }
13 | map[s[i]] = t[i];
14 | visited.add(t[i]);
15 | }
16 | return true;
17 | };
18 |
--------------------------------------------------------------------------------
/src/leetcode/jewels-and-stones/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} J
3 | * @param {string} S
4 | * @return {number}
5 | */
6 | var numJewelsInStones = function(J, S) {
7 | if (!J.length || !S.length) return 0;
8 | const hash = {};
9 | for (let i = 0; i < J.length; i++) {
10 | hash[J[i]] = true;
11 | }
12 | let count = 0;
13 | for (let i = 0; i < S.length; i++) {
14 | if (hash[S[i]]) {
15 | count += 1;
16 | }
17 | }
18 | return count;
19 | };
20 |
--------------------------------------------------------------------------------
/src/leetcode/jump-game-ii/45. Jump Game II.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/jump-game-ii/45. Jump Game II.pdf
--------------------------------------------------------------------------------
/src/leetcode/jump-game-ii/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number}
4 | */
5 | var jump = function(nums) {
6 | let end = 0;
7 | let fartest = 0;
8 | let nSteps = 0;
9 | for (let i = 0; i < nums.length - 1; i++) {
10 | fartest = Math.max(fartest, i + nums[i]);
11 | if (i === end) {
12 | end = fartest;
13 | nSteps += 1;
14 | }
15 | }
16 | return nSteps;
17 | };
18 |
--------------------------------------------------------------------------------
/src/leetcode/jump-game/55. Jump Game.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/jump-game/55. Jump Game.pdf
--------------------------------------------------------------------------------
/src/leetcode/jump-game/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {boolean}
4 | */
5 | var canJump = function(nums) {
6 | let f = 0;
7 | for (let i = 0; i < nums.length; i++) {
8 | if (f >= i) {
9 | f = Math.max(f, i + nums[i]);
10 | }
11 | }
12 | return f >= nums.length - 1;
13 | };
14 |
--------------------------------------------------------------------------------
/src/leetcode/k-closest-points-to-origin/973. K Closest Points to Origin.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/k-closest-points-to-origin/973. K Closest Points to Origin.pdf
--------------------------------------------------------------------------------
/src/leetcode/k-closest-points-to-origin/topk.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/k-closest-points-to-origin/topk.pdf
--------------------------------------------------------------------------------
/src/leetcode/knight-dialer/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | Dynamic Programming
6 |
7 | dp stands for number of combinations with N digits at i
8 |
9 | recursion:
10 |
11 | ```
12 | dp[N][i] = dp[N - 1][j], for j in neighbors
13 | ```
14 |
15 | optimize with O(N) of space complexity
16 |
17 | ```
18 | next[i] += pre[neighbor] for neighbor in neighbors
19 | ```
20 |
--------------------------------------------------------------------------------
/src/leetcode/knight-probability-in-chessboard/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | The probability of `k` steps at `(i, j)` is equal to the sum of `k - 1` steps at `(x, y)` where `(x, y)` is the position around `(i, j)`.
6 |
7 | ```js
8 | dp[k][i][j] = (() => {
9 | let p = 0;
10 | for (const [di, dj] of dirs) {
11 | const x = i + di;
12 | const y = j + dj;
13 | p += (dp[k - 1][x][y] * 1) / 8;
14 | }
15 | return p;
16 | })();
17 | ```
18 |
--------------------------------------------------------------------------------
/src/leetcode/koko-eating-bananas/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} piles
3 | * @param {number} H
4 | * @return {number}
5 | */
6 | var minEatingSpeed = function(piles, H) {
7 | let left = 0;
8 | let right = Math.max(...piles);
9 | while (left < right) {
10 | const mid = Math.floor((left + right) / 2);
11 | const sum = piles.reduce((acc, cur) => acc + Math.ceil(cur / mid), 0);
12 | if (sum > H) {
13 | left = mid + 1;
14 | } else {
15 | right = mid;
16 | }
17 | }
18 | return left;
19 | };
20 |
--------------------------------------------------------------------------------
/src/leetcode/kth-largest-element-in-an-array/README.md:
--------------------------------------------------------------------------------
1 | ## README
2 |
3 | ### Test Cases
4 |
5 | ```
6 | [1,2,5,3,4], k = 3
7 | [5,(4),1,2,3]
8 |
9 | [1,4,5,3,2], k = 3
10 | [4,5,3,(2),1]
11 |
12 | [1,1,3,4,5,2]
13 | [3,4,5,1,1,2]
14 | [3,4,5,2,1,1]
15 | ```
16 |
--------------------------------------------------------------------------------
/src/leetcode/kth-largest-element-in-an-array/index.spec.js:
--------------------------------------------------------------------------------
1 | import fn from './index';
2 |
3 | test('kth-largest-element-in-an-array', () => {
4 | const arr = [1, 2, 3, 8, 4, 9, 7, 5];
5 | const sortedArr = arr.slice().sort((a, b) => b - a);
6 | const k = 3;
7 | const result = fn(arr, 3);
8 | expect(result).toEqual(sortedArr[k - 1]);
9 | });
10 |
--------------------------------------------------------------------------------
/src/leetcode/kth-smallest-element-in-a-sorted-matrix/378. Kth Smallest Element in a Sorted Matrix.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/kth-smallest-element-in-a-sorted-matrix/378. Kth Smallest Element in a Sorted Matrix.pdf
--------------------------------------------------------------------------------
/src/leetcode/largest-rectangle-in-histogram/Largest Rectangle in Histogram 3.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/largest-rectangle-in-histogram/Largest Rectangle in Histogram 3.pdf
--------------------------------------------------------------------------------
/src/leetcode/last-substring-in-lexicographical-order/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} s
3 | * @return {string}
4 | */
5 | var lastSubstring = function(s) {
6 | let max = '';
7 | for (let i = 0; i < s.length; i++) {
8 | if (s.substring(i) > max) {
9 | max = s.substring(i);
10 | }
11 | }
12 | return max;
13 | };
14 |
--------------------------------------------------------------------------------
/src/leetcode/length-of-last-word/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} s
3 | * @return {number}
4 | */
5 | var lengthOfLastWord = function(s) {
6 | let lastWord = '';
7 | for (const word of s.split(' ')) {
8 | if (word.length) {
9 | lastWord = word;
10 | }
11 | }
12 | return lastWord.length;
13 | };
14 |
--------------------------------------------------------------------------------
/src/leetcode/license-key-formatting/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} S
3 | * @param {number} K
4 | * @return {string}
5 | */
6 | var licenseKeyFormatting = function(S, K) {
7 | const s = S.replace(/-/g, '').toUpperCase();
8 | const output = [];
9 | const mod = s.length % K;
10 | for (let i = s.length - 1; i >= mod; i -= K) {
11 | output.push(s.slice(i - K + 1, i + 1));
12 | }
13 | if (mod !== 0) {
14 | output.push(s.slice(0, mod));
15 | }
16 | return output.reverse().join('-');
17 | };
18 |
--------------------------------------------------------------------------------
/src/leetcode/linked-list-cycle/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for singly-linked list.
3 | * function ListNode(val) {
4 | * this.val = val;
5 | * this.next = null;
6 | * }
7 | */
8 |
9 | /**
10 | * @param {ListNode} head
11 | * @return {boolean}
12 | */
13 | var hasCycle = function(head) {
14 | let slow = head;
15 | let fast = head;
16 | while (slow && fast && fast.next) {
17 | slow = slow.next;
18 | fast = fast.next.next;
19 | if (slow === fast) {
20 | return true;
21 | }
22 | }
23 | return false;
24 | };
25 |
--------------------------------------------------------------------------------
/src/leetcode/longest-absolute-file-path/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | Iterate over string. Each time, keep going until `\n` is met. In the process of iteration, we need to know the depth and name of that directory or file. And then keep popping out stack if `depth < stack.length`. Then put `name` into stack. Then we check if name is a file name. If so, we compute and update max value.
6 |
--------------------------------------------------------------------------------
/src/leetcode/longest-arithmetic-sequence/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | - `dp[i][diff]` stands for length of longest arithmetic sequence ending at `i` with `diff`. Similar to LIS, we scan each elements before `i` to see if `diff` exists ending at `j`. If exists, extends `dp[j][diff]` by 1.
6 | - Since `diff` can be a very large number, we use an array of object to store diff as key.
7 |
--------------------------------------------------------------------------------
/src/leetcode/longest-arithmetic-sequence/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} A
3 | * @return {number}
4 | */
5 | var longestArithSeqLength = function(A) {
6 | const m = A.length;
7 | const dp = [...new Array(m)].map(() => ({}));
8 | let max = 2;
9 | for (let i = 0; i < m; i++) {
10 | for (let j = 0; j < i; j++) {
11 | const diff = A[i] - A[j];
12 | dp[i][diff] = (dp[j][diff] || 1) + 1;
13 | max = Math.max(max, dp[i][diff]);
14 | }
15 | }
16 | return max;
17 | };
18 |
--------------------------------------------------------------------------------
/src/leetcode/longest-common-prefix/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string[]} strs
3 | * @return {string}
4 | */
5 | var longestCommonPrefix = function(strs) {
6 | if (!strs.length) {
7 | return '';
8 | }
9 | let prefix = strs[0];
10 | for (const str of strs) {
11 | while (prefix !== str.substring(0, prefix.length)) {
12 | prefix = prefix.substring(0, prefix.length - 1);
13 | }
14 | }
15 | return prefix;
16 | };
17 |
--------------------------------------------------------------------------------
/src/leetcode/longest-common-subsequence/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | ```js
6 | dp[i][j] = (() => {
7 | if (text1[i - 1] === text2[j - 1]) {
8 | return dp[i - 1][j - 1] + 1;
9 | }
10 | return Math.max(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);
11 | })();
12 | ```
13 |
--------------------------------------------------------------------------------
/src/leetcode/longest-continuous-increasing-subsequence/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number}
4 | */
5 | var findLengthOfLCIS = function(nums) {
6 | if (!nums.length) {
7 | return 0;
8 | }
9 | let n = 1;
10 | let max = n;
11 | for (let i = 1; i < nums.length; i++) {
12 | if (nums[i] > nums[i - 1]) {
13 | n += 1;
14 | } else {
15 | n = 1;
16 | }
17 | max = Math.max(max, n);
18 | }
19 | return max;
20 | };
21 |
--------------------------------------------------------------------------------
/src/leetcode/longest-palindrome/index.spec.js:
--------------------------------------------------------------------------------
1 | import fn from './index';
2 |
3 | test('longest-palindrome', () => {
4 | expect(fn('ccc')).toEqual(3);
5 | });
6 |
7 | test('longest-palindrome', () => {
8 | expect(fn('abccccdd')).toEqual(7);
9 | });
10 |
--------------------------------------------------------------------------------
/src/leetcode/longest-palindromic-subsequence/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | `dp[i][j]` stands for longest palindromic subsequence within substring `s[i:j]`
6 |
7 | ```js
8 | // prettier-ignore
9 | dp[i][j] = s[i] === s[j]
10 | ? dp[i + 1][j - 1] + 2
11 | : Math.max(dp[i][j - 1], dp[i + 1][j]);
12 | ```
13 |
--------------------------------------------------------------------------------
/src/leetcode/longest-repeating-character-replacement/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | ```js
6 | const window = 'AAABC';
7 | ```
8 |
9 | If a sliding window with `total length` = 5 and `max freq` = 3, then number of required operations to transform to repeating string is `total length - max freq`.
10 |
11 | So we can use a sliding window to keep tracking total length in sliding window and maximum frequency.
12 |
--------------------------------------------------------------------------------
/src/leetcode/longest-string-chain/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | ```
6 | dp[i] = max {
7 | dp[j] if words[i] is a predecessor of words[j]
8 | }
9 | ```
10 |
--------------------------------------------------------------------------------
/src/leetcode/longest-string-chain/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string[]} words
3 | * @return {number}
4 | */
5 | var longestStrChain = function(words) {
6 | words.sort((a, b) => a.length - b.length);
7 | const dp = {};
8 | let max = 1;
9 | for (const word of words) {
10 | dp[word] = 1;
11 | for (let i = 0; i < word.length; i++) {
12 | const predecessor = word.substring(0, i) + word.substring(i + 1);
13 | dp[word] = Math.max(dp[word], (dp[predecessor] || 0) + 1);
14 | }
15 | max = Math.max(max, dp[word]);
16 | }
17 | return max;
18 | };
19 |
--------------------------------------------------------------------------------
/src/leetcode/longest-substring-without-repeating-characters/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} s
3 | * @return {number}
4 | */
5 | var lengthOfLongestSubstring = function(s) {
6 | const visited = new Set();
7 | let start = 0;
8 | let max = 0;
9 | for (let i = 0; i < s.length; i++) {
10 | while (visited.has(s[i])) {
11 | visited.delete(s[start]);
12 | start += 1;
13 | }
14 | visited.add(s[i]);
15 | max = Math.max(max, i - start + 1);
16 | }
17 | return max;
18 | };
19 |
--------------------------------------------------------------------------------
/src/leetcode/longest-valid-parentheses/32. Longest Valid Parentheses.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/longest-valid-parentheses/32. Longest Valid Parentheses.pdf
--------------------------------------------------------------------------------
/src/leetcode/majority-element/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number}
4 | */
5 | var majorityElement = function(nums) {
6 | let el = nums[0];
7 | let count = 1;
8 | for (let i = 1; i < nums.length; i++) {
9 | count += nums[i] === el ? 1 : -1;
10 | if (count === 0) {
11 | el = nums[i];
12 | count = 1;
13 | }
14 | }
15 | return el;
16 | };
17 |
--------------------------------------------------------------------------------
/src/leetcode/majority-element/v1.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number}
4 | */
5 | var majorityElement = function(nums) {
6 | const n = nums.length;
7 | let output = 0;
8 | for (let i = 0; i < 32; i++) {
9 | // prettier-ignore
10 | const nOnes = nums
11 | .map(num => (num >> i) & 1)
12 | .reduce((acc, cur) => acc + cur, 0)
13 | const isMajority = nOnes > n / 2;
14 | if (isMajority) {
15 | output = output | (2 ** i);
16 | }
17 | }
18 | return output;
19 | };
20 |
--------------------------------------------------------------------------------
/src/leetcode/max-chunks-to-make-sorted/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} arr
3 | * @return {number}
4 | */
5 | var maxChunksToSorted = function(arr) {
6 | let nChunks = 0;
7 | for (let i = 0; i < arr.length; i++) {
8 | let max = arr[i];
9 | while (max !== i && i < arr.length) {
10 | i += 1;
11 | max = Math.max(max, arr[i]);
12 | }
13 | nChunks += 1;
14 | }
15 | return nChunks;
16 | };
17 |
--------------------------------------------------------------------------------
/src/leetcode/max-consecutive-ones-ii/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | When flipping a zero, we connect previous and current consecutive one's. So to know the max consecutive one's, we only need to know previous and current one. So we use `pre` and `cur` to store the length of previous and current consecutive one's. We update pre and cur depending on `nums[i]`. And at the same time, we also update `max` value.
6 |
7 | - Note
8 | - We initialize `pre` with `-1`. So that if we never encounter `0`, `-1 + 1` will always be zero without affecting `max`.
9 |
--------------------------------------------------------------------------------
/src/leetcode/max-consecutive-ones-ii/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number}
4 | */
5 | var findMaxConsecutiveOnes = function(nums) {
6 | let pre = -1;
7 | let cur = 0;
8 | let max = 1;
9 | for (let i = 0; i < nums.length; i++) {
10 | if (nums[i] === 1) {
11 | cur += 1;
12 | } else {
13 | pre = cur;
14 | cur = 0;
15 | }
16 | max = Math.max(max, pre + 1 + cur);
17 | }
18 | return max;
19 | };
20 |
--------------------------------------------------------------------------------
/src/leetcode/max-consecutive-ones/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number}
4 | */
5 | var findMaxConsecutiveOnes = function(nums) {
6 | let nConsecutiveOnes = nums[0];
7 | let max = nConsecutiveOnes;
8 | for (let i = 1; i < nums.length; i++) {
9 | nConsecutiveOnes = nums[i] + (nums[i] === 1 && nums[i - 1] === 1 ? nConsecutiveOnes : 0);
10 | max = Math.max(max, nConsecutiveOnes);
11 | }
12 | return max;
13 | };
14 |
--------------------------------------------------------------------------------
/src/leetcode/max-points-on-a-line/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | - Iterate over combinations of any two points. Each iteration, we do followings:
6 | - Count nEquals
7 | - Count frequency of each slope
8 | - Summarize frequency and nEquals
9 | - `max = Math.max(max, 1 + maxFreq + nEquals)`
10 | - Note
11 | - For javascript, there is a division precision issue
12 | - http://adripofjavascript.com/blog/drips/avoiding-problems-with-decimal-math-in-javascript.html
13 | - To prevent the precision issue, multiply slope with a very large number
14 |
--------------------------------------------------------------------------------
/src/leetcode/max-points-on-a-line/submit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/max-points-on-a-line/submit.png
--------------------------------------------------------------------------------
/src/leetcode/maximum-69-number/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} num
3 | * @return {number}
4 | */
5 | var maximum69Number = function(num) {
6 | const str = num + '';
7 | for (let i = 0; i < str.length; i++) {
8 | if (str[i] === '6') {
9 | return parseInt(str.substring(0, i) + '9' + str.substring(i + 1));
10 | }
11 | }
12 | return num;
13 | };
14 |
--------------------------------------------------------------------------------
/src/leetcode/maximum-length-of-repeated-subarray/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | ```js
6 | dp[i][j] = A[i - 1] === B[j - 1] ? dp[i - 1][j - 1] + 1 : 0;
7 | ```
8 |
9 | Define `dp[i][j]` as repeated length containing last element with length `i, j`.
10 |
11 | So if `A[i - 1] === B[j - 1]`, extends length by 1, otherwise set to zero.
12 |
13 | It can be reduced to O(n) as:
14 |
15 | ```js
16 | next[j] = A[i - 1] === B[j - 1] ? dp[j - 1] + 1 : 0;
17 | ```
18 |
19 | Time Complexity: O(mn)
20 | Space Complexity: O(n)
21 |
--------------------------------------------------------------------------------
/src/leetcode/maximum-number-of-events-that-can-be-attended/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[][]} events
3 | * @return {number}
4 | */
5 | var maxEvents = function(events) {
6 | events.sort((a, b) => (a[1] !== b[1] ? a[1] - b[1] : a[0] - b[0]));
7 | const visited = new Set();
8 | let nEvents = 0;
9 | for (const [s, e] of events) {
10 | for (let i = s; i <= e; i++) {
11 | if (!visited.has(i)) {
12 | visited.add(i);
13 | nEvents += 1;
14 | break;
15 | }
16 | }
17 | }
18 | return nEvents;
19 | };
20 |
--------------------------------------------------------------------------------
/src/leetcode/maximum-product-subarray/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number}
4 | */
5 |
6 | var maxProduct = function(nums) {
7 | let maxSoFar = 1;
8 | let minSoFar = 1;
9 | let max = -Infinity;
10 | for (const n of nums) {
11 | [maxSoFar, minSoFar] = [
12 | Math.max(n, n * maxSoFar, n * minSoFar),
13 | Math.min(n, n * maxSoFar, n * minSoFar),
14 | ];
15 | max = Math.max(max, maxSoFar);
16 | }
17 | return max;
18 | };
19 |
--------------------------------------------------------------------------------
/src/leetcode/maximum-product-subarray/index.spec.js:
--------------------------------------------------------------------------------
1 | import fn from './index';
2 |
3 | test('maximum-product-subarray', () => {
4 | expect(fn([2, 3, -2, 4])).toEqual(6);
5 | });
6 |
--------------------------------------------------------------------------------
/src/leetcode/maximum-size-subarray-sum-equals-k/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @param {number} k
4 | * @return {number}
5 | */
6 | var maxSubArrayLen = function(nums, k) {
7 | const map = { 0: -1 };
8 | let max = 0;
9 | let sum = 0;
10 | for (let i = 0; i < nums.length; i++) {
11 | sum += nums[i];
12 | if (sum - k in map) {
13 | max = Math.max(max, i - map[sum - k]);
14 | }
15 | if (!(sum in map)) {
16 | map[sum] = i;
17 | }
18 | }
19 | return max;
20 | };
21 |
--------------------------------------------------------------------------------
/src/leetcode/maximum-subarray-sum-with-one-deletion/1186. Maximum Subarray Sum with One Deletion.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/maximum-subarray-sum-with-one-deletion/1186. Maximum Subarray Sum with One Deletion.pdf
--------------------------------------------------------------------------------
/src/leetcode/maximum-subarray-sum-with-one-deletion/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} arr
3 | * @return {number}
4 | */
5 | var maximumSum = function(arr) {
6 | const m = arr.length;
7 | let dp = [-Infinity, -Infinity];
8 | let max = -Infinity;
9 | for (let i = 1; i <= m; i++) {
10 | const next = [0, 0];
11 | next[0] = Math.max(arr[i - 1] + dp[0], arr[i - 1]);
12 | next[1] = Math.max(arr[i - 1] + dp[1], arr[i - 1], dp[0]);
13 | dp = next;
14 | max = Math.max(max, ...dp);
15 | }
16 | return max;
17 | };
18 |
--------------------------------------------------------------------------------
/src/leetcode/maximum-subarray/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number}
4 | */
5 | var maxSubArray = function(nums) {
6 | let max = -Infinity;
7 | let maxSoFar = max;
8 | for (const n of nums) {
9 | maxSoFar = Math.max(maxSoFar + n, n);
10 | max = Math.max(max, maxSoFar);
11 | }
12 | return max;
13 | };
14 |
--------------------------------------------------------------------------------
/src/leetcode/maximum-subarray/index.spec.js:
--------------------------------------------------------------------------------
1 | import fn from './index';
2 |
3 | test('maximum-subarray', () => {
4 | expect(fn([-2, 1, -3, 4, -1, 2, 1, -5, 4])).toEqual(6);
5 | });
6 |
--------------------------------------------------------------------------------
/src/leetcode/maximum-sum-circular-subarray/918. Maximum Sum Circular Subarray.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/maximum-sum-circular-subarray/918. Maximum Sum Circular Subarray.pdf
--------------------------------------------------------------------------------
/src/leetcode/maximum-sum-of-3-non-overlapping-subarrays/689. Maximum Sum of 3 Non-Overlapping Subarrays.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/maximum-sum-of-3-non-overlapping-subarrays/689. Maximum Sum of 3 Non-Overlapping Subarrays.pdf
--------------------------------------------------------------------------------
/src/leetcode/maximum-swap/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | # Algorithm
4 |
5 | Starting from the beginning, search for the element that is:
6 |
7 | - Greater than `num[i]`
8 | - Existing in `map`
9 | - `j` > `i`
10 |
11 | And then swap `num[i]` with `num[j]`.
12 |
--------------------------------------------------------------------------------
/src/leetcode/maximum-vacation-days/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | Define `dp[i][p]` as maximum value at `ith` day at `pth` city.
6 |
7 | ```js
8 | dp[i][p] = Math.max(
9 | dp[i][p],
10 | dp[i - 1][q] + days[p][i] if (be able to stay at p)
11 | )
12 | ```
13 |
14 | So `dp[i][p]` is `dp[i - 1][q] + days[p][i]` if `p` is reachable from `q` for all `q`.
15 |
--------------------------------------------------------------------------------
/src/leetcode/median-of-two-sorted-arrays/IMG_1777.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/median-of-two-sorted-arrays/IMG_1777.JPG
--------------------------------------------------------------------------------
/src/leetcode/meeting-rooms-ii/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[][]} intervals
3 | * @return {number}
4 | */
5 | var minMeetingRooms = function(intervals) {
6 | const timeline = [];
7 | for (const [s, e] of intervals) {
8 | timeline.push([s, 1]);
9 | timeline.push([e, -1]);
10 | }
11 | timeline.sort((a, b) => (a[0] !== b[0] ? a[0] - b[0] : a[1] - b[1]));
12 | let count = 0;
13 | let max = 0;
14 | for (const [t, delta] of timeline) {
15 | count += delta;
16 | max = Math.max(max, count);
17 | }
18 | return max;
19 | };
20 |
--------------------------------------------------------------------------------
/src/leetcode/merge-k-sorted-lists/screencapture-leetcode-submissions-detail-191108256-2018-11-23-01_51_44.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/merge-k-sorted-lists/screencapture-leetcode-submissions-detail-191108256-2018-11-23-01_51_44.png
--------------------------------------------------------------------------------
/src/leetcode/min-cost-climbing-stairs/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} cost
3 | * @return {number}
4 | */
5 |
6 | /*
7 | f(i) = Math.min(
8 | f(i - 2) + cost[i],
9 | f(i - 1) + cost[i],
10 | )
11 | */
12 |
13 | var minCostClimbingStairs = function(cost) {
14 | let x = cost[0];
15 | let y = cost[1];
16 | let output;
17 | cost.push(0);
18 | for (let i = 2; i < cost.length; i++) {
19 | output = Math.min(x, y) + cost[i];
20 | x = y;
21 | y = output;
22 | }
23 | return output;
24 | };
25 |
--------------------------------------------------------------------------------
/src/leetcode/minimize-malware-spread/924. Minimize Malware Spread.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/minimize-malware-spread/924. Minimize Malware Spread.pdf
--------------------------------------------------------------------------------
/src/leetcode/minimum-add-to-make-parentheses-valid/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} S
3 | * @return {number}
4 | */
5 | var minAddToMakeValid = function(S) {
6 | let stack = 0;
7 | let nSteps = 0;
8 | for (let i = 0; i < S.length; i++) {
9 | if (S[i] === '(') {
10 | stack += 1;
11 | } else if (S[i] === ')') {
12 | if (!stack) {
13 | nSteps += 1;
14 | } else {
15 | stack -= 1;
16 | }
17 | }
18 | }
19 | return nSteps + stack;
20 | };
21 |
--------------------------------------------------------------------------------
/src/leetcode/minimum-area-rectangle/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | - Create a set to store all points. So that given (x, y), we can know if this point exists or not.
6 | - Iterate over combinations of two points representing diagonal points of the rectangle.
7 | - If rest of the two points exists in the set, we have found a rectangle. Then update min value.
8 | - Finally return min value.
9 |
--------------------------------------------------------------------------------
/src/leetcode/minimum-depth-of-binary-tree/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for a binary tree node.
3 | * function TreeNode(val) {
4 | * this.val = val;
5 | * this.left = this.right = null;
6 | * }
7 | */
8 | /**
9 | * @param {TreeNode} root
10 | * @return {number}
11 | */
12 | var minDepth = function(root) {
13 | if (!root) {
14 | return 0;
15 | }
16 | const left = minDepth(root.left);
17 | const right = minDepth(root.right);
18 | if (left && right) {
19 | return Math.min(left, right) + 1;
20 | }
21 | return (left || right) + 1;
22 | };
23 |
--------------------------------------------------------------------------------
/src/leetcode/minimum-domino-rotations-for-equal-row/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | In the rotated result, all values must either be `A[0]` or `B[0]`.
6 |
7 | There are 4 possible combinations. So we compute all 4 combinations and take the minimum.
8 |
9 | - All `A` is equal to `A[0]`
10 | - All `A` is equal to `B[0]`
11 | - All `B` is equal to `A[0]`
12 | - All `B` is equal to `B[0]`
13 |
14 | `count` This function counts how many swaps are required to make all elements in first array equal to target.
15 |
--------------------------------------------------------------------------------
/src/leetcode/minimum-falling-path-sum/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | Define `dp[i][j]` as path sum from first row sum up to `(i, j)`. So at `(i, j)`, the path can come from left, middle or right.
6 |
7 | ```js
8 | dp[i][j] = A[i][j] + Math.min(dp[i - 1][j - 1], dp[i - 1][j], dp[i - 1][j + 1]);
9 | ```
10 |
11 | This formula takes `O(MN)` space. We can optimize it to use `O(N)` space.
12 |
13 | ```js
14 | next[j] = A[i][j] + Math.min(dp[j - 1], dp[j], dp[j + 1]);
15 | ```
16 |
--------------------------------------------------------------------------------
/src/leetcode/minimum-path-sum/index.spec.js:
--------------------------------------------------------------------------------
1 | import fn from './index';
2 |
3 | test('minimum-path-sum', () => {
4 | expect(fn([[1, 3, 1], [1, 5, 1], [4, 2, 1]])).toEqual(7);
5 | });
6 |
--------------------------------------------------------------------------------
/src/leetcode/minimum-size-subarray-sum/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} s
3 | * @param {number[]} nums
4 | * @return {number}
5 | */
6 | var minSubArrayLen = function(s, nums) {
7 | let sum = 0;
8 | let start = 0;
9 | let min = Infinity;
10 | for (let i = 0; i < nums.length; i++) {
11 | sum += nums[i];
12 | while (sum >= s) {
13 | min = Math.min(min, i - start + 1);
14 | sum -= nums[start];
15 | start += 1;
16 | }
17 | }
18 | return min < Infinity ? min : 0;
19 | };
20 |
--------------------------------------------------------------------------------
/src/leetcode/minimum-time-visiting-all-points/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[][]} points
3 | * @return {number}
4 | */
5 | var minTimeToVisitAllPoints = function(points) {
6 | let sum = 0;
7 | for (let i = 1; i < points.length; i++) {
8 | sum += getTime(points[i - 1], points[i]);
9 | }
10 | return sum;
11 | };
12 |
13 | function getTime([x1, y1], [x2, y2]) {
14 | return Math.max(Math.abs(x1 - x2), Math.abs(y1 - y2));
15 | }
16 |
--------------------------------------------------------------------------------
/src/leetcode/minimum-window-subsequence/727. Minimum Window Subsequence.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/minimum-window-subsequence/727. Minimum Window Subsequence.pdf
--------------------------------------------------------------------------------
/src/leetcode/missing-number/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number}
4 | */
5 |
6 | const swap = (arr, i, j) => {
7 | const tmp = arr[i];
8 | arr[i] = arr[j];
9 | arr[j] = tmp;
10 | };
11 |
12 | var missingNumber = function(nums) {
13 | for (let i = 0; i < nums.length; i++) {
14 | while (nums[i] !== i && nums[i] !== undefined) {
15 | swap(nums, i, nums[i]);
16 | }
17 | }
18 | for (let i = 0; i < nums.length; i++) {
19 | if (nums[i] !== i) {
20 | return i;
21 | }
22 | }
23 | return nums.length;
24 | };
25 |
--------------------------------------------------------------------------------
/src/leetcode/monotonic-array/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} A
3 | * @return {boolean}
4 | */
5 | var isMonotonic = function(A) {
6 | let delta = 0;
7 | for (let i = 0; i < A.length - 1; i++) {
8 | if ((delta > 0) & (A[i + 1] < A[i]) || (delta < 0 && A[i + 1] > A[i])) {
9 | return false;
10 | }
11 | if (delta === 0) {
12 | delta = A[i + 1] - A[i];
13 | }
14 | }
15 | return true;
16 | };
17 |
--------------------------------------------------------------------------------
/src/leetcode/most-stones-removed-with-same-row-or-column/947. Most Stones Removed with Same Row or Column.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/most-stones-removed-with-same-row-or-column/947. Most Stones Removed with Same Row or Column.pdf
--------------------------------------------------------------------------------
/src/leetcode/move-zeroes/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {void} Do not return anything, modify nums in-place instead.
4 | */
5 |
6 | var moveZeroes = function(nums) {
7 | let j = 0;
8 | for (let i = 0; i < nums.length; i++) {
9 | if (nums[i] !== 0) {
10 | [nums[i], nums[j]] = [nums[j], nums[i]];
11 | j++;
12 | }
13 | }
14 | };
15 |
--------------------------------------------------------------------------------
/src/leetcode/multiply-strings/index.spec.js:
--------------------------------------------------------------------------------
1 | import fn from './index';
2 |
3 | test('multiply-strings', () => {
4 | expect(fn('111111', '11')).toEqual('1222221');
5 | });
6 |
7 | test('multiply-strings', () => {
8 | expect(fn('111111', '0')).toEqual('0');
9 | });
10 |
11 | test('multiply-strings', () => {
12 | expect(fn('999999999', '999999999')).toEqual('999999998000000001');
13 | });
14 |
--------------------------------------------------------------------------------
/src/leetcode/my-calendar-i/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | Use an array to store sorted intervals. For each booking, use `upperBound` to search for interval with minimum start that is greater than input start time. Then we check if it's overlapped with any of `events[i - 1]` or `event[i]`. If it's overlapped, it's not bookable. Otherwise, it's bookable and insert interval at the index.
6 |
--------------------------------------------------------------------------------
/src/leetcode/n-queens/N-Queens.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/n-queens/N-Queens.pdf
--------------------------------------------------------------------------------
/src/leetcode/next-greater-element-i/496. Next Greater Element I.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/next-greater-element-i/496. Next Greater Element I.pdf
--------------------------------------------------------------------------------
/src/leetcode/next-greater-element-i/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums1
3 | * @param {number[]} nums2
4 | * @return {number[]}
5 | */
6 | var nextGreaterElement = function(nums1, nums2) {
7 | const stack = [];
8 | const map = {};
9 | for (const i of nums2) {
10 | while (stack.length && i > stack[stack.length - 1]) {
11 | map[stack[stack.length - 1]] = i;
12 | stack.pop();
13 | }
14 | stack.push(i);
15 | }
16 | return nums1.map((i) => (i in map ? map[i] : -1));
17 | };
18 |
--------------------------------------------------------------------------------
/src/leetcode/next-greater-element-ii/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number[]}
4 | */
5 | var nextGreaterElements = function(nums) {
6 | const stack = [];
7 | const map = {};
8 | const m = nums.length;
9 | for (let i = 0; i < 2 * m; i++) {
10 | const num = nums[i % m];
11 | while (stack.length && nums[stack[stack.length - 1]] < num) {
12 | map[stack.pop()] = num;
13 | }
14 | if (i < m) {
15 | stack.push(i);
16 | }
17 | }
18 | return nums.map((_, i) => (i in map ? map[i] : -1));
19 | };
20 |
--------------------------------------------------------------------------------
/src/leetcode/next-permutation/Next Permutation.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/next-permutation/Next Permutation.pdf
--------------------------------------------------------------------------------
/src/leetcode/non-overlapping-intervals/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | First of all, sort intervals by start time.
6 |
7 | `pre` points to the previous interval that is not removed.
8 | `nRemoved` stores number of intervals to remove
9 |
10 | Iterate over intervals.
11 |
12 | If previous interval is overlapped with current one, increment `nRemoved` by one and preserve the one with earlier end time. That is, set `pre` to the one with earlier end time.
13 |
14 | Otherwise, set `pre` to current one.
15 |
--------------------------------------------------------------------------------
/src/leetcode/number-of-burgers-with-no-waste-of-ingredients/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | ```
6 | 4x + 2y = A
7 | x + y = B
8 | x = (A - 2B) / 2
9 | y = (4B - A) / 2
10 | ```
11 |
--------------------------------------------------------------------------------
/src/leetcode/number-of-burgers-with-no-waste-of-ingredients/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} tomatoSlices
3 | * @param {number} cheeseSlices
4 | * @return {number[]}
5 | */
6 | var numOfBurgers = function(tomatoSlices, cheeseSlices) {
7 | const x = (tomatoSlices - 2 * cheeseSlices) / 2;
8 | const y = (4 * cheeseSlices - tomatoSlices) / 2;
9 | if (Number.isInteger(x) && x >= 0 && Number.isInteger(y) && y >= 0) {
10 | return [x, y];
11 | }
12 | return [];
13 | };
14 |
--------------------------------------------------------------------------------
/src/leetcode/number-of-days-between-two-dates/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} date1
3 | * @param {string} date2
4 | * @return {number}
5 | */
6 | var daysBetweenDates = function(date1, date2) {
7 | const t1 = new Date(date1).getTime();
8 | const t2 = new Date(date2).getTime();
9 | return Math.abs(t2 - t1) / (24 * 60 * 60 * 1000);
10 | };
11 |
--------------------------------------------------------------------------------
/src/leetcode/number-of-islands-ii/submit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/number-of-islands-ii/submit.png
--------------------------------------------------------------------------------
/src/leetcode/number-of-operations-to-make-network-connected/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | If there are n computers, it only requires n - 1 edges to make it connected. So if there are more than n - 1 edges, it must be able to make it connected.
6 |
7 | Use DFS to find number of groups. To connect those disconnected groups, it requires (number of groups - 1) moves.
8 |
--------------------------------------------------------------------------------
/src/leetcode/number-of-subarrays-with-bounded-maximum/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | Number of subarrays between [L, R] is equal to `number of subarrays less than R` - `number of subarrays less than L`.
6 |
--------------------------------------------------------------------------------
/src/leetcode/number-of-subarrays-with-bounded-maximum/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} A
3 | * @param {number} L
4 | * @param {number} R
5 | * @return {number}
6 | */
7 | var numSubarrayBoundedMax = function(A, L, R) {
8 | return count(A, R) - count(A, L - 1);
9 | };
10 |
11 | function count(arr, max) {
12 | let output = 0;
13 | let nTarget = 0;
14 | for (const num of arr) {
15 | nTarget = num <= max ? nTarget + 1 : 0;
16 | output += nTarget;
17 | }
18 | return output;
19 | }
20 |
--------------------------------------------------------------------------------
/src/leetcode/number-of-submatrices-that-sum-to-target/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | Use `left` and `right` to find all combinations of columns. That is, `left` starts from `0 ~ n`. `right` starts from `left ~ n`. So that it will start from any position and with any width. For each fixed width, we store the sum in each row between column `left` and `right` to `arr[i]`. Then we can use 1-D subarray sum equals to target technique to count how many submatrix sum equals to target.
6 |
7 | Time Complexity: O(n\*\*3)
8 | Space Complexity: O(n)
9 |
--------------------------------------------------------------------------------
/src/leetcode/number-of-valid-subarrays/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number}
4 | */
5 | var validSubarrays = function(nums) {
6 | const stack = [];
7 | let count = 0;
8 | for (const num of nums) {
9 | while (stack.length && num < stack[stack.length - 1]) {
10 | count += stack.length;
11 | stack.pop();
12 | }
13 | stack.push(num);
14 | }
15 | while (stack.length) {
16 | count += stack.length;
17 | stack.pop();
18 | }
19 | return count;
20 | };
21 |
--------------------------------------------------------------------------------
/src/leetcode/one-edit-distance/README.md:
--------------------------------------------------------------------------------
1 | ## README
2 |
3 | ### Algorithm
4 |
5 | ```
6 | s | t
7 | insert: ab acb
8 | delete: acb ab
9 | replace: abc adc
10 | ```
11 |
12 | - If difference in length is greater than 1, return false.
13 | - Iterate over s and t, find out the first different character.
14 | - If `t.length > s.length`, insert a character to s at `i` and compare with t.
15 | - If `s.length > t.length`, delete a character from s at `i` and compare with t.
16 | - If `s.length === t.length`, replace a character in s at `i` and compare with t.
17 |
--------------------------------------------------------------------------------
/src/leetcode/paint-fence/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} n
3 | * @param {number} k
4 | * @return {number}
5 | */
6 | var numWays = function(n, k) {
7 | const dp = [0, k, k * k];
8 | if (n <= 2) {
9 | return dp[n];
10 | }
11 | for (let i = 3; i <= n; i++) {
12 | const result = dp[1] * (k - 1) + dp[2] * (k - 1);
13 | [dp[0], dp[1], dp[2]] = [dp[1], dp[2], result];
14 | }
15 | return dp[2];
16 | };
17 |
--------------------------------------------------------------------------------
/src/leetcode/palindrome-linked-list/README.md:
--------------------------------------------------------------------------------
1 | ## README
2 |
3 | ### Algorithm
4 |
5 | - Split the list into two with equal length
6 | - Reverse the left of the list during the process
7 | - Compare the two lists for equality. They should be equal if it's a palindrome.
8 |
--------------------------------------------------------------------------------
/src/leetcode/palindrome-number/9. Palindrome Number.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/palindrome-number/9. Palindrome Number.pdf
--------------------------------------------------------------------------------
/src/leetcode/palindrome-number/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} x
3 | * @return {boolean}
4 | */
5 | var isPalindrome = function(x) {
6 | if (x < 0) return false;
7 | let y = x;
8 | let n = 0;
9 | while (y) {
10 | n = n * 10 + (y % 10);
11 | y = Math.floor(y / 10);
12 | }
13 | return n === x;
14 | };
15 |
--------------------------------------------------------------------------------
/src/leetcode/palindrome-permutation/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} s
3 | * @return {boolean}
4 | */
5 | var canPermutePalindrome = function(s) {
6 | const freq = {};
7 | for (const c of s) {
8 | freq[c] = (freq[c] || 0) + 1;
9 | }
10 | let nOdds = 0;
11 | for (const c in freq) {
12 | if (freq[c] % 2 === 1) {
13 | nOdds += 1;
14 | }
15 | if (nOdds > 1) {
16 | return false;
17 | }
18 | }
19 | return true;
20 | };
21 |
--------------------------------------------------------------------------------
/src/leetcode/pancake-sorting/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | ```
6 | A[i] is a permutation of [1, 2, ..., A.length]
7 | ```
8 |
9 | We iterate starting from A.length to 1. For each time, if i is not on its position, we reverse array to make i to A[0], then reverse array to make it to its corresponding position.
10 |
--------------------------------------------------------------------------------
/src/leetcode/partition-array-into-disjoint-intervals/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} A
3 | * @return {number}
4 | */
5 | var partitionDisjoint = function(A) {
6 | const partition = { max: A[0], index: 0 };
7 | let max = A[0];
8 | for (let i = 1; i < A.length; i++) {
9 | max = Math.max(max, A[i]);
10 | if (A[i] < partition.max) {
11 | partition.max = max;
12 | partition.index = i;
13 | }
14 | }
15 | return partition.index + 1;
16 | };
17 |
--------------------------------------------------------------------------------
/src/leetcode/partition-labels/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} S
3 | * @return {number[]}
4 | */
5 | var partitionLabels = function(S) {
6 | const map = {};
7 | for (let i = 0; i < S.length; i++) {
8 | map[S[i]] = i;
9 | }
10 | const output = [];
11 | let start = 0;
12 | let end = 0;
13 | for (let i = 0; i < S.length; i++) {
14 | end = Math.max(end, map[S[i]]);
15 | if (i === end) {
16 | output.push(i - start + 1);
17 | start = i + 1;
18 | }
19 | }
20 | return output;
21 | };
22 |
--------------------------------------------------------------------------------
/src/leetcode/pascals-triangle-ii/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} rowIndex
3 | * @return {number[]}
4 | */
5 | /*
6 | f(i, j) = f(i - 1, j - 1) + f(i - 1, j)
7 | */
8 | const getRow = function(rowIndex) {
9 | const output = new Array(rowIndex + 1).fill(0);
10 | output[0] = 1;
11 | for (let i = 1; i <= rowIndex; i++) {
12 | for (let j = i; j > 0; j--) {
13 | output[j] = (output[j - 1] || 0) + (output[j] || 0);
14 | }
15 | }
16 | return output;
17 | };
18 |
19 | export default getRow;
20 |
--------------------------------------------------------------------------------
/src/leetcode/pascals-triangle-ii/index.spec.js:
--------------------------------------------------------------------------------
1 | import fn from './index';
2 |
3 | test('pascals-triangle-ii', () => {
4 | expect(fn(3)).toEqual([1, 3, 3, 1]);
5 | });
6 |
--------------------------------------------------------------------------------
/src/leetcode/pascals-triangle/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} numRows
3 | * @return {number[][]}
4 | */
5 | const generate = function(numRows) {
6 | if (!numRows) {
7 | return [];
8 | }
9 | const output = new Array(numRows);
10 | output[0] = [1];
11 | for (let i = 1; i < numRows; i++) {
12 | output[i] = new Array(i + 1).fill(0);
13 | for (let j = 0; j < i + 1; j++) {
14 | output[i][j] = (output[i - 1][j - 1] || 0) + (output[i - 1][j] || 0);
15 | }
16 | }
17 | return output;
18 | };
19 |
20 | export default generate;
21 |
--------------------------------------------------------------------------------
/src/leetcode/pascals-triangle/index.spec.js:
--------------------------------------------------------------------------------
1 | import fn from './index';
2 |
3 | test('pascals-triangle', () => {
4 | expect(fn(5)).toEqual([
5 | [1],
6 | [1, 1],
7 | [1, 2, 1],
8 | [1, 3, 3, 1],
9 | [1, 4, 6, 4, 1],
10 | ]);
11 | });
12 |
--------------------------------------------------------------------------------
/src/leetcode/peak-index-in-a-mountain-array/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} A
3 | * @return {number}
4 | */
5 | var peakIndexInMountainArray = function(A) {
6 | let left = 0;
7 | let right = A.length;
8 | while (left < right) {
9 | const mid = Math.floor((left + right) / 2);
10 | if (A[mid] < A[mid + 1]) {
11 | left = mid + 1;
12 | } else {
13 | right = mid;
14 | }
15 | }
16 | return left;
17 | };
18 |
--------------------------------------------------------------------------------
/src/leetcode/perfect-squares/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} n
3 | * @return {number}
4 | */
5 | var numSquares = function(n) {
6 | const dp = new Array(n + 1).fill(0);
7 | dp[1] = 1;
8 | for (let i = 2; i <= n; i++) {
9 | dp[i] = helper(i, dp);
10 | }
11 | return dp[n];
12 | };
13 |
14 | function helper(i, dp) {
15 | let min = Infinity;
16 | let j = 1;
17 | while (i - j ** 2 >= 0) {
18 | min = Math.min(min, 1 + dp[i - j ** 2]);
19 | j += 1;
20 | }
21 | return min;
22 | }
23 |
--------------------------------------------------------------------------------
/src/leetcode/perfect-squares/index.spec.js:
--------------------------------------------------------------------------------
1 | import fn from './index';
2 |
3 | test('perfect-squares', () => {
4 | expect(fn(0)).toEqual(0);
5 | });
6 |
7 | test('perfect-squares', () => {
8 | expect(fn(12)).toEqual(3);
9 | });
10 |
11 | test('perfect-squares', () => {
12 | expect(fn(111)).toEqual(4);
13 | });
14 |
--------------------------------------------------------------------------------
/src/leetcode/permutations/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number[][]}
4 | */
5 | var permute = function(nums, selected = new Set(), output = []) {
6 | if (selected.size === nums.length) {
7 | output.push([...selected].map((i) => nums[i]));
8 | return output;
9 | }
10 | for (let i = 0; i < nums.length; i++) {
11 | if (!selected.has(i)) {
12 | selected.add(i);
13 | permute(nums, selected, output);
14 | selected.delete(i);
15 | }
16 | }
17 | return output;
18 | };
19 |
--------------------------------------------------------------------------------
/src/leetcode/permutations/index.spec.js:
--------------------------------------------------------------------------------
1 | import fn from './index';
2 |
3 | test('permutations', () => {
4 | expect(fn([1, 2, 3])).toEqual([
5 | [1, 2, 3],
6 | [1, 3, 2],
7 | [2, 1, 3],
8 | [2, 3, 1],
9 | [3, 1, 2],
10 | [3, 2, 1],
11 | ]);
12 | });
13 |
--------------------------------------------------------------------------------
/src/leetcode/plus-one/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} digits
3 | * @return {number[]}
4 | */
5 | var plusOne = function(digits) {
6 | const output = [];
7 | let c = 1;
8 | let i = digits.length - 1;
9 | while (c || i >= 0) {
10 | const sum = (digits[i] || 0) + c;
11 | output.unshift(sum % 10);
12 | c = Math.floor(sum / 10);
13 | i -= 1;
14 | }
15 | return output;
16 | };
17 |
--------------------------------------------------------------------------------
/src/leetcode/populating-next-right-pointers-in-each-node-ii/117. Populating Next Right Pointers in Each Node II.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/populating-next-right-pointers-in-each-node-ii/117. Populating Next Right Pointers in Each Node II.pdf
--------------------------------------------------------------------------------
/src/leetcode/populating-next-right-pointers-in-each-node/116. Populating Next Right Pointers in Each Node.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/populating-next-right-pointers-in-each-node/116. Populating Next Right Pointers in Each Node.pdf
--------------------------------------------------------------------------------
/src/leetcode/power-of-two/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} n
3 | * @return {boolean}
4 | */
5 | var isPowerOfTwo = function(n) {
6 | if (!n) {
7 | return false;
8 | }
9 | let nOnes = 0;
10 | let num = n;
11 | while (num) {
12 | nOnes += num & 1;
13 | num = num >> 1;
14 | if (nOnes >= 2) {
15 | return false;
16 | }
17 | }
18 | return true;
19 | };
20 |
--------------------------------------------------------------------------------
/src/leetcode/powx-n/50. Pow(x, n).pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/powx-n/50. Pow(x, n).pdf
--------------------------------------------------------------------------------
/src/leetcode/powx-n/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} x
3 | * @param {number} n
4 | * @return {number}
5 | */
6 | const MIN = -(2 ** 31);
7 |
8 | var myPow = function(x, n) {
9 | if (x > 1 && n <= MIN) {
10 | return 0;
11 | }
12 | let p = x;
13 | let q = Math.abs(n);
14 | let output = 1;
15 | while (q > 0) {
16 | output = (q & 1) === 1 ? output * p : output;
17 | p = p * p;
18 | q = q >> 1;
19 | }
20 | return n >= 0 ? output : 1 / output;
21 | };
22 |
--------------------------------------------------------------------------------
/src/leetcode/powx-n/recursive.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} x
3 | * @param {number} n
4 | * @return {number}
5 | */
6 | var myPow = function(x, n) {
7 | if (n === 0) {
8 | return 1;
9 | }
10 | if (n === 1) {
11 | return x;
12 | }
13 | const m = Math.abs(n);
14 | const p = Math.floor(m / 2);
15 | const val = myPow(x, p);
16 | const result = m % 2 === 1 ? x * val * val : val * val;
17 | return n > 0 ? result : 1 / result;
18 | };
19 |
--------------------------------------------------------------------------------
/src/leetcode/prison-cells-after-n-days/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} cells
3 | * @param {number} N
4 | * @return {number[]}
5 | */
6 | var prisonAfterNDays = function(cells, N) {
7 | N = N % 14 > 0 ? N % 14 : 14;
8 | const m = cells.length;
9 | let arr = [...cells];
10 | for (let i = 0; i < N; i++) {
11 | const next = new Array(m).fill(0);
12 | for (let j = 1; j < m - 1; j++) {
13 | next[j] = arr[j - 1] === arr[j + 1] ? 1 : 0;
14 | }
15 | arr = next;
16 | }
17 | return arr;
18 | };
19 |
--------------------------------------------------------------------------------
/src/leetcode/product-of-array-except-self/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number[]}
4 | */
5 | var productExceptSelf = function(nums) {
6 | const output = new Array(nums.length).fill(1);
7 | let p = nums[0];
8 | for (let i = 1; i < nums.length; i++) {
9 | output[i] *= p;
10 | p *= nums[i];
11 | }
12 | p = nums[nums.length - 1];
13 | for (let i = nums.length - 2; i >= 0; i--) {
14 | output[i] *= p;
15 | p *= nums[i];
16 | }
17 | return output;
18 | };
19 |
--------------------------------------------------------------------------------
/src/leetcode/product-of-array-except-self/index.spec.js:
--------------------------------------------------------------------------------
1 | import fn from './index';
2 |
3 | test('product-of-array-except-self', () => {
4 | expect(fn([1, 2, 3, 4])).toEqual([24, 12, 8, 6]);
5 | });
6 |
--------------------------------------------------------------------------------
/src/leetcode/queens-that-can-attack-the-king/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | Use BFS to search for the position of queens. There are 8 directions going out from king. For every direction, keep going until position is no longer valid or there exists a queen on the path.
6 |
--------------------------------------------------------------------------------
/src/leetcode/random-pick-index/reservoir_sampling.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/random-pick-index/reservoir_sampling.png
--------------------------------------------------------------------------------
/src/leetcode/random-pick-with-weight/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | 1. Transform weights to accumulate sum.
4 | 2. Use lower bound to search for index.
5 |
6 | ex:
7 |
8 | ```js
9 | const weights = [3, 3, 3, 4];
10 | const arr = [3, 6, 9, 13];
11 | ```
12 |
13 | So if `r = 12`, index will be 3.
14 | if `r = 7`, index will be 2.
15 |
--------------------------------------------------------------------------------
/src/leetcode/range-sum-query-2d-immutable/304. Range Sum Query 2D - Immutable.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/range-sum-query-2d-immutable/304. Range Sum Query 2D - Immutable.pdf
--------------------------------------------------------------------------------
/src/leetcode/range-sum-query-2d-mutable/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## References
4 |
5 | - http://bgmeow.xyz/2017/03/25/LeetCode-308/
6 |
--------------------------------------------------------------------------------
/src/leetcode/reaching-points/780. Reaching Points.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/reaching-points/780. Reaching Points.pdf
--------------------------------------------------------------------------------
/src/leetcode/reconstruct-itinerary/332. Reconstruct Itinerary.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/reconstruct-itinerary/332. Reconstruct Itinerary.pdf
--------------------------------------------------------------------------------
/src/leetcode/rectangle-overlap/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} rec1
3 | * @param {number[]} rec2
4 | * @return {boolean}
5 | */
6 | var isRectangleOverlap = function(rec1, rec2) {
7 | const xOverlap = [Math.max(rec1[0], rec2[0]), Math.min(rec1[2], rec2[2])];
8 | const yOverlap = [Math.max(rec1[1], rec2[1]), Math.min(rec1[3], rec2[3])];
9 | return isValid(xOverlap) && isValid(yOverlap);
10 | };
11 |
12 | function isValid([start, end]) {
13 | if (start >= end) {
14 | return false;
15 | }
16 | return true;
17 | }
18 |
--------------------------------------------------------------------------------
/src/leetcode/regular-expression-matching/10. Regular Expression Matching.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/regular-expression-matching/10. Regular Expression Matching.pdf
--------------------------------------------------------------------------------
/src/leetcode/remove-duplicates-from-sorted-array/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @return {number}
4 | */
5 |
6 | var removeDuplicates = function(nums) {
7 | let j = 1;
8 | for (let i = 1; i < nums.length; i++) {
9 | if (nums[i] !== nums[j - 1]) {
10 | [nums[i], nums[j]] = [nums[j], nums[i]];
11 | j += 1;
12 | }
13 | }
14 | return j;
15 | };
16 |
--------------------------------------------------------------------------------
/src/leetcode/remove-duplicates-from-sorted-list/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for singly-linked list.
3 | * function ListNode(val) {
4 | * this.val = val;
5 | * this.next = null;
6 | * }
7 | */
8 | /**
9 | * @param {ListNode} head
10 | * @return {ListNode}
11 | */
12 | var deleteDuplicates = function(head) {
13 | if (!head) {
14 | return head;
15 | }
16 | let ptr = head.next;
17 | while (ptr && ptr.val === head.val) {
18 | ptr = ptr.next;
19 | }
20 | head.next = ptr;
21 | deleteDuplicates(ptr);
22 | return head;
23 | };
24 |
--------------------------------------------------------------------------------
/src/leetcode/remove-element/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @param {number} val
4 | * @return {number}
5 | */
6 | var removeElement = function(nums, val) {
7 | let j = 0;
8 | for (let i = 0; i < nums.length; i++) {
9 | if (nums[i] !== val) {
10 | [nums[i], nums[j]] = [nums[j], nums[i]];
11 | j += 1;
12 | }
13 | }
14 | return j;
15 | };
16 |
--------------------------------------------------------------------------------
/src/leetcode/remove-interval/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[][]} intervals
3 | * @param {number[]} toBeRemoved
4 | * @return {number[][]}
5 | */
6 | var removeInterval = function(intervals, toBeRemoved) {
7 | const [rs, re] = toBeRemoved;
8 | const arr = [];
9 | for (const [s, e] of intervals) {
10 | if (e <= rs || s >= re) {
11 | arr.push([s, e]);
12 | } else {
13 | if (s < rs) {
14 | arr.push([s, rs]);
15 | }
16 | if (e > re) {
17 | arr.push([re, e]);
18 | }
19 | }
20 | }
21 | return arr;
22 | };
23 |
--------------------------------------------------------------------------------
/src/leetcode/remove-linked-list-elements/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for singly-linked list.
3 | * function ListNode(val) {
4 | * this.val = val;
5 | * this.next = null;
6 | * }
7 | */
8 | /**
9 | * @param {ListNode} head
10 | * @param {number} val
11 | * @return {ListNode}
12 | */
13 | var removeElements = function(head, val) {
14 | if (!head) {
15 | return head;
16 | }
17 | head.next = removeElements(head.next, val);
18 | return head.val !== val ? head : head.next;
19 | };
20 |
--------------------------------------------------------------------------------
/src/leetcode/remove-linked-list-elements/screencapture-leetcode-submissions-detail-192938904-2018-12-02-23_17_08.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/remove-linked-list-elements/screencapture-leetcode-submissions-detail-192938904-2018-12-02-23_17_08.png
--------------------------------------------------------------------------------
/src/leetcode/remove-outermost-parentheses/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} S
3 | * @return {string}
4 | */
5 | var removeOuterParentheses = function(S) {
6 | const stack = [];
7 | let output = '';
8 | for (let i = 0; i < S.length; i++) {
9 | if (S[i] === '(') {
10 | stack.push(i);
11 | } else if (S[i] === ')') {
12 | const left = stack.pop();
13 | if (!stack.length) {
14 | output += S.substring(left + 1, i);
15 | }
16 | }
17 | }
18 | return output;
19 | };
20 |
--------------------------------------------------------------------------------
/src/leetcode/remove-sub-folders-from-the-filesystem/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string[]} folder
3 | * @return {string[]}
4 | */
5 | var removeSubfolders = function(folder) {
6 | folder.sort();
7 | const output = [];
8 | let parent = null;
9 | for (const path of folder) {
10 | if (!path.startsWith(parent)) {
11 | output.push(path);
12 | parent = path + '/';
13 | }
14 | }
15 | return output;
16 | };
17 |
--------------------------------------------------------------------------------
/src/leetcode/repeated-substring-pattern/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} s
3 | * @return {boolean}
4 | */
5 | var repeatedSubstringPattern = function(s) {
6 | const m = s.length;
7 | for (let length = 1; length < m; length++) {
8 | const isDivisible = m % length === 0;
9 | const repeated = s.substring(0, length).repeat(m / length);
10 | if (isDivisible && repeated === s) {
11 | return true;
12 | }
13 | }
14 | return false;
15 | };
16 |
--------------------------------------------------------------------------------
/src/leetcode/restore-ip-addresses/93. Restore IP Addresses.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/restore-ip-addresses/93. Restore IP Addresses.pdf
--------------------------------------------------------------------------------
/src/leetcode/reverse-integer/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number} x
3 | * @return {number}
4 | */
5 |
6 | const MAX = 2 ** 31 - 1;
7 | const MIN = -(2 ** 31);
8 |
9 | var reverse = function(x) {
10 | const sign = x < 0 ? -1 : 1;
11 | x = Math.abs(x);
12 | let output = 0;
13 | while (x > 0) {
14 | output = 10 * output + (x % 10);
15 | x = Math.floor(x / 10);
16 | const isOverflowed = output > MAX || output < MIN;
17 | if (isOverflowed) {
18 | return 0;
19 | }
20 | }
21 | return sign * output;
22 | };
23 |
--------------------------------------------------------------------------------
/src/leetcode/reverse-linked-list-ii/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | - find m - 1, n + 1
6 | - reverse m for n - m + 1 times
7 | - connect m - 1, reversed and n + 1
8 |
--------------------------------------------------------------------------------
/src/leetcode/reverse-linked-list-ii/submission-screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/reverse-linked-list-ii/submission-screenshot.png
--------------------------------------------------------------------------------
/src/leetcode/reverse-linked-list/iterative.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for singly-linked list.
3 | * function ListNode(val) {
4 | * this.val = val;
5 | * this.next = null;
6 | * }
7 | */
8 | /**
9 | * @param {ListNode} head
10 | * @return {ListNode}
11 | */
12 | var reverseList = function(head) {
13 | let pre = null;
14 | let ptr = head;
15 | let next;
16 | while (ptr) {
17 | next = ptr.next;
18 | ptr.next = pre;
19 | pre = ptr;
20 | ptr = next;
21 | }
22 | return pre;
23 | };
24 |
--------------------------------------------------------------------------------
/src/leetcode/reverse-linked-list/recursive.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for singly-linked list.
3 | * function ListNode(val) {
4 | * this.val = val;
5 | * this.next = null;
6 | * }
7 | */
8 | /**
9 | * @param {ListNode} head
10 | * @return {ListNode}
11 | */
12 | var reverseList = function(head) {
13 | if (!head || !head.next) {
14 | return head;
15 | }
16 | const root = reverseList(head.next);
17 | head.next.next = head;
18 | head.next = null;
19 | return root;
20 | };
21 |
--------------------------------------------------------------------------------
/src/leetcode/reverse-nodes-in-k-group/screencapture-leetcode-submissions-detail-192938162-2018-12-02-23_09_39.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/reverse-nodes-in-k-group/screencapture-leetcode-submissions-detail-192938162-2018-12-02-23_09_39.png
--------------------------------------------------------------------------------
/src/leetcode/reverse-only-letters/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} S
3 | * @return {string}
4 | */
5 | var reverseOnlyLetters = function(S) {
6 | let output = '';
7 | let j = S.length - 1;
8 | for (let i = 0; i < S.length; i++) {
9 | if (!isLetter(S[i])) {
10 | output += S[i];
11 | } else {
12 | while (!isLetter(S[j])) {
13 | j -= 1;
14 | }
15 | output += S[j];
16 | j -= 1;
17 | }
18 | }
19 | return output;
20 | };
21 |
22 | function isLetter(c) {
23 | return /[a-zA-Z]/.test(c);
24 | }
25 |
--------------------------------------------------------------------------------
/src/leetcode/reverse-string/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} s
3 | * @return {string}
4 | */
5 | var reverseString = function(s) {
6 | const output = [];
7 | for (let i = s.length - 1; i >= 0; i--) {
8 | output.push(s[i]);
9 | }
10 | return output.join('');
11 | };
12 |
--------------------------------------------------------------------------------
/src/leetcode/robot-room-cleaner/489. Robot Room Cleaner.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/robot-room-cleaner/489. Robot Room Cleaner.pdf
--------------------------------------------------------------------------------
/src/leetcode/roman-to-integer/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {string} s
3 | * @return {number}
4 | */
5 |
6 | const map = {
7 | I: 1,
8 | V: 5,
9 | X: 10,
10 | L: 50,
11 | C: 100,
12 | D: 500,
13 | M: 1000,
14 | };
15 |
16 | var romanToInt = function(s) {
17 | let output = 0;
18 | for (let i = 0; i < s.length; i++) {
19 | output += (() => {
20 | if (map[s[i]] >= (map[s[i + 1]] || 0)) {
21 | return map[s[i]];
22 | }
23 | return -1 * map[s[i]];
24 | })();
25 | }
26 | return output;
27 | };
28 |
--------------------------------------------------------------------------------
/src/leetcode/rotate-image/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[][]} matrix
3 | * @return {void} Do not return anything, modify matrix in-place instead.
4 | */
5 | var rotate = function(matrix) {
6 | matrix.reverse();
7 | const n = matrix.length;
8 | for (let i = 0; i < n; i++) {
9 | for (let j = i + 1; j < n; j++) {
10 | [matrix[i][j], matrix[j][i]] = [matrix[j][i], matrix[i][j]];
11 | }
12 | }
13 | };
14 |
--------------------------------------------------------------------------------
/src/leetcode/rotate-list/61. Rotate List.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/rotate-list/61. Rotate List.pdf
--------------------------------------------------------------------------------
/src/leetcode/search-a-2d-matrix-ii/240. Search a 2D Matrix II.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/search-a-2d-matrix-ii/240. Search a 2D Matrix II.pdf
--------------------------------------------------------------------------------
/src/leetcode/search-in-rotated-sorted-array-ii/81. Search in Rotated Sorted Array II.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/search-in-rotated-sorted-array-ii/81. Search in Rotated Sorted Array II.pdf
--------------------------------------------------------------------------------
/src/leetcode/search-in-rotated-sorted-array/33. Search in Rotated Sorted Array.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/search-in-rotated-sorted-array/33. Search in Rotated Sorted Array.pdf
--------------------------------------------------------------------------------
/src/leetcode/search-in-rotated-sorted-array/README.md:
--------------------------------------------------------------------------------
1 | ## README
2 |
3 | ### Test Cases
4 |
5 | ```
6 | [4,5,6,7,0,1,2] // (4, 7) is sorted
7 | [6,7,0,1,2,4,5] // (1, 5) is sorted
8 | [0,1,2,4,5,6,7] // (0, 4) (4, 7) is sorted
9 | ```
10 |
11 | There will always be one side sorted. So we can check if given target is in the range to include or exclude the range.
12 |
13 | ### Analysis
14 |
15 | Time Complexity: `O(log(N))`
16 |
--------------------------------------------------------------------------------
/src/leetcode/search-insert-position/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {number[]} nums
3 | * @param {number} target
4 | * @return {number}
5 | */
6 | var searchInsert = function(nums, target) {
7 | return lowerBound(nums, target);
8 | };
9 |
10 | function lowerBound(arr, target) {
11 | let left = 0;
12 | let right = arr.length;
13 | while (left < right) {
14 | const mid = Math.floor((left + right) / 2);
15 | if (target > arr[mid]) {
16 | left = mid + 1;
17 | } else {
18 | right = mid;
19 | }
20 | }
21 | return left;
22 | }
23 |
--------------------------------------------------------------------------------
/src/leetcode/sequential-digits/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | Use DFS to create numbers starting from the same digit until value is greater than high.
6 |
7 | ex: `1`, `12`, `123`
8 |
--------------------------------------------------------------------------------
/src/leetcode/serialize-and-deserialize-bst/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | Comparing to serializing Binary Tree, we can ignore `null` value in serializing Binary Search Tree by giving boundary.
6 |
7 | ex:
8 |
9 | ```js
10 | const serializedStr = [4, 2, 1, 6, 5, 7];
11 | ```
12 |
13 | This is the serialized data of binary search tree. When constructing tree rooted at value 2, we give it boundary `min = -Infinity` and `max = 4`. So that we know value 6 does not belong to it. We can return null.
14 |
--------------------------------------------------------------------------------
/src/leetcode/set-matrix-zeroes/73. Set Matrix Zeroes.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bobwei/algorithms/6ab7978dc72d512f714960a8c4b39d8358e11d32/src/leetcode/set-matrix-zeroes/73. Set Matrix Zeroes.pdf
--------------------------------------------------------------------------------
/src/leetcode/shortest-path-to-get-all-keys/README.md:
--------------------------------------------------------------------------------
1 | # README
2 |
3 | ## Algorithm
4 |
5 | Similar to `shortest-path-in-a-grid-with-obstacles-elimination`.
6 |
7 | Main idea is to model state as (set of acquired keys, current position). Then, we can run a standard BFS.
8 |
9 | `dist[k][i][j]` means shortest path from some origin to `(i, j)` with keys selected encoded as k.
10 |
--------------------------------------------------------------------------------
/src/leetcode/shortest-subarray-with-sum-at-least-k/README.md:
--------------------------------------------------------------------------------
1 | ## README
2 |
3 | ### Algorithm
4 |
5 |
6 |
7 |