├── .eslintignore ├── .eslintrc ├── .gitignore ├── .prettierrc ├── Readme.md ├── cheetsheat.md ├── labels.txt ├── package-lock.json ├── package.json ├── playground.js ├── playground.py ├── playground.ts ├── src ├── eloquent-javascript │ ├── 1.ts │ ├── 2.ts │ └── 3.ts ├── online-assessment │ └── google │ │ └── tokyo-intern │ │ └── pizza-shop.ts ├── problems │ ├── 100.Same-Tree.ts │ ├── 1004.Max-Consecutive-Ones-III.ts │ ├── 1007-Minimum-Domino-Rotations-For-Equal-Row.ts │ ├── 1009-Complement-of-Base-10-Integer.ts │ ├── 101-Symmetric-Tree.ts │ ├── 1010.Pairs-of-Songs-With-Total-Durations-Divisible-by-60.ts │ ├── 102-Binary-Tree-Level-Order-Traversal.ts │ ├── 1021.Remove-Outermost-Parentheses.ts │ ├── 1022-Sum-of-Root-To-Leaf-Binary-Numbers.ts │ ├── 1026.Maximum-Difference-Between-Node-and-Ancestor.ts │ ├── 1028.Recover-a-Tree-From-Preorder-Traversal.ts │ ├── 103.Binary-Tree-Zigzag-Level-Order-Traversal.ts │ ├── 104-Maximum-Depth-of-Binary-Tree.ts │ ├── 104.Maximum-Depth-of-Binary-Tree.ts │ ├── 1042-Flower-Planting-With-No-Adjacent.ts │ ├── 1047.Remove-All-Adjacent-Duplicates-In-String.ts │ ├── 1048.Longest-String-Chain.ts │ ├── 105.Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal.ts │ ├── 107.Binary-Tree-Level-Order-Traversal-II.ts │ ├── 1094-Car-Pooling.ts │ ├── 110.Balanced-Binary-Tree.ts │ ├── 1103-Distribute-Candies-to-People.ts │ ├── 1110.Delete-Nodes-And-Return-Forest.ts │ ├── 112-Path-Sum.ts │ ├── 1123.Lowest-Common-Ancestor-of-Deepest-Leaves.ts │ ├── 1129-Shortest-Path-with-Alternating-Colors.ts │ ├── 113.Path-Sum-II.ts │ ├── 114.Flatten-Binary-Tree-to-Linked-List.ts │ ├── 1145.Binary-Tree-Coloring-Game.ts │ ├── 116-Populating-Next-Right-Pointers-in-Each-Node.ts │ ├── 1161-Maximum-Level-Sum-of-a-Binary-Tree.ts │ ├── 1161.Maximum-Level-Sum-of-a-Binary-Tree.ts │ ├── 117.Populating-Next-Right-Pointers-in-Each-Node-II.ts │ ├── 118-Pascal's-Triangle.ts │ ├── 119-Pascal's-Triangle-II.ts │ ├── 1190.Reverse-Substrings-Between-Each-Pair-of-Parentheses.ts │ ├── 12.Integer-to-Roman.ts │ ├── 120.Triangle.ts │ ├── 1202.Smallest-String-With-Swaps.ts │ ├── 121-Best-Time-to-Buy-and-Sell-Stock.ts │ ├── 123-Best-Time-to-Buy-and-Sell-Stock-III.ts │ ├── 124.Binary-Tree-Maximum-Path-Sum.ts │ ├── 1249.Minimum-Remove-to-Make-Valid-Parentheses.ts │ ├── 125-Valid-Palindrome.ts │ ├── 1261.Find-Elements-in-a-Contaminated-Binary-Tree.ts │ ├── 1267-Count-Servers-that-Communicate.ts │ ├── 1268.Search-Suggestions-System.ts │ ├── 1277-Count-Square-Submatrices-with-All-Ones.ts │ ├── 1283-Find-the-Smallest-Divisor-Given-a-Threshold.ts │ ├── 1286-Iterator-for-Combination.ts │ ├── 1288-Remove-Covered-Intervals.ts │ ├── 129.Sum-Root-to-Leaf-Numbers.ts │ ├── 1295-Find-Numbers-with-Even-Number-of-Digits.ts │ ├── 13.Roman-to-Integer.ts │ ├── 1302.Deepest-Leaves-Sum.ts │ ├── 1305-All-Elements-in-Two-Binary-Search-Trees.ts │ ├── 1306-Jump-Game-III.ts │ ├── 1313-Decompress-Run-Length-Encoded-List.ts │ ├── 1314-Matrix-Block-Sum.ts │ ├── 1315.Sum-of-Nodes-with-Even-Valued-Grandparent.ts │ ├── 1329.Sort-the-Matrix-Diagonally.ts │ ├── 133-Clone-Graph.ts │ ├── 1337-The-K-Weakest-Rows-in-a-Matrix.ts │ ├── 1337.The-K-Weakest-Rows-in-a-Matrix.ts │ ├── 1339.Maximum-Product-of-Splitted-Binary-Tree.ts │ ├── 134-Gas-Station.ts │ ├── 1345.Jump-Game-IV.ts │ ├── 1351-Count-Negative-Numbers-in-a-Sorted-Matrix.ts │ ├── 136.Single-Number.ts │ ├── 1367.Linked-List-in-Binary-Tree.ts │ ├── 1372.Longest-ZigZag-Path-in-a-Binary-Tree.ts │ ├── 1379.Find-a-Corresponding-Node-of-a-Binary-Tree-in-a-Clone-of-That-Tree.ts │ ├── 1381.Design-a-Stack-With-Increment-Operation.ts │ ├── 1387-Sort-Integers-by-The-Power-Value.ts │ ├── 139-Word-Break.ts │ ├── 142-Linked-List-Cycle-II.ts │ ├── 143-Reorder-List.ts │ ├── 1431-Kids-With-the-Greatest-Number-of-Candies.ts │ ├── 1437.Check-If-All-1's-Are-at-Least-Length-K-Places-Away.ts │ ├── 144-Binary-Tree-Preorder-Traversal.ts │ ├── 1441.Build-an-Array-With-Stack-Operations.ts │ ├── 1448.Count-Good-Nodes-in-Binary-Tree.ts │ ├── 145-Binary-Tree-Postorder-Traversal.ts │ ├── 1457.Pseudo-Palindromic-Paths-in-a-Binary-Tree.ts │ ├── 1465.Maximum-Area-of-a-Piece-of-Cake-After-Horizontal-and-Vertical-Cuts.ts │ ├── 1475.Final-Prices-With-a-Special-Discount-in-a-Shop.ts │ ├── 1492.The-kth-Factor-of-n.ts │ ├── 150.Evaluate-Reverse-Polish-Notation.ts │ ├── 1502-Can-Make-Arithmetic-Progression-From-Sequence.ts │ ├── 1512-Number-of-Good-Pairs.ts │ ├── 152-Maximum-Product-Subarray.ts │ ├── 1528-Shuffle-String.ts │ ├── 1544.Make-The-String-Great.ts │ ├── 1551.Minimum-Operations-to-Make-Array-Equal.ts │ ├── 1557-Minimum-Number-of-Vertices-to-Reach-All-Nodes.ts │ ├── 1598.Crawler-Log-Folder.ts │ ├── 160.Intersection-of-Two-Linked-Lists.ts │ ├── 1609.Even-Odd-Tree.ts │ ├── 1614.Maximum-Nesting-Depth-of-the-Parentheses.ts │ ├── 1615-Maximal-Network-Rank.ts │ ├── 1640.Check-Array-Formation-Through-Concatenation.ts │ ├── 1641.Count-Sorted-Vowel-Strings.ts │ ├── 1642.Furthest-Building-You-Can-Reach.ts │ ├── 1646.Get-Maximum-in-Generated-Array.ts │ ├── 165-Compare-Version-Numbers.ts │ ├── 1664.Ways-to-Make-a-Fair-Array.ts │ ├── 167-Two-Sum-II-Input-array-is-sorted.ts │ ├── 1672.Richest-Customer-Wealth.ts │ ├── 1689.Partitioning-Into-Minimum-Number Of Deci-Binary-Numbers.ts │ ├── 1695.Maximum-Erasure-Value.ts │ ├── 17.Letter-Combinations-of-a-Phone-Number.ts │ ├── 1704.Determine-if-String-Halves-Are-Alike.ts │ ├── 1706.Where-Will-the-Ball-Fall.ts │ ├── 171-Excel-Sheet-Column-Number.ts │ ├── 1710.Maximum-Units-on-a-Truck.ts │ ├── 173.Binary-Search-Tree-Iterator.ts │ ├── 1748.Sum-of-Unique-Elements.ts │ ├── 179-Largest-Number.ts │ ├── 188-Best-Time-to-Buy-and-Sell-Stock-IV.ts │ ├── 189.Rotate-Array.ts │ ├── 1971.Find-if-Path-Exists-in-Graph.ts │ ├── 198-House-Robber.ts │ ├── 2.Add-Two-Numbers.ts │ ├── 20.Valid-Parentheses.ts │ ├── 207-Course-Schedule.ts │ ├── 21.Merge-Two-Sorted-Lists.ts │ ├── 210.Course-Schedule-II.ts │ ├── 211-Add-and-Search-Word-Data-structure-design.ts │ ├── 213-House-Robber-II.ts │ ├── 216-Combination-Sum-III.ts │ ├── 22.Generate-Parentheses.ts │ ├── 227.Basic-Calculator-II.ts │ ├── 229-Majority-Element-II.ts │ ├── 23.Merge-k-Sorted-Lists.ts │ ├── 230.Kth-Smallest-Element-in-a-BST.ts │ ├── 235.Lowest-Common-Ancestor-of-a-Binary-Search-Tree.ts │ ├── 236.Lowest-Common-Ancestor-of-a-Binary-Tree.ts │ ├── 240.Search-a-2D-Matrix-II.ts │ ├── 257.Binary-Tree-Paths.ts │ ├── 268.Missing-Number.ts │ ├── 274-H-Index.ts │ ├── 299-Bulls-and-Cows.ts │ ├── 303-Range-Sum-Query-Immutable.ts │ ├── 318.Maximum-Product-of-Word-Lengths.ts │ ├── 322.Coin-Change.ts │ ├── 326.Power-of-Three.ts │ ├── 329.Longest-Increasing-Path-in-a-Matrix.ts │ ├── 334.Increasing-Triplet-Subsequence.ts │ ├── 337.House-Robber-III.ts │ ├── 338.Counting-Bits.ts │ ├── 341.Flatten-Nested-List-Iterator.ts │ ├── 342-Power-of-Four.ts │ ├── 349-Intersection-of-Two-Arrays.ts │ ├── 354.Russian-Doll-Envelopes.ts │ ├── 376.Wiggle-Subsequence.ts │ ├── 377-Combination-Sum-IV.ts │ ├── 382-Linked-List-Random-Node.ts │ ├── 389.Find-the-Difference.ts │ ├── 39-Combination-Sum.ts │ ├── 392.Is-Subsequence.ts │ ├── 399-Evaluate-Division.ts │ ├── 40-Combination-Sum-II.ts │ ├── 404-Sum-of-Left-Leaves.ts │ ├── 409-Longest-Palindrome.ts │ ├── 41-First-Missing-Positive.ts │ ├── 412-Fizz-Buzz.ts │ ├── 413.Arithmetic-Slices.ts │ ├── 417.Pacific-Atlantic-Water-Flow.ts │ ├── 429.N-ary-Tree-Level-Order-Traversal.ts │ ├── 430-Flatten-a-Multilevel-Doubly-Linked-List.ts │ ├── 435-Non-overlapping-Intervals.ts │ ├── 436-Find-Right-Interval.ts │ ├── 437-Path-Sum-III.ts │ ├── 438.Find-All-Anagrams-in-a-String.ts │ ├── 442-Find-All-Duplicates-in-an-Array.ts │ ├── 45.Jump-Game-II.ts │ ├── 450-Delete-Node-in-a-BST.ts │ ├── 454.4Sum-II.ts │ ├── 462.Minimum-Moves-to-Equal-Array-Elements-II.ts │ ├── 470-Implement-Rand10()-Using-Rand7().ts │ ├── 474.Ones-and-Zeroes.ts │ ├── 485-Max-Consecutive-Ones.ts │ ├── 49.Group-Anagrams.ts │ ├── 495-Teemo-Attacking.ts │ ├── 496.Next-Greater-Element-I.ts │ ├── 501.Find-Mode-in-Binary-Search-Tree.ts │ ├── 503.Next-Greater-Element-II.ts │ ├── 509.Fibonacci-Number.ts │ ├── 513.Find-Bottom-Left-Tree-Value.ts │ ├── 515.Find-Largest-Value-in-Each-Tree-Row.ts │ ├── 520-detect-capital.ts │ ├── 524.Longest-Word-in-Dictionary-through-Deleting.ts │ ├── 525.Contiguous-Array.ts │ ├── 526.Beautiful-Arrangement.ts │ ├── 53-Maximum-Subarray.ts │ ├── 53.Maximum-Subarray.ts │ ├── 530.Minimum-Absolute-Difference-in-BST.ts │ ├── 538.Convert-BST-to-Greater-Tree.ts │ ├── 547-Friend-Circles.ts │ ├── 55.Jump-Game.ts │ ├── 56-Merge-Intervals.ts │ ├── 560.Subarray-Sum-Equals-K.ts │ ├── 563.Binary-Tree-Tilt.ts │ ├── 566.Reshape-the-Matrix.ts │ ├── 567.Permutation-in-String.ts │ ├── 57-Insert-Interval.ts │ ├── 572.Subtree-of-Another-Tree.ts │ ├── 575.Distribute.Candies.ts │ ├── 581.Shortest-Unsorted-Continuous-Subarray.ts │ ├── 589.N-ary-Tree-Preorder-Traversal.ts │ ├── 59.Spiral-Matrix-II.ts │ ├── 605.Can-Place-Flowers.ts │ ├── 61-Rotate-List.ts │ ├── 62-Unique-Paths.ts │ ├── 622.Design-Circular-Queue.ts │ ├── 623.Add-One-Row-to-Tree.ts │ ├── 63-Unique-Paths-II.ts │ ├── 637.Average-of-Levels-in-Binary-Tree.ts │ ├── 645.Set-Mismatch.ts │ ├── 647.Palindromic-Substrings.ts │ ├── 652.Find-Duplicate-Subtrees.ts │ ├── 653-Two-Sum-IV-Input-is-a-BST.ts │ ├── 655-Print-Binary-Tree.ts │ ├── 658.Find-K-Closest-Elements.ts │ ├── 665.Non-decreasing-Array.ts │ ├── 667.Beautiful-Arrangement-II.ts │ ├── 671.Second-Minimum-Node-In-a-Binary-Tree.ts │ ├── 682.Baseball-Game.ts │ ├── 684-Redundant-Connection.ts │ ├── 687.Longest-Univalue-Path.ts │ ├── 695.Max-Area-of-Island.ts │ ├── 70.Climbing-Stairs.ts │ ├── 701-Insert-into-a-Binary-Search-Tree.ts │ ├── 701.Insert-into-a-Binary-Search-Tree.ts │ ├── 704-Binary-Search.ts │ ├── 705-Design-HashSet.ts │ ├── 713-Subarray-Product-Less-Than-K.ts │ ├── 714-Best-Time-to-Buy-and-Sell-Stock-with-Transaction-Fee.ts │ ├── 729.My-Calendar-I.ts │ ├── 73.Set-Matrix-Zeroes.ts │ ├── 735-Asteroid-Collision.ts │ ├── 739.Daily-Temperatures.ts │ ├── 743-Network-Delay-Time.ts │ ├── 744-Find-Smallest-Letter-Greater-Than-Target.ts │ ├── 746-Min-Cost-Climbing-Stairs.ts │ ├── 748.Shortest-Completing-Word.ts │ ├── 763-Partition-Labels.ts │ ├── 775.Global-and-Local-Inversions.ts │ ├── 78.Subsets.ts │ ├── 783.Minimum-Distance-Between-BST-Nodes.ts │ ├── 784.Letter-Case-Permutation.ts │ ├── 795.Number-of-Subarrays-with-Bounded-Maximum.ts │ ├── 797-All-Paths-From-Source-to-Target.ts │ ├── 799-Champagne-Tower.ts │ ├── 802-Find-Eventual-Safe-States.ts │ ├── 82.Remove-Duplicates-from-Sorted-List-II.ts │ ├── 820.Short-Encoding-of-Words.ts │ ├── 824-Goat-Latin.ts │ ├── 841-Keys-and-Rooms.ts │ ├── 844.Backspace-String-Compare.ts │ ├── 849-Maximize-Distance-to-Closest-Person.ts │ ├── 852-Peak-Index-in-a-Mountain-Array.ts │ ├── 856.Score-of-Parentheses.ts │ ├── 86.Partition-List.ts │ ├── 863.All-Nodes-Distance-K-in-Binary-Tree.ts │ ├── 865.Smallest-Subtree-with-all-the-Deepest-Nodes.ts │ ├── 869.Reordered-Power-of-2.ts │ ├── 870.Advantage-Shuffle.ts │ ├── 88-Merge-Sorted-Array.ts │ ├── 890.Find-and-Replace-Pattern.ts │ ├── 897-Increasing-Order-Search-Tree.ts │ ├── 905-Sort-Array-By-Parity.ts │ ├── 916.Word-Subsets.ts │ ├── 92.Reverse-Linked-List-II.ts │ ├── 921.Minimum-Add-to-Make-Parentheses-Valid.ts │ ├── 923.3Sum-With-Multiplicity.ts │ ├── 926.Flip-String-to-Monotone-Increasing.ts │ ├── 931-Minimum-Falling-Path-Sum.ts │ ├── 94-Binary-Tree-Inorder-Traversal.ts │ ├── 949-Largest-Time-for-Given-Digits.ts │ ├── 958.Check-Completeness-of-a-Binary-Tree.ts │ ├── 965-Univalued-Binary-Tree.ts │ ├── 966.Vowel-Spellchecker.ts │ ├── 967-Numbers-With-Same-Consecutive-Differences.ts │ ├── 969-Pancake-Sorting.ts │ ├── 97.Interleaving-String.ts │ ├── 971.Flip-Binary-Tree-To-Match-Preorder-Traversal.ts │ ├── 977-Squares-of-a-Sorted-Array.ts │ ├── 977.Squares-of-a-Sorted-Array.ts │ ├── 98.Validate-Binary-Search-Tree.ts │ ├── 980-Unique-Paths-III.ts │ ├── 983-Minimum-Cost-For-Tickets.ts │ ├── 987-Vertical-Order-Traversal-of-a-Binary-Tree.ts │ ├── 987.Vertical-Order-Traversal-of-a-Binary-Tree.ts │ ├── 988.Smallest-String-Starting-From-Leaf.ts │ ├── 990-Satisfiability-of-Equality-Equations.ts │ ├── 991.Broken-Calculator.ts │ ├── 993.Cousins-in-Binary-Tree.ts │ ├── 994-Rotting-Oranges.ts │ └── 997-Find-the-Town-Judge.ts └── utils │ └── classes │ ├── ListNode.ts │ ├── TreeNode.ts │ └── Trie.ts ├── tests.txt └── tsconfig.json /.eslintignore: -------------------------------------------------------------------------------- 1 | !**/.eslintrc* 2 | node_modules* 3 | dist 4 | *.svg 5 | *.ico 6 | *.json 7 | .gitignore 8 | *.md 9 | *.log 10 | playground.ts 11 | dist 12 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "plugins": [ 5 | "@typescript-eslint" 6 | ], 7 | "extends": [ 8 | "eslint:recommended", 9 | "plugin:@typescript-eslint/eslint-recommended", 10 | "plugin:@typescript-eslint/recommended" 11 | ], 12 | "rules": { 13 | "@typescript-eslint/no-inferrable-types": "off" 14 | } 15 | } 16 | 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # Leetcode TypeScript Solutions by eddyhdzg 2 | 3 | Leetcode profile - [leetcode.com/eddyhdzg/](https://leetcode.com/eddyhdzg/) 4 | 5 | - I had 143 problems solved in different languages (c++, js, ts, python) before I actually started to document my problems on August 1,2020. 6 | 7 | - Now I will stick with typescript 8 | 9 | - I will try to submit 1 or 2 new typescript solution per day. 10 | 11 | - Btw sometimes I actually submit .js solutions because there is a bigger community and I want to see how my code performs in comparison with other submissions. 12 | 13 | ### Download typescript 14 | 15 | ```sh 16 | npm install -g typescript 17 | npm install -g ts-node 18 | 19 | ``` 20 | 21 | ### Run typescript file 22 | 23 | ```sh 24 | ts-node playground.ts 25 | ``` 26 | 27 | ### Convert ts code to js file 28 | 29 | ```sh 30 | tsc playground.ts --outFile playground.js 31 | ``` 32 | -------------------------------------------------------------------------------- /cheetsheat.md: -------------------------------------------------------------------------------- 1 | 1. Array from 1 to n 2 | 3 | ### .keys 4 | 5 | ``` 6 | Array.from(Array(10).keys()) 7 | [...Array(10).keys()] 8 | [ ...Array(N).keys() ].map( i => i+1); 9 | Array.from(Array(N), (_, i) => i+1) 10 | Array.from({ length: N }, (_, i) => i+1) 11 | [ ...Array(N).keys() ].map((i) => f(i)) 12 | ``` 13 | 14 | #### Bidimentional array 15 | 16 | ``` 17 | const dp = Array(m).fill(null).map(() => Array(n)); 18 | ``` 19 | 20 | ### Slice vs Splice 21 | 22 | splice() changes the original array whereas slice() doesn't but both of them returns array object. 23 | 24 | slice is end is not inclusive 25 | -------------------------------------------------------------------------------- /labels.txt: -------------------------------------------------------------------------------- 1 | // Labels for Leetcode Discuss 2 | 3 | 1) Title 4 | JavaScript / TypeScript Solution 5 | or 6 | JavaScript / TypeScript Solutions 7 | 8 | 2) Footer 9 | More leetcode TypeScript solutions at https://github.com/eddyhdzg/leetcode-typescript-solutions 10 | 11 | 3) Tag 12 | typescript 13 | javascript 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "leetcode-eddyhdzg-typescript", 3 | "version": "1.0.0", 4 | "description": "Leetcode profile - [leetcode.com/eddyhdzg/](https://leetcode.com/eddyhdzg/)", 5 | "main": "./", 6 | "scripts": { 7 | "lint": "eslint . --ext .ts", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "@datastructures-js/priority-queue": "^5.3.0" 14 | }, 15 | "devDependencies": { 16 | "@typescript-eslint/eslint-plugin": "^5.10.1", 17 | "@typescript-eslint/parser": "^5.10.1", 18 | "eslint": "^8.7.0", 19 | "prettier": "^2.5.1", 20 | "typescript": "^4.5.5" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /playground.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eddyhdzg/leetcode-typescript-solutions/2793246b9b9b7dfcb9a3f3dac7528272b32d87ca/playground.js -------------------------------------------------------------------------------- /playground.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eddyhdzg/leetcode-typescript-solutions/2793246b9b9b7dfcb9a3f3dac7528272b32d87ca/playground.py -------------------------------------------------------------------------------- /playground.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eddyhdzg/leetcode-typescript-solutions/2793246b9b9b7dfcb9a3f3dac7528272b32d87ca/playground.ts -------------------------------------------------------------------------------- /src/eloquent-javascript/1.ts: -------------------------------------------------------------------------------- 1 | export const fizzBuzz = () => { 2 | let i = 1; 3 | 4 | while (i <= 15) { 5 | if (!(i % 3) && !(i % 5)) console.log("FIZZBUZZ"); 6 | else if (!(i % 3)) console.log("FIZZ"); 7 | else if (!(i % 5)) console.log("BUZZ"); 8 | else console.log(i); 9 | i++; 10 | } 11 | }; 12 | 13 | export const chessboard = (size: number = 8) => { 14 | let a = ""; 15 | let b = ""; 16 | const board: string[] = []; 17 | 18 | for (let i = 0; i < size; i++) { 19 | if (i % 2) { 20 | a += "#"; 21 | b += " "; 22 | } else { 23 | a += " "; 24 | b += "#"; 25 | } 26 | } 27 | 28 | for (let i = 0; i < size; i++) { 29 | if (i % 2) board.push(b); 30 | else board.push(a); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /src/eloquent-javascript/2.ts: -------------------------------------------------------------------------------- 1 | export const minimum = (a: number, b: number) => { 2 | return a < b ? a : b; 3 | }; 4 | 5 | export const recursion = (num: number): "even" | "odd" => { 6 | if (num === 0) return "even"; 7 | if (Math.abs(num) === 1) return "odd"; 8 | return recursion(Math.abs(num) - 2); 9 | }; 10 | 11 | export const countChar = (s: string, char: string) => { 12 | let count = 0; 13 | for (let i = 0; i < s.length; i++) { 14 | if (s.charAt(i) === char) count++; 15 | } 16 | 17 | return count; 18 | }; 19 | 20 | export const beanCounting = (s: string) => { 21 | return countChar(s, "B"); 22 | }; 23 | -------------------------------------------------------------------------------- /src/problems/100.Same-Tree.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | // Runtime: 88 ms, faster than 16.33% of TypeScript online submissions for Same Tree. 3 | // Memory Usage: 40.2 MB, less than 44.90% of TypeScript online submissions for Same Tree. 4 | function isSameTree(p: TreeNode | null, q: TreeNode | null): boolean { 5 | if (!p && !q) return true; 6 | if (!p || !q) return false; 7 | if (p.val !== q.val) return false; 8 | return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); 9 | } 10 | 11 | // JS 12 | // Runtime: 72 ms, faster than 93.50% of JavaScript online submissions for Same Tree. 13 | // Memory Usage: 38.9 MB, less than 41.53% of JavaScript online submissions for Same Tree. 14 | // var isSameTree = function (p, q) { 15 | // if (!p && !q) return true; 16 | // if (!p || !q) return false; 17 | // if (p.val !== q.val) return false; 18 | // return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); 19 | // }; 20 | -------------------------------------------------------------------------------- /src/problems/1004.Max-Consecutive-Ones-III.ts: -------------------------------------------------------------------------------- 1 | function longestOnes(nums: number[], k: number): number { 2 | let right = 0; 3 | let left = 0; 4 | let res = 0; 5 | 6 | while (right < nums.length) { 7 | if (nums[right] === 0) k--; 8 | if (k < 0 && nums[left++] === 0) k++; 9 | right++; 10 | res = Math.max(res, right - left); 11 | } 12 | 13 | return res; 14 | } 15 | -------------------------------------------------------------------------------- /src/problems/1009-Complement-of-Base-10-Integer.ts: -------------------------------------------------------------------------------- 1 | function bitwiseComplement(N: number): number { 2 | const complement = parseInt('1'.repeat(N.toString(2).length), 2); 3 | return N ^ complement; 4 | } 5 | -------------------------------------------------------------------------------- /src/problems/101-Symmetric-Tree.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 80 ms, faster than 84.30% of JavaScript online submissions for Symmetric Tree. 2 | // Memory Usage: 38.8 MB, less than 15.79% of JavaScript online submissions for Symmetric Tree. 3 | 4 | function isSymmetric(root: TreeNode | null): boolean { 5 | if (!root) return true; 6 | const helper = (node1: TreeNode | null, node2: TreeNode | null): boolean => { 7 | if (!node1 && !node2) return true; 8 | if (node1 && node2) { 9 | return ( 10 | node1.val === node2.val && 11 | helper(node1.left, node2.right) && 12 | helper(node1.right, node2.left) 13 | ); 14 | } 15 | return false; 16 | }; 17 | 18 | return helper(root.left, root.right); 19 | } 20 | -------------------------------------------------------------------------------- /src/problems/102-Binary-Tree-Level-Order-Traversal.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 72 ms, faster than 88.87% of JavaScript online submissions for Binary Tree Level Order Traversal. 2 | // Memory Usage: 38.5 MB, less than 15.78% of JavaScript online submissions for Binary Tree Level Order Traversal. 3 | 4 | class TreeNode { 5 | val: number; 6 | left: TreeNode | null; 7 | right: TreeNode | null; 8 | constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { 9 | this.val = val === undefined ? 0 : val; 10 | this.left = left === undefined ? null : left; 11 | this.right = right === undefined ? null : right; 12 | } 13 | } 14 | 15 | function levelOrder(root: TreeNode | null): number[][] { 16 | const res: number[][] = []; 17 | 18 | const helper = (node: TreeNode | null, i: number) => { 19 | if (!node) return; 20 | helper(node.left, i + 1); 21 | res[i] ? res[i].push(node.val) : (res[i] = [node.val]); 22 | helper(node.right, i + 1); 23 | }; 24 | 25 | helper(root, 0); 26 | 27 | return res; 28 | } 29 | -------------------------------------------------------------------------------- /src/problems/1021.Remove-Outermost-Parentheses.ts: -------------------------------------------------------------------------------- 1 | function removeOuterParentheses(s: string): string { 2 | let counter = 0; 3 | let res = ''; 4 | 5 | for (let i = 0; i < s.length; i++) { 6 | if (s.charAt(i) === '(') { 7 | if (counter) res += s.charAt(i); 8 | counter++; 9 | } 10 | if (s.charAt(i) === ')') { 11 | if (counter > 1) res += s.charAt(i); 12 | counter--; 13 | } 14 | } 15 | 16 | return res; 17 | } 18 | -------------------------------------------------------------------------------- /src/problems/1022-Sum-of-Root-To-Leaf-Binary-Numbers.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 80 ms, faster than 100.00% of TypeScript online submissions for Sum of Root To Leaf Binary Numbers. 2 | // Memory Usage: 39.2 MB, less than 100.00% of TypeScript online submissions for Sum of Root To Leaf Binary Numbers. 3 | 4 | function sumRootToLeaf(root: TreeNode | null, sum: string = ''): number { 5 | if (!root) { 6 | return 0; 7 | } 8 | 9 | const nextSum = sum + root.val; 10 | 11 | if (!root.left && !root.right) { 12 | return parseInt(nextSum, 2); 13 | } 14 | 15 | return sumRootToLeaf(root.left, nextSum) + sumRootToLeaf(root.right, nextSum); 16 | } 17 | 18 | 19 | // Runtime: 76 ms, faster than 95.48% of JavaScript online submissions for Sum of Root To Leaf Binary Numbers. 20 | // Memory Usage: 38.4 MB, less than 77.97% of JavaScript online submissions for Sum of Root To Leaf Binary Numbers. 21 | 22 | // var sumRootToLeaf = function (root, sum = '') { 23 | // if (!root) { 24 | // return 0; 25 | // } 26 | 27 | // const nextSum = sum + root.val; 28 | // if (!root.left && !root.right) { 29 | // return parseInt(nextSum, 2); 30 | // } 31 | 32 | // return sumRootToLeaf(root.left, nextSum) + sumRootToLeaf(root.right, nextSum); 33 | }; 34 | 35 | -------------------------------------------------------------------------------- /src/problems/1028.Recover-a-Tree-From-Preorder-Traversal.ts: -------------------------------------------------------------------------------- 1 | const match = (value: number) => { 2 | return new RegExp('(? { 6 | const stop = S.indexOf('-'); 7 | return Number(S.slice(0, stop !== -1 ? stop : S.length)); 8 | }; 9 | 10 | function recoverFromPreorder(S: string): TreeNode | null { 11 | if (!S.length) return null; 12 | return helper(S, 0); 13 | } 14 | 15 | const helper = (S: string, depth: number): TreeNode | null => { 16 | if (!S.length) return null; 17 | const newDepth = depth + 1; 18 | const newNode = new TreeNode(getNumber(S)); 19 | 20 | const leftIndex = S.search(match(newDepth)); 21 | // Case 1: Leaf 22 | if (leftIndex == -1) return newNode; 23 | 24 | const leftStart = leftIndex + newDepth; 25 | const rightIndex = S.slice(leftStart).search(match(newDepth)); 26 | // Case 2: One Child 27 | if (rightIndex === -1) { 28 | newNode.left = helper(S.slice(leftStart), newDepth); 29 | return newNode; 30 | } 31 | 32 | // Case 3: Two Children 33 | const rightStart = leftStart + rightIndex + newDepth; 34 | newNode.left = helper(S.slice(leftStart, leftStart + rightIndex), newDepth); 35 | newNode.right = helper(S.slice(rightStart), newDepth); 36 | return newNode; 37 | }; 38 | -------------------------------------------------------------------------------- /src/problems/103.Binary-Tree-Zigzag-Level-Order-Traversal.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | function zigzagLevelOrder(root: TreeNode | null): number[][] { 3 | if (!root) return []; 4 | let stack: TreeNode[] = [root]; 5 | const res: number[][] = []; 6 | let i = 0; 7 | 8 | while (stack.length) { 9 | const newStack: TreeNode[] = []; 10 | res.push([]); 11 | 12 | for (const node of stack) { 13 | res[i].push(node.val); 14 | if (node.left) newStack.push(node.left); 15 | if (node.right) newStack.push(node.right); 16 | } 17 | 18 | stack = newStack; 19 | i++; 20 | } 21 | 22 | for (let i = 1; i < res.length; i += 2) res[i].reverse(); 23 | return res; 24 | } 25 | 26 | // JS 27 | // var zigzagLevelOrder = function (root) { 28 | // if (!root) return []; 29 | // let stack = [root]; 30 | // const res = []; 31 | // let i = 0; 32 | 33 | // while (stack.length) { 34 | // const newStack = []; 35 | // res.push([]); 36 | 37 | // for (const node of stack) { 38 | // res[i].push(node.val); 39 | // if (node.left) newStack.push(node.left); 40 | // if (node.right) newStack.push(node.right); 41 | // } 42 | 43 | // stack = newStack; 44 | // i++; 45 | // } 46 | 47 | // for (let i = 1; i < res.length; i += 2) res[i].reverse(); 48 | // return res; 49 | // }; 50 | -------------------------------------------------------------------------------- /src/problems/104-Maximum-Depth-of-Binary-Tree.ts: -------------------------------------------------------------------------------- 1 | // Recursion 2 | // Runtime: 84 ms, faster than 58.89% of JavaScript online submissions for Maximum Depth of Binary Tree. 3 | // Memory Usage: 38.8 MB, less than 56.66% of JavaScript online submissions for Maximum Depth of Binary Tree. 4 | function maxDepth(root: TreeNode | null, i: number = 0): number { 5 | if (!root) return i; 6 | return Math.max(i, maxDepth(root.left, i + 1), maxDepth(root.right, i + 1)); 7 | } 8 | 9 | // Helper Recursion 10 | // Runtime: 80 ms, faster than 74.61% of JavaScript online submissions for Maximum Depth of Binary Tree. 11 | // Memory Usage: 39.8 MB, less than 13.64% of JavaScript online submissions for Maximum Depth of Binary Tree. 12 | 13 | function maxDepth(root: TreeNode | null): number { 14 | const helper = (node: TreeNode | null, i: number): number => { 15 | if (!node) return i; 16 | return Math.max(i, helper(node.left, i + 1), helper(node.right, i + 1)); 17 | }; 18 | 19 | return helper(root, 0); 20 | } 21 | -------------------------------------------------------------------------------- /src/problems/104.Maximum-Depth-of-Binary-Tree.ts: -------------------------------------------------------------------------------- 1 | function maxDepth(root: TreeNode | null): number { 2 | if (!root) return 0; 3 | return 1 + Math.max(maxDepth(root.left), maxDepth(root.right)); 4 | } 5 | -------------------------------------------------------------------------------- /src/problems/1042-Flower-Planting-With-No-Adjacent.ts: -------------------------------------------------------------------------------- 1 | function gardenNoAdj(n: number, paths: number[][]): number[] { 2 | const graph: { [key: string]: number[] } = {}; 3 | const flowers: { [key: string]: number } = {}; 4 | for (let i = 1; i <= n; i++) graph[i] = []; 5 | 6 | paths.forEach(([x, y]) => { 7 | graph[x].push(y); 8 | graph[y].push(x); 9 | }); 10 | 11 | const getFlower = (i: number) => { 12 | const possibleTypes = new Set([1, 2, 3, 4]); 13 | graph[i].forEach((garden) => { 14 | possibleTypes.delete(flowers[garden]); 15 | }); 16 | 17 | return Math.min(...possibleTypes); 18 | }; 19 | 20 | for (let i = 1; i <= n; i++) { 21 | flowers[i] = getFlower(i); 22 | } 23 | 24 | return Object.values(flowers); 25 | } 26 | -------------------------------------------------------------------------------- /src/problems/1047.Remove-All-Adjacent-Duplicates-In-String.ts: -------------------------------------------------------------------------------- 1 | function removeDuplicates(S: string): string { 2 | const stack: string[] = []; 3 | 4 | for (let i = 0; i < S.length; i++) { 5 | if (S.charAt(i) === stack[stack.length - 1]) stack.pop(); 6 | else stack.push(S.charAt(i)); 7 | } 8 | 9 | return stack.join(''); 10 | } 11 | -------------------------------------------------------------------------------- /src/problems/1048.Longest-String-Chain.ts: -------------------------------------------------------------------------------- 1 | function longestStrChain(words: string[]): number { 2 | words.sort((a, b) => a.length - b.length); 3 | const hash: { [key: string]: number } = {}; 4 | 5 | words.forEach((word) => { 6 | hash[word] = 1; 7 | 8 | for (let i = 0; i < word.length; i++) { 9 | const prev = word.slice(0, i) + word.slice(i + 1); 10 | if (prev in hash) { 11 | hash[word] = Math.max(hash[word], hash[prev] + 1); 12 | } 13 | } 14 | }); 15 | 16 | return Math.max(...Object.values(hash)); 17 | } 18 | -------------------------------------------------------------------------------- /src/problems/105.Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal.ts: -------------------------------------------------------------------------------- 1 | function buildTree(preorder: number[], inorder: number[]): TreeNode | null { 2 | if (!preorder.length) return null; 3 | const idx = inorder.indexOf(preorder[0]); 4 | const root = new TreeNode(inorder[idx]); 5 | root.left = buildTree(preorder.slice(1, idx + 1), inorder.slice(0, idx)); 6 | root.right = buildTree(preorder.slice(idx + 1), inorder.slice(idx + 1)); 7 | return root; 8 | } 9 | -------------------------------------------------------------------------------- /src/problems/107.Binary-Tree-Level-Order-Traversal-II.ts: -------------------------------------------------------------------------------- 1 | function levelOrderBottom(root: TreeNode | null): number[][] { 2 | const res: number[][] = []; 3 | 4 | const helper = (node: TreeNode | null, level: number) => { 5 | if (!node) return; 6 | if (!res[level]) res.push([node.val]); 7 | else res[level].push(node.val); 8 | helper(node.left, level + 1); 9 | helper(node.right, level + 1); 10 | }; 11 | 12 | helper(root, 0); 13 | 14 | return res.reverse(); 15 | } 16 | -------------------------------------------------------------------------------- /src/problems/1094-Car-Pooling.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | // Runtime: 88 ms, faster than 100.00% of TypeScript online submissions for Car Pooling. 3 | // Memory Usage: 38.9 MB, less than 100.00% of TypeScript online submissions for Car Pooling. 4 | function carPooling(trips: number[][], capacity: number): boolean { 5 | const lastLocation = trips.reduce((prev, [, , curr]) => { 6 | return Math.max(prev, curr); 7 | }, 0); 8 | 9 | const dp = Array(lastLocation).fill(0); 10 | 11 | trips.forEach(([num, start, end]) => { 12 | for (let i = start; i < end; i++) dp[i] += num; 13 | }); 14 | 15 | return Math.max(...dp) <= capacity; 16 | } 17 | 18 | // JS 19 | // Runtime: 72 ms, faster than 99.21% of JavaScript online submissions for Car Pooling. 20 | // Memory Usage: 38.5 MB, less than 71.65% of JavaScript online submissions for Car Pooling. 21 | // var carPooling = function (trips, capacity) { 22 | // const lastLocation = trips.reduce((prev, [, , curr]) => { 23 | // return Math.max(prev, curr); 24 | // }, 0); 25 | 26 | // const dp = Array(lastLocation).fill(0); 27 | 28 | // trips.forEach(([num, start, end]) => { 29 | // for (let i = start; i < end; i++) dp[i] += num; 30 | // }); 31 | 32 | // return Math.max(...dp) <= capacity; 33 | // }; 34 | -------------------------------------------------------------------------------- /src/problems/110.Balanced-Binary-Tree.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | // Runtime: 96 ms, faster than 100.00% of TypeScript online submissions for Balanced Binary Tree. 3 | // Memory Usage: 44.7 MB, less than 64.71% of TypeScript online submissions for Balanced Binary Tree. 4 | 5 | function isBalanced(root: TreeNode | null): boolean { 6 | if (!root) return true; 7 | 8 | const left = helper(root.left); 9 | const right = helper(root.right); 10 | 11 | return ( 12 | Math.abs(left - right) <= 1 && 13 | isBalanced(root.left) && 14 | isBalanced(root.right) 15 | ); 16 | } 17 | 18 | const helper = (node: TreeNode | null): number => { 19 | if (!node) return 0; 20 | 21 | const left = helper(node.left); 22 | const right = helper(node.right); 23 | 24 | return Math.max(left, right) + 1; 25 | }; 26 | -------------------------------------------------------------------------------- /src/problems/1103-Distribute-Candies-to-People.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 76 ms, faster than 48.28% of JavaScript online submissions for Distribute Candies to People. 2 | // Memory Usage: 36.6 MB, less than 34.48% of JavaScript online submissions for Distribute Candies to People. 3 | function distributeCandies(candies: number, num_people: number): number[] { 4 | const res: number[] = new Array(num_people).fill(0); 5 | let i = 1; 6 | while (candies > 0) { 7 | res[(i - 1) % num_people] += Math.min(i, candies); 8 | candies -= i; 9 | i++; 10 | } 11 | return res; 12 | } 13 | 14 | // Generating an array with the distributions 15 | // Runtime: 72 ms, faster than 68.10% of JavaScript online submissions for Distribute Candies to People. 16 | // Memory Usage: 38.1 MB, less than 5.17% of JavaScript online submissions for Distribute Candies to People. 17 | 18 | function distributeCandies(candies: number, num_people: number): number[] { 19 | const distributions: number[] = []; 20 | let x = 1; 21 | while (candies > 0) { 22 | if (candies >= x) { 23 | candies -= x; 24 | distributions.push(x); 25 | } else { 26 | distributions.push(candies); 27 | candies = 0; 28 | } 29 | x++; 30 | } 31 | 32 | const res = new Array(num_people).fill(0); 33 | 34 | for (let i = 0; i < num_people; i++) { 35 | for (let j = i; j < distributions.length; j += num_people) { 36 | res[i] += distributions[j]; 37 | } 38 | } 39 | 40 | return res; 41 | } 42 | -------------------------------------------------------------------------------- /src/problems/1110.Delete-Nodes-And-Return-Forest.ts: -------------------------------------------------------------------------------- 1 | function delNodes( 2 | root: TreeNode | null, 3 | to_delete: number[] 4 | ): Array { 5 | const res: Array = []; 6 | const set = new Set(to_delete); 7 | 8 | const dfs = (node: TreeNode | null): TreeNode | null => { 9 | if (!node) return node; 10 | node.left = dfs(node.left); 11 | node.right = dfs(node.right); 12 | 13 | if (set.has(node.val)) { 14 | if (node?.left) { 15 | res.push(node.left); 16 | } 17 | if (node?.right) { 18 | res.push(node.right); 19 | } 20 | 21 | return null; 22 | } 23 | 24 | return node; 25 | }; 26 | 27 | if (root && !set.has(root.val)) { 28 | res.push(root); 29 | } 30 | 31 | dfs(root); 32 | 33 | return res; 34 | } 35 | -------------------------------------------------------------------------------- /src/problems/112-Path-Sum.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 84 ms, faster than 73.82% of JavaScript online submissions for Path Sum. 2 | // Memory Usage: 39.9 MB, less than 30.91% of JavaScript online submissions for Path Sum. 3 | 4 | function hasPathSum(root: TreeNode | null, sum: number): boolean { 5 | if (!root) return false; 6 | const nextSum = sum - root.val; 7 | return ( 8 | (nextSum === 0 && isLeaf(root)) || 9 | hasPathSum(root.left, nextSum) || 10 | hasPathSum(root.right, nextSum) 11 | ); 12 | } 13 | const isLeaf = (node: TreeNode | null): boolean => { 14 | return Boolean(node && !node.left && !node.right); 15 | }; 16 | -------------------------------------------------------------------------------- /src/problems/113.Path-Sum-II.ts: -------------------------------------------------------------------------------- 1 | function pathSum(root: TreeNode | null, targetSum: number): number[][] { 2 | const res: number[][] = []; 3 | 4 | const traverse = (node: TreeNode | null, path: number[], sum: number) => { 5 | if (!node) return; 6 | 7 | const newSum = sum + node.val; 8 | 9 | if (!node.left && !node.right && newSum === targetSum) { 10 | res.push([...path, node.val]); 11 | } 12 | 13 | traverse(node.left, [...path, node.val], newSum); 14 | traverse(node.right, [...path, node.val], newSum); 15 | }; 16 | 17 | traverse(root, [], 0); 18 | return res; 19 | } 20 | -------------------------------------------------------------------------------- /src/problems/114.Flatten-Binary-Tree-to-Linked-List.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | export function flatten(root: TreeNode | null): void { 3 | if (!root) return; 4 | const stack: TreeNode[] = [root]; 5 | 6 | while (stack.length) { 7 | const curr = stack.pop()!; 8 | if (curr.right) stack.push(curr.right); 9 | if (curr.left) stack.push(curr.left); 10 | 11 | if (stack.length) curr.right = stack[0]; 12 | curr.left = null; 13 | } 14 | } 15 | 16 | // JS 17 | // const flatten = function (root) { 18 | // if (!root) return; 19 | // const stack = [root]; 20 | 21 | // while (stack.length) { 22 | // const curr = stack.pop(); 23 | // if (curr.right) stack.push(curr.right); 24 | // if (curr.left) stack.push(curr.left); 25 | 26 | // if (stack.length) curr.right = stack[stack.length - 1]; 27 | // curr.left = null; 28 | // } 29 | // }; 30 | -------------------------------------------------------------------------------- /src/problems/1145.Binary-Tree-Coloring-Game.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | function btreeGameWinningMove( 3 | root: TreeNode | null, 4 | n: number, 5 | x: number 6 | ): boolean { 7 | const count = (node: TreeNode | null): number => { 8 | if (!node) return 0; 9 | return count(node.left) + count(node.right) + 1; 10 | }; 11 | 12 | const find = (node: TreeNode | null): TreeNode | null => { 13 | if (!node) return null; 14 | if (node.val === x) return node; 15 | return find(node.left) || find(node.right); 16 | }; 17 | 18 | const xNode = find(root); 19 | const left = count(xNode!.left); 20 | const right = count(xNode!.right); 21 | const parent = n - left - right - 1; 22 | const y = Math.max(left, right, parent); 23 | 24 | return y > n / 2; 25 | } 26 | 27 | // JS 28 | // var btreeGameWinningMove = function (root, n, x) { 29 | // const count = (node) => { 30 | // if (!node) return 0; 31 | // return count(node.left) + count(node.right) + 1; 32 | // }; 33 | 34 | // const find = (node) => { 35 | // if (!node) return false; 36 | // if (node.val === x) return node; 37 | // return find(node.left) || find(node.right); 38 | // }; 39 | 40 | // const xNode = find(root); 41 | // const left = count(xNode.left); 42 | // const right = count(xNode.right); 43 | // const parent = n - left - right - 1; 44 | // const y = Math.max(left, right, parent); 45 | 46 | // return y > n - y; 47 | // }; 48 | -------------------------------------------------------------------------------- /src/problems/116-Populating-Next-Right-Pointers-in-Each-Node.ts: -------------------------------------------------------------------------------- 1 | interface Node { 2 | val: number; 3 | left: Node | null; 4 | right: Node | null; 5 | next: Node | null; 6 | } 7 | 8 | function connect(root: Node | null): Node | null { 9 | if (!root) return root; 10 | let queue: Node[] = [root]; 11 | 12 | while (queue.length) { 13 | const nextQueue: Node[] = []; 14 | 15 | while (queue.length) { 16 | const curr = queue.shift()!; 17 | 18 | if (queue.length) curr.next = queue[0]; 19 | if (curr.left) nextQueue.push(curr.left); 20 | if (curr.right) nextQueue.push(curr.right); 21 | } 22 | 23 | queue = nextQueue; 24 | } 25 | 26 | return root; 27 | } 28 | -------------------------------------------------------------------------------- /src/problems/1161-Maximum-Level-Sum-of-a-Binary-Tree.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 188 ms, faster than 89.35% of JavaScript online submissions for Maximum Level Sum of a Binary Tree. 2 | // Memory Usage: 55.5 MB, less than 60.46% of JavaScript online submissions for Maximum Level Sum of a Binary Tree. 3 | 4 | function maxLevelSum(root: TreeNode | null): number { 5 | const arr: number[] = []; 6 | 7 | const helper = (node: TreeNode | null, level: number) => { 8 | if (!node) return; 9 | arr[level] ? (arr[level] += node.val) : arr.push(node.val); 10 | helper(node.left, level + 1); 11 | helper(node.right, level + 1); 12 | }; 13 | 14 | helper(root, 0); 15 | 16 | return arr.indexOf(Math.max(...arr)) + 1; 17 | } 18 | -------------------------------------------------------------------------------- /src/problems/117.Populating-Next-Right-Pointers-in-Each-Node-II.ts: -------------------------------------------------------------------------------- 1 | function connect(root: Node | null): Node | null { 2 | if (!root) return root; 3 | const stack: Node[] = [root]; 4 | 5 | while (stack.length) { 6 | let prev: Node | null = null; 7 | const nextStack: Node[] = []; 8 | 9 | while (stack.length) { 10 | const curr = stack.shift()!; 11 | if (prev) { 12 | prev!.next = curr; 13 | } 14 | prev = curr; 15 | 16 | if (curr.left) nextStack.push(curr.left); 17 | if (curr.right) nextStack.push(curr.right); 18 | } 19 | 20 | stack.push(...nextStack); 21 | } 22 | 23 | return root; 24 | } 25 | -------------------------------------------------------------------------------- /src/problems/118-Pascal's-Triangle.ts: -------------------------------------------------------------------------------- 1 | function generate(numRows: number): number[][] { 2 | const dp: number[][] = Array(numRows) 3 | .fill(null) 4 | .map((_, i) => Array(i + 1)); 5 | 6 | for (let i = 0; i < dp.length; i++) { 7 | dp[i][0] = 1; 8 | dp[i][dp[i].length - 1] = 1; 9 | } 10 | 11 | for (let i = 2; i < dp.length; i++) { 12 | for (let j = 1; j < dp[i].length - 1; j++) { 13 | dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j]; 14 | } 15 | } 16 | 17 | return dp; 18 | } 19 | -------------------------------------------------------------------------------- /src/problems/119-Pascal's-Triangle-II.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 72 ms, faster than 63.17% of JavaScript online submissions for Pascal's Triangle II. 2 | // Memory Usage: 37.9 MB, less than 6.55% of JavaScript online submissions for Pascal's Triangle II. 3 | 4 | function getRow(rowIndex: number): number[] { 5 | const res: number[][] = [[1], [1, 1]]; 6 | for (let i = 2; i <= rowIndex; i++) { 7 | const aux: number[] = []; 8 | 9 | for (let j = 1; j < i; j++) { 10 | aux.push(res[i - 1][j - 1] + res[i - 1][j]); 11 | } 12 | 13 | res.push([1, ...aux, 1]); 14 | } 15 | 16 | return res[rowIndex]; 17 | } 18 | -------------------------------------------------------------------------------- /src/problems/120.Triangle.ts: -------------------------------------------------------------------------------- 1 | // Buttom-Up 2 | var minimumTotal = function (triangle) { 3 | for (let i = triangle.length - 2; ~i; i--) { 4 | for (let j = 0; j < triangle.length; j++) { 5 | triangle[i][j] += Math.min(triangle[i + 1][j], triangle[i + 1][j + 1]); 6 | } 7 | } 8 | return triangle[0][0]; 9 | }; 10 | 11 | // Top-Down 12 | var minimumTotal = function (triangle) { 13 | for (let i = 1; i < triangle.length; i++) { 14 | triangle[i][0] += triangle[i - 1][0]; // First in row 15 | triangle[i][i] += triangle[i - 1][i - 1]; // Last in row 16 | 17 | for (let j = 1; j < i; j++) { 18 | triangle[i][j] += Math.min(triangle[i - 1][j - 1], triangle[i - 1][j]); 19 | } 20 | } 21 | 22 | return Math.min(...triangle[triangle.length - 1]); 23 | }; 24 | -------------------------------------------------------------------------------- /src/problems/1202.Smallest-String-With-Swaps.ts: -------------------------------------------------------------------------------- 1 | function smallestStringWithSwaps(s: string, pairs: number[][]): string { 2 | if (!pairs.length) return s; 3 | 4 | const res = Array(s.length).fill(s.length); 5 | const map: { [key: string]: number[] } = {}; 6 | const visited = new Set(); 7 | let chars: string[] = []; 8 | let indexes: number[] = []; 9 | 10 | const dfs = (i: number) => { 11 | if (visited.has(i)) return; 12 | visited.add(i); 13 | const nodes = map[i]; 14 | chars.push(s[i]); 15 | indexes.push(i); 16 | if (!nodes) return; 17 | for (const n of nodes) { 18 | dfs(n); 19 | } 20 | }; 21 | 22 | for (const [u, v] of pairs) { 23 | if (map[u] == undefined) map[u] = []; 24 | if (map[v] == undefined) map[v] = []; 25 | 26 | map[u].push(v); 27 | map[v].push(u); 28 | } 29 | 30 | for (let i = 0; i < s.length; i++) { 31 | chars = []; 32 | indexes = []; 33 | dfs(i); 34 | chars.sort(); 35 | indexes.sort((a, b) => a - b); 36 | for (let j = 0; j < indexes.length; j++) { 37 | res[indexes[j]] = chars[j]; 38 | } 39 | } 40 | 41 | return res.join(""); 42 | } 43 | -------------------------------------------------------------------------------- /src/problems/121-Best-Time-to-Buy-and-Sell-Stock.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | function maxProfit(prices: number[]): number { 3 | let min = Number.MAX_SAFE_INTEGER; 4 | let max = 0; 5 | 6 | prices.forEach((price) => { 7 | min = Math.min(min, price); 8 | max = Math.max(max, price - min); 9 | }); 10 | 11 | return max; 12 | } 13 | -------------------------------------------------------------------------------- /src/problems/123-Best-Time-to-Buy-and-Sell-Stock-III.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 96 ms, faster than 45.28% of JavaScript online submissions for Best Time to Buy and Sell Stock III. 2 | // Memory Usage: 38.8 MB, less than 49.81% of JavaScript online submissions for Best Time to Buy and Sell Stock III. 3 | // @ts-ignore 4 | function maxProfit(prices: number[]): number { 5 | if (prices.length <= 1) return 0; 6 | 7 | let leftMin = Number.MAX_SAFE_INTEGER; 8 | let rightMax = Number.MIN_SAFE_INTEGER; 9 | let leftProfit = 0; 10 | let rightProfit = 0; 11 | const leftArray: number[] = new Array(prices.length); 12 | const rightArray: number[] = new Array(prices.length); 13 | 14 | for (let i = 0; i < prices.length; i++) { 15 | leftMin = Math.min(leftMin, prices[i]); 16 | leftProfit = Math.max(leftProfit, prices[i] - leftMin); 17 | leftArray[i] = leftProfit; 18 | 19 | rightMax = Math.max(rightMax, prices[prices.length - 1 - i]); 20 | rightProfit = Math.max( 21 | rightProfit, 22 | rightMax - prices[prices.length - 1 - i] 23 | ); 24 | rightArray[prices.length - 1 - i] = rightProfit; 25 | } 26 | 27 | const mergedArray = leftArray.map( 28 | (leftValue, i) => leftValue + rightArray[i] 29 | ); 30 | 31 | return Math.max(...mergedArray); 32 | } 33 | -------------------------------------------------------------------------------- /src/problems/124.Binary-Tree-Maximum-Path-Sum.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | function maxPathSum(root: TreeNode | null): number { 3 | let res = -Infinity; 4 | 5 | const traverse = (node: TreeNode | null): number => { 6 | if (!node) return 0; 7 | const left = Math.max(0, traverse(node.left)); 8 | const right = Math.max(0, traverse(node.right)); 9 | res = Math.max(res, node.val + left + right); 10 | return node.val + Math.max(left, right); 11 | }; 12 | 13 | traverse(root); 14 | return res; 15 | } 16 | 17 | // JS 18 | // var maxPathSum = function (root) { 19 | // let res = -Infinity; 20 | 21 | // const traverse = (node) => { 22 | // if (!node) return 0; 23 | // const left = Math.max(0, traverse(node.left)); 24 | // const right = Math.max(0, traverse(node.right)); 25 | // res = Math.max(res, node.val + left + right); 26 | // return node.val + Math.max(left, right); 27 | // }; 28 | 29 | // traverse(root); 30 | // return res; 31 | // }; 32 | -------------------------------------------------------------------------------- /src/problems/125-Valid-Palindrome.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 84 ms, faster than 82.42% of JavaScript online submissions for Valid Palindrome. 2 | // Memory Usage: 38.5 MB, less than 70.25% of JavaScript online submissions for Valid Palindrome. 3 | 4 | function isPalindrome(s: string): boolean { 5 | const auxS = s.replace(/[^a-z\d]/g, '').toLocaleLowerCase(); 6 | 7 | const len = auxS.length - 1; 8 | for (let i = 0, j = len; i <= Math.floor(len / 2); i++, j--) { 9 | if (auxS[i] !== auxS[j]) return false; 10 | } 11 | return true; 12 | } 13 | -------------------------------------------------------------------------------- /src/problems/1261.Find-Elements-in-a-Contaminated-Binary-Tree.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | // Runtime: 128 ms, faster than 100.00% of TypeScript online submissions for Find Elements in a Contaminated Binary Tree. 3 | // Memory Usage: 48.8 MB, less than 100.00% of TypeScript online submissions for Find Elements in a Contaminated Binary Tree. 4 | 5 | class FindElements { 6 | set = new Set(); 7 | 8 | constructor(root: TreeNode | null) { 9 | this.decontaminateTree(root, 0); 10 | } 11 | 12 | private decontaminateTree = (node: TreeNode | null, nextVal: number) => { 13 | if (!node) return; 14 | node.val = nextVal; 15 | this.set.add(nextVal); 16 | 17 | const nextLeftValue = 2 * nextVal + 1; 18 | const nextRightValue = 2 * nextVal + 2; 19 | 20 | this.decontaminateTree(node.left, nextLeftValue); 21 | this.decontaminateTree(node.right, nextRightValue); 22 | }; 23 | 24 | find(target: number): boolean { 25 | return this.set.has(target); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/problems/1268.Search-Suggestions-System.ts: -------------------------------------------------------------------------------- 1 | function suggestedProducts(products: string[], searchWord: string): string[][] { 2 | products.sort(); 3 | const res: string[][] = new Array(searchWord.length).fill([]); 4 | 5 | for (let idx = 0; idx < searchWord.length; idx++) { 6 | const next: string[] = []; 7 | for (let i = 0; i < products.length; i++) { 8 | if (products[i][idx] === searchWord[idx]) { 9 | next.push(products[i]); 10 | res[idx].length < 3 && res[idx].push(products[i]); 11 | } 12 | } 13 | products = next; 14 | } 15 | return res; 16 | } 17 | -------------------------------------------------------------------------------- /src/problems/1277-Count-Square-Submatrices-with-All-Ones.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | // Runtime: 168 ms, faster than 15.32% of JavaScript online submissions for Count Square Submatrices with All Ones. 3 | // Memory Usage: 41 MB, less than 45.95% of JavaScript online submissions for Count Square Submatrices with All Ones. 4 | 5 | // JS 6 | // Runtime: 96 ms, faster than 83.33% of TypeScript online submissions for Count Square Submatrices with All Ones. 7 | // Memory Usage: 42.1 MB, less than 16.67% of TypeScript online submissions for Count Square Submatrices with All Ones. 8 | 9 | function countSquares(matrix: number[][]): number { 10 | let res = 0; 11 | 12 | const checkSquare = (i: number, j: number) => { 13 | const a = matrix[i - 1][j - 1]; 14 | const b = matrix[i][j - 1]; 15 | const c = matrix[i - 1][j]; 16 | 17 | if (a && b && c) { 18 | matrix[i][j] += Math.min(a, b, c); 19 | } 20 | }; 21 | 22 | for (let i = 1; i < matrix.length; i++) { 23 | for (let j = 1; j < matrix[0].length; j++) { 24 | if (matrix[i][j]) checkSquare(i, j); 25 | } 26 | } 27 | 28 | for (let i = 0; i < matrix.length; i++) { 29 | for (let j = 0; j < matrix[0].length; j++) { 30 | if (matrix[i][j]) { 31 | res += matrix[i][j]; 32 | } 33 | } 34 | } 35 | 36 | return res; 37 | } 38 | -------------------------------------------------------------------------------- /src/problems/1283-Find-the-Smallest-Divisor-Given-a-Threshold.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | function smallestDivisor(nums: number[], threshold: number): number { 3 | let l = 1; 4 | let r = Math.max(...nums); 5 | 6 | while (l < r) { 7 | const mid = Math.floor((l + r) / 2); 8 | const sum = nums.reduce((acc, num) => acc + Math.ceil(num / mid), 0); 9 | 10 | if (sum > threshold) l = mid + 1; 11 | else r = mid; 12 | } 13 | 14 | return l; 15 | } 16 | 17 | // JS 18 | // var smallestDivisor = function (nums, threshold) { 19 | // let l = 1; 20 | // let r = Math.max(...nums); 21 | 22 | // while (l < r) { 23 | // const mid = Math.floor((l + r) / 2); 24 | // const sum = nums.reduce((acc, num) => acc + Math.ceil(num / mid), 0); 25 | 26 | // if (sum > threshold) l = mid + 1; 27 | // else r = mid; 28 | // } 29 | 30 | // return l; 31 | // }; 32 | -------------------------------------------------------------------------------- /src/problems/1286-Iterator-for-Combination.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 108 ms, faster than 100.00% of TypeScript online submissions for Iterator for Combination. 2 | // Memory Usage: 46.7 MB, less than 100.00% of TypeScript online submissions for Iterator for Combination. 3 | 4 | class CombinationIterator { 5 | private characters: string; 6 | private combinationLength: number; 7 | private combinations: string[]; 8 | private size: number; 9 | private current: number; 10 | 11 | constructor(characters: string, combinationLength: number) { 12 | this.characters = characters; 13 | this.combinationLength = combinationLength; 14 | this.current = 0; 15 | this.combinations = []; 16 | this.generateCombinations([], this.characters.split('')); 17 | this.size = this.combinations.length; 18 | } 19 | 20 | private generateCombinations( 21 | have: string[] = [], 22 | stack: string[] = [] 23 | ): void { 24 | if (have.length >= this.combinationLength) { 25 | this.combinations.push(have.join('')); 26 | return; 27 | } 28 | 29 | for (let i = 0; i < stack.length; i++) { 30 | const newStack = stack.filter((_, index) => index > i); 31 | this.generateCombinations([...have, stack[i]], newStack); 32 | } 33 | } 34 | 35 | next(): string { 36 | return this.combinations[this.current++]; 37 | } 38 | 39 | hasNext(): boolean { 40 | return this.current < this.size; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/problems/1288-Remove-Covered-Intervals.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | // Runtime: 92 ms, faster than 50.00% of TypeScript online submissions for Remove Covered Intervals. 3 | // Memory Usage: 41.1 MB, less than 50.00% of TypeScript online submissions for Remove Covered Intervals. 4 | function removeCoveredIntervals(intervals: number[][]): number { 5 | intervals.sort(([a, b], [c, d]) => a - c || d - b); 6 | 7 | let res = 0; 8 | let end = Number.MIN_SAFE_INTEGER; 9 | 10 | intervals.forEach(([, b]) => { 11 | if (b > end) res++; 12 | 13 | end = Math.max(end, b); 14 | }); 15 | 16 | return res; 17 | } 18 | 19 | // JS 20 | // Runtime: 84 ms, faster than 83.33% of JavaScript online submissions for Remove Covered Intervals. 21 | // Memory Usage: 40.5 MB, less than 40.00% of JavaScript online submissions for Remove Covered Intervals. 22 | 23 | // var removeCoveredIntervals = function (intervals) { 24 | // intervals.sort(([a, b], [c, d]) => a - c || d - b); 25 | 26 | // let res = 0; 27 | // let end = Number.MIN_SAFE_INTEGER; 28 | 29 | // intervals.forEach(([, b]) => { 30 | // if (b > end) res++; 31 | 32 | // end = Math.max(end, b); 33 | // }); 34 | 35 | // return res; 36 | // }; 37 | -------------------------------------------------------------------------------- /src/problems/129.Sum-Root-to-Leaf-Numbers.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | // Runtime: 88 ms, faster than 56.52% of TypeScript online submissions for Sum Root to Leaf Numbers. 3 | // Memory Usage: 40.5 MB, less than 26.09% of TypeScript online submissions for Sum Root to Leaf Numbers. 4 | const helper = (node: TreeNode | null, sum: number) => { 5 | if (!node) return 0; 6 | const newSum = sum * 10 + node.val; 7 | if (!node.left && !node.right) return newSum; 8 | return helper(node.left, newSum) + helper(node.right, newSum); 9 | }; 10 | 11 | function sumNumbers(root: TreeNode | null): number { 12 | return helper(root, 0); 13 | } 14 | 15 | // JS 16 | // Runtime: 76 ms, faster than 93.96% of JavaScript online submissions for Sum Root to Leaf Numbers. 17 | // Memory Usage: 39.2 MB, less than 100.00% of JavaScript online submissions for Sum Root to Leaf Numbers. 18 | // const helper = (node, sum) => { 19 | // if (!node) return 0; 20 | // const newSum = sum * 10 + node.val; 21 | // if (!node.left && !node.right) return newSum; 22 | // return helper(node.left, newSum) + helper(node.right, newSum); 23 | // }; 24 | 25 | // var sumNumbers = function (root) { 26 | // return helper(root, 0); 27 | // }; 28 | -------------------------------------------------------------------------------- /src/problems/1295-Find-Numbers-with-Even-Number-of-Digits.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 68 ms, faster than 93.42% of JavaScript online submissions for Find Numbers with Even Number of Digits. 2 | // Memory Usage: 37.5 MB, less than 25.14% of JavaScript online submissions for Find Numbers with Even Number of Digits. 3 | 4 | function findNumbers(nums: number[]): number { 5 | return nums.reduce((acc, curr) => { 6 | const numString = curr.toString(); 7 | 8 | if (numString.length % 2 === 0) { 9 | return acc + 1; 10 | } 11 | return acc; 12 | }, 0); 13 | } 14 | -------------------------------------------------------------------------------- /src/problems/13.Roman-to-Integer.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | // Runtime: 172 ms, faster than 70.96% of TypeScript online submissions for Roman to Integer. 3 | // Memory Usage: 45.7 MB, less than 91.78% of TypeScript online submissions for Roman to Integer. 4 | const hash = { 5 | I: 1, 6 | V: 5, 7 | X: 10, 8 | L: 50, 9 | C: 100, 10 | D: 500, 11 | M: 1000, 12 | }; 13 | 14 | function romanToInt(s: string): number { 15 | let ans = hash[s[s.length - 1]]; 16 | 17 | for (let i = 0; i < s.length - 1; i++) { 18 | if (hash[s[i]] < hash[s[i + 1]]) ans -= hash[s[i]]; 19 | else ans += hash[s[i]]; 20 | } 21 | 22 | return ans; 23 | } 24 | 25 | // JS 26 | // Runtime: 152 ms, faster than 95.38% of JavaScript online submissions for Roman to Integer. 27 | // Memory Usage: 43.7 MB, less than 99.20% of JavaScript online submissions for Roman to Integer. 28 | // const hash = { 29 | // I: 1, 30 | // V: 5, 31 | // X: 10, 32 | // L: 50, 33 | // C: 100, 34 | // D: 500, 35 | // M: 1000, 36 | // }; 37 | 38 | // function romanToInt(s: string): number { 39 | // let ans = hash[s[s.length - 1]]; 40 | 41 | // for (let i = 0; i < s.length - 1; i++) { 42 | // if (hash[s[i]] < hash[s[i + 1]]) ans -= hash[s[i]]; 43 | // else ans += hash[s[i]]; 44 | // } 45 | 46 | // return ans; 47 | // } 48 | -------------------------------------------------------------------------------- /src/problems/1302.Deepest-Leaves-Sum.ts: -------------------------------------------------------------------------------- 1 | function deepestLeavesSum(root: TreeNode | null): number { 2 | if (!root) return 0; 3 | let queue: TreeNode[] = [root]; 4 | const levels: number[] = []; 5 | 6 | while (queue.length) { 7 | levels.unshift(0); 8 | const newQueue: TreeNode[] = []; 9 | 10 | while (queue.length) { 11 | const curr = queue.shift()!; 12 | levels[0] += curr.val; 13 | 14 | if (curr.left) newQueue.push(curr.left); 15 | if (curr.right) newQueue.push(curr.right); 16 | } 17 | 18 | queue = newQueue; 19 | } 20 | 21 | return levels[0]; 22 | } 23 | -------------------------------------------------------------------------------- /src/problems/1305-All-Elements-in-Two-Binary-Search-Trees.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 204 ms, faster than 56.04% of JavaScript online submissions for All Elements in Two Binary Search Trees. 2 | // Memory Usage: 48.8 MB, less than 52.19% of JavaScript online submissions for All Elements in Two Binary Search Trees. 3 | var getAllElements = function (root1, root2, list = []) { 4 | const getAllNodes = (root) => { 5 | if (root) { 6 | list.push(root.val); 7 | getAllNodes(root.left); 8 | getAllNodes(root.right); 9 | } 10 | }; 11 | 12 | getAllNodes(root1); 13 | getAllNodes(root2); 14 | 15 | return list.sort((a, b) => a - b); 16 | }; 17 | 18 | // Runtime: 188 ms, faster than 100.00% of TypeScript online submissions for All Elements in Two Binary Search Trees. 19 | // Memory Usage: 47.9 MB, less than 100.00% of TypeScript online submissions for All Elements in Two Binary Search Trees. 20 | function getAllElements( 21 | root1: TreeNode | null, 22 | root2: TreeNode | null, 23 | list: number[] = [] 24 | ): number[] { 25 | const getAllNodes = (root: TreeNode | null) => { 26 | if (root) { 27 | list.push(root.val); 28 | getAllNodes(root.left); 29 | getAllNodes(root.right); 30 | } 31 | }; 32 | 33 | getAllNodes(root1); 34 | getAllNodes(root2); 35 | 36 | return list.sort((a, b) => a - b); 37 | } 38 | -------------------------------------------------------------------------------- /src/problems/1306-Jump-Game-III.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | // Runtime: 76 ms, faster than 100.00% of TypeScript online submissions for Jump Game III. 3 | // Memory Usage: 43.9 MB, less than 100.00% of TypeScript online submissions for Jump Game III. 4 | function canReach(arr: number[], start: number): boolean { 5 | const visited = new Set(); 6 | const stack = [start]; 7 | 8 | while (stack.length) { 9 | const curr = stack.shift()!; 10 | 11 | if (arr[curr] === 0) { 12 | return true; 13 | } 14 | 15 | visited.add(curr); 16 | 17 | const left = curr - arr[curr]; 18 | const right = curr + arr[curr]; 19 | 20 | if (left >= 0 && !visited.has(left)) { 21 | stack.push(left); 22 | } 23 | 24 | if (right < arr.length && !visited.has(right)) { 25 | stack.push(right); 26 | } 27 | } 28 | 29 | return false; 30 | } 31 | -------------------------------------------------------------------------------- /src/problems/1313-Decompress-Run-Length-Encoded-List.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 84 ms, faster than 95.38% of JavaScript online submissions for Decompress Run-Length Encoded List. 2 | // Memory Usage: 37.5 MB, less than 99.75% of JavaScript online submissions for Decompress Run-Length Encoded List. 3 | 4 | function decompressRLElist(nums: number[]): number[] { 5 | const res = []; 6 | 7 | for (let i = 0; i < nums.length - 1; i += 2) { 8 | res.push(...new Array(nums[i]).fill(nums[i + 1])); 9 | } 10 | 11 | return res; 12 | } 13 | -------------------------------------------------------------------------------- /src/problems/1315.Sum-of-Nodes-with-Even-Valued-Grandparent.ts: -------------------------------------------------------------------------------- 1 | function sumEvenGrandparent(root: TreeNode | null): number { 2 | let sum = 0; 3 | 4 | const traverse = ( 5 | node: TreeNode | null, 6 | evenParent: boolean, 7 | evenGrandParent: boolean 8 | ) => { 9 | if (!node) return; 10 | 11 | traverse(node.left, !(node.val % 2), evenParent); 12 | if (evenGrandParent) sum += node.val; 13 | traverse(node.right, !(node.val % 2), evenParent); 14 | }; 15 | 16 | traverse(root, false, false); 17 | 18 | return sum; 19 | } 20 | -------------------------------------------------------------------------------- /src/problems/1329.Sort-the-Matrix-Diagonally.ts: -------------------------------------------------------------------------------- 1 | function diagonalSort(mat: number[][]): number[][] { 2 | const hash: { [key: string]: number[] } = {}; 3 | const res: number[][] = Array(mat.length) 4 | .fill(null) 5 | .map(() => Array(mat[0].length)); 6 | 7 | // Construct hash 8 | for (let i = 0; i < mat.length; i++) { 9 | for (let j = 0; j < mat[0].length; j++) { 10 | const k = i - j; 11 | if (k in hash) hash[k].push(mat[i][j]); 12 | else hash[k] = [mat[i][j]]; 13 | } 14 | } 15 | 16 | // Sort 17 | Object.keys(hash).forEach((key) => { 18 | hash[key].sort((a, b) => a - b); 19 | }); 20 | 21 | // Construct sorder array 22 | Object.keys(hash).forEach((key) => { 23 | let i = 0; 24 | let j = 0; 25 | 26 | if (Number(key) < 0) { 27 | j += Math.abs(Number(key)); 28 | } 29 | if (Number(key) > 0) { 30 | i += Number(key); 31 | } 32 | 33 | hash[key].forEach((val) => { 34 | res[i++][j++] = val; 35 | }); 36 | }); 37 | 38 | return res; 39 | } 40 | -------------------------------------------------------------------------------- /src/problems/1337-The-K-Weakest-Rows-in-a-Matrix.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 80 ms, faster than 62.73% of JavaScript online submissions for The K Weakest Rows in a Matrix. 2 | // Memory Usage: 38.8 MB, less than 11.11% of JavaScript online submissions for The K Weakest Rows in a Matrix. 3 | 4 | type Hash = { 5 | [key: string]: number; 6 | }; 7 | 8 | function kWeakestRows(mat: number[][], k: number): number[] { 9 | const hash: Hash = {}; 10 | 11 | mat.forEach((row, rowIndex) => { 12 | hash[rowIndex] = 0; 13 | row.forEach((val) => { 14 | if (val) { 15 | hash[rowIndex]++; 16 | } 17 | }); 18 | }); 19 | 20 | return Object.entries(hash) 21 | .sort(([, a], [, b]) => a - b) 22 | .map(([key]) => parseInt(key)) 23 | .slice(0, k); 24 | } 25 | -------------------------------------------------------------------------------- /src/problems/1337.The-K-Weakest-Rows-in-a-Matrix.ts: -------------------------------------------------------------------------------- 1 | function kWeakestRows(mat: number[][], k: number): number[] { 2 | const hash: { [key: string]: number } = {}; 3 | 4 | for (let i = 0; i < mat.length; i++) { 5 | hash[i] = 0; 6 | 7 | for (let j = 0; j < mat[0].length; j++) { 8 | if (mat[i][j]) { 9 | hash[i]++; 10 | } 11 | } 12 | } 13 | 14 | return Object.entries(hash) 15 | .sort(([, b], [, d]) => b - d) 16 | .map(([a]) => Number(a)) 17 | .splice(0, k); 18 | } 19 | -------------------------------------------------------------------------------- /src/problems/1339.Maximum-Product-of-Splitted-Binary-Tree.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | // Runtime: 188 ms, faster than 100.00% of TypeScript online submissions for Maximum Product of Splitted Binary Tree. 3 | // Memory Usage: 65.9 MB, less than 100.00% of TypeScript online submissions for Maximum Product of Splitted Binary Tree. 4 | 5 | const getSum = (node: TreeNode | null): number => { 6 | if (!node) return 0; 7 | return node.val + getSum(node.left) + getSum(node.right); 8 | }; 9 | 10 | function maxProduct(root: TreeNode | null): number { 11 | let res = 1; 12 | const total = getSum(root); 13 | 14 | const dfs = (node: TreeNode | null): number => { 15 | if (!node) return 0; 16 | const sub = node.val + dfs(node.left) + dfs(node.right); 17 | res = Math.max(res, sub * (total - sub)); 18 | return sub; 19 | }; 20 | 21 | dfs(root); 22 | 23 | return res % (10 ** 9 + 7); 24 | } 25 | -------------------------------------------------------------------------------- /src/problems/1345.Jump-Game-IV.ts: -------------------------------------------------------------------------------- 1 | function minJumps(arr: number[]): number { 2 | const hash: { [key: string]: Set } = {}; 3 | 4 | for (let i = 0; i < arr.length; i++) { 5 | const curr = arr[i]; 6 | if (!(curr in hash)) { 7 | hash[curr] = new Set(); 8 | } 9 | hash[curr].add(i); 10 | } 11 | 12 | const neighbours = (idx: number): number[] => { 13 | const res: number[] = []; 14 | 15 | if (idx + 1 < arr.length) res.push(idx + 1); 16 | if (idx - 1 >= 0) res.push(idx - 1); 17 | 18 | res.push(...hash[arr[idx]]); 19 | hash[arr[idx]].clear(); 20 | 21 | return res; 22 | }; 23 | 24 | let steps = 0; 25 | 26 | const visited = new Set([0]); 27 | let queue: number[] = [0]; 28 | 29 | while (true) { 30 | let newQueue: number[] = []; 31 | 32 | while (queue.length) { 33 | let idx = queue.pop()!; 34 | if (idx === arr.length - 1) { 35 | return steps; 36 | } 37 | 38 | for (let neigh of neighbours(idx)) { 39 | if (!visited.has(neigh)) { 40 | visited.add(neigh); 41 | newQueue.push(neigh); 42 | } 43 | } 44 | } 45 | 46 | steps++; 47 | queue = newQueue; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/problems/136.Single-Number.ts: -------------------------------------------------------------------------------- 1 | function singleNumber(nums: number[]): number { 2 | const set = new Set(); 3 | 4 | for (let i = 0; i < nums.length; i++) { 5 | if (set.has(nums[i])) set.delete(nums[i]); 6 | else set.add(nums[i]); 7 | } 8 | 9 | return [...set.values()][0]; 10 | } 11 | -------------------------------------------------------------------------------- /src/problems/1379.Find-a-Corresponding-Node-of-a-Binary-Tree-in-a-Clone-of-That-Tree.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | // Runtime: 324 ms, faster than 80.00% of TypeScript online submissions for Find a Corresponding Node of a Binary Tree in a Clone of That Tree. 3 | // Memory Usage: 60.6 MB, less than 40.00% of TypeScript online submissions for Find a Corresponding Node of a Binary Tree in a Clone of That Tree. 4 | 5 | function getTargetCopy( 6 | original: TreeNode | null, 7 | cloned: TreeNode | null, 8 | target: TreeNode | null 9 | ): TreeNode | null { 10 | const dfs = (o: TreeNode | null, c: TreeNode | null): TreeNode | null => { 11 | if (!o) return null; 12 | 13 | const left = dfs(o.left, c!.left); 14 | 15 | if (left) { 16 | return left; 17 | } 18 | 19 | if (o === target) { 20 | return c; 21 | } 22 | 23 | return dfs(o.right, c!.right); 24 | }; 25 | 26 | return dfs(original, cloned); 27 | } 28 | -------------------------------------------------------------------------------- /src/problems/1381.Design-a-Stack-With-Increment-Operation.ts: -------------------------------------------------------------------------------- 1 | class CustomStack { 2 | maxSize: number; 3 | stack: number[]; 4 | constructor(maxSize: number) { 5 | this.maxSize = maxSize; 6 | this.stack = []; 7 | } 8 | 9 | push(x: number): void { 10 | if (this.stack.length < this.maxSize) { 11 | this.stack.push(x); 12 | } 13 | } 14 | 15 | pop(): number { 16 | return this.stack.pop() ?? -1; 17 | } 18 | 19 | increment(k: number, val: number): void { 20 | const j = Math.min(k, this.stack.length); 21 | for (let i = 0; i < j; i++) { 22 | this.stack[i] += val; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/problems/1387-Sort-Integers-by-The-Power-Value.ts: -------------------------------------------------------------------------------- 1 | // Short Version 2 | function getKth(lo: number, hi: number, k: number): number { 3 | const hash: { [key: string]: number } = {}; 4 | for (let i = lo; i <= hi; i++) hash[i] = getPower(i); 5 | return parseInt(Object.entries(hash).sort(([, a], [, b]) => a - b)[k - 1][0]); 6 | } 7 | 8 | const getPower = (x: number, power: number = 0): number => { 9 | if (x === 1) return power; 10 | return x % 2 ? getPower(3 * x + 1, power + 1) : getPower(x / 2, power + 1); 11 | }; 12 | 13 | // Long Version 14 | function getKth(lo: number, hi: number, k: number): number { 15 | const hash: { [key: string]: number } = {}; 16 | 17 | for (let i = lo; i <= hi; i++) { 18 | hash[i] = getPower(i); 19 | } 20 | 21 | const arr = Object.entries(hash).sort(([, a], [, b]) => a - b); 22 | const res = arr[k - 1][0]; 23 | return parseInt(res); 24 | } 25 | 26 | const getPower = (x: number, power: number = 0): number => { 27 | if (x === 1) return power; 28 | if (x % 2) { 29 | return getPower(3 * x + 1, power + 1); 30 | } 31 | return getPower(x / 2, power + 1); 32 | }; 33 | -------------------------------------------------------------------------------- /src/problems/139-Word-Break.ts: -------------------------------------------------------------------------------- 1 | function wordBreak(s: string, wordDict: string[]): boolean { 2 | const dp: boolean[] = Array(s.length + 1).fill(false); 3 | dp[0] = true; 4 | 5 | for (let i = 1; i <= s.length; i++) { 6 | for (let j = i; j <= s.length; j++) { 7 | const curr = s.slice(i - 1, j); 8 | if (wordDict.includes(curr) && dp[j - curr.length]) dp[j] = true; 9 | } 10 | } 11 | 12 | return dp[s.length]; 13 | } 14 | -------------------------------------------------------------------------------- /src/problems/143-Reorder-List.ts: -------------------------------------------------------------------------------- 1 | // Stacks 2 | function reorderList(head: ListNode | null): void { 3 | const stack: ListNode[] = []; 4 | 5 | while (head) { 6 | stack.push(head); 7 | head = head.next; 8 | } 9 | 10 | while (stack.length >= 3) { 11 | stack[0].next = stack[stack.length - 1]; 12 | stack[stack.length - 1].next = stack[1]; 13 | stack[stack.length - 2].next = null; 14 | 15 | stack.shift(); 16 | stack.pop(); 17 | } 18 | } 19 | 20 | // ListNodes 21 | function reorderList(head: ListNode | null): void { 22 | while (head?.next?.next) { 23 | const next = head.next; 24 | let penult = head.next; 25 | let last = head.next.next; 26 | 27 | while (last?.next) { 28 | penult = last; 29 | last = last.next; 30 | } 31 | 32 | head.next = last; 33 | last.next = next; 34 | penult.next = null; 35 | head = head.next.next; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/problems/1431-Kids-With-the-Greatest-Number-of-Candies.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 80 ms, faster than 89.39% of JavaScript online submissions for Kids With the Greatest Number of Candies. 2 | // Memory Usage: 37.2 MB, less than 80.34% of JavaScript online submissions for Kids With the Greatest Number of Candies. 3 | 4 | function kidsWithCandies(candies: number[], extraCandies: number): boolean[] { 5 | const max = Math.max(...candies); 6 | return candies.map((curr) => curr + extraCandies >= max); 7 | } 8 | -------------------------------------------------------------------------------- /src/problems/1437.Check-If-All-1's-Are-at-Least-Length-K-Places-Away.ts: -------------------------------------------------------------------------------- 1 | function kLengthApart(nums: number[], k: number): boolean { 2 | let count = 0; 3 | 4 | for (let i = 0; i < nums.length; i++) { 5 | if (nums[i]) { 6 | if (count < k) return false; 7 | count = 0; 8 | } else count++; 9 | } 10 | 11 | return true; 12 | } 13 | -------------------------------------------------------------------------------- /src/problems/144-Binary-Tree-Preorder-Traversal.ts: -------------------------------------------------------------------------------- 1 | // Recursion 2 | // Runtime: 64 ms, faster than 94.85% of JavaScript online submissions for Binary Tree Preorder Traversal. 3 | // Memory Usage: 37.2 MB, less than 5.08% of JavaScript online submissions for Binary Tree Preorder Traversal. 4 | 5 | function preorderTraversal(root: TreeNode | null): number[] { 6 | if (!root) return []; 7 | 8 | return [ 9 | root.val, 10 | ...preorderTraversal(root.left), 11 | ...preorderTraversal(root.right), 12 | ]; 13 | } 14 | 15 | // Helper Function 16 | // Runtime: 64 ms, faster than 94.85% of JavaScript online submissions for Binary Tree Preorder Traversal. 17 | // Memory Usage: 37 MB, less than 6.10% of JavaScript online submissions for Binary Tree Preorder Traversal. 18 | 19 | function preorderTraversal(root: TreeNode | null): number[] { 20 | const res: number[] = []; 21 | 22 | const helper = (node: TreeNode | null) => { 23 | if (!node) return; 24 | res.push(node.val); 25 | helper(node.left); 26 | helper(node.right); 27 | }; 28 | helper(root); 29 | 30 | return res; 31 | } 32 | -------------------------------------------------------------------------------- /src/problems/1441.Build-an-Array-With-Stack-Operations.ts: -------------------------------------------------------------------------------- 1 | // JS 2 | var buildArray = function (target, n) { 3 | const res = []; 4 | const flag = Math.min(target[target.length - 1], n); 5 | for (let i = 1; i <= flag; i++) { 6 | res.push('Push'); 7 | if (!target.includes(i)) res.push('Pop'); 8 | } 9 | 10 | return res; 11 | }; 12 | 13 | // TS 14 | function buildArray(target: number[], n: number): string[] { 15 | const res: ('Push' | 'Pop')[] = []; 16 | const flag = Math.min(target[target.length - 1], n); 17 | for (let i = 1; i <= flag; i++) { 18 | res.push('Push'); 19 | if (!target.includes(i)) res.push('Pop'); 20 | } 21 | 22 | return res; 23 | } 24 | -------------------------------------------------------------------------------- /src/problems/1448.Count-Good-Nodes-in-Binary-Tree.ts: -------------------------------------------------------------------------------- 1 | // JS 2 | var goodNodes = function (root) { 3 | const helper = (node, max) => { 4 | if (!node) return 0; 5 | 6 | const newMax = Math.max(max, node.val); 7 | const goodNode = node.val >= max ? 1 : 0; 8 | 9 | return goodNode + helper(node.left, newMax) + helper(node.right, newMax); 10 | }; 11 | 12 | return helper(root, Number.MIN_SAFE_INTEGER); 13 | }; 14 | 15 | // TS 16 | function goodNodes(root: TreeNode | null): number { 17 | const helper = (node: TreeNode | null, max: number): number => { 18 | if (!node) return 0; 19 | 20 | const newMax = Math.max(max, node.val); 21 | const goodNode = node.val >= max ? 1 : 0; 22 | 23 | return goodNode + helper(node.left, newMax) + helper(node.right, newMax); 24 | }; 25 | 26 | return helper(root, Number.MIN_SAFE_INTEGER); 27 | } 28 | -------------------------------------------------------------------------------- /src/problems/145-Binary-Tree-Postorder-Traversal.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 76 ms, faster than 50.75% of JavaScript online submissions for Binary Tree Postorder Traversal. 2 | // Memory Usage: 37 MB, less than 6.24% of JavaScript online submissions for Binary Tree Postorder Traversal. 3 | 4 | function postorderTraversal(root: TreeNode | null): number[] { 5 | if (!root) return []; 6 | 7 | return [ 8 | ...postorderTraversal(root.left), 9 | ...postorderTraversal(root.right), 10 | root.val, 11 | ]; 12 | } 13 | -------------------------------------------------------------------------------- /src/problems/1465.Maximum-Area-of-a-Piece-of-Cake-After-Horizontal-and-Vertical-Cuts.ts: -------------------------------------------------------------------------------- 1 | function maxArea( 2 | h: number, 3 | w: number, 4 | horizontalCuts: number[], 5 | verticalCuts: number[] 6 | ): number { 7 | horizontalCuts.sort((a, b) => a - b); 8 | verticalCuts.sort((a, b) => a - b); 9 | 10 | horizontalCuts.unshift(0); 11 | verticalCuts.unshift(0); 12 | horizontalCuts.push(h); 13 | verticalCuts.push(w); 14 | 15 | let hMax = 0; 16 | let vMax = 0; 17 | 18 | for (let i = 1; i < verticalCuts.length; i++) { 19 | hMax = Math.max(hMax, verticalCuts[i] - verticalCuts[i - 1]); 20 | } 21 | 22 | for (let i = 1; i < horizontalCuts.length; i++) { 23 | vMax = Math.max(vMax, horizontalCuts[i] - horizontalCuts[i - 1]); 24 | } 25 | 26 | return (hMax * vMax) % (1e9 + 7); 27 | } 28 | -------------------------------------------------------------------------------- /src/problems/1475.Final-Prices-With-a-Special-Discount-in-a-Shop.ts: -------------------------------------------------------------------------------- 1 | function finalPrices(prices: number[]): number[] { 2 | const getDiscount = (i: number) => { 3 | for (let j = i + 1; j < prices.length; j++) { 4 | if (prices[j] <= prices[i]) { 5 | return prices[i] - prices[j]; 6 | } 7 | } 8 | 9 | return prices[i]; 10 | }; 11 | 12 | return prices.map((_, i) => getDiscount(i)); 13 | } 14 | -------------------------------------------------------------------------------- /src/problems/1492.The-kth-Factor-of-n.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | // Runtime: 72 ms, faster than 100.00% of TypeScript online submissions for The kth Factor of n. 3 | // Memory Usage: 40.2 MB, less than 100.00% of TypeScript online submissions for The kth Factor of n. 4 | function kthFactor(n: number, k: number): number { 5 | const factors: number[] = [1]; 6 | 7 | for (let i = 2; i <= n / 2; i++) { 8 | if (n % i === 0) { 9 | factors.push(i); 10 | } 11 | } 12 | 13 | factors.push(n); 14 | 15 | return factors.length > k - 1 ? factors[k - 1] : -1; 16 | } 17 | 18 | // JS 19 | // Runtime: 72 ms, faster than 98.21% of JavaScript online submissions for The kth Factor of n. 20 | // Memory Usage: 38.7 MB, less than 42.86% of JavaScript online submissions for The kth Factor of n. 21 | // var kthFactor = function (n, k) { 22 | // const factors = [1]; 23 | 24 | // for (let i = 2; i <= n / 2; i++) { 25 | // if (n % i === 0) { 26 | // factors.push(i); 27 | // } 28 | // } 29 | 30 | // factors.push(n); 31 | 32 | // return factors.length > k - 1 ? factors[k - 1] : -1; 33 | // }; 34 | -------------------------------------------------------------------------------- /src/problems/150.Evaluate-Reverse-Polish-Notation.ts: -------------------------------------------------------------------------------- 1 | const evaluate: { [key: string]: (a: number, b: number) => number } = { 2 | '+': (a: number, b: number) => a + b, 3 | '-': (a: number, b: number) => a - b, 4 | '*': (a: number, b: number) => a * b, 5 | '/': (a: number, b: number) => Math.trunc(a / b), 6 | }; 7 | 8 | function evalRPN(tokens: string[]): number { 9 | const stack: number[] = []; 10 | 11 | while (tokens.length) { 12 | const t = tokens.shift()!; 13 | if (t in evaluate) { 14 | const b = stack.pop()!; 15 | const a = stack.pop()!; 16 | stack.push(evaluate[t](a, b)); 17 | } else stack.push(Math.trunc(Number(t))); 18 | } 19 | 20 | return stack[0]; 21 | } 22 | -------------------------------------------------------------------------------- /src/problems/1502-Can-Make-Arithmetic-Progression-From-Sequence.ts: -------------------------------------------------------------------------------- 1 | function canMakeArithmeticProgression(arr: number[]): boolean { 2 | arr.sort((a, b) => a - b); 3 | const dif = Math.abs(arr[1] - arr[0]); 4 | 5 | for (let i = 1; i < arr.length; i++) { 6 | if (arr[i] - arr[i - 1] !== dif) return false; 7 | } 8 | 9 | return true; 10 | } 11 | -------------------------------------------------------------------------------- /src/problems/1512-Number-of-Good-Pairs.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 72 ms, faster than 83.53% of JavaScript online submissions for Number of Good Pairs. 2 | // Memory Usage: 36.8 MB, less than 13.38% of JavaScript online submissions for Number of Good 3 | 4 | function numIdenticalPairs(nums: number[]): number { 5 | const hash: { [key: string]: number } = {}; 6 | const arr: number[] = []; 7 | arr.push(0, 0); 8 | for (let i = 2; i < 100; i++) arr.push(arr[i - 1] + i - 1); 9 | 10 | nums.forEach((i) => { 11 | hash[i] ? hash[i]++ : (hash[i] = 1); 12 | }); 13 | 14 | return Object.values(hash).reduce((acc, curr) => { 15 | return curr > 1 ? acc + arr[curr] : acc; 16 | }, 0); 17 | } 18 | -------------------------------------------------------------------------------- /src/problems/152-Maximum-Product-Subarray.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | // Runtime: 80 ms, faster than 90.91% of TypeScript online submissions for Maximum Product Subarray. 3 | // Memory Usage: 38.8 MB, less than 54.54% of TypeScript online submissions for Maximum Product Subarray. 4 | function maxProduct(nums: number[]): number { 5 | let currMax = nums[0]; 6 | let currMin = nums[0]; 7 | let res = nums[0]; 8 | 9 | for (let i = 1; i < nums.length; i++) { 10 | const tempMax = currMax; 11 | 12 | currMax = Math.max(nums[i], nums[i] * currMax, nums[i] * currMin); 13 | currMin = Math.min(nums[i], nums[i] * currMin, nums[i] * tempMax); 14 | res = Math.max(res, currMax); 15 | } 16 | 17 | return res; 18 | } 19 | // JS 20 | // Runtime: 88 ms, faster than 48.23% of JavaScript online submissions for Maximum Product Subarray. 21 | // Memory Usage: 37.4 MB, less than 39.01% of JavaScript online submissions for Maximum Product Subarray. 22 | // const maxProduct = function (nums) { 23 | // let currMax = nums[0]; 24 | // let currMin = nums[0]; 25 | // let res = nums[0]; 26 | 27 | // for (let i = 1; i < nums.length; i++) { 28 | // const tempMax = currMax; 29 | 30 | // currMax = Math.max(nums[i], nums[i] * currMax, nums[i] * currMin); 31 | // currMin = Math.min(nums[i], nums[i] * currMin, nums[i] * tempMax); 32 | // res = Math.max(res, currMax); 33 | // } 34 | 35 | // return res; 36 | // }; 37 | -------------------------------------------------------------------------------- /src/problems/1528-Shuffle-String.ts: -------------------------------------------------------------------------------- 1 | // Hash 2 | // Runtime: 88 ms, faster than 69.49% of JavaScript online submissions for Shuffle String. 3 | // Memory Usage: 38.3 MB, less than 49.80% of JavaScript online submissions for Shuffle String. 4 | 5 | function restoreString(s: string, indices: number[]): string { 6 | const hash: { [key: string]: string } = {}; 7 | 8 | indices.forEach((num, index) => { 9 | hash[num] = s[index]; 10 | }); 11 | 12 | return Object.values(hash).join(''); 13 | } 14 | 15 | // One Liner 16 | // Runtime: 92 ms, faster than 56.12% of JavaScript online submissions for Shuffle String. 17 | // Memory Usage: 38.3 MB, less than 48.06% of JavaScript online submissions for Shuffle String. 18 | 19 | function restoreString(s: string, indices: number[]): string { 20 | return indices.map((_, i) => s[indices.indexOf(i)]).join(''); 21 | } 22 | 23 | // Auxiliary string 24 | // Runtime: 96 ms, faster than 42.96% of JavaScript online submissions for Shuffle String. 25 | // Memory Usage: 38.3 MB, less than 49.49% of JavaScript online submissions for Shuffle String. 26 | function restoreString(s: string, indices: number[]): string { 27 | let res: string = ''; 28 | 29 | for (let i = 0; i < indices.length; i++) { 30 | res += indices.indexOf(i); 31 | } 32 | 33 | return res; 34 | } 35 | -------------------------------------------------------------------------------- /src/problems/1544.Make-The-String-Great.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | function makeGood(s: string): string { 3 | const stack: string[] = []; 4 | 5 | let i = 0; 6 | 7 | const isBad = (c1: string, c2: string) => { 8 | return Math.abs(c1.charCodeAt(0) - c2.charCodeAt(0)) === 32; 9 | }; 10 | 11 | while (i < s.length) { 12 | stack.push(s.charAt(i)); 13 | 14 | while ( 15 | stack.length > 1 && 16 | isBad(stack[stack.length - 2], stack[stack.length - 1]) 17 | ) { 18 | stack.pop(); 19 | stack.pop(); 20 | } 21 | 22 | i++; 23 | } 24 | 25 | return stack.join(''); 26 | } 27 | 28 | // JS 29 | // var makeGood = function (s) { 30 | // const stack = []; 31 | 32 | // let i = 0; 33 | 34 | // const isBad = (c1, c2) => { 35 | // return Math.abs(c1.charCodeAt(0) - c2.charCodeAt(0)) === 32; 36 | // }; 37 | 38 | // while (i < s.length) { 39 | // stack.push(s.charAt(i)); 40 | 41 | // while ( 42 | // stack.length > 1 && 43 | // isBad(stack[stack.length - 2], stack[stack.length - 1]) 44 | // ) { 45 | // stack.pop(); 46 | // stack.pop(); 47 | // } 48 | 49 | // i++; 50 | // } 51 | 52 | // return stack.join(''); 53 | // }; 54 | -------------------------------------------------------------------------------- /src/problems/1551.Minimum-Operations-to-Make-Array-Equal.ts: -------------------------------------------------------------------------------- 1 | // Method 1 2 | var minOperations = function (n) { 3 | let res = 0; 4 | for (let i = 0; i < n / 2; i++) { 5 | res += n - (2 * i + 1); 6 | } 7 | return res; 8 | }; 9 | 10 | // Method 2 - Math 11 | var minOperations = function (n) { 12 | return Math.floor(n ** 2 / 4); 13 | }; 14 | -------------------------------------------------------------------------------- /src/problems/1557-Minimum-Number-of-Vertices-to-Reach-All-Nodes.ts: -------------------------------------------------------------------------------- 1 | // Set 2 | function findSmallestSetOfVertices(n: number, edges: number[][]): number[] { 3 | const set = new Set(Array.from({ length: n }, (_, i) => i)); 4 | edges.forEach(([_, to]) => set.delete(to)); 5 | return [...set]; 6 | } 7 | 8 | // Hash 9 | function findSmallestSetOfVertices(n: number, edges: number[][]): number[] { 10 | const hash: { [key: string]: number } = {}; 11 | 12 | for (let i = 0; i < n; i++) hash[i] = 0; 13 | 14 | edges.forEach(([, to]) => { 15 | hash[to] ? hash[to]++ : (hash[to] = 1); 16 | }); 17 | 18 | return Object.entries(hash) 19 | .filter(([, to]) => to === 0) 20 | .map(([from]) => parseInt(from)); 21 | } 22 | -------------------------------------------------------------------------------- /src/problems/1598.Crawler-Log-Folder.ts: -------------------------------------------------------------------------------- 1 | // JS 2 | var minOperations = function (logs) { 3 | let count = 0; 4 | 5 | for (const log of logs) { 6 | if (log === '../') count = Math.max(count - 1, 0); 7 | else if (log !== './') count++; 8 | } 9 | 10 | return count; 11 | }; 12 | 13 | // TS 14 | function minOperations(logs: string[]): number { 15 | let count = 0; 16 | 17 | for (const log of logs) { 18 | if (log === '../') count = Math.max(count - 1, 0); 19 | else if (log !== './') count++; 20 | } 21 | 22 | return count; 23 | } 24 | -------------------------------------------------------------------------------- /src/problems/160.Intersection-of-Two-Linked-Lists.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | // Runtime: 108 ms, faster than 89.34% of TypeScript online submissions for Intersection of Two Linked Lists. 3 | // Memory Usage: 46.7 MB, less than 54.10% of TypeScript online submissions for Intersection of Two Linked Lists. 4 | function getIntersectionNode( 5 | headA: ListNode | null, 6 | headB: ListNode | null 7 | ): ListNode | null { 8 | let currA = headA; 9 | let currB = headB; 10 | 11 | while (currA !== currB) { 12 | if (currA === currB) return currA; 13 | 14 | if (currA) currA = currA.next; 15 | else currA = headB; 16 | 17 | if (currB) currB = currB.next; 18 | else currB = headA; 19 | } 20 | 21 | return currA; 22 | } 23 | 24 | // JS 25 | // Runtime: 96 ms, faster than 98.22% of JavaScript online submissions for Intersection of Two Linked Lists. 26 | // Memory Usage: 46.2 MB, less than 40.41% of JavaScript online submissions for Intersection of Two Linked Lists. 27 | // var getIntersectionNode = function (headA, headB) { 28 | // let currA = headA; 29 | // let currB = headB; 30 | 31 | // while (currA !== currB) { 32 | // if (currA === currB) return currA; 33 | 34 | // if (currA) currA = currA.next; 35 | // else currA = headB; 36 | 37 | // if (currB) currB = currB.next; 38 | // else currB = headA; 39 | // } 40 | 41 | // return currA; 42 | // }; 43 | -------------------------------------------------------------------------------- /src/problems/1614.Maximum-Nesting-Depth-of-the-Parentheses.ts: -------------------------------------------------------------------------------- 1 | function maxDepth(s: string): number { 2 | let maxCount = 0; 3 | let count = 0; 4 | 5 | for (let i = 0; i < s.length; i++) { 6 | if (s.charAt(i) === '(') { 7 | count++; 8 | maxCount = Math.max(maxCount, count); 9 | } else if (s.charAt(i) === ')') { 10 | count--; 11 | } 12 | } 13 | 14 | return maxCount; 15 | } 16 | -------------------------------------------------------------------------------- /src/problems/1615-Maximal-Network-Rank.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | function maximalNetworkRank(n: number, roads: number[][]): number { 3 | const count = Array(n).fill(0); 4 | 5 | const mat: boolean[][] = Array(n) 6 | .fill(null) 7 | .map(() => Array(n).fill(false)); 8 | 9 | roads.forEach(([a, b]) => { 10 | mat[a][b] = true; 11 | mat[b][a] = true; 12 | 13 | count[a]++; 14 | count[b]++; 15 | }); 16 | 17 | let res = 0; 18 | 19 | for (let i = 0; i < n; i++) { 20 | for (let j = i + 1; j < n; j++) { 21 | const aux = count[i] + count[j] - (mat[i][j] ? 1 : 0); 22 | res = Math.max(aux, res); 23 | } 24 | } 25 | 26 | return res; 27 | } 28 | // JS 29 | // var maximalNetworkRank = function (n, roads) { 30 | // const count = Array(n).fill(0); 31 | 32 | // const mat = Array(n) 33 | // .fill(null) 34 | // .map(() => Array(n).fill(false)); 35 | 36 | // roads.forEach(([a, b]) => { 37 | // mat[a][b] = true; 38 | // mat[b][a] = true; 39 | 40 | // count[a]++; 41 | // count[b]++; 42 | // }); 43 | 44 | // let res = 0; 45 | 46 | // for (let i = 0; i < n; i++) { 47 | // for (let j = i + 1; j < n; j++) { 48 | // let aux = count[i] + count[j] - (mat[i][j] ? 1 : 0); 49 | // res = Math.max(aux, res); 50 | // } 51 | // } 52 | 53 | // return res; 54 | // }; 55 | -------------------------------------------------------------------------------- /src/problems/1641.Count-Sorted-Vowel-Strings.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | function countVowelStrings(n: number): number { 3 | const dp: number[][] = Array(n + 1) 4 | .fill(null) 5 | .map(() => Array(6).fill(0)); 6 | 7 | for (let i = 1; i <= 5; i++) { 8 | dp[1][i] = i; 9 | } 10 | 11 | for (let i = 2; i <= n; i++) { 12 | for (let j = 1; j <= 5; j++) { 13 | dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; 14 | } 15 | } 16 | 17 | return dp[n][5]; 18 | } 19 | 20 | countVowelStrings(5); 21 | 22 | // // JS 23 | // var countVowelStrings = function (n) { 24 | // const dp = Array(n + 1) 25 | // .fill(null) 26 | // .map(() => Array(6).fill(0)); 27 | 28 | // for (let i = 1; i <= 5; i++) { 29 | // dp[1][i] = i; 30 | // } 31 | 32 | // for (let i = 2; i <= n; i++) { 33 | // for (let j = 1; j <= 5; j++) { 34 | // dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; 35 | // } 36 | // } 37 | 38 | // return dp[n][5]; 39 | // }; 40 | -------------------------------------------------------------------------------- /src/problems/1642.Furthest-Building-You-Can-Reach.ts: -------------------------------------------------------------------------------- 1 | function furthestBuilding( 2 | heights: number[], 3 | bricks: number, 4 | ladders: number 5 | ): number { 6 | const pq = new MaxPriorityQueue({ priority: (x) => x }); 7 | 8 | let i = 0; 9 | while (i < heights.length) { 10 | if (heights[i] >= heights[i + 1]) { 11 | i++; 12 | continue; 13 | } 14 | 15 | const diff = heights[i + 1] - heights[i]; 16 | 17 | // if not enough bricks are left 18 | if (diff > bricks) { 19 | // if not enough ladders are left 20 | if (ladders === 0) break; 21 | 22 | // if the max bricks used at once > current jump 23 | // replace the max bricks with a ladder and use those bricks for current jump 24 | // else use ladder for the current jump 25 | if (!pq.isEmpty() && pq.front().element > diff) { 26 | bricks += pq.dequeue().element - diff; 27 | pq.enqueue(diff); 28 | } 29 | ladders--; 30 | } else { 31 | bricks -= diff; 32 | pq.enqueue(diff); 33 | } 34 | i++; 35 | } 36 | 37 | return i; 38 | } 39 | -------------------------------------------------------------------------------- /src/problems/1646.Get-Maximum-in-Generated-Array.ts: -------------------------------------------------------------------------------- 1 | function getMaximumGenerated(n: number): number { 2 | if (n <= 1) return n; 3 | 4 | const dp: number[] = Array(n + 1).fill(0); 5 | dp[1] = 1; 6 | 7 | for (let i = 2; i <= n; i++) { 8 | if (i % 2) { 9 | const j = Math.floor(i / 2); 10 | dp[i] = dp[j] + dp[j + 1]; 11 | } else { 12 | dp[i] = dp[i / 2]; 13 | } 14 | } 15 | 16 | return Math.max(...dp); 17 | } 18 | -------------------------------------------------------------------------------- /src/problems/1664.Ways-to-Make-a-Fair-Array.ts: -------------------------------------------------------------------------------- 1 | function waysToMakeFair(nums: number[]): number { 2 | let evens = 0; 3 | let odds = 0; 4 | 5 | for (let i = 0; i < nums.length; i++) { 6 | if (i % 2) odds += nums[i]; 7 | else evens += nums[i]; 8 | } 9 | 10 | let prevEvens = 0; 11 | let prevOdds = 0; 12 | let postEvens = evens; 13 | let postOdds = odds; 14 | 15 | let res = 0; 16 | 17 | for (let i = 0; i < nums.length; i++) { 18 | if (i % 2) postOdds -= nums[i]; 19 | else postEvens -= nums[i]; 20 | 21 | if (prevEvens + postOdds === prevOdds + postEvens) { 22 | res++; 23 | } 24 | 25 | if (i % 2) prevOdds += nums[i]; 26 | else prevEvens += nums[i]; 27 | } 28 | 29 | return res; 30 | } 31 | 32 | waysToMakeFair([2, 1, 6, 4]); 33 | -------------------------------------------------------------------------------- /src/problems/167-Two-Sum-II-Input-array-is-sorted.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 104 ms, faster than 29.94% of JavaScript online submissions for Two Sum II - Input array is sorted. 2 | // Memory Usage: 36.3 MB, less than 59.48% of JavaScript online submissions for Two Sum II - Input array is sorted. 3 | 4 | function twoSum(numbers: number[], target: number): number[] { 5 | const hash: { [key: string]: number } = {}; 6 | 7 | for (let i = 0; i < numbers.length; i++) { 8 | const n = target - numbers[i]; 9 | const find = hash[n]; 10 | if (find !== undefined) return [find + 1, i + 1]; 11 | hash[numbers[i]] = i; 12 | } 13 | return []; 14 | } 15 | -------------------------------------------------------------------------------- /src/problems/1672.Richest-Customer-Wealth.ts: -------------------------------------------------------------------------------- 1 | function maximumWealth(accounts: number[][]): number { 2 | const wealths = accounts.map((account) => 3 | account.reduce((prev, curr) => prev + curr, 0) 4 | ); 5 | 6 | return Math.max(...wealths); 7 | } 8 | -------------------------------------------------------------------------------- /src/problems/1689.Partitioning-Into-Minimum-Number Of Deci-Binary-Numbers.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | function minPartitions(n: string): number { 3 | return Math.max(...n.split('').map(Number)); 4 | } 5 | 6 | // JS 7 | // var minPartitions = function (n) { 8 | // return Math.max(...n.split('')); 9 | // }; 10 | -------------------------------------------------------------------------------- /src/problems/1695.Maximum-Erasure-Value.ts: -------------------------------------------------------------------------------- 1 | function maximumUniqueSubarray(nums: number[]): number { 2 | let res = 0; 3 | let sum = 0; 4 | const set = new Set(); 5 | 6 | let left = 0; 7 | let right = 0; 8 | 9 | while (right < nums.length) { 10 | console.log(left, right, set); 11 | 12 | if (set.has(nums[right])) { 13 | set.delete(nums[left]); 14 | sum -= nums[left]; 15 | left++; 16 | } else { 17 | set.add(nums[right]); 18 | sum += nums[right]; 19 | right++; 20 | res = Math.max(res, sum); 21 | } 22 | } 23 | 24 | return res; 25 | } 26 | -------------------------------------------------------------------------------- /src/problems/17.Letter-Combinations-of-a-Phone-Number.ts: -------------------------------------------------------------------------------- 1 | const hash: { [key: string]: string[] } = { 2 | 2: ['a', 'b', 'c'], 3 | 3: ['d', 'e', 'f'], 4 | 4: ['g', 'h', 'i'], 5 | 5: ['j', 'k', 'l'], 6 | 6: ['m', 'n', 'o'], 7 | 7: ['p', 'q', 'r', 's'], 8 | 8: ['t', 'u', 'v'], 9 | 9: ['w', 'x', 'y', 'z'], 10 | }; 11 | 12 | function letterCombinations(digits: string): string[] { 13 | if (!digits) return []; 14 | 15 | const visited = new Set(); 16 | const res: string[] = []; 17 | 18 | const helper = (s: string, left: string) => { 19 | if (visited.has(s)) return; 20 | visited.add(s); 21 | 22 | if (!left) { 23 | res.push(s); 24 | return; 25 | } 26 | 27 | const newLeft = left.slice(1); 28 | 29 | hash[left[0]].forEach((c) => { 30 | helper(s + c, newLeft); 31 | }); 32 | }; 33 | 34 | helper('', digits); 35 | return res; 36 | } 37 | -------------------------------------------------------------------------------- /src/problems/1704.Determine-if-String-Halves-Are-Alike.ts: -------------------------------------------------------------------------------- 1 | const vowels = new Set(['a', 'e', 'i', 'o', 'u']); 2 | 3 | const countVowels = (s: string) => { 4 | return s.split('').reduce((prev, c) => { 5 | return prev + Number(vowels.has(c)); 6 | }, 0); 7 | }; 8 | 9 | function halvesAreAlike(s: string): boolean { 10 | const lower = s.toLocaleLowerCase(); 11 | const first = lower.substr(0, s.length / 2); 12 | const second = lower.substr(s.length / 2); 13 | return countVowels(first) === countVowels(second); 14 | } 15 | -------------------------------------------------------------------------------- /src/problems/1706.Where-Will-the-Ball-Fall.ts: -------------------------------------------------------------------------------- 1 | function findBall(grid: number[][]): number[] { 2 | const m = grid.length; 3 | const n = grid[0].length; 4 | const res: number[] = []; 5 | for (let start = 0; start < n; start++) { 6 | let j = start; 7 | for (let i = 0; i < m; i++) { 8 | const dir = grid[i][j]; 9 | if (dir === grid[i][j + dir]) j += dir; 10 | else { 11 | i = m; 12 | j = -1; 13 | } 14 | } 15 | res[start] = j; 16 | } 17 | return res; 18 | } 19 | -------------------------------------------------------------------------------- /src/problems/171-Excel-Sheet-Column-Number.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 76 ms, faster than 98.09% of JavaScript online submissions for Excel Sheet Column Number. 2 | // Memory Usage: 38.3 MB, less than 28.67% of JavaScript online submissions for Excel Sheet Column Number. 3 | 4 | function titleToNumber(s: string): number { 5 | let res = 0; 6 | for (let i = 0; i < s.length; i++) { 7 | res += (s.charCodeAt(i) - 64) * 26 ** (s.length - i - 1); 8 | } 9 | return res; 10 | } 11 | -------------------------------------------------------------------------------- /src/problems/1710.Maximum-Units-on-a-Truck.ts: -------------------------------------------------------------------------------- 1 | function maximumUnits(boxTypes: number[][], truckSize: number): number { 2 | boxTypes.sort(([, a], [, b]) => b - a); 3 | let res = 0; 4 | let i = 0; 5 | 6 | while (truckSize && i < boxTypes.length) { 7 | const count = Math.min(boxTypes[i][0], truckSize); 8 | res += count * boxTypes[i][1]; 9 | truckSize -= count; 10 | i++; 11 | } 12 | 13 | return res; 14 | } 15 | -------------------------------------------------------------------------------- /src/problems/1748.Sum-of-Unique-Elements.ts: -------------------------------------------------------------------------------- 1 | function sumOfUnique(nums: number[]): number { 2 | const hash: { [key: string]: number } = {}; 3 | 4 | nums.forEach((num) => { 5 | num in hash ? num++ : (hash[num] = 1); 6 | }); 7 | 8 | const res = Object.entries(hash) 9 | .filter(([key, value]) => value === 1) 10 | .reduce((acc, [curr]) => acc + Number(curr), 0); 11 | 12 | return res; 13 | } 14 | -------------------------------------------------------------------------------- /src/problems/179-Largest-Number.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | // Runtime: 84 ms, faster than 87.50% of TypeScript online submissions for Largest Number. 3 | // Memory Usage: 40.5 MB, less than 12.50% of TypeScript online submissions for Largest Number. 4 | function largestNumber(nums: number[]): string { 5 | const res = nums 6 | .map((n) => n.toString()) 7 | .sort((a, b) => { 8 | return a.concat(b) > b.concat(a) ? -1 : 1; 9 | }) 10 | .join(''); 11 | 12 | return res.charAt(0) === '0' ? '0' : res; 13 | } 14 | 15 | // JS 16 | // Runtime: 88 ms, faster than 51.58% of JavaScript online submissions for Largest Number. 17 | // Memory Usage: 40.9 MB, less than 12.63% of JavaScript online submissions for Largest Number. 18 | // var largestNumber = function (nums) { 19 | // const res = nums 20 | // .map((n) => n.toString()) 21 | // .sort((a, b) => { 22 | // return a.concat(b) > b.concat(a) ? -1 : 1; 23 | // }) 24 | // .join(''); 25 | 26 | // return res.charAt(0) === '0' ? '0' : res; 27 | // }; 28 | -------------------------------------------------------------------------------- /src/problems/189.Rotate-Array.ts: -------------------------------------------------------------------------------- 1 | function rotate(nums: number[], k: number): void { 2 | let i = k % nums.length; 3 | while (i) { 4 | nums.unshift(nums.pop()!); 5 | i--; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/problems/1971.Find-if-Path-Exists-in-Graph.ts: -------------------------------------------------------------------------------- 1 | function validPath( 2 | _: number, 3 | edges: number[][], 4 | source: number, 5 | destination: number 6 | ): boolean { 7 | if (source === destination) return true; 8 | 9 | const uf: { [vertice: number]: Set } = {}; 10 | for (const [u, v] of edges) { 11 | if (uf[u] == undefined) uf[u] = new Set(); 12 | if (uf[v] == undefined) uf[v] = new Set(); 13 | 14 | uf[u].add(v); 15 | uf[v].add(u); 16 | } 17 | 18 | const visited = new Set(); 19 | 20 | const dfs = (x: number, target: number): boolean => { 21 | if (visited.has(x) || !(x in uf)) return false; 22 | visited.add(x); 23 | const neighbours = uf[x]; 24 | if (neighbours.has(target)) return true; 25 | return Array.from(neighbours).some((neighbour) => dfs(neighbour, target)); 26 | }; 27 | 28 | return dfs(source, destination); 29 | } 30 | -------------------------------------------------------------------------------- /src/problems/20.Valid-Parentheses.ts: -------------------------------------------------------------------------------- 1 | // JS 2 | // Runtime: 72 ms, faster than 95.77% of JavaScript online submissions for Valid Parentheses. 3 | // Memory Usage: 38.8 MB, less than 59.66% of JavaScript online submissions for Valid Parentheses. 4 | var isValid = function (s) { 5 | const hash = { 6 | '(': ')', 7 | '{': '}', 8 | '[': ']', 9 | }; 10 | 11 | const stack = []; 12 | 13 | for (const char of s) { 14 | if (char in hash) stack.push(char); 15 | else { 16 | const top = stack.pop(); 17 | if (top === undefined || hash[top] !== char) { 18 | return false; 19 | } 20 | } 21 | } 22 | 23 | return !stack.length; 24 | }; 25 | 26 | // TS 27 | // Runtime: 76 ms, faster than 96.60% of TypeScript online submissions for Valid Parentheses. 28 | // Memory Usage: 40.4 MB, less than 48.64% of TypeScript online submissions for Valid Parentheses. 29 | function isValid(s: string): boolean { 30 | const hash: { [key: string]: string } = { 31 | '(': ')', 32 | '{': '}', 33 | '[': ']', 34 | }; 35 | 36 | const stack: string[] = []; 37 | 38 | for (const char of s) { 39 | if (char in hash) stack.push(char); 40 | else { 41 | const top = stack.pop(); 42 | if (top === undefined || hash[top] !== char) { 43 | return false; 44 | } 45 | } 46 | } 47 | 48 | return !stack.length; 49 | } 50 | -------------------------------------------------------------------------------- /src/problems/21.Merge-Two-Sorted-Lists.ts: -------------------------------------------------------------------------------- 1 | function mergeTwoLists( 2 | l1: ListNode | null, 3 | l2: ListNode | null 4 | ): ListNode | null { 5 | const dummy = new ListNode(0); 6 | let curr = dummy; 7 | 8 | while (l1 && l2) { 9 | if (l1.val < l2.val) { 10 | curr.next = l1; 11 | l1 = l1.next; 12 | } else { 13 | curr.next = l2; 14 | l2 = l2.next; 15 | } 16 | curr = curr.next; 17 | } 18 | 19 | while (l1) { 20 | curr.next = l1; 21 | l1 = l1.next; 22 | curr = curr.next; 23 | } 24 | 25 | while (l2) { 26 | curr.next = l2; 27 | l2 = l2.next; 28 | curr = curr.next; 29 | } 30 | 31 | return dummy.next; 32 | } 33 | -------------------------------------------------------------------------------- /src/problems/210.Course-Schedule-II.ts: -------------------------------------------------------------------------------- 1 | function findOrder(numCourses: number, prerequisites: number[][]): number[] { 2 | const ranks: number[] = Array(numCourses).fill(0); 3 | const graph: { [key: string]: number[] } = {}; 4 | const order: number[] = []; 5 | for (let i = 0; i < numCourses; i++) graph[i] = []; 6 | 7 | prerequisites.forEach(([course, prerequisite]) => { 8 | graph[prerequisite].push(course); 9 | ranks[course]++; 10 | }); 11 | 12 | const visited = new Set(); 13 | const queue: number[] = []; 14 | 15 | ranks.forEach((rank, i) => { 16 | if (rank === 0) queue.push(i); 17 | }); 18 | 19 | while (queue.length) { 20 | const curr = queue.shift()!; 21 | visited.add(curr); 22 | order.push(curr); 23 | 24 | graph[curr].forEach((nextCourse) => { 25 | ranks[nextCourse]--; 26 | if (ranks[nextCourse] === 0) queue.push(nextCourse); 27 | }); 28 | } 29 | 30 | return visited.size === numCourses ? order : []; 31 | } 32 | -------------------------------------------------------------------------------- /src/problems/211-Add-and-Search-Word-Data-structure-design.ts: -------------------------------------------------------------------------------- 1 | class WordDictionary { 2 | child: { [key: string]: WordDictionary }; 3 | isWord: boolean; 4 | constructor() { 5 | this.child = {}; 6 | this.isWord = false; 7 | } 8 | 9 | addWord(word: string): void { 10 | let curr: WordDictionary = this; 11 | 12 | for (const char of word) { 13 | if (!curr.child[char]) { 14 | curr.child[char] = new WordDictionary(); 15 | } 16 | curr = curr.child[char]; 17 | } 18 | 19 | curr.isWord = true; 20 | } 21 | 22 | search(word: string): boolean { 23 | let curr: WordDictionary = this; 24 | 25 | for (let i = 0; i < word.length; i++) { 26 | const char = word[i]; 27 | if (char === ".") { 28 | const rest = word.slice(i + 1); 29 | 30 | for (const key in curr.child) { 31 | if (curr.child[key].search(rest)) { 32 | return true; 33 | } 34 | } 35 | return false; 36 | } 37 | 38 | if (!curr.child[char]) { 39 | return false; 40 | } 41 | 42 | curr = curr.child[char]; 43 | } 44 | 45 | return curr.isWord; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/problems/22.Generate-Parentheses.ts: -------------------------------------------------------------------------------- 1 | function generateParenthesis(n: number): string[] { 2 | const res: string[] = []; 3 | 4 | const helper = (s: string, open: number, close: number) => { 5 | if (!close) { 6 | res.push(s); 7 | return; 8 | } 9 | 10 | if (open) { 11 | helper(s + '(', open - 1, close); 12 | } 13 | 14 | if (close > open) { 15 | helper(s + ')', open, close - 1); 16 | } 17 | }; 18 | 19 | helper('', n, n); 20 | return res; 21 | } 22 | 23 | // var generateParenthesis = function (n) { 24 | // const res = []; 25 | 26 | // const helper = (s, open, close) => { 27 | // if (!close) { 28 | // res.push(s); 29 | // return; 30 | // } 31 | 32 | // if (open) { 33 | // helper(s + '(', open - 1, close); 34 | // } 35 | 36 | // if (close > open) { 37 | // helper(s + ')', open, close - 1); 38 | // } 39 | // }; 40 | 41 | // helper('', n, n); 42 | // return res; 43 | // }; 44 | -------------------------------------------------------------------------------- /src/problems/227.Basic-Calculator-II.ts: -------------------------------------------------------------------------------- 1 | const isNumber = (char: string) => char !== '' && !isNaN(Number(char)); 2 | 3 | function calculate(s: string): number { 4 | s = s.replace(/\s/g, ''); 5 | const stack: number[] = []; 6 | let num = 0; 7 | let op = '+'; 8 | 9 | const evaluate = () => { 10 | switch (op) { 11 | case '+': 12 | stack.push(num); 13 | break; 14 | case '-': 15 | stack.push(-num); 16 | break; 17 | case '*': 18 | stack.push(stack.pop()! * num); 19 | break; 20 | case '/': 21 | stack.push(Math.trunc(stack.pop()! / num)); 22 | break; 23 | } 24 | 25 | num = 0; 26 | }; 27 | 28 | for (let i = 0; i <= s.length; i++) { 29 | if (isNumber(s.charAt(i))) { 30 | num = num * 10 + +s[i]; 31 | } else { 32 | evaluate(); 33 | op = s[i]; 34 | num = 0; 35 | } 36 | } 37 | 38 | return stack.reduce((a, b) => a + b); 39 | } 40 | -------------------------------------------------------------------------------- /src/problems/229-Majority-Element-II.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 76 ms, faster than 94.58% of JavaScript online submissions for Majority Element II. 2 | // Memory Usage: 38.7 MB, less than 71.25% of JavaScript online submissions for Majority Element II. 3 | var majorityElement = function (nums) { 4 | const m = nums.length / 3; 5 | const hash = {}; 6 | 7 | nums.forEach((num) => { 8 | if (!(num in hash)) hash[num] = 1; 9 | else hash[num]++; 10 | }); 11 | 12 | return Object.entries(hash) 13 | .filter(([, val]) => val > m) 14 | .map(([key]) => parseInt(key)); 15 | }; 16 | 17 | // Runtime: 92 ms, faster than 20.00% of TypeScript online submissions for Majority Element II. 18 | // Memory Usage: 40 MB, less than 100.00% of TypeScript online submissions for Majority Element II. 19 | function majorityElement(nums: number[]): number[] { 20 | const m = nums.length / 3; 21 | const hash: { [key: string]: number } = {}; 22 | 23 | nums.forEach((num) => { 24 | if (!(num in hash)) hash[num] = 1; 25 | else hash[num]++; 26 | }); 27 | 28 | return Object.entries(hash) 29 | .filter(([, val]) => val > m) 30 | .map(([key]) => parseInt(key)); 31 | } 32 | -------------------------------------------------------------------------------- /src/problems/23.Merge-k-Sorted-Lists.ts: -------------------------------------------------------------------------------- 1 | function mergeKLists(lists: Array): ListNode | null { 2 | const dummy = new ListNode(0); 3 | let curr = dummy; 4 | 5 | const items: ListNode[] = []; 6 | 7 | lists.forEach((list) => { 8 | if (list) { 9 | items.push(list); 10 | } 11 | }); 12 | 13 | while (items.length) { 14 | let min = { val: items[0].val, i: 0 }; 15 | 16 | items.forEach((item, i) => { 17 | if (item.val < min.val) { 18 | min = { val: item?.val, i }; 19 | } 20 | }); 21 | 22 | const next = items[min.i]; 23 | curr.next = next; 24 | curr = curr.next; 25 | 26 | if (items[min.i].next !== null) { 27 | items[min.i] = items[min.i].next!; 28 | } else { 29 | items.splice(min.i, 1); 30 | } 31 | } 32 | 33 | return dummy.next; 34 | } 35 | -------------------------------------------------------------------------------- /src/problems/230.Kth-Smallest-Element-in-a-BST.ts: -------------------------------------------------------------------------------- 1 | // JS 2 | // Runtime: 96 ms, faster than 51.83% of JavaScript online submissions for Kth Smallest Element in a BST. 3 | // Memory Usage: 44.2 MB, less than 78.62% of JavaScript online submissions for Kth Smallest Element in a BST. 4 | var kthSmallest = function (root, k) { 5 | let res; 6 | 7 | const inOrderTraverse = (node) => { 8 | if (!node || res !== undefined) return; 9 | inOrderTraverse(node.left); 10 | k--; 11 | if (k === 0) res = node.val; 12 | inOrderTraverse(node.right); 13 | }; 14 | 15 | inOrderTraverse(root); 16 | 17 | return res; 18 | }; 19 | 20 | // TS 21 | function kthSmallest(root: TreeNode | null, k: number): number { 22 | let res: number | undefined; 23 | 24 | const inOrderTraverse = (node: TreeNode | null) => { 25 | if (!node || res !== undefined) return; 26 | inOrderTraverse(node.left); 27 | k--; 28 | if (k === 0) res = node.val; 29 | inOrderTraverse(node.right); 30 | }; 31 | 32 | inOrderTraverse(root); 33 | 34 | return res!; 35 | } 36 | -------------------------------------------------------------------------------- /src/problems/235.Lowest-Common-Ancestor-of-a-Binary-Search-Tree.ts: -------------------------------------------------------------------------------- 1 | function lowestCommonAncestor( 2 | root: TreeNode | null, 3 | p: TreeNode | null, 4 | q: TreeNode | null 5 | ): TreeNode | null { 6 | if (p.val < root.val && q.val < root.val) { 7 | return lowestCommonAncestor(root.left, p, q); 8 | } 9 | 10 | if (p.val > root.val && q.val > root.val) { 11 | return lowestCommonAncestor(root.right, p, q); 12 | } 13 | 14 | return root; 15 | } 16 | -------------------------------------------------------------------------------- /src/problems/236.Lowest-Common-Ancestor-of-a-Binary-Tree.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | function lowestCommonAncestor( 3 | root: TreeNode | null, 4 | p: TreeNode | null, 5 | q: TreeNode | null 6 | ): TreeNode | null { 7 | if (!root || root === p || root === q) return root; 8 | const left = lowestCommonAncestor(root.left, p, q); 9 | const right = lowestCommonAncestor(root.right, p, q); 10 | return left && right ? root : left || right; 11 | } 12 | 13 | // JS 14 | // var lowestCommonAncestor = function (root, p, q) { 15 | // if (!root || root === p || root === q) return root; // edge case or found p or q: return root 16 | // const left = lowestCommonAncestor(root.left, p, q); // look if left child has p or q 17 | // const right = lowestCommonAncestor(root.right, p, q); // look if right child has p or q 18 | // return left && right ? root : left || right; // if both children returned a node, then current is an ancestor of p and q 19 | // }; 20 | -------------------------------------------------------------------------------- /src/problems/240.Search-a-2D-Matrix-II.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | function searchMatrix(matrix: number[][], target: number): boolean { 3 | let r = matrix.length - 1; 4 | let c = 0; 5 | 6 | while (r >= 0 && c < matrix[0].length) { 7 | if (matrix[r][c] === target) return true; 8 | else if (matrix[r][c] > target) r--; 9 | else c++; 10 | } 11 | 12 | return false; 13 | } 14 | 15 | // JS 16 | // var searchMatrix = function (matrix, target) { 17 | // let r = matrix.length - 1; 18 | // let c = 0; 19 | 20 | // while (r >= 0 && c < matrix[0].length) { 21 | // if (matrix[r][c] === target) return true; 22 | // else if (matrix[r][c] > target) r--; 23 | // else c++; 24 | // } 25 | 26 | // return false; 27 | // }; 28 | -------------------------------------------------------------------------------- /src/problems/257.Binary-Tree-Paths.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 84 ms, faster than 90.00% of TypeScript online submissions for Binary Tree Paths. 2 | // Memory Usage: 40.3 MB, less than 50.00% of TypeScript online submissions for Binary Tree Paths. 3 | function binaryTreePaths(root: TreeNode | null): string[] { 4 | const res: string[] = []; 5 | 6 | const helper = (node: TreeNode | null | undefined, path: string) => { 7 | if (!node) return; 8 | 9 | const newPath = path + `${node.val}->`; 10 | 11 | if (!node.left && !node.right) { 12 | res.push(path + node.val); 13 | return; 14 | } 15 | 16 | helper(node.left, newPath); 17 | helper(node.right, newPath); 18 | }; 19 | 20 | helper(root, ''); 21 | 22 | return res; 23 | } 24 | -------------------------------------------------------------------------------- /src/problems/268.Missing-Number.ts: -------------------------------------------------------------------------------- 1 | // JS 2 | // Runtime: 76 ms, faster than 97.36% of JavaScript online submissions for Missing Number. 3 | // Memory Usage: 41.6 MB, less than 21.88% of JavaScript online submissions for Missing Number. 4 | var missingNumber = function (nums) { 5 | let sum = nums.length; 6 | for (let i = 0; i < nums.length; i++) { 7 | sum += i - nums[i]; 8 | } 9 | 10 | return sum; 11 | }; 12 | 13 | // TS 14 | // Runtime: 84 ms, faster than 94.29% of TypeScript online submissions for Missing Number. 15 | // Memory Usage: 41.4 MB, less than 39.29% of TypeScript online submissions for Missing Number. 16 | function missingNumber(nums: number[]): number { 17 | let sum = nums.length; 18 | for (let i = 0; i < nums.length; i++) { 19 | sum += i - nums[i]; 20 | } 21 | 22 | return sum; 23 | } 24 | -------------------------------------------------------------------------------- /src/problems/274-H-Index.ts: -------------------------------------------------------------------------------- 1 | // Iterative 2 | // Runtime: 72 ms, faster than 64.25% of JavaScript online submissions for H-Index. 3 | // Memory Usage: 36.9 MB, less than 17.87% of JavaScript online submissions for H-Index. 4 | function hIndex(citations: number[]): number { 5 | citations.sort((a, b) => b - a); 6 | 7 | let h = 0; 8 | 9 | for (let i = 0; i < citations.length; i++) { 10 | if (citations[i] < i + 1) { 11 | return h; 12 | } 13 | 14 | h = i + 1; 15 | } 16 | 17 | return h; 18 | } 19 | 20 | // Binary Search 21 | // Runtime: 72 ms, faster than 64.25% of JavaScript online submissions for H-Index. 22 | // Memory Usage: 36.9 MB, less than 17.87% of JavaScript online submissions for H-Index. 23 | function hIndex(citations: number[]): number { 24 | citations.sort((a, b) => b - a); 25 | 26 | let l = 0; 27 | let r = citations.length - 1; 28 | 29 | while (l < r) { 30 | const mid = Math.floor((l + r) / 2); 31 | if (citations[mid] === mid + 1) return mid + 1; 32 | if (citations[mid] > mid) l = mid + 1; 33 | else r = mid; 34 | } 35 | 36 | return l; 37 | } 38 | -------------------------------------------------------------------------------- /src/problems/303-Range-Sum-Query-Immutable.ts: -------------------------------------------------------------------------------- 1 | class NumArray { 2 | nums: number[]; 3 | 4 | constructor(nums: number[]) { 5 | this.nums = nums; 6 | } 7 | 8 | sumRange(i: number, j: number): number { 9 | let sum = 0; 10 | for (let k = i; k <= j; k++) { 11 | sum += this.nums[k]; 12 | } 13 | return sum; 14 | } 15 | } 16 | class NumArray { 17 | sums: number[]; 18 | 19 | constructor(nums: number[]) { 20 | this.sums = nums; 21 | for (let i = 1; i < nums.length; i++) { 22 | this.sums[i] += this.sums[i - 1]; 23 | } 24 | this.sums.unshift(0); 25 | } 26 | 27 | sumRange(i: number, j: number): number { 28 | return this.sums[j + 1] - this.sums[i]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/problems/318.Maximum-Product-of-Word-Lengths.ts: -------------------------------------------------------------------------------- 1 | function maxProduct(words: string[]): number { 2 | let res = 0; 3 | words.sort((a, b) => a.length - b.length); 4 | 5 | const hash: { 6 | [key: string]: { 7 | chars: Set; 8 | }; 9 | } = {}; 10 | 11 | words.forEach((word) => { 12 | hash[word] = { 13 | chars: new Set(word), 14 | }; 15 | }); 16 | 17 | for (let i = 0; i < words.length; i++) { 18 | const w1 = words[i]; 19 | for (let j = i + 1; j < words.length; j++) { 20 | const w2 = words[j]; 21 | 22 | const intersection = [...hash[w1].chars].filter((c) => 23 | hash[w2].chars.has(c) 24 | ); 25 | if (!intersection.length) { 26 | res = Math.max(res, w1.length * w2.length); 27 | } 28 | } 29 | } 30 | 31 | return res; 32 | } 33 | -------------------------------------------------------------------------------- /src/problems/322.Coin-Change.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | // Runtime: 112 ms, faster than 100.00% of TypeScript online submissions for Coin Change. 3 | // Memory Usage: 43.7 MB, less than 76.71% of TypeScript online submissions for Coin Change. 4 | function coinChange(coins: number[], amount: number): number { 5 | const dp: number[] = Array(amount + 1).fill(amount + 1); 6 | dp[0] = 0; 7 | 8 | for (const coin of coins) { 9 | for (let i = coin; i <= amount; i++) { 10 | dp[i] = Math.min(dp[i], dp[i - coin] + 1); 11 | } 12 | } 13 | 14 | return dp[amount] > amount ? -1 : dp[amount]; 15 | } 16 | 17 | // JS 18 | // Runtime: 100 ms, faster than 98.33% of JavaScript online submissions for Coin Change. 19 | // Memory Usage: 42.9 MB, less than 82.68% of JavaScript online submissions for Coin Change. 20 | // var coinChange = function (coins, amount) { 21 | // const dp = Array(amount + 1).fill(amount + 1); 22 | // dp[0] = 0; 23 | 24 | // for (const coin of coins) { 25 | // for (let i = coin; i <= amount; i++) { 26 | // dp[i] = Math.min(dp[i], dp[i - coin] + 1); 27 | // } 28 | // } 29 | 30 | // return dp[amount] > amount ? -1 : dp[amount]; 31 | // }; 32 | -------------------------------------------------------------------------------- /src/problems/326.Power-of-Three.ts: -------------------------------------------------------------------------------- 1 | function isPowerOfThree(n: number): boolean { 2 | let num = 1; 3 | while (num < n) num *= 3; 4 | return num === n; 5 | } 6 | -------------------------------------------------------------------------------- /src/problems/329.Longest-Increasing-Path-in-a-Matrix.ts: -------------------------------------------------------------------------------- 1 | const directions = [ 2 | [-1, 0], 3 | [0, 1], 4 | [1, 0], 5 | [0, -1], 6 | ]; 7 | 8 | function longestIncreasingPath(matrix: number[][]): number { 9 | if (!matrix.length || !matrix[0].length) return 0; 10 | 11 | const dp = Array(matrix.length) 12 | .fill(null) 13 | .map(() => Array(matrix[0].length).fill(1)); 14 | 15 | const dfs = (i: number, j: number, max: number, path: number) => { 16 | if ( 17 | i < 0 || 18 | i >= matrix.length || 19 | j < 0 || 20 | j >= matrix[0].length || 21 | matrix[i][j] <= max || 22 | path < dp[i][j] 23 | ) { 24 | return; 25 | } 26 | 27 | dp[i][j] = path; 28 | directions.forEach(([x, y]) => dfs(i + x, j + y, matrix[i][j], path + 1)); 29 | }; 30 | 31 | for (let i = 0; i < matrix.length; i++) { 32 | for (let j = 0; j < matrix[0].length; j++) { 33 | dfs(i, j, Number.MIN_SAFE_INTEGER, 1); 34 | } 35 | } 36 | 37 | let res = 1; 38 | 39 | for (let i = 0; i < matrix.length; i++) { 40 | for (let j = 0; j < matrix[0].length; j++) { 41 | res = Math.max(res, dp[i][j]); 42 | } 43 | } 44 | 45 | return res; 46 | } 47 | -------------------------------------------------------------------------------- /src/problems/334.Increasing-Triplet-Subsequence.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | // Runtime: 88 ms, faster than 63.64% of TypeScript online submissions for Increasing Triplet Subsequence. 3 | // Memory Usage: 40.3 MB, less than 63.64% of TypeScript online submissions for Increasing Triplet Subsequence. 4 | function increasingTriplet(nums: number[]): boolean { 5 | let one = Infinity; 6 | let two = Infinity; 7 | 8 | for (let i = 0; i < nums.length; i++) { 9 | if (nums[i] <= one) { 10 | one = nums[i]; 11 | } else if (nums[i] <= two) { 12 | two = nums[i]; 13 | } else { 14 | return true; 15 | } 16 | } 17 | 18 | return false; 19 | } 20 | 21 | // JS 22 | // Runtime: 64 ms, faster than 99.66% of JavaScript online submissions for Increasing Triplet Subsequence. 23 | // Memory Usage: 39 MB, less than 56.66% of JavaScript online submissions for Increasing Triplet Subsequence. 24 | // var increasingTriplet = function (nums) { 25 | // let one = Infinity; 26 | // let two = Infinity; 27 | 28 | // for (let i = 0; i < nums.length; i++) { 29 | // if (nums[i] <= one) { 30 | // one = nums[i]; 31 | // } else if (nums[i] <= two) { 32 | // two = nums[i]; 33 | // } else { 34 | // return true; 35 | // } 36 | // } 37 | 38 | // return false; 39 | // }; 40 | -------------------------------------------------------------------------------- /src/problems/337.House-Robber-III.ts: -------------------------------------------------------------------------------- 1 | const dfs = (node: TreeNode | null): [number, number] => { 2 | if (!node) return [0, 0]; 3 | 4 | const left = dfs(node.left); 5 | const right = dfs(node.right); 6 | 7 | const withNode = node.val + left[1] + right[1]; 8 | const withoutNode = Math.max(...left) + Math.max(...right); 9 | 10 | return [withNode, withoutNode]; 11 | }; 12 | 13 | function rob(root: TreeNode | null): number { 14 | return Math.max(...dfs(root)); 15 | } 16 | -------------------------------------------------------------------------------- /src/problems/338.Counting-Bits.ts: -------------------------------------------------------------------------------- 1 | function countBits(num: number): number[] { 2 | const bits = Array(num + 1) 3 | .fill(null) 4 | .map((_, i) => i.toString(2).replace(/0/g, '').length); 5 | 6 | return bits; 7 | } 8 | -------------------------------------------------------------------------------- /src/problems/341.Flatten-Nested-List-Iterator.ts: -------------------------------------------------------------------------------- 1 | class NestedIterator { 2 | list: number[]; 3 | index: number; 4 | constructor(nestedList: NestedInteger[]) { 5 | this.list = []; 6 | this.index = 0; 7 | this.flatten(nestedList); 8 | } 9 | 10 | flatten(nestedList: NestedInteger[]): void { 11 | while (nestedList.length) { 12 | const curr = nestedList.shift(); 13 | if (curr.isInteger()) { 14 | this.list.push(curr.getInteger()); 15 | } else this.flatten(curr.getList()); 16 | } 17 | } 18 | 19 | hasNext(): boolean { 20 | return this.index < this.list.length; 21 | } 22 | 23 | next(): number { 24 | return this.list[this.index++]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/problems/342-Power-of-Four.ts: -------------------------------------------------------------------------------- 1 | // Iteration 2 | // Runtime: 92 ms, faster than 58.82% of JavaScript online submissions for Power of Four. 3 | // Memory Usage: 38.2 MB, less than 14.29% of JavaScript online submissions for Power of Four. 4 | 5 | function isPowerOfFour(num: number, x = 1): boolean { 6 | while (x < num) x *= 4; 7 | return x === num; 8 | } 9 | 10 | // Regex 11 | // Runtime: 100 ms, faster than 39.10% of JavaScript online submissions for Power of Four. 12 | // Memory Usage: 37.8 MB, less than 14.29% of JavaScript online submissions for Power of Four. 13 | 14 | function isPowerOfFour(num: number): boolean { 15 | return /^1(00)*$/.test(num.toString(2)); 16 | } 17 | -------------------------------------------------------------------------------- /src/problems/349-Intersection-of-Two-Arrays.ts: -------------------------------------------------------------------------------- 1 | // 1 Set and 1 Filter 2 | // Runtime: 56 ms, faster than 99.63% of JavaScript online submissions for Intersection of Two Arrays. 3 | // Memory Usage: 34.1 MB, less than 86.81% of JavaScript online submissions for Intersection of Two Arrays. 4 | 5 | function intersection(nums1: number[], nums2: number[]): number[] { 6 | return [...new Set(nums1.filter((num) => nums2.includes(num)))]; 7 | } 8 | 9 | // 2 Sets 1 filter 10 | // Runtime: 72 ms, faster than 75.69% of JavaScript online submissions for Intersection of Two Arrays. 11 | // Memory Usage: 37.8 MB, less than 9.89% of JavaScript online submissions for Intersection of Two Arrays. 12 | 13 | function intersection(nums1: number[], nums2: number[]): number[] { 14 | const set1 = new Set(nums1); 15 | const set2 = new Set(nums2); 16 | return [...set1].filter((num) => set2.has(num)); 17 | } 18 | 19 | // 2 Sets and 2 forEach 20 | // Runtime: 112 ms, faster than 10.61% of JavaScript online submissions for Intersection of Two Arrays. 21 | // Memory Usage: 37 MB, less than 21.98% of JavaScript online submissions for Intersection of Two Arrays. 22 | 23 | function intersection(nums1: number[], nums2: number[]): number[] { 24 | const set = new Set(); 25 | const res = new Set(); 26 | nums1.forEach((num) => set.add(num)); 27 | nums2.forEach((num) => { 28 | if (set.has(num)) res.add(num); 29 | }); 30 | return [...res]; 31 | } 32 | -------------------------------------------------------------------------------- /src/problems/354.Russian-Doll-Envelopes.ts: -------------------------------------------------------------------------------- 1 | function maxEnvelopes(envelopes: number[][]): number { 2 | if (!envelopes.length) return 0; 3 | envelopes.sort(([a, b], [c, d]) => a - c || d - b); 4 | const dp = Array(envelopes.length).fill(1); 5 | 6 | for (let i = 1; i < envelopes.length; i++) { 7 | for (let j = 0; j < i; j++) { 8 | if ( 9 | envelopes[j][0] < envelopes[i][0] && 10 | envelopes[j][1] < envelopes[i][1] 11 | ) { 12 | dp[i] = Math.max(dp[i], dp[j] + 1); 13 | } 14 | } 15 | } 16 | 17 | return Math.max(...dp); 18 | } 19 | -------------------------------------------------------------------------------- /src/problems/376.Wiggle-Subsequence.ts: -------------------------------------------------------------------------------- 1 | function wiggleMaxLength(nums: number[]): number { 2 | let dp: number[] = Array(nums.length - 1).fill(null); 3 | 4 | for (let i = 0; i < dp.length; i++) { 5 | const curr = nums[i + 1] - nums[i]; 6 | if (curr > 0) dp[i] = 1; 7 | else if (curr < 0) dp[i] = 0; 8 | else dp[i] = -1; 9 | } 10 | 11 | dp = dp.filter((num) => num !== -1); 12 | 13 | let i = 1; 14 | while (i < dp.length) { 15 | if (dp[i] === dp[i - 1]) dp.splice(i, 1); 16 | else i++; 17 | } 18 | 19 | return dp.length + 1; 20 | } 21 | -------------------------------------------------------------------------------- /src/problems/377-Combination-Sum-IV.ts: -------------------------------------------------------------------------------- 1 | const combinationSum4 = (nums: number[], target: number) => { 2 | const dp: number[] = new Array(target + 1).fill(0); 3 | dp[0] = 1; 4 | 5 | for (let i = 1; i <= target; i++) { 6 | nums.forEach((num) => { 7 | if (num <= i) { 8 | dp[i] += dp[i - num]; 9 | } 10 | }); 11 | } 12 | 13 | return dp[target]; 14 | }; 15 | 16 | // JS 17 | // Runtime: 92 ms, faster than 26.11% of JavaScript online submissions for Combination Sum IV. 18 | // Memory Usage: 38.2 MB, less than 48.33% of JavaScript online submissions for Combination Sum IV. 19 | // var combinationSum4 = function (nums, target) { 20 | // const dp = new Array(target + 1).fill(0); 21 | // dp[0] = 1; 22 | 23 | // for (let i = 1; i <= target; i++) { 24 | // nums.forEach((num) => { 25 | // if (num <= i) { 26 | // dp[i] += dp[i - num]; 27 | // } 28 | // }); 29 | // } 30 | // return dp[target]; 31 | // }; 32 | -------------------------------------------------------------------------------- /src/problems/382-Linked-List-Random-Node.ts: -------------------------------------------------------------------------------- 1 | // Without Follow-up 2 | class Solution { 3 | head: ListNode | null; 4 | length: number; 5 | constructor(head: ListNode | null) { 6 | this.head = head; 7 | this.length = this.getLength(); 8 | } 9 | 10 | getLength(): number { 11 | let len = 0; 12 | let curr = this.head; 13 | while (curr) { 14 | len++; 15 | curr = curr.next; 16 | } 17 | return len; 18 | } 19 | 20 | // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random 21 | getRandomInt(max: number) { 22 | return Math.floor(Math.random() * Math.floor(max)); 23 | } 24 | 25 | getRandom(): number { 26 | let curr = this.head; 27 | let jumps = this.getRandomInt(this.length); 28 | while (jumps) { 29 | jumps--; 30 | curr = curr!.next; 31 | } 32 | return curr!.val; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/problems/389.Find-the-Difference.ts: -------------------------------------------------------------------------------- 1 | function findTheDifference(s: string, t: string): string { 2 | const sArray = new Array(26).fill(0); 3 | const tArray = new Array(26).fill(0); 4 | 5 | for (let i = 0; i < s.length; i++) { 6 | sArray[s[i].charCodeAt(0) - 97]++; 7 | } 8 | 9 | for (let i = 0; i < t.length; i++) { 10 | tArray[t[i].charCodeAt(0) - 97]++; 11 | } 12 | 13 | for (let i = 0; i < 26; i++) { 14 | if (sArray[i] !== tArray[i]) { 15 | return String.fromCharCode(i + 97); 16 | } 17 | } 18 | 19 | return ""; 20 | } 21 | -------------------------------------------------------------------------------- /src/problems/392.Is-Subsequence.ts: -------------------------------------------------------------------------------- 1 | function isSubsequence(s: string, t: string): boolean { 2 | let j = 0; 3 | for (let i = 0; i < t.length && j < s.length; i++) { 4 | if (t[i] === s[j]) j++; 5 | } 6 | 7 | return j === s.length; 8 | } 9 | -------------------------------------------------------------------------------- /src/problems/40-Combination-Sum-II.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 112 ms, faster than 37.50% of TypeScript online submissions for Combination Sum II. 2 | // Memory Usage: 43.1 MB, less than 25.00% of TypeScript online submissions for Combination Sum II. 3 | 4 | function combinationSum2(candidates: number[], target: number): number[][] { 5 | const res: number[][] = []; 6 | 7 | candidates.sort((a, b) => a - b); 8 | 9 | const combinationSum2Helper = ( 10 | nums: number[] = [], 11 | lastIndex: number = 0, 12 | sum: number = 0 13 | ) => { 14 | if (sum > target) return; 15 | if (sum === target) res.push(nums); 16 | const visited = new Set(); 17 | 18 | for (let i = lastIndex; i < candidates.length; i++) { 19 | if (!visited.has(candidates[i])) { 20 | combinationSum2Helper( 21 | [...nums, candidates[i]], 22 | i + 1, 23 | sum + candidates[i] 24 | ); 25 | visited.add(candidates[i]); 26 | } 27 | } 28 | }; 29 | 30 | combinationSum2Helper(); 31 | 32 | return res; 33 | } 34 | -------------------------------------------------------------------------------- /src/problems/404-Sum-of-Left-Leaves.ts: -------------------------------------------------------------------------------- 1 | function sumOfLeftLeaves(root: TreeNode | null, isLeftNode = false): number { 2 | if (!root) return 0; 3 | if (isLeftNode && !root.left && !root.right) return root.val; 4 | 5 | return sumOfLeftLeaves(root.left, true) + sumOfLeftLeaves(root.right); 6 | } 7 | -------------------------------------------------------------------------------- /src/problems/409-Longest-Palindrome.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 76 ms, faster than 81.42% of JavaScript online submissions for Longest Palindrome. 2 | // Memory Usage: 37.9 MB, less than 45.27% of JavaScript online submissions for Longest Palindrome. 3 | 4 | function longestPalindrome(s: string): number { 5 | const hash: { [key: string]: number } = {}; 6 | 7 | s.split('').forEach((char) => (hash[char] ? hash[char]++ : (hash[char] = 1))); 8 | 9 | let odd = false; 10 | let res = Object.values(hash).reduce((acc, curr) => { 11 | if (curr % 2 === 0) { 12 | return (acc += curr); 13 | } 14 | odd = true; 15 | return (acc += curr - 1); 16 | }, 0); 17 | 18 | if (odd) { 19 | res++; 20 | } 21 | 22 | return res; 23 | } 24 | -------------------------------------------------------------------------------- /src/problems/41-First-Missing-Positive.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | // Runtime: 80 ms, faster than 82.43% of TypeScript online submissions for First Missing Positive. 3 | // Memory Usage: 40.5 MB, less than 8.11% of TypeScript online submissions for First Missing Positive. 4 | function firstMissingPositive(nums: number[]): number { 5 | const set = new Set(nums); 6 | let res = 1; 7 | while (set.has(res)) res++; 8 | return res; 9 | } 10 | 11 | // JS 12 | // Runtime: 80 ms, faster than 57.95% of JavaScript online submissions for First Missing Positive. 13 | // Memory Usage: 39 MB, less than 10.61% of JavaScript online submissions for First Missing Positive. 14 | // var firstMissingPositive = function (nums) { 15 | // const set = new Set(nums); 16 | // let res = 1; 17 | // while (set.has(res)) res++; 18 | // return res; 19 | // }; 20 | -------------------------------------------------------------------------------- /src/problems/412-Fizz-Buzz.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 88 ms, faster than 44.71% of JavaScript online submissions for Fizz Buzz. 2 | // Memory Usage: 38.9 MB, less than 51.65% of JavaScript online submissions for Fizz Buzz. 3 | 4 | function fizzBuzz(n: number): string[] { 5 | return [...Array(n).keys()].map((i) => { 6 | const num = i + 1; 7 | if (num % 3 === 0 && num % 5 === 0) return 'FizzBuzz'; 8 | if (num % 3 === 0) return 'Fizz'; 9 | if (num % 5 === 0) return 'Buzz'; 10 | return num.toString(); 11 | }); 12 | } 13 | -------------------------------------------------------------------------------- /src/problems/413.Arithmetic-Slices.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | // Runtime: 84 ms, faster than 83.33% of TypeScript online submissions for Arithmetic Slices. 3 | // Memory Usage: 39.4 MB, less than 50.00% of TypeScript online submissions for Arithmetic Slices. 4 | function numberOfArithmeticSlices(A: number[]): number { 5 | const difs: number[] = Array(A.length).fill(0); 6 | const dp: number[] = Array(A.length).fill(0); 7 | 8 | for (let i = 1; i < A.length; i++) { 9 | difs[i] = A[i] - A[i - 1]; 10 | } 11 | 12 | for (let i = 2; i < A.length; i++) { 13 | if (difs[i] === difs[i - 1]) { 14 | dp[i] = dp[i - 1] + 1; 15 | } 16 | } 17 | 18 | return dp.reduce((acc, curr) => acc + curr, 0); 19 | } 20 | 21 | // JS 22 | // Runtime: 72 ms, faster than 89.58% of JavaScript online submissions for Arithmetic Slices. 23 | // Memory Usage: 38.7 MB, less than 31.25% of JavaScript online submissions for Arithmetic Slices. 24 | // var numberOfArithmeticSlices = function (A) { 25 | // const difs = Array(A.length).fill(0); 26 | // const dp = Array(A.length).fill(0); 27 | 28 | // for (let i = 1; i < A.length; i++) { 29 | // difs[i] = A[i] - A[i - 1]; 30 | // } 31 | 32 | // for (let i = 2; i < A.length; i++) { 33 | // if (difs[i] === difs[i - 1]) { 34 | // dp[i] = dp[i - 1] + 1; 35 | // } 36 | // } 37 | 38 | // return dp.reduce((acc, curr) => acc + curr, 0); 39 | // }; 40 | -------------------------------------------------------------------------------- /src/problems/430-Flatten-a-Multilevel-Doubly-Linked-List.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 68 ms, faster than 97.25% of JavaScript online submissions for Flatten a Multilevel Doubly Linked List. 2 | // Memory Usage: 40 MB, less than 10.62% of JavaScript online submissions for Flatten a Multilevel Doubly Linked List. 3 | 4 | class LLNode { 5 | val: number; 6 | prev: LLNode | null; 7 | next: LLNode | null; 8 | child: LLNode | null; 9 | constructor(val?: number, prev?: LLNode, next?: LLNode, child?: LLNode) { 10 | this.val = val === undefined ? 0 : val; 11 | this.prev = prev === undefined ? null : prev; 12 | this.next = next === undefined ? null : next; 13 | this.child = child === undefined ? null : child; 14 | } 15 | } 16 | 17 | function flatten(head: LLNode | null): LLNode | null { 18 | const queue: LLNode[] = []; 19 | let curr: LLNode | null = head; 20 | let prev: LLNode | null = null; 21 | 22 | while (curr || queue.length) { 23 | if (curr) { 24 | if (curr.child) { 25 | if (curr.next) { 26 | queue.push(curr.next); 27 | } 28 | 29 | curr.next = curr.child; 30 | curr.child.prev = curr; 31 | curr.child = null; 32 | } 33 | 34 | prev = curr; 35 | curr = curr.next; 36 | } else { 37 | curr = queue.pop()!; 38 | prev!.next = curr; 39 | curr.prev = prev; 40 | } 41 | } 42 | 43 | return head; 44 | } 45 | -------------------------------------------------------------------------------- /src/problems/435-Non-overlapping-Intervals.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 96 ms, faster than 25.70% of JavaScript online submissions for Non-overlapping Intervals. 2 | // Memory Usage: 38.7 MB, less than 22.09% of JavaScript online submissions for Non-overlapping Intervals. 3 | 4 | function eraseOverlapIntervals(intervals: number[][]): number { 5 | if (intervals.length < 2) return 0; 6 | intervals.sort(([, a], [, b]) => a - b); 7 | let count = 0; 8 | let pervEnd = intervals[0][1]; 9 | 10 | for (let i = 1; i < intervals.length; i++) { 11 | if (pervEnd > intervals[i][0]) count++; 12 | else pervEnd = intervals[i][1]; 13 | } 14 | return count; 15 | } 16 | -------------------------------------------------------------------------------- /src/problems/436-Find-Right-Interval.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 568 ms, faster than 22.50% of JavaScript online submissions for Find Right Interval. 2 | // Memory Usage: 43.7 MB, less than 75.00% of JavaScript online submissions for Find Right Interval. 3 | 4 | type Interval = { 5 | index: number; 6 | start: number; 7 | end: number; 8 | }; 9 | function findRightInterval(intervals: number[][]): number[] { 10 | const helper: Interval[] = intervals 11 | .map(([start, end], index) => ({ 12 | index, 13 | start, 14 | end, 15 | })) 16 | .sort((a, b) => a.start - b.start); 17 | 18 | return intervals.map(([, end]) => { 19 | const auxIndex = helper.findIndex(({ start }) => start >= end); 20 | return auxIndex === -1 ? -1 : helper[auxIndex].index; 21 | }); 22 | } 23 | -------------------------------------------------------------------------------- /src/problems/437-Path-Sum-III.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 132 ms, faster than 40.87% of JavaScript online submissions for Path Sum III. 2 | // Memory Usage: 39.9 MB, less than 78.84% of JavaScript online submissions for Path Sum III. 3 | 4 | /* 5 | class TreeNode { 6 | val: number; 7 | left: TreeNode | null; 8 | right: TreeNode | null; 9 | constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { 10 | this.val = val === undefined ? 0 : val; 11 | this.left = left === undefined ? null : left; 12 | this.right = right === undefined ? null : right; 13 | } 14 | } 15 | */ 16 | 17 | function pathSum(root: TreeNode | null, sum: number): number { 18 | if (!root) return 0; 19 | return helper(root, sum) + pathSum(root.left, sum) + pathSum(root.right, sum); 20 | } 21 | 22 | const helper = (root: TreeNode | null, sum: number): number => { 23 | if (!root) return 0; 24 | const match = root.val === sum ? 1 : 0; 25 | 26 | return ( 27 | match + 28 | helper(root.left, sum - root.val) + 29 | helper(root.right, sum - root.val) 30 | ); 31 | }; 32 | -------------------------------------------------------------------------------- /src/problems/438.Find-All-Anagrams-in-a-String.ts: -------------------------------------------------------------------------------- 1 | function findAnagrams(s: string, p: string): number[] { 2 | const res: number[] = []; 3 | const hash: { [key: string]: number } = {}; 4 | 5 | const isAnagrams = () => { 6 | return Object.values(hash).every((value) => value === 0); 7 | }; 8 | 9 | for (const char of p) { 10 | if (!(char in hash)) { 11 | hash[char] = 0; 12 | } 13 | hash[char]++; 14 | } 15 | 16 | let left = 0; 17 | let right = 0; 18 | 19 | while (right < s.length) { 20 | if (s[right] in hash) { 21 | hash[s[right]]--; 22 | } 23 | right++; 24 | 25 | if (right - left === p.length) { 26 | if (isAnagrams()) res.push(left); 27 | if (s[left] in hash) { 28 | hash[s[left]]++; 29 | } 30 | left++; 31 | } 32 | } 33 | 34 | return res; 35 | } 36 | -------------------------------------------------------------------------------- /src/problems/442-Find-All-Duplicates-in-an-Array.ts: -------------------------------------------------------------------------------- 1 | // Hash and Array 2 | // Runtime: 132 ms, faster than 55.59% of JavaScript online submissions for Find All Duplicates in an Array. 3 | // Memory Usage: 47.9 MB, less than 21.43% of JavaScript online submissions for Find All Duplicates in an Array. 4 | 5 | function findDuplicates(nums: number[]): number[] { 6 | const hash: { [key: string]: number } = {}; 7 | const res: number[] = []; 8 | nums.forEach((num) => { 9 | hash[num] ? res.push(num) : (hash[num] = 1); 10 | }); 11 | return res; 12 | } 13 | -------------------------------------------------------------------------------- /src/problems/45.Jump-Game-II.ts: -------------------------------------------------------------------------------- 1 | function jump(nums: number[]): number { 2 | const dp = Array(nums.length).fill(Infinity); 3 | dp[0] = 0; 4 | 5 | for (let i = 0; i < nums.length; i++) { 6 | for (let j = i + 1; j < nums.length && j <= i + nums[i]; j++) { 7 | dp[j] = Math.min(dp[j], dp[i] + 1); 8 | } 9 | } 10 | 11 | return dp[dp.length - 1]; 12 | } 13 | -------------------------------------------------------------------------------- /src/problems/454.4Sum-II.ts: -------------------------------------------------------------------------------- 1 | function fourSumCount( 2 | A: number[], 3 | B: number[], 4 | C: number[], 5 | D: number[] 6 | ): number { 7 | let res = 0; 8 | const ABHash: { [key: string]: number } = {}; 9 | 10 | for (let i = 0; i < A.length; i++) { 11 | for (let j = 0; j < B.length; j++) { 12 | const AB = A[i] + B[j]; 13 | 14 | AB in ABHash ? ABHash[AB]++ : (ABHash[AB] = 1); 15 | } 16 | } 17 | 18 | for (let i = 0; i < C.length; i++) { 19 | for (let j = 0; j < D.length; j++) { 20 | const CD = -(C[i] + D[j]); 21 | 22 | if (CD in ABHash) { 23 | res += ABHash[-CD]; 24 | } 25 | } 26 | } 27 | 28 | return res; 29 | } 30 | -------------------------------------------------------------------------------- /src/problems/462.Minimum-Moves-to-Equal-Array-Elements-II.ts: -------------------------------------------------------------------------------- 1 | function minMoves2(nums: number[]): number { 2 | nums.sort((a, b) => a - b); 3 | const mid = Math.floor(nums.length / 2); 4 | const median = nums.length % 2 ? nums[mid] : (nums[mid] + nums[mid - 1]) / 2; 5 | let steps = 0; 6 | for (const num of nums) { 7 | steps += Math.abs(num - median); 8 | } 9 | 10 | return steps; 11 | } 12 | -------------------------------------------------------------------------------- /src/problems/470-Implement-Rand10()-Using-Rand7().ts: -------------------------------------------------------------------------------- 1 | // Runtime: 100 ms, faster than 94.29% of JavaScript online submissions for Implement Rand10() Using Rand7(). 2 | // Memory Usage: 43.9 MB, less than 54.29% of JavaScript online submissions for Implement Rand10() Using Rand7(). 3 | const rand10 = function () { 4 | let random = 41; 5 | while (random > 40) { 6 | random = 7 * (rand7() - 1) + rand7(); 7 | } 8 | return (random % 10) + 1; 9 | }; 10 | -------------------------------------------------------------------------------- /src/problems/474.Ones-and-Zeroes.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | function findMaxForm(strs: string[], m: number, n: number): number { 3 | const dp: number[][] = Array.from({ length: m + 1 }, () => 4 | Array(n + 1).fill(0) 5 | ); 6 | 7 | for (let i = 0; i < strs.length; i++) { 8 | const [zeros, ones] = strs[i].split('').reduce( 9 | (acc, char) => { 10 | if (char === '0') return [acc[0] + 1, acc[1]]; 11 | return [acc[0], acc[1] + 1]; 12 | }, 13 | [0, 0] 14 | ); 15 | 16 | for (let j = m; j >= zeros; j--) { 17 | for (let k = n; k >= ones; k--) { 18 | dp[j][k] = Math.max(dp[j][k], dp[j - zeros][k - ones] + 1); 19 | } 20 | } 21 | } 22 | 23 | return dp[m][n]; 24 | } 25 | 26 | // JS 27 | // var findMaxForm = function (strs, m, n) { 28 | // const dp = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0)); 29 | 30 | // for (let i = 0; i < strs.length; i++) { 31 | // const [zeros, ones] = strs[i].split('').reduce( 32 | // (acc, char) => { 33 | // if (char === '0') return [acc[0] + 1, acc[1]]; 34 | // return [acc[0], acc[1] + 1]; 35 | // }, 36 | // [0, 0] 37 | // ); 38 | 39 | // for (let j = m; j >= zeros; j--) { 40 | // for (let k = n; k >= ones; k--) { 41 | // dp[j][k] = Math.max(dp[j][k], dp[j - zeros][k - ones] + 1); 42 | // } 43 | // } 44 | // } 45 | 46 | // return dp[m][n]; 47 | // }; 48 | -------------------------------------------------------------------------------- /src/problems/485-Max-Consecutive-Ones.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 88 ms, faster than 44.97% of JavaScript online submissions for Max Consecutive Ones. 2 | // Memory Usage: 39.3 MB, less than 37.76% of JavaScript online submissions for Max Consecutive Ones. 3 | 4 | function findMaxConsecutiveOnes(nums: number[]): number { 5 | let res = 0; 6 | let aux = 0; 7 | 8 | nums.forEach((num) => { 9 | if (num) { 10 | aux++; 11 | } else { 12 | res = Math.max(res, aux); 13 | aux = 0; 14 | } 15 | }); 16 | res = Math.max(res, aux); 17 | 18 | return res; 19 | } 20 | -------------------------------------------------------------------------------- /src/problems/49.Group-Anagrams.ts: -------------------------------------------------------------------------------- 1 | const sortString = (str: string) => [...str].sort().join(''); 2 | 3 | function groupAnagrams(strs: string[]): string[][] { 4 | const hash: { [key: string]: string[] } = {}; 5 | 6 | for (const str of strs) { 7 | const sortedStr = sortString(str); 8 | if (!(sortedStr in hash)) { 9 | hash[sortedStr] = []; 10 | } 11 | hash[sortedStr].push(str); 12 | } 13 | 14 | return Object.values(hash); 15 | } 16 | -------------------------------------------------------------------------------- /src/problems/495-Teemo-Attacking.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | // Runtime: 88 ms, faster than 75.00% of TypeScript online submissions for Teemo Attacking. 3 | // Memory Usage: 43.1 MB, less than 25.00% of TypeScript online submissions for Teemo Attacking. 4 | function findPoisonedDuration(timeSeries: number[], duration: number): number { 5 | if (!timeSeries.length || duration <= 0) return 0; 6 | 7 | let res = duration; 8 | for (let i = 1; i < timeSeries.length; i++) 9 | res += Math.min(timeSeries[i] - timeSeries[i - 1], duration); 10 | return res; 11 | } 12 | 13 | // JS 14 | // Runtime: 88 ms, faster than 42.22% of JavaScript online submissions for Teemo Attacking. 15 | // Memory Usage: 43.2 MB, less than 8.89% of JavaScript online submissions for Teemo Attacking. 16 | // function findPoisonedDuration(timeSeries: number[], duration: number): number { 17 | // if (!timeSeries.length || duration <= 0) return 0; 18 | 19 | // let res = duration; 20 | // for (let i = 1; i < timeSeries.length; i++) 21 | // res += Math.min(timeSeries[i] - timeSeries[i - 1], duration); 22 | // return res; 23 | // } 24 | -------------------------------------------------------------------------------- /src/problems/496.Next-Greater-Element-I.ts: -------------------------------------------------------------------------------- 1 | function nextGreaterElement(nums1: number[], nums2: number[]): number[] { 2 | const hash: { [key: string]: number } = {}; 3 | const stack: number[] = []; 4 | 5 | for (const num of nums2) { 6 | while (stack.length && stack[stack.length - 1] < num) { 7 | hash[stack.pop()!] = num; 8 | } 9 | stack.push(num); 10 | } 11 | 12 | return nums1.map((num) => { 13 | return num in hash ? hash[num] : -1; 14 | }); 15 | } 16 | 17 | // var nextGreaterElement = function (nums1, nums2) { 18 | // const hash = {}; 19 | // const stack = []; 20 | 21 | // for (const num of nums2) { 22 | // while (stack.length && stack[stack.length - 1] < num) { 23 | // hash[stack.pop()] = num; 24 | // } 25 | // stack.push(num); 26 | // } 27 | 28 | // return nums1.map((num) => { 29 | // return num in hash ? hash[num] : -1; 30 | // }); 31 | // }; 32 | -------------------------------------------------------------------------------- /src/problems/501.Find-Mode-in-Binary-Search-Tree.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | // Runtime: 96 ms, faster than 100.00% of TypeScript online submissions for Find Mode in Binary Search Tree. 3 | // Memory Usage: 45.2 MB, less than 100.00% of TypeScript online submissions for Find Mode in Binary Search Tree. 4 | function findMode(root: TreeNode | null): number[] { 5 | let res: number[] = []; 6 | let prev: number | null = null; 7 | let count: number = 0; 8 | let max: number = 0; 9 | 10 | const traverse = (node: TreeNode | null) => { 11 | if (!node) return; 12 | 13 | traverse(node.left); 14 | 15 | if (node.val !== prev) { 16 | prev = node.val; 17 | count = 0; 18 | } 19 | 20 | count++; 21 | 22 | if (count > max) { 23 | res = [node.val]; 24 | max = count; 25 | } else if (count === max) { 26 | res.push(node.val); 27 | } 28 | 29 | traverse(node.right); 30 | }; 31 | 32 | traverse(root); 33 | 34 | return res; 35 | } 36 | -------------------------------------------------------------------------------- /src/problems/503.Next-Greater-Element-II.ts: -------------------------------------------------------------------------------- 1 | function nextGreaterElements(nums: number[]): number[] { 2 | const res: number[] = Array(nums.length).fill(-1); 3 | const doubleNums = [...nums, ...nums]; 4 | const stack: [number, number][] = []; // [val,index] 5 | 6 | let i = 0; 7 | while (i < doubleNums.length) { 8 | while (stack.length && doubleNums[i] > stack[stack.length - 1][0]) { 9 | const [, stackIndex] = stack.pop()!; 10 | if (stackIndex < nums.length) { 11 | res[stackIndex] = doubleNums[i]; 12 | } 13 | } 14 | stack.push([doubleNums[i], i]); 15 | i++; 16 | } 17 | 18 | return res; 19 | } 20 | -------------------------------------------------------------------------------- /src/problems/509.Fibonacci-Number.ts: -------------------------------------------------------------------------------- 1 | // Recursion 2 | // function fib(n: number): number { 3 | // if (n <= 1) return n; 4 | // return fib(n - 1) + fib(n - 2); 5 | // } 6 | 7 | // DP 8 | function fib(n: number): number { 9 | const dp = Array(n + 1).fill(null); 10 | dp[0] = 0; 11 | dp[1] = 1; 12 | 13 | for (let i = 2; i <= n; i++) { 14 | dp[i] = dp[i - 1] + dp[i - 2]; 15 | } 16 | 17 | return dp[n]; 18 | } 19 | -------------------------------------------------------------------------------- /src/problems/515.Find-Largest-Value-in-Each-Tree-Row.ts: -------------------------------------------------------------------------------- 1 | // JS 2 | var largestValues = function (root) { 3 | if (!root) return []; 4 | const res = []; 5 | let queue = [root]; 6 | let level = 0; 7 | 8 | while (queue.length) { 9 | const newQueue = []; 10 | res[level] = Number.MIN_SAFE_INTEGER; 11 | 12 | while (queue.length) { 13 | const curr = queue.pop(); 14 | res[level] = Math.max(curr.val, res[level]); 15 | 16 | if (curr.left) newQueue.push(curr.left); 17 | if (curr.right) newQueue.push(curr.right); 18 | } 19 | 20 | queue = newQueue; 21 | level++; 22 | } 23 | 24 | return res; 25 | }; 26 | 27 | // TS 28 | function largestValues(root: TreeNode | null): number[] { 29 | if (!root) return []; 30 | const res: number[] = []; 31 | let queue: TreeNode[] = [root]; 32 | let level = 0; 33 | 34 | while (queue.length) { 35 | const newQueue: TreeNode[] = []; 36 | res[level] = Number.MIN_SAFE_INTEGER; 37 | 38 | while (queue.length) { 39 | const curr = queue.pop()!; 40 | res[level] = Math.max(curr.val, res[level]); 41 | 42 | if (curr.left) newQueue.push(curr.left); 43 | if (curr.right) newQueue.push(curr.right); 44 | } 45 | 46 | queue = newQueue; 47 | level++; 48 | } 49 | 50 | return res; 51 | } 52 | -------------------------------------------------------------------------------- /src/problems/520-detect-capital.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 76 ms, faster than 82.72% of JavaScript online submissions for Detect Capital. 2 | // Memory Usage: 37.4 MB, less than 25.00% of JavaScript online submissions for Detect Capital. 3 | 4 | function detectCapitalUse(word: string) { 5 | const pascalCase = word.charAt(0).toUpperCase() + word.slice(1).toLowerCase(); 6 | return ( 7 | word === pascalCase || 8 | word === word.toLocaleLowerCase() || 9 | word === word.toLocaleUpperCase() 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /src/problems/524.Longest-Word-in-Dictionary-through-Deleting.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | const canBeFormed = (s: string, d: string) => { 3 | let i = 0; 4 | let j = 0; 5 | 6 | while (i < s.length && j < d.length) { 7 | if (s[i] === d[j]) j++; 8 | i++; 9 | } 10 | 11 | return j === d.length; 12 | }; 13 | 14 | function findLongestWord(s: string, d: string[]): string { 15 | const res = d 16 | .filter((word) => canBeFormed(s, word)) 17 | .sort((a, b) => b.length - a.length || a.localeCompare(b)); 18 | 19 | return res.length ? res[0] : ''; 20 | } 21 | 22 | // JS 23 | // const canBeFormed = (s, d) => { 24 | // let i = 0; 25 | // let j = 0; 26 | 27 | // while (i < s.length && j < d.length) { 28 | // if (s[i] === d[j]) j++; 29 | // i++; 30 | // } 31 | 32 | // return j === d.length; 33 | // }; 34 | 35 | // var findLongestWord = function (s, d) { 36 | // const res = d 37 | // .filter((word) => canBeFormed(s, word)) 38 | // .sort((a, b) => b.length - a.length || a.localeCompare(b)); 39 | 40 | // return res.length ? res[0] : ''; 41 | // }; 42 | -------------------------------------------------------------------------------- /src/problems/525.Contiguous-Array.ts: -------------------------------------------------------------------------------- 1 | function findMaxLength(nums: number[]): number { 2 | let maxLength = 0; 3 | let count = 0; 4 | const map = new Map(); 5 | map.set(0, -1); 6 | 7 | for (let i = 0; i < nums.length; i++) { 8 | nums[i] ? count++ : count--; 9 | if (map.has(count)) { 10 | maxLength = Math.max(maxLength, i - map.get(count)!); 11 | } else { 12 | map.set(count, i); 13 | } 14 | } 15 | 16 | return maxLength; 17 | } 18 | -------------------------------------------------------------------------------- /src/problems/526.Beautiful-Arrangement.ts: -------------------------------------------------------------------------------- 1 | function countArrangement(n: number): number { 2 | let res = 0; 3 | 4 | const dfs = (queue: number[], stock: number[]) => { 5 | if (!stock.length) { 6 | res++; 7 | return; 8 | } 9 | 10 | for (let i = 0; i < stock.length; i++) { 11 | const curr = stock[i]; 12 | 13 | if (curr % (queue.length + 1) === 0 || (queue.length + 1) % curr === 0) { 14 | const rest = stock.filter((_, index) => i !== index); 15 | dfs([...queue, curr], rest); 16 | } 17 | } 18 | }; 19 | 20 | const initialStock = Array.from({ length: n }, (_, i) => i + 1); 21 | 22 | dfs([], initialStock); 23 | 24 | return res; 25 | } 26 | -------------------------------------------------------------------------------- /src/problems/53-Maximum-Subarray.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 76 ms, faster than 87.39% of JavaScript online submissions for Maximum Subarray. 2 | // Memory Usage: 37.8 MB, less than 19.68% of JavaScript online submissions for Maximum Subarray. 3 | 4 | function maxSubArray(nums: number[]): number { 5 | for (let i = 1; i < nums.length; i++) { 6 | if (nums[i - 1] > 0) { 7 | nums[i] = Math.max(nums[i] + nums[i - 1], nums[i]); 8 | } 9 | } 10 | 11 | return Math.max(...nums); 12 | } 13 | -------------------------------------------------------------------------------- /src/problems/53.Maximum-Subarray.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eddyhdzg/leetcode-typescript-solutions/2793246b9b9b7dfcb9a3f3dac7528272b32d87ca/src/problems/53.Maximum-Subarray.ts -------------------------------------------------------------------------------- /src/problems/538.Convert-BST-to-Greater-Tree.ts: -------------------------------------------------------------------------------- 1 | // JS 2 | var convertBST = function (root) { 3 | let prev = 0; 4 | 5 | const traverse = (node) => { 6 | if (!node) return; 7 | 8 | traverse(node.right); 9 | prev = node.val += prev; 10 | traverse(node.left); 11 | }; 12 | 13 | traverse(root); 14 | return root; 15 | }; 16 | 17 | // TS 18 | function convertBST(root: TreeNode | null): TreeNode | null { 19 | let prev = 0; 20 | 21 | const traverse = (node: TreeNode | null) => { 22 | if (!node) return; 23 | 24 | traverse(node.right); 25 | prev = node.val += prev; 26 | traverse(node.left); 27 | }; 28 | 29 | traverse(root); 30 | return root; 31 | } 32 | -------------------------------------------------------------------------------- /src/problems/547-Friend-Circles.ts: -------------------------------------------------------------------------------- 1 | function findCircleNum(isConnected: number[][]): number { 2 | let circles = 0; 3 | const visited = new Set(); 4 | 5 | const dfs = (i: number) => { 6 | for (let j = 0; j < isConnected.length; j++) { 7 | if (isConnected[i][j] && !visited.has(j)) { 8 | visited.add(j); 9 | dfs(j); 10 | } 11 | } 12 | }; 13 | 14 | for (let i = 0; i < isConnected.length; i++) { 15 | if (!visited.has(i)) { 16 | circles++; 17 | dfs(i); 18 | } 19 | } 20 | 21 | return circles; 22 | } 23 | 24 | // JavaScript 25 | /* 26 | var findCircleNum = function (M) { 27 | let circles = 0; 28 | const visited = new Set(); 29 | 30 | const dfs = (i) => { 31 | for (let j = 0; j < M.length; j++) { 32 | if (M[i][j] && !visited.has(j)) { 33 | visited.add(j); 34 | dfs(j); 35 | } 36 | } 37 | }; 38 | 39 | for (let i = 0; i < M.length; i++) { 40 | if (!visited.has(i)) { 41 | circles++; 42 | dfs(i); 43 | } 44 | } 45 | 46 | return circles; 47 | }; 48 | */ 49 | -------------------------------------------------------------------------------- /src/problems/55.Jump-Game.ts: -------------------------------------------------------------------------------- 1 | function canJump(nums: number[]): boolean { 2 | const dp = Array(nums.length).fill(false); 3 | dp[0] = true; 4 | 5 | let i = 0; 6 | let count = nums[0]; 7 | while (i < nums.length && count > 0) { 8 | dp[i] = true; 9 | count = Math.max(--count, nums[i]); 10 | i++; 11 | } 12 | 13 | return dp[dp.length - 1]; 14 | } 15 | -------------------------------------------------------------------------------- /src/problems/56-Merge-Intervals.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | function merge(intervals: number[][]): number[][] { 3 | intervals.sort(([a], [c]) => a - c); 4 | 5 | let i = 1; 6 | 7 | while (i < intervals.length) { 8 | const [a, b] = intervals[i - 1]; 9 | const [c, d] = intervals[i]; 10 | 11 | if (b >= c) intervals.splice(i - 1, 2, [a, Math.max(b, d)]); 12 | else i++; 13 | } 14 | 15 | return intervals; 16 | } 17 | 18 | // JS 19 | // var merge = function (intervals) { 20 | // intervals.sort(([a], [c]) => a - c); 21 | 22 | // let i = 1; 23 | 24 | // while (i < intervals.length) { 25 | // const [a, b] = intervals[i - 1]; 26 | // const [c, d] = intervals[i]; 27 | 28 | // if (b >= c) intervals.splice(i - 1, 2, [a, Math.max(b, d)]); 29 | // else i++; 30 | // } 31 | 32 | // return intervals; 33 | // }; 34 | -------------------------------------------------------------------------------- /src/problems/560.Subarray-Sum-Equals-K.ts: -------------------------------------------------------------------------------- 1 | function subarraySum(nums: number[], k: number): number { 2 | const hash: { [sum: string]: number } = { 0: 1 }; 3 | let sum = 0; 4 | let res = 0; 5 | 6 | for (let i = 0; i < nums.length; i++) { 7 | sum += nums[i]; 8 | const diff = sum - k; 9 | if (hash[diff]) res += hash[diff]; 10 | hash[sum] = (hash[sum] ?? 0) + 1; 11 | } 12 | 13 | return res; 14 | } 15 | -------------------------------------------------------------------------------- /src/problems/563.Binary-Tree-Tilt.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | // Runtime: 84 ms, faster than 100.00% of TypeScript online submissions for Binary Tree Tilt. 3 | // Memory Usage: 44.4 MB, less than 75.00% of TypeScript online submissions for Binary Tree Tilt. 4 | function findTilt(root: TreeNode | null): number { 5 | let res = 0; 6 | const traverse = (node: TreeNode | null): number => { 7 | if (!node) return 0; 8 | const left = traverse(node.left); 9 | const right = traverse(node.right); 10 | res += Math.abs(left - right); 11 | 12 | return node.val + left + right; 13 | }; 14 | 15 | traverse(root); 16 | 17 | return res; 18 | } 19 | 20 | // JS 21 | // Runtime: 96 ms, faster than 45.85% of JavaScript online submissions for Binary Tree Tilt. 22 | // Memory Usage: 43.6 MB, less than 33.79% of JavaScript online submissions for Binary Tree Tilt. 23 | // var findTilt = function (root) { 24 | // let res = 0; 25 | // const traverse = (node) => { 26 | // if (!node) return 0; 27 | // const left = traverse(node.left); 28 | // const right = traverse(node.right); 29 | // res += Math.abs(left - right); 30 | 31 | // return node.val + left + right; 32 | // }; 33 | 34 | // traverse(root); 35 | 36 | // return res; 37 | // }; 38 | -------------------------------------------------------------------------------- /src/problems/566.Reshape-the-Matrix.ts: -------------------------------------------------------------------------------- 1 | function matrixReshape(mat: number[][], r: number, c: number): number[][] { 2 | const rows = mat.length; 3 | const columns = mat[0].length; 4 | 5 | if (rows * columns !== c * r) return mat; 6 | 7 | const res: number[][] = Array(r) 8 | .fill(null) 9 | .map(() => Array(c)); 10 | 11 | let resi = 0; 12 | let resj = 0; 13 | 14 | for (let i = 0; i < rows; i++) { 15 | for (let j = 0; j < columns; j++) { 16 | res[resi][resj] = mat[i][j]; 17 | resj++; 18 | if (resj === c) { 19 | resj = 0; 20 | resi++; 21 | } 22 | } 23 | } 24 | 25 | return res; 26 | } 27 | -------------------------------------------------------------------------------- /src/problems/567.Permutation-in-String.ts: -------------------------------------------------------------------------------- 1 | function checkInclusion(s1: string, s2: string): boolean { 2 | const chars = new Array(26).fill(0); 3 | 4 | const isPermutation = () => chars.every((char) => char === 0); 5 | 6 | for (const char of s1) { 7 | chars[char.charCodeAt(0) - 97]++; 8 | } 9 | 10 | for (let i = 0; i < s2.length; i++) { 11 | chars[s2[i].charCodeAt(0) - 97]--; 12 | 13 | if (i >= s1.length) { 14 | chars[s2[i - s1.length].charCodeAt(0) - 97]++; 15 | } 16 | 17 | if (isPermutation()) return true; 18 | } 19 | 20 | return false; 21 | } 22 | -------------------------------------------------------------------------------- /src/problems/572.Subtree-of-Another-Tree.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | function isSubtree(s: TreeNode | null, t: TreeNode | null): boolean { 3 | if (!s) return false; 4 | return isSubtreeEqual(s, t) || isSubtree(s.right, t) || isSubtree(s.left, t); 5 | } 6 | 7 | const isSubtreeEqual = (s: TreeNode | null, t: TreeNode | null) => { 8 | if (!s && !t) return true; 9 | if (!s || !t) return false; 10 | return ( 11 | s.val === t.val && 12 | isSubtreeEqual(s.left, t.left) && 13 | isSubtreeEqual(s.right, t.right) 14 | ); 15 | }; 16 | 17 | // JS 18 | // var isSubtree = function (s, t) { 19 | // if (!s) return false; 20 | 21 | // return isSubtreeEqual(s, t) || isSubtree(s.right, t) || isSubtree(s.left, t); 22 | // }; 23 | 24 | // const isSubtreeEqual = (s, t) => { 25 | // if (!s && !t) return true; 26 | // if (!s || !t) return false; 27 | // return ( 28 | // s.val === t.val && 29 | // isSubtreeEqual(s.left, t.left) && 30 | // isSubtreeEqual(s.right, t.right) 31 | // ); 32 | // }; 33 | -------------------------------------------------------------------------------- /src/problems/575.Distribute.Candies.ts: -------------------------------------------------------------------------------- 1 | function distributeCandies(candyType: number[]): number { 2 | return Math.min(new Set(candyType).size, candyType.length / 2); 3 | } 4 | -------------------------------------------------------------------------------- /src/problems/581.Shortest-Unsorted-Continuous-Subarray.ts: -------------------------------------------------------------------------------- 1 | // // TS 2 | function findUnsortedSubarray(nums: number[]): number { 3 | const sorted = [...nums].sort((a, b) => a - b); 4 | 5 | let left = Infinity; 6 | let right = 0; 7 | 8 | for (let i = 0; i < nums.length; i++) { 9 | if (nums[i] !== sorted[i]) { 10 | left = Math.min(left, i); 11 | right = Math.max(right, i); 12 | } 13 | } 14 | 15 | return right ? right - left + 1 : 0; 16 | } 17 | 18 | // // JS 19 | // var findUnsortedSubarray = function (nums) { 20 | // const sorted = [...nums].sort((a, b) => a - b); 21 | 22 | // let left = Infinity; 23 | // let right = 0; 24 | 25 | // for (let i = 0; i < nums.length; i++) { 26 | // if (nums[i] !== sorted[i]) { 27 | // left = Math.min(left, i); 28 | // right = Math.max(right, i); 29 | // } 30 | // } 31 | 32 | // return right ? right - left + 1 : 0; 33 | // }; 34 | -------------------------------------------------------------------------------- /src/problems/589.N-ary-Tree-Preorder-Traversal.ts: -------------------------------------------------------------------------------- 1 | interface Node { 2 | val: number; 3 | children: Node[]; 4 | } 5 | 6 | function preorder(root: Node | null): number[] { 7 | if (!root) return []; 8 | 9 | const res: number[] = []; 10 | 11 | const traverse = (node: Node | null) => { 12 | if (!node) return; 13 | res.push(node.val); 14 | 15 | node.children.forEach((child) => { 16 | traverse(child); 17 | }); 18 | }; 19 | 20 | traverse(root); 21 | 22 | return res; 23 | } 24 | -------------------------------------------------------------------------------- /src/problems/59.Spiral-Matrix-II.ts: -------------------------------------------------------------------------------- 1 | function generateMatrix(n: number): number[][] { 2 | const res: number[][] = Array(n) 3 | .fill(null) 4 | .map(() => Array(n).fill(null)); 5 | 6 | let rb = 0; 7 | let re = n - 1; 8 | let cb = 0; 9 | let ce = n - 1; 10 | 11 | let counter = 1; 12 | 13 | while (rb <= re && cb <= ce) { 14 | for (let i = cb; i <= ce; i++) { 15 | res[rb][i] = counter++; 16 | } 17 | rb++; 18 | 19 | for (let i = rb; i <= re; i++) { 20 | res[i][ce] = counter++; 21 | } 22 | ce--; 23 | 24 | if (rb <= re) { 25 | for (let i = ce; i >= cb; i--) { 26 | res[re][i] = counter++; 27 | } 28 | } 29 | re--; 30 | 31 | if (cb <= ce) { 32 | for (let i = re; i >= rb; i--) { 33 | res[i][cb] = counter++; 34 | } 35 | } 36 | cb++; 37 | } 38 | 39 | return res; 40 | } 41 | -------------------------------------------------------------------------------- /src/problems/62-Unique-Paths.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 84 ms, faster than 55.56% of TypeScript online submissions for Unique Paths. 2 | // Memory Usage: 38 MB, less than 22.22% of TypeScript online submissions for Unique Paths. 3 | 4 | function uniquePaths(m: number, n: number): number { 5 | const dp: number[][] = Array(m) 6 | .fill(null) 7 | .map(() => Array(n)); 8 | 9 | for (let i = 0; i < dp.length; i++) dp[i][0] = 1; 10 | for (let j = 0; j < dp[0].length; j++) dp[0][j] = 1; 11 | 12 | for (let i = 1; i < dp.length; i++) { 13 | for (let j = 1; j < dp[0].length; j++) { 14 | dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; 15 | } 16 | } 17 | 18 | return dp[m - 1][n - 1]; 19 | } 20 | 21 | uniquePaths(3, 7); 22 | 23 | // Runtime: 84 ms, faster than 36.59% of JavaScript online submissions for Unique Paths. 24 | // Memory Usage: 37.7 MB, less than 19.45% of JavaScript online submissions for Unique Paths. 25 | 26 | // var uniquePaths = function (m, n) { 27 | // const dp = Array(m) 28 | // .fill(null) 29 | // .map(() => Array(n)); 30 | 31 | // // Initialize first row and first column with 1s 32 | // for (let i = 0; i < dp.length; i++) dp[i][0] = 1; 33 | // for (let j = 0; j < dp[0].length; j++) dp[0][j] = 1; 34 | 35 | // for (let i = 1; i < dp.length; i++) { 36 | // for (let j = 1; j < dp[0].length; j++) { 37 | // dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; 38 | // } 39 | // } 40 | 41 | // return dp[m - 1][n - 1]; 42 | // }; 43 | -------------------------------------------------------------------------------- /src/problems/623.Add-One-Row-to-Tree.ts: -------------------------------------------------------------------------------- 1 | function addOneRow( 2 | root: TreeNode | null, 3 | v: number, 4 | d: number 5 | ): TreeNode | null { 6 | if (d === 1) return new TreeNode(v, root, null); 7 | if (d === 2) { 8 | root!.left = new TreeNode(v, root!.left, null); 9 | root!.right = new TreeNode(v, null, root!.right); 10 | } else { 11 | if (root!.left) addOneRow(root!.left, v, d - 1); 12 | if (root!.right) addOneRow(root!.right, v, d - 1); 13 | } 14 | return root; 15 | } 16 | -------------------------------------------------------------------------------- /src/problems/637.Average-of-Levels-in-Binary-Tree.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | function averageOfLevels(root: TreeNode | null): number[] { 3 | if (!root) return []; 4 | let stack: TreeNode[] = [root]; 5 | const res: number[] = []; 6 | 7 | while (stack.length) { 8 | let sum = 0; 9 | const newStack: TreeNode[] = []; 10 | 11 | for (let node of stack) { 12 | sum += node.val; 13 | if (node.left) newStack.push(node.left); 14 | if (node.right) newStack.push(node.right); 15 | } 16 | 17 | res.push(sum / stack.length); 18 | stack = newStack; 19 | } 20 | 21 | return res; 22 | } 23 | 24 | // JS 25 | // var averageOfLevels = function (root) { 26 | // let stack = [root]; 27 | // const res = []; 28 | 29 | // while (stack.length) { 30 | // let sum = 0; 31 | // const newStack = []; 32 | 33 | // for (let node of stack) { 34 | // sum += node.val; 35 | // if (node.left) newStack.push(node.left); 36 | // if (node.right) newStack.push(node.right); 37 | // } 38 | 39 | // res.push(sum / stack.length); 40 | // stack = newStack; 41 | // } 42 | 43 | // return res; 44 | // }; 45 | -------------------------------------------------------------------------------- /src/problems/645.Set-Mismatch.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | // Runtime: 100 ms, faster than 66.67% of TypeScript online submissions for Set Mismatch. 3 | // Memory Usage: 44.5 MB, less than 100.00% of TypeScript online submissions for Set Mismatch. 4 | function findErrorNums(nums: number[]): number[] { 5 | let twice = 0; 6 | let missing = 0; 7 | const hash: { [key: number]: boolean } = {}; 8 | 9 | for (let num of nums) { 10 | if (num in hash) twice = num; 11 | else hash[num] = true; 12 | } 13 | 14 | let i = 1; 15 | while (!missing) { 16 | if (!(i in hash)) missing = i; 17 | else i++; 18 | } 19 | 20 | return [twice, missing]; 21 | } 22 | 23 | // JS 24 | // Runtime: 88 ms, faster than 89.16% of JavaScript online submissions for Set Mismatch. 25 | // Memory Usage: 43.6 MB, less than 51.81% of JavaScript online submissions for Set Mismatch. 26 | // var findErrorNums = function (nums) { 27 | // let twice = 0; 28 | // let missing = 0; 29 | // const hash = {}; 30 | 31 | // for (let num of nums) { 32 | // if (num in hash) twice = num; 33 | // else hash[num] = true; 34 | // } 35 | 36 | // let i = 1; 37 | // while (!missing) { 38 | // if (!(i in hash)) missing = i; 39 | // else i++; 40 | // } 41 | 42 | // return [twice, missing]; 43 | // }; 44 | -------------------------------------------------------------------------------- /src/problems/647.Palindromic-Substrings.ts: -------------------------------------------------------------------------------- 1 | function countSubstrings(s: string): number { 2 | const n = s.length; 3 | const dp: boolean[][] = Array(n) 4 | .fill(null) 5 | .map(() => Array(n)); 6 | let res = 0; 7 | 8 | for (let i = 0; i < n; i++, res++) { 9 | dp[i][i] = true; 10 | } 11 | 12 | for (let i = 0; i < n; i++) { 13 | if (s[i] === s[i + 1]) { 14 | dp[i][i + 1] = true; 15 | res++; 16 | } 17 | } 18 | 19 | for (let len = 3; len <= s.length; len++) { 20 | for (let i = 0, j = i + len - 1; j < s.length; i++, j++) { 21 | dp[i][j] = dp[i + 1][j - 1] && s.charAt(i) == s.charAt(j); 22 | if (dp[i][j]) res++; 23 | } 24 | } 25 | 26 | return res; 27 | } 28 | -------------------------------------------------------------------------------- /src/problems/652.Find-Duplicate-Subtrees.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | // Runtime: 124 ms, faster than 90.48% of TypeScript online submissions for Find Duplicate Subtrees. 3 | // Memory Usage: 46.1 MB, less than 38.10% of TypeScript online submissions for Find Duplicate Subtrees. 4 | function findDuplicateSubtrees(root: TreeNode | null): Array { 5 | const map = new Map(); 6 | const res: Array = []; 7 | 8 | function dfs(node: TreeNode | null) { 9 | if (!node) return null; 10 | const subtree = `${node.val}.${dfs(node.left)}.${dfs(node.right)}`; 11 | map.set(subtree, (map.get(subtree) || 0) + 1); 12 | if (map.get(subtree) === 2) res.push(node); 13 | 14 | return subtree; 15 | } 16 | 17 | dfs(root); 18 | return res; 19 | } 20 | 21 | // JS 22 | // Runtime: 128 ms, faster than 71.93% of JavaScript online submissions for Find Duplicate Subtrees. 23 | // Memory Usage: 45.3 MB, less than 94.30% of JavaScript online submissions for Find Duplicate Subtrees. 24 | // var findDuplicateSubtrees = function (root) { 25 | // const map = new Map(); 26 | // const res = []; 27 | 28 | // function dfs(node) { 29 | // if (!node) return null; 30 | // const subtree = `${node.val}.${dfs(node.left)}.${dfs(node.right)}`; 31 | // map.set(subtree, (map.get(subtree) || 0) + 1); 32 | // if (map.get(subtree) === 2) res.push(node); 33 | 34 | // return subtree; 35 | // } 36 | 37 | // dfs(root); 38 | // return res; 39 | // }; 40 | -------------------------------------------------------------------------------- /src/problems/653-Two-Sum-IV-Input-is-a-BST.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | // Runtime: 124 ms, faster than 55.56% of TypeScript online submissions for Two Sum IV - Input is a BST. 3 | // Memory Usage: 47.8 MB, less than 66.67% of TypeScript online submissions for Two Sum IV - Input is a BST. 4 | function findTarget(root: TreeNode | null, k: number): boolean { 5 | const set = new Set(); 6 | 7 | const queue: (TreeNode | null)[] = [root]; 8 | 9 | while (queue.length) { 10 | const curr = queue.shift()!; 11 | if (curr) { 12 | if (set.has(k - curr.val)) { 13 | return true; 14 | } 15 | set.add(curr.val); 16 | queue.push(curr.left, curr.right); 17 | } 18 | } 19 | 20 | return false; 21 | } 22 | 23 | // JS 24 | // Runtime: 120 ms, faster than 48.77% of JavaScript online submissions for Two Sum IV - Input is a BST. 25 | // Memory Usage: 47.5 MB, less than 83.00% of JavaScript online submissions for Two Sum IV - Input is a BST. 26 | // var findTarget = function (root, k) { 27 | // const set = new Set(); 28 | 29 | // const queue = [root]; 30 | 31 | // while (queue.length) { 32 | // const curr = queue.shift(); 33 | // if (curr) { 34 | // if (set.has(k - curr.val)) { 35 | // return true; 36 | // } 37 | // set.add(curr.val); 38 | // queue.push(curr.left, curr.right); 39 | // } 40 | // } 41 | 42 | // return false; 43 | // }; 44 | -------------------------------------------------------------------------------- /src/problems/658.Find-K-Closest-Elements.ts: -------------------------------------------------------------------------------- 1 | // Window 2 | // O(n) 3 | function findClosestElements(arr: number[], k: number, x: number): number[] { 4 | let left = 0; 5 | let right = arr.length - 1; 6 | 7 | while (right - left >= k) { 8 | x - arr[left] <= arr[right] - x ? right-- : left++; 9 | } 10 | 11 | return arr.slice(left, right + 1); 12 | } 13 | 14 | // Distance Sort 15 | // O(nlogn) 16 | // function findClosestElements(arr: number[], k: number, x: number): number[] { 17 | // const map: { [key: string]: number } = {}; 18 | 19 | // arr.forEach((num) => { 20 | // map[num] = Math.abs(x - num); 21 | // }); 22 | 23 | // const sorted = [...arr].sort((a, b) => map[a] - map[b]); 24 | // const res = sorted.slice(0, k).sort((a, b) => a - b); 25 | // return res; 26 | // } 27 | -------------------------------------------------------------------------------- /src/problems/665.Non-decreasing-Array.ts: -------------------------------------------------------------------------------- 1 | function checkPossibility(nums: number[]): boolean { 2 | let i = 0; 3 | let count = 0; 4 | 5 | while (i < nums.length - 1 && count < 2) { 6 | if (nums[i] > nums[i + 1]) { 7 | if (i > 0) { 8 | if (nums[i - 1] > nums[i + 1]) { 9 | nums[i + 1] = nums[i]; 10 | } 11 | } 12 | count++; 13 | } 14 | i++; 15 | } 16 | 17 | return count < 2; 18 | } 19 | -------------------------------------------------------------------------------- /src/problems/667.Beautiful-Arrangement-II.ts: -------------------------------------------------------------------------------- 1 | function constructArray(n: number, k: number): number[] { 2 | let res = Array.from({ length: n }, (_, i) => i + 1); 3 | for (let i = 1; i < k; i++) { 4 | const x = res.slice(0, i); 5 | const y = res.slice(i); 6 | res = [...x, ...y.reverse()]; 7 | } 8 | return res; 9 | } 10 | -------------------------------------------------------------------------------- /src/problems/671.Second-Minimum-Node-In-a-Binary-Tree.ts: -------------------------------------------------------------------------------- 1 | function findSecondMinimumValue(root: TreeNode | null): number { 2 | if (!root) return -1; 3 | let min: number = root.val; 4 | let res: number = Infinity; 5 | 6 | const traverse = (node: TreeNode | null) => { 7 | if (!node) return; 8 | 9 | if (node.val === min) { 10 | traverse(node.left); 11 | traverse(node.right); 12 | } else if (node.val > min && node.val < res) { 13 | res = node.val; 14 | } 15 | }; 16 | 17 | traverse(root); 18 | 19 | return res === Infinity ? -1 : res; 20 | } 21 | -------------------------------------------------------------------------------- /src/problems/682.Baseball-Game.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | function calPoints(ops: string[]): number { 3 | const stack: number[] = []; 4 | 5 | for (let i = 0; i < ops.length; i++) { 6 | if (ops[i] === '+') { 7 | stack.push(stack[stack.length - 2] + stack[stack.length - 1]); 8 | } else if (ops[i] === 'D') { 9 | stack.push(2 * stack[stack.length - 1]); 10 | } else if (ops[i] === 'C') { 11 | stack.pop(); 12 | } else { 13 | stack.push(Number(ops[i])); 14 | } 15 | } 16 | 17 | return stack.reduce((acc, curr) => acc + curr, 0); 18 | } 19 | 20 | // JS 21 | // var calPoints = function (ops) { 22 | // const stack = []; 23 | 24 | // for (let i = 0; i < ops.length; i++) { 25 | // if (ops[i] === '+') { 26 | // stack.push(stack[stack.length - 2] + stack[stack.length - 1]); 27 | // } else if (ops[i] === 'D') { 28 | // stack.push(2 * stack[stack.length - 1]); 29 | // } else if (ops[i] === 'C') { 30 | // stack.pop(); 31 | // } else { 32 | // stack.push(Number(ops[i])); 33 | // } 34 | // } 35 | 36 | // return stack.reduce((acc, curr) => acc + curr, 0); 37 | // }; 38 | -------------------------------------------------------------------------------- /src/problems/684-Redundant-Connection.ts: -------------------------------------------------------------------------------- 1 | function findRedundantConnection(edges: number[][]): number[] { 2 | const uf: { [key: string]: number } = {}; 3 | 4 | const find = (x: number): number => { 5 | if (!uf[x]) { 6 | uf[x] = x; 7 | } 8 | 9 | return uf[x] === x ? x : uf[find(x)]; 10 | }; 11 | 12 | const union = (a: number, b: number): void => { 13 | uf[find(a)] = uf[find(b)]; 14 | }; 15 | 16 | for (const edge of edges) { 17 | const [u, v] = edge; 18 | 19 | if (find(u) === find(v)) return edge; 20 | 21 | union(u, v); 22 | } 23 | 24 | return []; 25 | } 26 | -------------------------------------------------------------------------------- /src/problems/687.Longest-Univalue-Path.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | function longestUnivaluePath(root: TreeNode | null): number { 3 | let res = 0; 4 | 5 | const traverse = (node: TreeNode | null, value?: number) => { 6 | if (!node) return 0; 7 | const left = traverse(node.left, node.val); 8 | const right = traverse(node.right, node.val); 9 | res = Math.max(res, left + right); 10 | return node.val === value ? Math.max(left, right) + 1 : 0; 11 | }; 12 | 13 | traverse(root); 14 | return res; 15 | } 16 | 17 | // JS 18 | // Runtime: 240 ms, faster than 96.33% of JavaScript online submissions for Longest Univalue Path. 19 | // Memory Usage: 59.6 MB, less than 52.29% of JavaScript online submissions for Longest Univalue Path. 20 | // var longestUnivaluePath = function (root) { 21 | // let res = 0; 22 | 23 | // const traverse = (node, value) => { 24 | // if (!node) return 0; 25 | // const left = traverse(node.left, node.val); 26 | // const right = traverse(node.right, node.val); 27 | // res = Math.max(res, left + right); 28 | // return node.val === value ? Math.max(left, right) + 1 : 0; 29 | // }; 30 | 31 | // traverse(root); 32 | // return res; 33 | // }; 34 | -------------------------------------------------------------------------------- /src/problems/695.Max-Area-of-Island.ts: -------------------------------------------------------------------------------- 1 | const dirs: [number, number][] = [ 2 | [-1, 0], 3 | [0, 1], 4 | [1, 0], 5 | [0, -1], 6 | ]; 7 | 8 | function maxAreaOfIsland(grid: number[][]): number { 9 | let res = 0; 10 | 11 | const sink = (x: number, y: number): number => { 12 | if ( 13 | x < 0 || 14 | x >= grid.length || 15 | y < 0 || 16 | y >= grid[0].length || 17 | !grid[x][y] 18 | ) 19 | return 0; 20 | 21 | grid[x][y] = 0; 22 | return dirs.reduce((prev, [a, b]) => prev + sink(a + x, b + y), 1); 23 | }; 24 | 25 | for (let i = 0; i < grid.length; i++) { 26 | for (let j = 0; j < grid[0].length; j++) { 27 | if (grid[i][j]) res = Math.max(res, sink(i, j)); 28 | } 29 | } 30 | 31 | return res; 32 | } 33 | -------------------------------------------------------------------------------- /src/problems/70.Climbing-Stairs.ts: -------------------------------------------------------------------------------- 1 | function isSubsequence(s: string, t: string): boolean { 2 | let j = 0; 3 | for (let i = 0; i < t.length && j < s.length; i++) { 4 | if (t[i] === s[j]) j++; 5 | } 6 | 7 | return j === s.length; 8 | } 9 | -------------------------------------------------------------------------------- /src/problems/701-Insert-into-a-Binary-Search-Tree.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | // Runtime: 128 ms, faster than 100.00% of TypeScript online submissions for Insert into a Binary Search Tree. 3 | // Memory Usage: 46.9 MB, less than 42.86% of TypeScript online submissions for Insert into a Binary Search Tree. 4 | function insertIntoBST(root: TreeNode | null, val: number): TreeNode | null { 5 | if (root === null) return new TreeNode(val); 6 | 7 | if (root.val > val) root.left = insertIntoBST(root.left, val); 8 | else root.right = insertIntoBST(root.right, val); 9 | 10 | return root; 11 | } 12 | 13 | // JS 14 | // Runtime: 120 ms, faster than 86.92% of JavaScript online submissions for Insert into a Binary Search Tree. 15 | // Memory Usage: 46.7 MB, less than 22.90% of JavaScript online submissions for Insert into a Binary Search Tree. 16 | // var insertIntoBST = function (root, val) { 17 | // if (root === null) return new TreeNode(val); 18 | 19 | // if (root.val > val) root.left = insertIntoBST(root.left, val); 20 | // else root.right = insertIntoBST(root.right, val); 21 | 22 | // return root; 23 | // }; 24 | -------------------------------------------------------------------------------- /src/problems/701.Insert-into-a-Binary-Search-Tree.ts: -------------------------------------------------------------------------------- 1 | // JS 2 | // Runtime: 128 ms, faster than 67.91% of JavaScript online submissions for Insert into a Binary Search Tree. 3 | // Memory Usage: 46.2 MB, less than 94.12% of JavaScript online submissions for Insert into a Binary Search Tree. 4 | var insertIntoBST = function (root, val) { 5 | if (!root) return new TreeNode(val); 6 | 7 | if (val < root.val) root.left = insertIntoBST(root.left, val); 8 | else root.right = insertIntoBST(root.right, val); 9 | 10 | return root; 11 | }; 12 | 13 | // TS 14 | // Runtime: 128 ms, faster than 92.31% of TypeScript online submissions for Insert into a Binary Search Tree. 15 | // Memory Usage: 46.8 MB, less than 100.00% of TypeScript online submissions for Insert into a Binary Search Tree. 16 | function insertIntoBST(root: TreeNode | null, val: number): TreeNode | null { 17 | if (!root) return new TreeNode(val); 18 | 19 | if (val < root.val) root.left = insertIntoBST(root.left, val); 20 | else root.right = insertIntoBST(root.right, val); 21 | 22 | return root; 23 | } 24 | -------------------------------------------------------------------------------- /src/problems/704-Binary-Search.ts: -------------------------------------------------------------------------------- 1 | // Binary Search 2 | // Runtime: 156 ms, faster than 5.70% of JavaScript online submissions for Binary Search. 3 | // Memory Usage: 40 MB, less than 33.97% of JavaScript online submissions for Binary Search. 4 | 5 | function search(nums: number[], target: number): number { 6 | let l = 0; 7 | let r = nums.length - 1; 8 | 9 | while (l < r) { 10 | let mid = Math.floor((l + r) / 2); 11 | if (nums[mid] < target) l = mid + 1; 12 | else r = mid; 13 | } 14 | 15 | return nums[l] === target ? l : -1; 16 | } 17 | -------------------------------------------------------------------------------- /src/problems/705-Design-HashSet.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 180 ms, faster than 85.27% of JavaScript online submissions for Design HashSet. 2 | // Memory Usage: 45.3 MB, less than 6.67% of JavaScript online submissions for Design HashSet. 3 | 4 | type Hash = { 5 | [key: string]: true | undefined; 6 | }; 7 | 8 | class MyHashSet { 9 | private hash: Hash = {}; 10 | 11 | constructor() { 12 | this.hash = {}; 13 | } 14 | 15 | add(key: number): void { 16 | this.hash[key] = true; 17 | } 18 | 19 | remove(key: number): void { 20 | delete this.hash[key]; 21 | } 22 | 23 | contains(key: number): boolean { 24 | return !!this.hash[key]; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/problems/713-Subarray-Product-Less-Than-K.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | // Runtime: 100 ms, faster than 100.00% of TypeScript online submissions for Subarray Product Less Than K. 3 | // Memory Usage: 47.6 MB, less than 12.50% of TypeScript online submissions for Subarray Product Less Than K. 4 | function numSubarrayProductLessThanK(nums: number[], k: number): number { 5 | let left = 0; 6 | let right = 0; 7 | let prod = 1; 8 | let res = 0; 9 | 10 | while (right < nums.length) { 11 | prod *= nums[right]; 12 | 13 | while (prod >= k && left < right) { 14 | prod /= nums[left]; 15 | left++; 16 | } 17 | 18 | if (prod < k) { 19 | res += right - left + 1; 20 | } 21 | right++; 22 | } 23 | return res; 24 | } 25 | // JS 26 | // Runtime: 112 ms, faster than 34.00% of JavaScript online submissions for Subarray Product Less Than K. 27 | // Memory Usage: 47.7 MB, less than 5.00% of JavaScript online submissions for Subarray Product Less Than K. 28 | // var numSubarrayProductLessThanK = function (nums, k) { 29 | // let left = 0; 30 | // let right = 0; 31 | // let prod = 1; 32 | // let res = 0; 33 | 34 | // while (right < nums.length) { 35 | // prod *= nums[right]; 36 | 37 | // while (prod >= k && left < right) { 38 | // prod /= nums[left]; 39 | // left++; 40 | // } 41 | 42 | // if (prod < k) { 43 | // res += right - left + 1; 44 | // } 45 | // right++; 46 | // } 47 | // return res; 48 | // }; 49 | -------------------------------------------------------------------------------- /src/problems/714-Best-Time-to-Buy-and-Sell-Stock-with-Transaction-Fee.ts: -------------------------------------------------------------------------------- 1 | function maxProfit(prices: number[], fee: number): number { 2 | let buying = 0; 3 | let selling = -prices[0]; 4 | 5 | for (let i = 1; i < prices.length; i++) { 6 | buying = Math.max(buying, selling + prices[i] - fee); 7 | selling = Math.max(selling, buying - prices[i]); 8 | } 9 | 10 | return buying; 11 | } 12 | -------------------------------------------------------------------------------- /src/problems/729.My-Calendar-I.ts: -------------------------------------------------------------------------------- 1 | class MyCalendar { 2 | intervals: [number, number][]; 3 | constructor() { 4 | this.intervals = []; 5 | } 6 | 7 | insert(start: number, end: number, index: number): void { 8 | this.intervals.splice(index, 0, [start, end]); 9 | } 10 | 11 | book(start: number, end: number): boolean { 12 | let i = 0; 13 | while (i < this.intervals.length && end < this.intervals[i][1]) { 14 | const [a, b] = this.intervals[i]; 15 | 16 | if (start <= a && end >= b) return false; // Outer 17 | if (start >= a && end <= b) return false; // Inner 18 | if (start <= a && end > a) return false; // A 19 | if (start < b && end >= b) return false; // B 20 | i++; 21 | } 22 | 23 | this.insert(start, end, i); 24 | 25 | return true; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/problems/73.Set-Matrix-Zeroes.ts: -------------------------------------------------------------------------------- 1 | function setZeroes(matrix: number[][]): void { 2 | const rows: Set = new Set([]); 3 | const columns: Set = new Set([]); 4 | 5 | for (let i = 0; i < matrix.length; i++) { 6 | for (let j = 0; j < matrix[0].length; j++) { 7 | if (!matrix[i][j]) { 8 | rows.add(i); 9 | columns.add(j); 10 | } 11 | } 12 | } 13 | 14 | for (let i = 0; i < matrix.length; i++) { 15 | for (let j = 0; j < matrix[0].length; j++) { 16 | if (rows.has(i) || columns.has(j)) { 17 | matrix[i][j] = 0; 18 | } 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/problems/739.Daily-Temperatures.ts: -------------------------------------------------------------------------------- 1 | function dailyTemperatures(temperatures: number[]): number[] { 2 | const res: number[] = Array(temperatures.length).fill(0); 3 | const stack: [number, number][] = []; // [temp,index] 4 | 5 | let i = 0; 6 | while (i < temperatures.length) { 7 | while (stack.length && temperatures[i] > stack[stack.length - 1][0]) { 8 | const [, stackI] = stack.pop()!; 9 | res[stackI] = i - stackI; 10 | } 11 | stack.push([temperatures[i], i]); 12 | i++; 13 | } 14 | 15 | return res; 16 | } 17 | -------------------------------------------------------------------------------- /src/problems/746-Min-Cost-Climbing-Stairs.ts: -------------------------------------------------------------------------------- 1 | function minCostClimbingStairs(cost: number[]): number { 2 | for (let i = 2; i < cost.length; i++) { 3 | cost[i] += Math.min(cost[i - 2], cost[i - 1]); 4 | } 5 | 6 | return Math.min(cost[cost.length - 1], cost[cost.length - 2]); 7 | } 8 | -------------------------------------------------------------------------------- /src/problems/748.Shortest-Completing-Word.ts: -------------------------------------------------------------------------------- 1 | // Removes spaces, removes digits, transforms to lowerCase 2 | const converPlate = (s: string) => s.toLowerCase().replace(/\s|\d/g, ''); 3 | 4 | // Returns an object with the freccuencies 5 | // Example 1: spst => { s: 2, p: 1, t: 1 } 6 | const countLetters = (s: string) => { 7 | const hash: { [key: string]: number } = {}; 8 | for (const c of s) { 9 | hash[c] ? hash[c]++ : (hash[c] = 1); 10 | } 11 | 12 | return hash; 13 | }; 14 | 15 | // Returns true if the answer is correct 16 | const compareWords = ( 17 | plateArray: [string, number][], 18 | wordHash: { [key: string]: number } 19 | ) => { 20 | for (let i = 0; i < plateArray.length; i++) { 21 | const [key, value] = plateArray[i]; 22 | if (!(key in wordHash) || value > wordHash[key]) return false; 23 | } 24 | return true; 25 | }; 26 | 27 | function shortestCompletingWord(licensePlate: string, words: string[]): string { 28 | words.sort((a, b) => a.length - b.length); 29 | const lowerPlate = converPlate(licensePlate); 30 | const plateHash = countLetters(lowerPlate); 31 | const plateArray = Object.entries(plateHash); // Easier to iterate 32 | 33 | for (const word of words) { 34 | const wordHash = countLetters(word); 35 | if (compareWords(plateArray, wordHash)) return word; 36 | } 37 | 38 | return ''; 39 | } 40 | -------------------------------------------------------------------------------- /src/problems/763-Partition-Labels.ts: -------------------------------------------------------------------------------- 1 | function partitionLabels(S: string): number[] { 2 | const last: number[] = new Array(26).fill(-1); 3 | 4 | S.split('').forEach((char, i) => { 5 | last[char.charCodeAt(0) - 97] = i; 6 | }); 7 | 8 | const partitions = []; 9 | let anchor = 0; 10 | let end = 0; 11 | 12 | for (let i = 0; i < S.length; i++) { 13 | end = Math.max(end, last[S.charCodeAt(i) - 'a'.charCodeAt(0)]); 14 | if (i === end) { 15 | partitions.push(i - anchor + 1); 16 | anchor = i + 1; 17 | } 18 | } 19 | 20 | return partitions; 21 | } 22 | -------------------------------------------------------------------------------- /src/problems/775.Global-and-Local-Inversions.ts: -------------------------------------------------------------------------------- 1 | // // TS 2 | // // 0(n^2) 3 | // function isIdealPermutation(A: number[]): boolean { 4 | // for (let i = 0; i < A.length; i++) { 5 | // for (let j = i + 2; j < A.length; j++) { 6 | // if (A[i] > A[j]) return false; 7 | // } 8 | // } 9 | 10 | // return true; 11 | // } 12 | 13 | // // 0(n) 14 | function isIdealPermutation(A: number[]): boolean { 15 | let max = -1; 16 | for (let i = 0; i < A.length - 2; i++) { 17 | max = Math.max(max, A[i]); 18 | if (max > A[i + 2]) return false; 19 | } 20 | 21 | return true; 22 | } 23 | 24 | // // JS 25 | // // 0(n^2) 26 | // var isIdealPermutation = function (A) { 27 | // for (let i = 0; i < A.length; i++) { 28 | // for (let j = i + 2; j < A.length; j++) { 29 | // if (A[i] > A[j]) return false; 30 | // } 31 | // } 32 | 33 | // return true; 34 | // }; 35 | 36 | // // 0(n) 37 | // var isIdealPermutation = function (A) { 38 | // let max = -1; 39 | // for (let i = 0; i < A.length - 2; i++) { 40 | // max = Math.max(max, A[i]); 41 | // if (max > A[i + 2]) return false; 42 | // } 43 | 44 | // return true; 45 | // }; 46 | -------------------------------------------------------------------------------- /src/problems/78.Subsets.ts: -------------------------------------------------------------------------------- 1 | function subsets(nums: number[]): number[][] { 2 | const res: number[][] = [[]]; 3 | 4 | for (let i = 0; i < nums.length; i++) { 5 | const curr = nums[i]; 6 | const aux = res.map((val) => [...val, curr]); 7 | res.push(...aux); 8 | } 9 | 10 | return res; 11 | } 12 | -------------------------------------------------------------------------------- /src/problems/783.Minimum-Distance-Between-BST-Nodes.ts: -------------------------------------------------------------------------------- 1 | function minDiffInBST(root: TreeNode | null): number { 2 | let prev: number | undefined; 3 | let res = Infinity; 4 | 5 | const inOrderTraverse = (node: TreeNode | null) => { 6 | if (!node) return; 7 | inOrderTraverse(node.left); 8 | if (prev !== undefined) { 9 | res = Math.min(node.val - prev, res); 10 | } 11 | prev = node.val; 12 | inOrderTraverse(node.right); 13 | }; 14 | inOrderTraverse(root); 15 | 16 | return res; 17 | } 18 | -------------------------------------------------------------------------------- /src/problems/795.Number-of-Subarrays-with-Bounded-Maximum.ts: -------------------------------------------------------------------------------- 1 | function numSubarrayBoundedMax( 2 | nums: number[], 3 | left: number, 4 | right: number 5 | ): number { 6 | let res = 0; 7 | let start = -1; 8 | let end = -1; 9 | 10 | for (let i = 0; i < nums.length; i++) { 11 | const curr = nums[i] > right ? 'RESET' : nums[i] >= left ? 'NEEDED' : 'OK'; 12 | 13 | switch (curr) { 14 | case 'OK': 15 | break; 16 | case 'NEEDED': 17 | end = i; 18 | break; 19 | case 'RESET': 20 | start = i; 21 | end = i; 22 | break; 23 | } 24 | 25 | res += end - start; 26 | } 27 | 28 | return res; 29 | } 30 | -------------------------------------------------------------------------------- /src/problems/797-All-Paths-From-Source-to-Target.ts: -------------------------------------------------------------------------------- 1 | // JS 2 | // Runtime: 120 ms, faster than 59.28% of JavaScript online submissions for All Paths From Source to Target. 3 | // Memory Usage: 47.2 MB, less than 18.57% of JavaScript online submissions for All Paths From Source to Target. 4 | var allPathsSourceTarget = function (graph) { 5 | const res = []; 6 | 7 | const dfs = (i, stack) => { 8 | if (stack.includes(i)) return; 9 | 10 | stack.push(i); 11 | 12 | if (i === graph.length - 1) res.push(stack); 13 | else graph[i].forEach((node) => dfs(node, [...stack])); 14 | }; 15 | 16 | dfs(0, []); 17 | return res; 18 | }; 19 | 20 | // TS 21 | // Runtime: 116 ms, faster than 80.00% of TypeScript online submissions for All Paths From Source to Target. 22 | // Memory Usage: 47.6 MB, less than 20.00% of TypeScript online submissions for All Paths From Source to Target. 23 | function allPathsSourceTarget(graph: number[][]): number[][] { 24 | const res: number[][] = []; 25 | 26 | const dfs = (i: number, stack: number[]) => { 27 | if (stack.includes(i)) return; 28 | 29 | stack.push(i); 30 | 31 | if (i === graph.length - 1) res.push(stack); 32 | else graph[i].forEach((node) => dfs(node, [...stack])); 33 | }; 34 | 35 | dfs(0, []); 36 | return res; 37 | } 38 | -------------------------------------------------------------------------------- /src/problems/802-Find-Eventual-Safe-States.ts: -------------------------------------------------------------------------------- 1 | function eventualSafeNodes(graph: number[][]): number[] { 2 | const res: number[] = []; 3 | const memo: { [key: string]: boolean } = {}; 4 | 5 | function traverse(node: number, visited: { [key: string]: boolean }) { 6 | if (node in memo) { 7 | return memo[node]; 8 | } 9 | if (!graph[node].length) { 10 | return true; 11 | } 12 | if (visited[node]) { 13 | return false; 14 | } 15 | for (let i = 0; i < graph[node].length; i++) { 16 | visited[node] = true; 17 | 18 | if (!traverse(graph[node][i], { ...visited })) { 19 | memo[node] = false; 20 | return false; 21 | } 22 | } 23 | 24 | memo[node] = true; 25 | return true; 26 | } 27 | 28 | for (let i = 0; i < graph.length; i++) { 29 | if (graph[i].length === 0) { 30 | res.push(i); 31 | memo[i] = true; 32 | } else if (traverse(i, {})) { 33 | res.push(i); 34 | } 35 | } 36 | return res; 37 | } 38 | -------------------------------------------------------------------------------- /src/problems/820.Short-Encoding-of-Words.ts: -------------------------------------------------------------------------------- 1 | function minimumLengthEncoding(words: string[]): number { 2 | const set = new Set(words); 3 | for (const word of words) 4 | if (set.has(word)) 5 | for (let i = 1; i < word.length; i++) set.delete(word.slice(i)); 6 | return Array.from(set).join().length + 1; 7 | } 8 | -------------------------------------------------------------------------------- /src/problems/824-Goat-Latin.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 64 ms, faster than 92.40% of JavaScript online submissions for Goat Latin. 2 | // Memory Usage: 36.7 MB, less than 43.76% of JavaScript online submissions for Goat Latin. 3 | 4 | function toGoatLatin(S: string): string { 5 | const vowels: string[] = ['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']; 6 | return S.split(' ') 7 | .map((word, i) => 8 | vowels.includes(word[0]) 9 | ? `${word}ma${'a'.repeat(i + 1)}` 10 | : `${word.slice(1) + word[0]}ma${'a'.repeat(i + 1)}` 11 | ) 12 | .join(' '); 13 | } 14 | -------------------------------------------------------------------------------- /src/problems/841-Keys-and-Rooms.ts: -------------------------------------------------------------------------------- 1 | function canVisitAllRooms(rooms: number[][]): boolean { 2 | const keys = new Set(); 3 | const queue = [0]; 4 | 5 | while (queue.length) { 6 | const curr = queue.shift()!; 7 | 8 | if (!keys.has(curr)) { 9 | keys.add(curr); 10 | queue.push(...rooms[curr]); 11 | } 12 | } 13 | 14 | return keys.size === rooms.length; 15 | } 16 | -------------------------------------------------------------------------------- /src/problems/844.Backspace-String-Compare.ts: -------------------------------------------------------------------------------- 1 | const helper = (str: string) => { 2 | const stack: string[] = []; 3 | 4 | for (let i = 0; i < str.length; i++) { 5 | if (str.charAt(i) === '#') stack.pop(); 6 | else stack.push(str.charAt(i)); 7 | } 8 | 9 | return stack.join(''); 10 | }; 11 | 12 | function backspaceCompare(s: string, t: string): boolean { 13 | return helper(s) === helper(t); 14 | } 15 | -------------------------------------------------------------------------------- /src/problems/852-Peak-Index-in-a-Mountain-Array.ts: -------------------------------------------------------------------------------- 1 | // Binary Search 2 | // Runtime: 56 ms, faster than 99.69% of JavaScript online submissions for Peak Index in a Mountain Array. 3 | // Memory Usage: 37.5 MB, less than 5.88% of JavaScript online submissions for Peak Index in a Mountain Array 4 | 5 | function peakIndexInMountainArray(A: number[]): number { 6 | let right = A.length - 1; 7 | let left = 0; 8 | 9 | while (left < right) { 10 | const mid = Math.floor((left + right) / 2); 11 | if (A[mid] < A[mid + 1]) { 12 | left = mid + 1; 13 | } else { 14 | right = mid; 15 | } 16 | } 17 | 18 | return left; 19 | } 20 | 21 | // Math.max() 22 | // Runtime: 68 ms, faster than 84.05% of JavaScript online submissions for Peak Index in a Mountain Array. 23 | // Memory Usage: 37.7 MB, less than 5.88% of JavaScript online submissions for Peak Index in a Mountain Array. 24 | 25 | function peakIndexInMountainArray(A: number[]): number { 26 | return A.indexOf(Math.max(...A)); 27 | } 28 | -------------------------------------------------------------------------------- /src/problems/856.Score-of-Parentheses.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | // Runtime: 76 ms, faster than 100.00% of TypeScript online submissions for Score of Parentheses. 3 | // Memory Usage: 39.1 MB, less than 81.82% of TypeScript online submissions for Score of Parentheses. 4 | function scoreOfParentheses(S: string): number { 5 | const stack: number[] = []; 6 | let score = 0; 7 | 8 | for (let c of S) { 9 | if (c === '(') { 10 | stack.push(score); 11 | score = 0; 12 | } else score = stack.pop()! + Math.max(score * 2, 1); 13 | } 14 | return score; 15 | } 16 | 17 | // JS 18 | // Runtime: 72 ms, faster than 95.70% of JavaScript online submissions for Score of Parentheses. 19 | // Memory Usage: 38.9 MB, less than 12.90% of JavaScript online submissions for Score of Parentheses. 20 | // var scoreOfParentheses = function (S) { 21 | // const stack = []; 22 | // let score = 0; 23 | 24 | // for (let c of S) { 25 | // if (c === '(') { 26 | // stack.push(score); 27 | // score = 0; 28 | // } else score = stack.pop() + Math.max(score * 2, 1); 29 | // } 30 | // return score; 31 | // }; 32 | -------------------------------------------------------------------------------- /src/problems/86.Partition-List.ts: -------------------------------------------------------------------------------- 1 | // JS 2 | // No Extra Memory 3 | var partition = function (head, x) { 4 | const dummyLess = new ListNode(); 5 | const dummyMore = new ListNode(); 6 | 7 | let less = dummyLess; 8 | let more = dummyMore; 9 | 10 | while (head) { 11 | if (head.val < x) less = less.next = head; 12 | else more = more.next = head; 13 | head = head.next; 14 | } 15 | 16 | less.next = dummyMore.next; 17 | more.next = null; 18 | return dummyLess.next; 19 | }; 20 | 21 | // JS 22 | // Extra Memory 23 | // var partition = function (head, x) { 24 | // const dummyLess = new ListNode(); 25 | // const dummyMore = new ListNode(); 26 | 27 | // let less = dummyLess; 28 | // let more = dummyMore; 29 | 30 | // while (head) { 31 | // if (head.val < x) less = less.next = new ListNode(head.val); 32 | // else more = more.next = new ListNode(head.val); 33 | // head = head.next; 34 | // } 35 | 36 | // less.next = more.next; 37 | // return dummyLess.next; 38 | // }; 39 | -------------------------------------------------------------------------------- /src/problems/863.All-Nodes-Distance-K-in-Binary-Tree.ts: -------------------------------------------------------------------------------- 1 | function distanceK( 2 | root: TreeNode | null, 3 | target: TreeNode | null, 4 | K: number 5 | ): number[] { 6 | if (!root || !target) return []; 7 | 8 | const parentHash: { [key: string]: TreeNode | null } = {}; 9 | 10 | const visited = new Set(); 11 | 12 | const findTarget = (node: TreeNode | null, parent: TreeNode | null) => { 13 | if (!node || target.val in parentHash) return; 14 | parentHash[node.val] = parent; 15 | findTarget(node.left, node); 16 | findTarget(node.right, node); 17 | }; 18 | 19 | findTarget(root, null); 20 | 21 | let queue: TreeNode[] = [target]; 22 | 23 | while (K) { 24 | const newQueue: TreeNode[] = []; 25 | 26 | while (queue.length) { 27 | const curr = queue.shift()!; 28 | visited.add(curr.val); 29 | 30 | if (parentHash[curr.val] && !visited.has(parentHash[curr.val]!.val)) { 31 | newQueue.push(parentHash[curr.val]!); 32 | } 33 | 34 | if (curr.left && !visited.has(curr.left.val)) newQueue.push(curr.left); 35 | if (curr.right && !visited.has(curr.right.val)) newQueue.push(curr.right); 36 | } 37 | 38 | queue = newQueue; 39 | K--; 40 | } 41 | 42 | return queue.map((node) => node.val); 43 | } 44 | -------------------------------------------------------------------------------- /src/problems/869.Reordered-Power-of-2.ts: -------------------------------------------------------------------------------- 1 | var reorderedPowerOf2 = function (N) { 2 | const set = new Set(); 3 | for (let cur = 1; cur < 10 ** 9; cur *= 2) set.add(String(cur)); 4 | 5 | const validate = (left: string, cur: string = '') => { 6 | if (left.length === 1) return set.has(cur + left[0]); 7 | for (let i = 0; i < left.length; i++) { 8 | const next = left.slice(0, i) + left.slice(i + 1); 9 | if (validate(next, cur + left[i])) return true; 10 | } 11 | return false; 12 | }; 13 | 14 | return validate(String(N)); 15 | }; 16 | -------------------------------------------------------------------------------- /src/problems/870.Advantage-Shuffle.ts: -------------------------------------------------------------------------------- 1 | function advantageCount(A: number[], B: number[]): number[] { 2 | const sortedA = [...A].sort((a, b) => a - b); 3 | const sortedB = [...B].sort((a, b) => a - b); 4 | const unused: number[] = []; 5 | const res: number[] = Array(A.length).fill(null); 6 | 7 | let i = 0; 8 | let j = 0; 9 | 10 | while (i < A.length) { 11 | if (sortedA[i] > sortedB[j]) { 12 | const index = B.indexOf(sortedB[j]); 13 | res[index] = sortedA[i]; 14 | B[index] = Infinity; 15 | j++; 16 | } else { 17 | unused.push(sortedA[i]); 18 | } 19 | 20 | i++; 21 | } 22 | 23 | for (let i = 0; i < A.length; i++) { 24 | if (res[i] === null) { 25 | res[i] = unused.pop()!; 26 | } 27 | } 28 | 29 | return res; 30 | } 31 | -------------------------------------------------------------------------------- /src/problems/88-Merge-Sorted-Array.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 72 ms, faster than 71.61% of JavaScript online submissions for Merge Sorted Array. 2 | // Memory Usage: 36.9 MB, less than 16.00% of JavaScript online submissions for Merge Sorted Array. 3 | 4 | function merge(nums1: number[], m: number, nums2: number[], n: number): void { 5 | const res = []; 6 | let i = 0; 7 | let j = 0; 8 | 9 | while (m - i && n - j) { 10 | if (nums1[i] < nums2[j]) { 11 | res.push(nums1[i]); 12 | i++; 13 | } else { 14 | res.push(nums2[j]); 15 | j++; 16 | } 17 | } 18 | 19 | while (m - i) { 20 | res.push(nums1[i]); 21 | i++; 22 | } 23 | 24 | while (n - j) { 25 | res.push(nums2[j]); 26 | j++; 27 | } 28 | 29 | res.forEach((num, index) => { 30 | nums1[index] = num; 31 | }); 32 | } 33 | -------------------------------------------------------------------------------- /src/problems/890.Find-and-Replace-Pattern.ts: -------------------------------------------------------------------------------- 1 | const findAndReplacePatternHelper = (word: string, pattern: string) => { 2 | const wHash: { [key: string]: string } = {}; 3 | const pHash: { [key: string]: string } = {}; 4 | 5 | for (let i = 0; i < pattern.length; i++) { 6 | const cW = word[i]; 7 | const cP = pattern[i]; 8 | 9 | if ( 10 | (cW in wHash && wHash[cW] !== cP) || 11 | (cP in pHash && pHash[cP] !== cW) 12 | ) { 13 | return false; 14 | } 15 | 16 | wHash[cW] = cP; 17 | pHash[cP] = cW; 18 | } 19 | 20 | return true; 21 | }; 22 | 23 | function findAndReplacePattern(words: string[], pattern: string): string[] { 24 | return words.filter((word) => findAndReplacePatternHelper(word, pattern)); 25 | } 26 | -------------------------------------------------------------------------------- /src/problems/905-Sort-Array-By-Parity.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 88 ms, faster than 87.75% of JavaScript online submissions for Sort Array By Parity. 2 | // Memory Usage: 38.6 MB, less than 80.78% of JavaScript online submissions for Sort Array By Parity. 3 | function sortArrayByParity(A: number[]): number[] { 4 | const res: number[] = []; 5 | A.forEach((val) => (val % 2 ? res.push(val) : res.unshift(val))); 6 | return res; 7 | } 8 | 9 | // Runtime: 524 ms, faster than 5.43% of JavaScript online submissions for Sort Array By Parity. 10 | // Memory Usage: 68.7 MB, less than 5.03% of JavaScript online submissions for Sort Array By Parity. 11 | function sortArrayByParity(A: number[]): number[] { 12 | return A.reduce((acc: number[], curr) => { 13 | return curr % 2 ? [...acc, curr] : [curr, ...acc]; 14 | }, []); 15 | } 16 | -------------------------------------------------------------------------------- /src/problems/916.Word-Subsets.ts: -------------------------------------------------------------------------------- 1 | const getFrequencies = (s: string): { [key: string]: number } => { 2 | const frequencies = {}; 3 | for (let i = 0; i < s.length; i++) { 4 | frequencies[s.charAt(i)] 5 | ? frequencies[s.charAt(i)]++ 6 | : (frequencies[s.charAt(i)] = 1); 7 | } 8 | return frequencies; 9 | }; 10 | 11 | function wordSubsets(A: string[], B: string[]): string[] { 12 | const hash: { [key: string]: number } = {}; 13 | 14 | B.forEach((b) => { 15 | const bFreqs = getFrequencies(b); 16 | Object.entries(bFreqs).forEach(([key, value]) => { 17 | !(key in hash) 18 | ? (hash[key] = value) 19 | : (hash[key] = Math.max(hash[key], value)); 20 | }); 21 | }); 22 | 23 | return A.filter((a) => { 24 | const aFreqs = getFrequencies(a); 25 | for (const [key, value] of Object.entries(hash)) { 26 | if (!(key in aFreqs) || value > aFreqs[key]) return false; 27 | } 28 | return true; 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /src/problems/92.Reverse-Linked-List-II.ts: -------------------------------------------------------------------------------- 1 | function reverseBetween( 2 | head: ListNode | null, 3 | left: number, 4 | right: number 5 | ): ListNode | null { 6 | const dummy = new ListNode(-1, head); 7 | let prev = dummy; 8 | let curr = head; 9 | let i = 1; 10 | while (curr && i < left) { 11 | prev = curr; 12 | curr = curr.next; 13 | i++; 14 | } 15 | 16 | const reverseHead = reverseBetweenHelper(curr, right - left + 1); 17 | prev!.next = reverseHead; 18 | return dummy.next; 19 | } 20 | 21 | const reverseBetweenHelper = (head: ListNode | null, steps: number) => { 22 | let prev: ListNode | null = null; 23 | let curr = head; 24 | 25 | while (curr && steps) { 26 | const next = curr.next; 27 | curr.next = prev; 28 | prev = curr; 29 | curr = next; 30 | steps--; 31 | } 32 | 33 | head!.next = curr; 34 | return prev; 35 | }; 36 | -------------------------------------------------------------------------------- /src/problems/921.Minimum-Add-to-Make-Parentheses-Valid.ts: -------------------------------------------------------------------------------- 1 | function minAddToMakeValid(s: string): number { 2 | const stack: string[] = []; 3 | 4 | for (let i = 0; i < s.length; i++) { 5 | if ( 6 | stack.length && 7 | s.charAt(i) === ')' && 8 | stack[stack.length - 1] === '(' 9 | ) { 10 | stack.pop(); 11 | } else { 12 | stack.push(s.charAt(i)); 13 | } 14 | } 15 | 16 | return stack.length; 17 | } 18 | -------------------------------------------------------------------------------- /src/problems/923.3Sum-With-Multiplicity.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | function threeSumMulti(arr: number[], target: number): number { 3 | const map = new Map(); 4 | const mod = 1000000007; 5 | let res = 0; 6 | 7 | for (let i = 0; i < arr.length; i++) { 8 | res = (res + (map.get(target - arr[i]) || 0)) % mod; 9 | 10 | for (let j = 0; j < i; j++) { 11 | let temp = arr[i] + arr[j]; 12 | map.set(temp, (map.get(temp) || 0) + 1); 13 | } 14 | } 15 | 16 | return res; 17 | } 18 | 19 | // JS 20 | // var threeSumMulti = function (arr, target) { 21 | // const map = new Map(); 22 | // const mod = 1000000007; 23 | // let res = 0; 24 | 25 | // for (let i = 0; i < arr.length; i++) { 26 | // res = (res + (map.get(target - arr[i]) || 0)) % mod; 27 | 28 | // for (let j = 0; j < i; j++) { 29 | // let temp = arr[i] + arr[j]; 30 | // map.set(temp, (map.get(temp) || 0) + 1); 31 | // } 32 | // } 33 | 34 | // return res; 35 | // }; 36 | -------------------------------------------------------------------------------- /src/problems/926.Flip-String-to-Monotone-Increasing.ts: -------------------------------------------------------------------------------- 1 | function minFlipsMonoIncr(s: string): number { 2 | let ones = 0; 3 | let flips = 0; 4 | for (let i = 0; i < s.length; i++) { 5 | if (s.charAt(i) == '0') flips = Math.min(flips + 1, ones); 6 | else ones++; 7 | } 8 | return flips; 9 | } 10 | -------------------------------------------------------------------------------- /src/problems/931-Minimum-Falling-Path-Sum.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | // Runtime: 88 ms, faster than 100.00% of TypeScript online submissions for Minimum Falling Path Sum. 3 | // Memory Usage: 41.1 MB, less than 50.00% of TypeScript online submissions for Minimum Falling Path Sum. 4 | function minFallingPathSum(A: number[][]): number { 5 | const MAX_WIDTH = A[0].length; 6 | 7 | for (let i = 1; i < A.length; i++) { 8 | for (let j = 0; j < A[0].length; j++) { 9 | const start = Math.max(j - 1, 0); 10 | const end = Math.min(j + 2, MAX_WIDTH); 11 | A[i][j] += Math.min(...A[i - 1].slice(start, end)); 12 | } 13 | } 14 | 15 | return Math.min(...A[A.length - 1]); 16 | } 17 | 18 | // JS 19 | // Runtime: 108 ms, faster than 34.40% of JavaScript online submissions for Minimum Falling Path Sum. 20 | // Memory Usage: 40.6 MB, less than 24.80% of JavaScript online submissions for Minimum Falling Path Sum. 21 | // var minFallingPathSum = function (A) { 22 | // const MAX_WIDTH = A[0].length; 23 | 24 | // for (let i = 1; i < A.length; i++) { 25 | // for (let j = 0; j < A[0].length; j++) { 26 | // const start = Math.max(j - 1, 0); 27 | // const end = Math.min(j + 2, MAX_WIDTH); 28 | // A[i][j] += Math.min(...A[i - 1].slice(start, end)); 29 | // } 30 | // } 31 | 32 | // return Math.min(...A[A.length - 1]); 33 | // }; 34 | -------------------------------------------------------------------------------- /src/problems/94-Binary-Tree-Inorder-Traversal.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 68 ms, faster than 85.67% of JavaScript online submissions for Binary Tree Inorder Traversal. 2 | // Memory Usage: 37.1 MB, less than 5.03% of JavaScript online submissions for Binary Tree Inorder Traversal. 3 | 4 | function inorderTraversal(root: TreeNode | null): number[] { 5 | if (!root) return []; 6 | 7 | return [ 8 | ...inorderTraversal(root.left), 9 | root.val, 10 | ...inorderTraversal(root.right), 11 | ]; 12 | } 13 | -------------------------------------------------------------------------------- /src/problems/958.Check-Completeness-of-a-Binary-Tree.ts: -------------------------------------------------------------------------------- 1 | function isCompleteTree(root: TreeNode | null): boolean { 2 | let seenNull = false; 3 | let queue: (TreeNode | null)[] = [root]; 4 | 5 | while (queue.length) { 6 | const next: (TreeNode | null)[] = []; 7 | 8 | for (let node of queue) { 9 | if (!node) seenNull = true; 10 | else { 11 | if (seenNull) return false; 12 | next.push(node.left); 13 | next.push(node.right); 14 | } 15 | } 16 | console.log(next); 17 | queue = next; 18 | } 19 | return true; 20 | } 21 | -------------------------------------------------------------------------------- /src/problems/965-Univalued-Binary-Tree.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | function isUnivalTree(root: TreeNode | null): boolean { 3 | if (!root) return true; 4 | 5 | const traverse = (node: TreeNode | null): boolean => { 6 | if (!node) return true; 7 | if (root.val !== node.val) return false; 8 | return traverse(node.left) && traverse(node.right); 9 | }; 10 | 11 | return traverse(root); 12 | } 13 | 14 | // JS 15 | // var isUnivalTree = function (root) { 16 | // if (!root) return true; 17 | 18 | // const traverse = (node) => { 19 | // if (!node) return true; 20 | // if (root.val !== node.val) return false; 21 | // return traverse(node.left) && traverse(node.right); 22 | // }; 23 | 24 | // return traverse(root); 25 | // }; 26 | -------------------------------------------------------------------------------- /src/problems/966.Vowel-Spellchecker.ts: -------------------------------------------------------------------------------- 1 | const regex = /[aeiou]/g; 2 | 3 | function spellchecker(wordlist: string[], queries: string[]): string[] { 4 | const orig = new Set(wordlist); 5 | const lower = new Map(); 6 | const mask = new Map(); 7 | 8 | for (let i = wordlist.length - 1; ~i; i--) { 9 | const word = wordlist[i]; 10 | const wlow = word.toLowerCase(); 11 | lower.set(wlow, word); 12 | mask.set(wlow.replace(regex, '*'), word); 13 | } 14 | 15 | return queries.map((query) => { 16 | if (orig.has(query)) return query; 17 | const qlow = query.toLowerCase(); 18 | const qmask = qlow.replace(regex, '*'); 19 | return lower.get(qlow) || mask.get(qmask) || ''; 20 | }); 21 | } 22 | -------------------------------------------------------------------------------- /src/problems/967-Numbers-With-Same-Consecutive-Differences.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 80 ms, faster than 89.83% of JavaScript online submissions for Numbers With Same Consecutive Differences. 2 | // Memory Usage: 39 MB, less than 10.17% of JavaScript online submissions for Numbers With Same Consecutive Differences. 3 | 4 | function numsSameConsecDiff(N: number, K: number): number[] { 5 | // return [0,1,2,3,4,5,6,7,8,9] 6 | if (N === 1) 7 | return Array(10) 8 | .fill(null) 9 | .map((_, i) => i); 10 | 11 | const res: number[] = []; 12 | 13 | const helper = (s: string) => { 14 | if (s.length === 0) { 15 | for (let i = 1; i <= 9; i++) helper(s + i); 16 | } 17 | 18 | if (s.length < N) { 19 | for (let i = 0; i <= 9; i++) { 20 | if (Math.abs(parseInt(s[s.length - 1]) - i) === K) helper(s + i); 21 | } 22 | } 23 | 24 | if (s.length === N) { 25 | if (Math.abs(parseInt(s[N - 1]) - parseInt(s[N - 2])) === K) { 26 | res.push(parseInt(s)); 27 | } 28 | } 29 | }; 30 | 31 | helper(''); 32 | return res; 33 | } 34 | -------------------------------------------------------------------------------- /src/problems/97.Interleaving-String.ts: -------------------------------------------------------------------------------- 1 | function isInterleave(s1: string, s2: string, s3: string): boolean { 2 | if (s3.length !== s1.length + s2.length) return false; 3 | 4 | const dp: boolean[][] = Array(s1.length + 1) 5 | .fill(null) 6 | .map(() => Array(s2.length + 1)); 7 | 8 | for (let i = 0; i <= s1.length; i++) { 9 | for (let j = 0; j <= s2.length; j++) { 10 | if (i == 0 && j == 0) { 11 | dp[i][j] = true; 12 | } else if (i == 0) { 13 | dp[i][j] = dp[i][j - 1] && s2.charAt(j - 1) == s3.charAt(i + j - 1); 14 | } else if (j == 0) { 15 | dp[i][j] = dp[i - 1][j] && s1.charAt(i - 1) == s3.charAt(i + j - 1); 16 | } else { 17 | dp[i][j] = 18 | (dp[i - 1][j] && s1.charAt(i - 1) == s3.charAt(i + j - 1)) || 19 | (dp[i][j - 1] && s2.charAt(j - 1) == s3.charAt(i + j - 1)); 20 | } 21 | } 22 | } 23 | 24 | return dp[s1.length][s2.length]; 25 | } 26 | -------------------------------------------------------------------------------- /src/problems/971.Flip-Binary-Tree-To-Match-Preorder-Traversal.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | function flipMatchVoyage(root: TreeNode | null, voyage: number[]): number[] { 3 | const res: number[] = []; 4 | 5 | const preorderTraverse = (node: TreeNode | null): boolean => { 6 | if (!node) return true; 7 | if (voyage[0] !== node.val) return false; 8 | voyage.shift(); 9 | 10 | if (node.left && node?.left.val !== voyage[0]) { 11 | res.push(node.val); 12 | return preorderTraverse(node.right) && preorderTraverse(node.left); 13 | } 14 | return preorderTraverse(node.left) && preorderTraverse(node.right); 15 | }; 16 | 17 | return preorderTraverse(root) ? res : [-1]; 18 | } 19 | 20 | // JS 21 | // var flipMatchVoyage = function (root, voyage) { 22 | // const res = []; 23 | 24 | // const preorderTraverse = (node) => { 25 | // if (!node) return true; 26 | // if (voyage[0] !== node.val) return false; 27 | // voyage.shift(); 28 | 29 | // if (node.left && node.left.val !== voyage[0]) { 30 | // [node.left, node.right] = [node.right, node.left]; // SWAP 31 | // res.push(node.val); 32 | // } 33 | // return preorderTraverse(node.left) && preorderTraverse(node.right); 34 | // }; 35 | 36 | // return preorderTraverse(root) ? res : [-1]; 37 | // }; 38 | -------------------------------------------------------------------------------- /src/problems/977-Squares-of-a-Sorted-Array.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 124 ms, faster than 61.36% of JavaScript online submissions for Squares of a Sorted Array. 2 | // Memory Usage: 44.1 MB, less than 7.69% of JavaScript online submissions for Squares of a Sorted Array. 3 | 4 | function sortedSquares(A: number[]): number[] { 5 | return A.map((num) => num ** 2).sort((a, b) => a - b); 6 | } 7 | -------------------------------------------------------------------------------- /src/problems/977.Squares-of-a-Sorted-Array.ts: -------------------------------------------------------------------------------- 1 | var sortedSquares = function (nums) { 2 | return nums.map((num) => num ** 2).sort((a, b) => a - b); 3 | }; 4 | -------------------------------------------------------------------------------- /src/problems/983-Minimum-Cost-For-Tickets.ts: -------------------------------------------------------------------------------- 1 | // Runtime: 128 ms, faster than 14.85% of JavaScript online submissions for Minimum Cost For Tickets. 2 | // Memory Usage: 36.5 MB, less than 89.52% of JavaScript online submissions for Minimum Cost For Tickets. 3 | 4 | function mincostTickets(days: number[], costs: number[]): number { 5 | const dp = new Array(days[days.length - 1] + 1); 6 | dp[0] = 0; 7 | for (let i = 1; i < dp.length; i++) { 8 | if (days.includes(i)) { 9 | dp[i] = Math.min( 10 | dp[i - 1] + costs[0], 11 | dp[Math.max(0, i - 7)] + costs[1], 12 | dp[Math.max(0, i - 30)] + costs[2] 13 | ); 14 | } else { 15 | dp[i] = dp[i - 1]; 16 | } 17 | } 18 | 19 | return dp.pop(); 20 | } 21 | -------------------------------------------------------------------------------- /src/problems/990-Satisfiability-of-Equality-Equations.ts: -------------------------------------------------------------------------------- 1 | function equationsPossible(equations: string[]): boolean { 2 | const uf: { [key: string]: string } = {}; 3 | 4 | equations.forEach(([char1, , , char2]) => { 5 | if (!uf[char1]) uf[char1] = char1; 6 | if (!uf[char2]) uf[char2] = char2; 7 | }); 8 | 9 | const find = (x: string): string => { 10 | return uf[x] === x ? x : find(uf[x]); 11 | }; 12 | 13 | const union = (a: string, b: string) => { 14 | uf[find(a)] = uf[find(b)]; 15 | }; 16 | 17 | equations.forEach(([a, s, , b]) => { 18 | if (s === '=') union(a, b); 19 | }); 20 | 21 | for (let i = 0; i < equations.length; i++) { 22 | const [a, s, , b] = equations[i]; 23 | if (s === '!') { 24 | if (find(uf[a]) === find(uf[b])) return false; 25 | } 26 | } 27 | 28 | return true; 29 | } 30 | -------------------------------------------------------------------------------- /src/problems/991.Broken-Calculator.ts: -------------------------------------------------------------------------------- 1 | function brokenCalc(X: number, Y: number): number { 2 | if (X >= Y) return X - Y; 3 | if (!(Y % 2)) return 1 + brokenCalc(X, Y / 2); 4 | return 1 + brokenCalc(X, Y + 1); 5 | } 6 | -------------------------------------------------------------------------------- /src/problems/993.Cousins-in-Binary-Tree.ts: -------------------------------------------------------------------------------- 1 | // TS 2 | // Runtime: 76 ms, faster than 100.00% of TypeScript online submissions for Cousins in Binary Tree. 3 | // Memory Usage: 40.1 MB, less than 100.00% of TypeScript online submissions for Cousins in Binary Tree. 4 | 5 | function isCousins(root: TreeNode | null, x: number, y: number): boolean { 6 | const nodes: { depth: number; parent: number | null }[] = []; 7 | 8 | const helper = ( 9 | node: TreeNode | null, 10 | depth: number = 0, 11 | parent: number | null = null 12 | ) => { 13 | if (!node) return 0; 14 | 15 | if (node.val === x || node.val === y) { 16 | nodes.push({ depth, parent: parent }); 17 | return; 18 | } 19 | 20 | helper(node.left, depth + 1, node.val); 21 | helper(node.right, depth + 1, node.val); 22 | }; 23 | 24 | helper(root); 25 | 26 | const [first, second] = nodes; 27 | 28 | if ( 29 | first && 30 | second && 31 | first.depth === second.depth && 32 | first.parent !== second.parent 33 | ) { 34 | return true; 35 | } 36 | 37 | return false; 38 | } 39 | -------------------------------------------------------------------------------- /src/problems/997-Find-the-Town-Judge.ts: -------------------------------------------------------------------------------- 1 | function findJudge(N: number, trust: number[][]): number { 2 | const array = new Array(N).fill(0); 3 | 4 | trust.forEach(([a, b]) => { 5 | array[a - 1]--; 6 | array[b - 1]++; 7 | }); 8 | 9 | const judge = array.indexOf(N - 1); 10 | return judge !== -1 ? judge + 1 : -1; 11 | } 12 | -------------------------------------------------------------------------------- /src/utils/classes/ListNode.ts: -------------------------------------------------------------------------------- 1 | class ListNode { 2 | val: number; 3 | next: ListNode | null; 4 | constructor(val?: number, next?: ListNode | null) { 5 | this.val = val === undefined ? 0 : val; 6 | this.next = next === undefined ? null : next; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/utils/classes/TreeNode.ts: -------------------------------------------------------------------------------- 1 | class TreeNode { 2 | val: number; 3 | left: TreeNode | null; 4 | right: TreeNode | null; 5 | constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { 6 | this.val = val === undefined ? 0 : val; 7 | this.left = left === undefined ? null : left; 8 | this.right = right === undefined ? null : right; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/classes/Trie.ts: -------------------------------------------------------------------------------- 1 | class Trie { 2 | child: { [Key: string]: Trie }; 3 | isEnd: boolean; 4 | 5 | constructor() { 6 | this.child = {}; 7 | this.isEnd = false; 8 | } 9 | 10 | insert(word: string): void { 11 | let curr: Trie = this; 12 | 13 | for (const char of word) { 14 | if (!(char in curr.child)) { 15 | curr.child[char] = new Trie(); 16 | } 17 | curr = curr.child[char]; 18 | } 19 | curr.isEnd = true; 20 | } 21 | 22 | search(word: string): boolean { 23 | let curr: Trie = this; 24 | 25 | for (const char of word) { 26 | if (!(char in curr.child)) { 27 | return false; 28 | } 29 | curr = curr.child[char]; 30 | } 31 | 32 | return curr.isEnd; 33 | } 34 | 35 | startsWith(prefix: string): boolean { 36 | let curr: Trie = this; 37 | 38 | for (const char of prefix) { 39 | if (!(char in curr.child)) { 40 | return false; 41 | } 42 | curr = curr.child[char]; 43 | } 44 | 45 | return true; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tests.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eddyhdzg/leetcode-typescript-solutions/2793246b9b9b7dfcb9a3f3dac7528272b32d87ca/tests.txt -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowJs": true, 4 | "baseUrl": "./src", 5 | "composite": false, 6 | "declaration": true, 7 | "declarationMap": true, 8 | "esModuleInterop": true, 9 | "forceConsistentCasingInFileNames": true, 10 | "inlineSources": false, 11 | "isolatedModules": false, 12 | // "lib": ["ES2021", "DOM", "DOM.Iterable"], 13 | // "target": "es6", 14 | "lib": ["es2017", "dom"], 15 | "target": "es6", 16 | "module": "commonjs", 17 | "moduleResolution": "node", 18 | "noUnusedLocals": false, 19 | "noUnusedParameters": false, 20 | "preserveWatchOutput": true, 21 | "resolveJsonModule": true, 22 | "skipLibCheck": true, 23 | "strict": true, 24 | }, 25 | "exclude": ["node_modules"], 26 | "include": ["./src", "./playground.ts"], 27 | } 28 | --------------------------------------------------------------------------------