diff --git a/README.md b/README.md index 0e594712..21b2efdb 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# 1,510 LeetCode solutions in JavaScript +# 2,250+ LeetCode solutions in JavaScript [https://leetcodejavascript.com](https://leetcodejavascript.com) @@ -161,19 +161,27 @@ 153|[Find Minimum in Rotated Sorted Array](./solutions/0153-find-minimum-in-rotated-sorted-array.js)|Medium| 154|[Find Minimum in Rotated Sorted Array II](./solutions/0154-find-minimum-in-rotated-sorted-array-ii.js)|Hard| 155|[Min Stack](./solutions/0155-min-stack.js)|Medium| +156|[Binary Tree Upside Down](./solutions/0156-binary-tree-upside-down.js)|Medium| +157|[Read N Characters Given Read4](./solutions/0157-read-n-characters-given-read4.js)|Easy| +158|[Read N Characters Given read4 II - Call Multiple Times](./solutions/0158-read-n-characters-given-read4-ii-call-multiple-times.js)|Hard| +159|[Longest Substring with At Most Two Distinct Characters](./solutions/0159-longest-substring-with-at-most-two-distinct-characters.js)|Medium| 160|[Intersection of Two Linked Lists](./solutions/0160-intersection-of-two-linked-lists.js)|Medium| +161|[One Edit Distance](./solutions/0161-one-edit-distance.js)|Medium| 162|[Find Peak Element](./solutions/0162-find-peak-element.js)|Medium| +163|[Missing Ranges](./solutions/0163-missing-ranges.js)|Easy| 164|[Maximum Gap](./solutions/0164-maximum-gap.js)|Medium| 165|[Compare Version Numbers](./solutions/0165-compare-version-numbers.js)|Medium| 166|[Fraction to Recurring Decimal](./solutions/0166-fraction-to-recurring-decimal.js)|Medium| 167|[Two Sum II - Input Array Is Sorted](./solutions/0167-two-sum-ii-input-array-is-sorted.js)|Easy| 168|[Excel Sheet Column Title](./solutions/0168-excel-sheet-column-title.js)|Easy| 169|[Majority Element](./solutions/0169-majority-element.js)|Easy| +170|[Two Sum III - Data structure design](./solutions/0170-two-sum-iii-data-structure-design.js)|Easy| 171|[Excel Sheet Column Number](./solutions/0171-excel-sheet-column-number.js)|Easy| 172|[Factorial Trailing Zeroes](./solutions/0172-factorial-trailing-zeroes.js)|Medium| 173|[Binary Search Tree Iterator](./solutions/0173-binary-search-tree-iterator.js)|Medium| 174|[Dungeon Game](./solutions/0174-dungeon-game.js)|Hard| 179|[Largest Number](./solutions/0179-largest-number.js)|Medium| +186|[Reverse Words in a String II](./solutions/0186-reverse-words-in-a-string-ii.js)|Medium| 187|[Repeated DNA Sequences](./solutions/0187-repeated-dna-sequences.js)|Medium| 188|[Best Time to Buy and Sell Stock IV](./solutions/0188-best-time-to-buy-and-sell-stock-iv.js)|Hard| 189|[Rotate Array](./solutions/0189-rotate-array.js)|Medium| @@ -224,44 +232,88 @@ 240|[Search a 2D Matrix II](./solutions/0240-search-a-2d-matrix-ii.js)|Medium| 241|[Different Ways to Add Parentheses](./solutions/0241-different-ways-to-add-parentheses.js)|Medium| 242|[Valid Anagram](./solutions/0242-valid-anagram.js)|Easy| +243|[Shortest Word Distance](./solutions/0243-shortest-word-distance.js)|Easy| +244|[Shortest Word Distance II](./solutions/0244-shortest-word-distance-ii.js)|Medium| +245|[Shortest Word Distance III](./solutions/0245-shortest-word-distance-iii.js)|Medium| +246|[Strobogrammatic Number](./solutions/0246-strobogrammatic-number.js)|Easy| +247|[Strobogrammatic Number II](./solutions/0247-strobogrammatic-number-ii.js)|Medium| +248|[Strobogrammatic Number III](./solutions/0248-strobogrammatic-number-iii.js)|Hard| +249|[Group Shifted Strings](./solutions/0249-group-shifted-strings.js)|Medium| +250|[Count Univalue Subtrees](./solutions/0250-count-univalue-subtrees.js)|Medium| +251|[Flatten 2D Vector](./solutions/0251-flatten-2d-vector.js)|Medium| +252|[Meeting Rooms](./solutions/0252-meeting-rooms.js)|Easy| +253|[Meeting Rooms II](./solutions/0253-meeting-rooms-ii.js)|Medium| +254|[Factor Combinations](./solutions/0254-factor-combinations.js)|Medium| +255|[Verify Preorder Sequence in Binary Search Tree](./solutions/0255-verify-preorder-sequence-in-binary-search-tree.js)|Medium| +256|[Paint House](./solutions/0256-paint-house.js)|Medium| 257|[Binary Tree Paths](./solutions/0257-binary-tree-paths.js)|Easy| 258|[Add Digits](./solutions/0258-add-digits.js)|Easy| +259|[3Sum Smaller](./solutions/0259-3sum-smaller.js)|Medium| 260|[Single Number III](./solutions/0260-single-number-iii.js)|Medium| +261|[Graph Valid Tree](./solutions/0261-graph-valid-tree.js)|Medium| 263|[Ugly Number](./solutions/0263-ugly-number.js)|Easy| 264|[Ugly Number II](./solutions/0264-ugly-number-ii.js)|Medium| +265|[Paint House II](./solutions/0265-paint-house-ii.js)|Hard| +266|[Palindrome Permutation](./solutions/0266-palindrome-permutation.js)|Easy| +267|[Palindrome Permutation II](./solutions/0267-palindrome-permutation-ii.js)|Medium| 268|[Missing Number](./solutions/0268-missing-number.js)|Easy| +269|[Alien Dictionary](./solutions/0269-alien-dictionary.js)|Hard| +270|[Closest Binary Search Tree Value](./solutions/0270-closest-binary-search-tree-value.js)|Easy| +271|[Encode and Decode Strings](./solutions/0271-encode-and-decode-strings.js)|Medium| +272|[Closest Binary Search Tree Value II](./solutions/0272-closest-binary-search-tree-value-ii.js)|Hard| 273|[Integer to English Words](./solutions/0273-integer-to-english-words.js)|Hard| 274|[H-Index](./solutions/0274-h-index.js)|Medium| 275|[H-Index II](./solutions/0275-h-index-ii.js)|Medium| +276|[Paint Fence](./solutions/0276-paint-fence.js)|Medium| +277|[Find the Celebrity](./solutions/0277-find-the-celebrity.js)|Medium| 278|[First Bad Version](./solutions/0278-first-bad-version.js)|Medium| 279|[Perfect Squares](./solutions/0279-perfect-squares.js)|Medium| +280|[Wiggle Sort](./solutions/0280-wiggle-sort.js)|Medium| +281|[Zigzag Iterator](./solutions/0281-zigzag-iterator.js)|Medium| 282|[Expression Add Operators](./solutions/0282-expression-add-operators.js)|Hard| 283|[Move Zeroes](./solutions/0283-move-zeroes.js)|Easy| 284|[Peeking Iterator](./solutions/0284-peeking-iterator.js)|Medium| +285|[Inorder Successor in BST](./solutions/0285-inorder-successor-in-bst.js)|Medium| +286|[Walls and Gates](./solutions/0286-walls-and-gates.js)|Medium| 287|[Find the Duplicate Number](./solutions/0287-find-the-duplicate-number.js)|Medium| +288|[Unique Word Abbreviation](./solutions/0288-unique-word-abbreviation.js)|Medium| 289|[Game of Life](./solutions/0289-game-of-life.js)|Medium| 290|[Word Pattern](./solutions/0290-word-pattern.js)|Easy| +291|[Word Pattern II](./solutions/0291-word-pattern-ii.js)|Medium| 292|[Nim Game](./solutions/0292-nim-game.js)|Easy| +293|[Flip Game](./solutions/0293-flip-game.js)|Easy| +294|[Flip Game II](./solutions/0294-flip-game-ii.js)|Medium| 295|[Find Median from Data Stream](./solutions/0295-find-median-from-data-stream.js)|Hard| +296|[Best Meeting Point](./solutions/0296-best-meeting-point.js)|Hard| 297|[Serialize and Deserialize Binary Tree](./solutions/0297-serialize-and-deserialize-binary-tree.js)|Hard| +298|[Binary Tree Longest Consecutive Sequence](./solutions/0298-binary-tree-longest-consecutive-sequence.js)|Medium| 299|[Bulls and Cows](./solutions/0299-bulls-and-cows.js)|Medium| 300|[Longest Increasing Subsequence](./solutions/0300-longest-increasing-subsequence.js)|Medium| 301|[Remove Invalid Parentheses](./solutions/0301-remove-invalid-parentheses.js)|Hard| +302|[Smallest Rectangle Enclosing Black Pixels](./solutions/0302-smallest-rectangle-enclosing-black-pixels.js)|Hard| 303|[Range Sum Query - Immutable](./solutions/0303-range-sum-query-immutable.js)|Easy| 304|[Range Sum Query 2D - Immutable](./solutions/0304-range-sum-query-2d-immutable.js)|Medium| +305|[Number of Islands II](./solutions/0305-number-of-islands-ii.js)|Hard| 306|[Additive Number](./solutions/0306-additive-number.js)|Medium| 307|[Range Sum Query - Mutable](./solutions/0307-range-sum-query-mutable.js)|Medium| +308|[Range Sum Query 2D - Mutable](./solutions/0308-range-sum-query-2d-mutable.js)|Medium| 309|[Best Time to Buy and Sell Stock with Cooldown](./solutions/0309-best-time-to-buy-and-sell-stock-with-cooldown.js)|Medium| 310|[Minimum Height Trees](./solutions/0310-minimum-height-trees.js)|Medium| +311|[Sparse Matrix Multiplication](./solutions/0311-sparse-matrix-multiplication.js)|Medium| 312|[Burst Balloons](./solutions/0312-burst-balloons.js)|Hard| 313|[Super Ugly Number](./solutions/0313-super-ugly-number.js)|Medium| +314|[Binary Tree Vertical Order Traversal](./solutions/0314-binary-tree-vertical-order-traversal.js)|Medium| 315|[Count of Smaller Numbers After Self](./solutions/0315-count-of-smaller-numbers-after-self.js)|Hard| 316|[Remove Duplicate Letters](./solutions/0316-remove-duplicate-letters.js)|Medium| +317|[Shortest Distance from All Buildings](./solutions/0317-shortest-distance-from-all-buildings.js)|Hard| 318|[Maximum Product of Word Lengths](./solutions/0318-maximum-product-of-word-lengths.js)|Medium| 319|[Bulb Switcher](./solutions/0319-bulb-switcher.js)|Medium| +320|[Generalized Abbreviation](./solutions/0320-generalized-abbreviation.js)|Medium| 321|[Create Maximum Number](./solutions/0321-create-maximum-number.js)|Hard| 322|[Coin Change](./solutions/0322-coin-change.js)|Medium| +323|[Number of Connected Components in an Undirected Graph](./solutions/0323-number-of-connected-components-in-an-undirected-graph.js)|Medium| 324|[Wiggle Sort II](./solutions/0324-wiggle-sort-ii.js)|Medium| +325|[Maximum Size Subarray Sum Equals k](./solutions/0325-maximum-size-subarray-sum-equals-k.js)|Medium| 326|[Power of Three](./solutions/0326-power-of-three.js)|Easy| 327|[Count of Range Sum](./solutions/0327-count-of-range-sum.js)|Hard| 328|[Odd Even Linked List](./solutions/0328-odd-even-linked-list.js)|Medium| @@ -269,27 +321,44 @@ 330|[Patching Array](./solutions/0330-patching-array.js)|Hard| 331|[Verify Preorder Serialization of a Binary Tree](./solutions/0331-verify-preorder-serialization-of-a-binary-tree.js)|Medium| 332|[Reconstruct Itinerary](./solutions/0332-reconstruct-itinerary.js)|Hard| +333|[Largest BST Subtree](./solutions/0333-largest-bst-subtree.js)|Medium| 334|[Increasing Triplet Subsequence](./solutions/0334-increasing-triplet-subsequence.js)|Medium| 335|[Self Crossing](./solutions/0335-self-crossing.js)|Hard| 336|[Palindrome Pairs](./solutions/0336-palindrome-pairs.js)|Hard| 337|[House Robber III](./solutions/0337-house-robber-iii.js)|Medium| 338|[Counting Bits](./solutions/0338-counting-bits.js)|Easy| +339|[Nested List Weight Sum](./solutions/0339-nested-list-weight-sum.js)|Medium| +340|[Longest Substring with At Most K Distinct Characters](./solutions/0340-longest-substring-with-at-most-k-distinct-characters.js)|Medium| 341|[Flatten Nested List Iterator](./solutions/0341-flatten-nested-list-iterator.js)|Medium| 342|[Power of Four](./solutions/0342-power-of-four.js)|Easy| 343|[Integer Break](./solutions/0343-integer-break.js)|Medium| 344|[Reverse String](./solutions/0344-reverse-string.js)|Easy| 345|[Reverse Vowels of a String](./solutions/0345-reverse-vowels-of-a-string.js)|Easy| +346|[Moving Average from Data Stream](./solutions/0346-moving-average-from-data-stream.js)|Easy| 347|[Top K Frequent Elements](./solutions/0347-top-k-frequent-elements.js)|Medium| +348|[Design Tic-Tac-Toe](./solutions/0348-design-tic-tac-toe.js)|Medium| 349|[Intersection of Two Arrays](./solutions/0349-intersection-of-two-arrays.js)|Easy| 350|[Intersection of Two Arrays II](./solutions/0350-intersection-of-two-arrays-ii.js)|Easy| +351|[Android Unlock Patterns](./solutions/0351-android-unlock-patterns.js)|Medium| 352|[Data Stream as Disjoint Intervals](./solutions/0352-data-stream-as-disjoint-intervals.js)|Hard| +353|[Design Snake Game](./solutions/0353-design-snake-game.js)|Medium| 354|[Russian Doll Envelopes](./solutions/0354-russian-doll-envelopes.js)|Hard| 355|[Design Twitter](./solutions/0355-design-twitter.js)|Medium| +356|[Line Reflection](./solutions/0356-line-reflection.js)|Medium| 357|[Count Numbers with Unique Digits](./solutions/0357-count-numbers-with-unique-digits.js)|Medium| +358|[Rearrange String k Distance Apart](./solutions/0358-rearrange-string-k-distance-apart.js)|Hard| +359|[Logger Rate Limiter](./solutions/0359-logger-rate-limiter.js)|Easy| +360|[Sort Transformed Array](./solutions/0360-sort-transformed-array.js)|Medium| +361|[Bomb Enemy](./solutions/0361-bomb-enemy.js)|Medium| +362|[Design Hit Counter](./solutions/0362-design-hit-counter.js)|Medium| 363|[Max Sum of Rectangle No Larger Than K](./solutions/0363-max-sum-of-rectangle-no-larger-than-k.js)|Hard| +364|[Nested List Weight Sum II](./solutions/0364-nested-list-weight-sum-ii.js)|Medium| 365|[Water and Jug Problem](./solutions/0365-water-and-jug-problem.js)|Medium| +366|[Find Leaves of Binary Tree](./solutions/0366-find-leaves-of-binary-tree.js)|Medium| 367|[Valid Perfect Square](./solutions/0367-valid-perfect-square.js)|Easy| 368|[Largest Divisible Subset](./solutions/0368-largest-divisible-subset.js)|Medium| +369|[Plus One Linked List](./solutions/0369-plus-one-linked-list.js)|Medium| +370|[Range Addition](./solutions/0370-range-addition.js)|Medium| 371|[Sum of Two Integers](./solutions/0371-sum-of-two-integers.js)|Medium| 372|[Super Pow](./solutions/0372-super-pow.js)|Medium| 373|[Find K Pairs with Smallest Sums](./solutions/0373-find-k-pairs-with-smallest-sums.js)|Medium| @@ -298,6 +367,7 @@ 376|[Wiggle Subsequence](./solutions/0376-wiggle-subsequence.js)|Medium| 377|[Combination Sum IV](./solutions/0377-combination-sum-iv.js)|Medium| 378|[Kth Smallest Element in a Sorted Matrix](./solutions/0378-kth-smallest-element-in-a-sorted-matrix.js)|Medium| +379|[Design Phone Directory](./solutions/0379-design-phone-directory.js)|Medium| 380|[Insert Delete GetRandom O(1)](./solutions/0380-insert-delete-getrandom-o1.js)|Medium| 381|[Insert Delete GetRandom O(1) - Duplicates allowed](./solutions/0381-insert-delete-getrandom-o1-duplicates-allowed.js)|Hard| 382|[Linked List Random Node](./solutions/0382-linked-list-random-node.js)|Medium| @@ -326,8 +396,10 @@ 405|[Convert a Number to Hexadecimal](./solutions/0405-convert-a-number-to-hexadecimal.js)|Easy| 406|[Queue Reconstruction by Height](./solutions/0406-queue-reconstruction-by-height.js)|Medium| 407|[Trapping Rain Water II](./solutions/0407-trapping-rain-water-ii.js)|Hard| +408|[Valid Word Abbreviation](./solutions/0408-valid-word-abbreviation.js)|Easy| 409|[Longest Palindrome](./solutions/0409-longest-palindrome.js)|Easy| 410|[Split Array Largest Sum](./solutions/0410-split-array-largest-sum.js)|Hard| +411|[Minimum Unique Word Abbreviation](./solutions/0411-minimum-unique-word-abbreviation.js)|Hard| 412|[Fizz Buzz](./solutions/0412-fizz-buzz.js)|Easy| 413|[Arithmetic Slices](./solutions/0413-arithmetic-slices.js)|Medium| 414|[Third Maximum Number](./solutions/0414-third-maximum-number.js)|Easy| @@ -1338,105 +1410,619 @@ 1734|[Decode XORed Permutation](./solutions/1734-decode-xored-permutation.js)|Medium| 1735|[Count Ways to Make Array With Product](./solutions/1735-count-ways-to-make-array-with-product.js)|Hard| 1736|[Latest Time by Replacing Hidden Digits](./solutions/1736-latest-time-by-replacing-hidden-digits.js)|Easy| +1737|[Change Minimum Characters to Satisfy One of Three Conditions](./solutions/1737-change-minimum-characters-to-satisfy-one-of-three-conditions.js)|Medium| +1738|[Find Kth Largest XOR Coordinate Value](./solutions/1738-find-kth-largest-xor-coordinate-value.js)|Medium| +1739|[Building Boxes](./solutions/1739-building-boxes.js)|Hard| +1742|[Maximum Number of Balls in a Box](./solutions/1742-maximum-number-of-balls-in-a-box.js)|Easy| +1743|[Restore the Array From Adjacent Pairs](./solutions/1743-restore-the-array-from-adjacent-pairs.js)|Medium| +1744|[Can You Eat Your Favorite Candy on Your Favorite Day?](./solutions/1744-can-you-eat-your-favorite-candy-on-your-favorite-day.js)|Medium| +1745|[Palindrome Partitioning IV](./solutions/1745-palindrome-partitioning-iv.js)|Hard| 1748|[Sum of Unique Elements](./solutions/1748-sum-of-unique-elements.js)|Easy| 1749|[Maximum Absolute Sum of Any Subarray](./solutions/1749-maximum-absolute-sum-of-any-subarray.js)|Medium| +1750|[Minimum Length of String After Deleting Similar Ends](./solutions/1750-minimum-length-of-string-after-deleting-similar-ends.js)|Medium| +1751|[Maximum Number of Events That Can Be Attended II](./solutions/1751-maximum-number-of-events-that-can-be-attended-ii.js)|Hard| 1752|[Check if Array Is Sorted and Rotated](./solutions/1752-check-if-array-is-sorted-and-rotated.js)|Easy| +1753|[Maximum Score From Removing Stones](./solutions/1753-maximum-score-from-removing-stones.js)|Medium| +1754|[Largest Merge Of Two Strings](./solutions/1754-largest-merge-of-two-strings.js)|Medium| +1755|[Closest Subsequence Sum](./solutions/1755-closest-subsequence-sum.js)|Hard| +1758|[Minimum Changes To Make Alternating Binary String](./solutions/1758-minimum-changes-to-make-alternating-binary-string.js)|Easy| +1759|[Count Number of Homogenous Substrings](./solutions/1759-count-number-of-homogenous-substrings.js)|Medium| +1760|[Minimum Limit of Balls in a Bag](./solutions/1760-minimum-limit-of-balls-in-a-bag.js)|Medium| +1761|[Minimum Degree of a Connected Trio in a Graph](./solutions/1761-minimum-degree-of-a-connected-trio-in-a-graph.js)|Hard| +1763|[Longest Nice Substring](./solutions/1763-longest-nice-substring.js)|Easy| 1764|[Form Array by Concatenating Subarrays of Another Array](./solutions/1764-form-array-by-concatenating-subarrays-of-another-array.js)|Medium| 1765|[Map of Highest Peak](./solutions/1765-map-of-highest-peak.js)|Medium| +1766|[Tree of Coprimes](./solutions/1766-tree-of-coprimes.js)|Hard| 1768|[Merge Strings Alternately](./solutions/1768-merge-strings-alternately.js)|Easy| 1769|[Minimum Number of Operations to Move All Balls to Each Box](./solutions/1769-minimum-number-of-operations-to-move-all-balls-to-each-box.js)|Medium| +1770|[Maximum Score from Performing Multiplication Operations](./solutions/1770-maximum-score-from-performing-multiplication-operations.js)|Hard| +1771|[Maximize Palindrome Length From Subsequences](./solutions/1771-maximize-palindrome-length-from-subsequences.js)|Hard| +1773|[Count Items Matching a Rule](./solutions/1773-count-items-matching-a-rule.js)|Easy| +1774|[Closest Dessert Cost](./solutions/1774-closest-dessert-cost.js)|Medium| +1775|[Equal Sum Arrays With Minimum Number of Operations](./solutions/1775-equal-sum-arrays-with-minimum-number-of-operations.js)|Medium| +1776|[Car Fleet II](./solutions/1776-car-fleet-ii.js)|Hard| +1779|[Find Nearest Point That Has the Same X or Y Coordinate](./solutions/1779-find-nearest-point-that-has-the-same-x-or-y-coordinate.js)|Easy| 1780|[Check if Number is a Sum of Powers of Three](./solutions/1780-check-if-number-is-a-sum-of-powers-of-three.js)|Medium| +1781|[Sum of Beauty of All Substrings](./solutions/1781-sum-of-beauty-of-all-substrings.js)|Medium| +1782|[Count Pairs Of Nodes](./solutions/1782-count-pairs-of-nodes.js)|Hard| +1784|[Check if Binary String Has at Most One Segment of Ones](./solutions/1784-check-if-binary-string-has-at-most-one-segment-of-ones.js)|Easy| +1785|[Minimum Elements to Add to Form a Given Sum](./solutions/1785-minimum-elements-to-add-to-form-a-given-sum.js)|Medium| +1786|[Number of Restricted Paths From First to Last Node](./solutions/1786-number-of-restricted-paths-from-first-to-last-node.js)|Medium| +1787|[Make the XOR of All Segments Equal to Zero](./solutions/1787-make-the-xor-of-all-segments-equal-to-zero.js)|Hard| 1790|[Check if One String Swap Can Make Strings Equal](./solutions/1790-check-if-one-string-swap-can-make-strings-equal.js)|Easy| 1791|[Find Center of Star Graph](./solutions/1791-find-center-of-star-graph.js)|Easy| +1792|[Maximum Average Pass Ratio](./solutions/1792-maximum-average-pass-ratio.js)|Medium| +1793|[Maximum Score of a Good Subarray](./solutions/1793-maximum-score-of-a-good-subarray.js)|Hard| +1796|[Second Largest Digit in a String](./solutions/1796-second-largest-digit-in-a-string.js)|Easy| +1797|[Design Authentication Manager](./solutions/1797-design-authentication-manager.js)|Medium| +1798|[Maximum Number of Consecutive Values You Can Make](./solutions/1798-maximum-number-of-consecutive-values-you-can-make.js)|Medium| +1799|[Maximize Score After N Operations](./solutions/1799-maximize-score-after-n-operations.js)|Hard| 1800|[Maximum Ascending Subarray Sum](./solutions/1800-maximum-ascending-subarray-sum.js)|Easy| +1801|[Number of Orders in the Backlog](./solutions/1801-number-of-orders-in-the-backlog.js)|Medium| +1802|[Maximum Value at a Given Index in a Bounded Array](./solutions/1802-maximum-value-at-a-given-index-in-a-bounded-array.js)|Medium| +1803|[Count Pairs With XOR in a Range](./solutions/1803-count-pairs-with-xor-in-a-range.js)|Hard| +1805|[Number of Different Integers in a String](./solutions/1805-number-of-different-integers-in-a-string.js)|Easy| +1806|[Minimum Number of Operations to Reinitialize a Permutation](./solutions/1806-minimum-number-of-operations-to-reinitialize-a-permutation.js)|Medium| +1807|[Evaluate the Bracket Pairs of a String](./solutions/1807-evaluate-the-bracket-pairs-of-a-string.js)|Medium| +1808|[Maximize Number of Nice Divisors](./solutions/1808-maximize-number-of-nice-divisors.js)|Hard| 1812|[Determine Color of a Chessboard Square](./solutions/1812-determine-color-of-a-chessboard-square.js)|Easy| +1813|[Sentence Similarity III](./solutions/1813-sentence-similarity-iii.js)|Medium| +1814|[Count Nice Pairs in an Array](./solutions/1814-count-nice-pairs-in-an-array.js)|Medium| +1815|[Maximum Number of Groups Getting Fresh Donuts](./solutions/1815-maximum-number-of-groups-getting-fresh-donuts.js)|Hard| +1816|[Truncate Sentence](./solutions/1816-truncate-sentence.js)|Easy| 1817|[Finding the Users Active Minutes](./solutions/1817-finding-the-users-active-minutes.js)|Medium| +1818|[Minimum Absolute Sum Difference](./solutions/1818-minimum-absolute-sum-difference.js)|Medium| +1819|[Number of Different Subsequences GCDs](./solutions/1819-number-of-different-subsequences-gcds.js)|Hard| +1822|[Sign of the Product of an Array](./solutions/1822-sign-of-the-product-of-an-array.js)|Easy| +1823|[Find the Winner of the Circular Game](./solutions/1823-find-the-winner-of-the-circular-game.js)|Medium| +1824|[Minimum Sideway Jumps](./solutions/1824-minimum-sideway-jumps.js)|Medium| +1825|[Finding MK Average](./solutions/1825-finding-mk-average.js)|Hard| +1827|[Minimum Operations to Make the Array Increasing](./solutions/1827-minimum-operations-to-make-the-array-increasing.js)|Easy| +1828|[Queries on Number of Points Inside a Circle](./solutions/1828-queries-on-number-of-points-inside-a-circle.js)|Medium| +1829|[Maximum XOR for Each Query](./solutions/1829-maximum-xor-for-each-query.js)|Medium| +1830|[Minimum Number of Operations to Make String Sorted](./solutions/1830-minimum-number-of-operations-to-make-string-sorted.js)|Hard| 1832|[Check if the Sentence Is Pangram](./solutions/1832-check-if-the-sentence-is-pangram.js)|Easy| 1833|[Maximum Ice Cream Bars](./solutions/1833-maximum-ice-cream-bars.js)|Medium| +1834|[Single-Threaded CPU](./solutions/1834-single-threaded-cpu.js)|Medium| +1835|[Find XOR Sum of All Pairs Bitwise AND](./solutions/1835-find-xor-sum-of-all-pairs-bitwise-and.js)|Hard| +1837|[Sum of Digits in Base K](./solutions/1837-sum-of-digits-in-base-k.js)|Easy| +1838|[Frequency of the Most Frequent Element](./solutions/1838-frequency-of-the-most-frequent-element.js)|Medium| +1839|[Longest Substring Of All Vowels in Order](./solutions/1839-longest-substring-of-all-vowels-in-order.js)|Medium| +1840|[Maximum Building Height](./solutions/1840-maximum-building-height.js)|Hard| +1844|[Replace All Digits with Characters](./solutions/1844-replace-all-digits-with-characters.js)|Easy| +1845|[Seat Reservation Manager](./solutions/1845-seat-reservation-manager.js)|Medium| +1846|[Maximum Element After Decreasing and Rearranging](./solutions/1846-maximum-element-after-decreasing-and-rearranging.js)|Medium| +1847|[Closest Room](./solutions/1847-closest-room.js)|Hard| +1848|[Minimum Distance to the Target Element](./solutions/1848-minimum-distance-to-the-target-element.js)|Easy| +1849|[Splitting a String Into Descending Consecutive Values](./solutions/1849-splitting-a-string-into-descending-consecutive-values.js)|Medium| +1850|[Minimum Adjacent Swaps to Reach the Kth Smallest Number](./solutions/1850-minimum-adjacent-swaps-to-reach-the-kth-smallest-number.js)|Medium| +1851|[Minimum Interval to Include Each Query](./solutions/1851-minimum-interval-to-include-each-query.js)|Hard| +1854|[Maximum Population Year](./solutions/1854-maximum-population-year.js)|Easy| +1855|[Maximum Distance Between a Pair of Values](./solutions/1855-maximum-distance-between-a-pair-of-values.js)|Medium| +1856|[Maximum Subarray Min-Product](./solutions/1856-maximum-subarray-min-product.js)|Medium| +1857|[Largest Color Value in a Directed Graph](./solutions/1857-largest-color-value-in-a-directed-graph.js)|Hard| +1859|[Sorting the Sentence](./solutions/1859-sorting-the-sentence.js)|Easy| +1860|[Incremental Memory Leak](./solutions/1860-incremental-memory-leak.js)|Medium| +1861|[Rotating the Box](./solutions/1861-rotating-the-box.js)|Medium| +1862|[Sum of Floored Pairs](./solutions/1862-sum-of-floored-pairs.js)|Hard| 1863|[Sum of All Subset XOR Totals](./solutions/1863-sum-of-all-subset-xor-totals.js)|Easy| +1864|[Minimum Number of Swaps to Make the Binary String Alternating](./solutions/1864-minimum-number-of-swaps-to-make-the-binary-string-alternating.js)|Medium| +1865|[Finding Pairs With a Certain Sum](./solutions/1865-finding-pairs-with-a-certain-sum.js)|Medium| +1866|[Number of Ways to Rearrange Sticks With K Sticks Visible](./solutions/1866-number-of-ways-to-rearrange-sticks-with-k-sticks-visible.js)|Hard| +1869|[Longer Contiguous Segments of Ones than Zeros](./solutions/1869-longer-contiguous-segments-of-ones-than-zeros.js)|Easy| +1870|[Minimum Speed to Arrive on Time](./solutions/1870-minimum-speed-to-arrive-on-time.js)|Medium| +1871|[Jump Game VII](./solutions/1871-jump-game-vii.js)|Medium| +1872|[Stone Game VIII](./solutions/1872-stone-game-viii.js)|Hard| +1876|[Substrings of Size Three with Distinct Characters](./solutions/1876-substrings-of-size-three-with-distinct-characters.js)|Easy| +1877|[Minimize Maximum Pair Sum in Array](./solutions/1877-minimize-maximum-pair-sum-in-array.js)|Medium| +1878|[Get Biggest Three Rhombus Sums in a Grid](./solutions/1878-get-biggest-three-rhombus-sums-in-a-grid.js)|Medium| +1879|[Minimum XOR Sum of Two Arrays](./solutions/1879-minimum-xor-sum-of-two-arrays.js)|Hard| 1880|[Check if Word Equals Summation of Two Words](./solutions/1880-check-if-word-equals-summation-of-two-words.js)|Easy| +1881|[Maximum Value after Insertion](./solutions/1881-maximum-value-after-insertion.js)|Medium| +1882|[Process Tasks Using Servers](./solutions/1882-process-tasks-using-servers.js)|Medium| +1883|[Minimum Skips to Arrive at Meeting On Time](./solutions/1883-minimum-skips-to-arrive-at-meeting-on-time.js)|Hard| +1884|[Egg Drop With 2 Eggs and N Floors](./solutions/1884-egg-drop-with-2-eggs-and-n-floors.js)|Medium| 1886|[Determine Whether Matrix Can Be Obtained By Rotation](./solutions/1886-determine-whether-matrix-can-be-obtained-by-rotation.js)|Easy| +1887|[Reduction Operations to Make the Array Elements Equal](./solutions/1887-reduction-operations-to-make-the-array-elements-equal.js)|Medium| +1888|[Minimum Number of Flips to Make the Binary String Alternating](./solutions/1888-minimum-number-of-flips-to-make-the-binary-string-alternating.js)|Medium| +1889|[Minimum Space Wasted From Packaging](./solutions/1889-minimum-space-wasted-from-packaging.js)|Hard| +1893|[Check if All the Integers in a Range Are Covered](./solutions/1893-check-if-all-the-integers-in-a-range-are-covered.js)|Easy| +1894|[Find the Student that Will Replace the Chalk](./solutions/1894-find-the-student-that-will-replace-the-chalk.js)|Medium| +1895|[Largest Magic Square](./solutions/1895-largest-magic-square.js)|Medium| +1896|[Minimum Cost to Change the Final Value of Expression](./solutions/1896-minimum-cost-to-change-the-final-value-of-expression.js)|Hard| +1897|[Redistribute Characters to Make All Strings Equal](./solutions/1897-redistribute-characters-to-make-all-strings-equal.js)|Easy| +1898|[Maximum Number of Removable Characters](./solutions/1898-maximum-number-of-removable-characters.js)|Medium| +1899|[Merge Triplets to Form Target Triplet](./solutions/1899-merge-triplets-to-form-target-triplet.js)|Medium| +1900|[The Earliest and Latest Rounds Where Players Compete](./solutions/1900-the-earliest-and-latest-rounds-where-players-compete.js)|Hard| +1901|[Find a Peak Element II](./solutions/1901-find-a-peak-element-ii.js)|Medium| +1903|[Largest Odd Number in String](./solutions/1903-largest-odd-number-in-string.js)|Easy| +1904|[The Number of Full Rounds You Have Played](./solutions/1904-the-number-of-full-rounds-you-have-played.js)|Medium| +1905|[Count Sub Islands](./solutions/1905-count-sub-islands.js)|Medium| +1906|[Minimum Absolute Difference Queries](./solutions/1906-minimum-absolute-difference-queries.js)|Medium| +1909|[Remove One Element to Make the Array Strictly Increasing](./solutions/1909-remove-one-element-to-make-the-array-strictly-increasing.js)|Easy| 1910|[Remove All Occurrences of a Substring](./solutions/1910-remove-all-occurrences-of-a-substring.js)|Medium| +1911|[Maximum Alternating Subsequence Sum](./solutions/1911-maximum-alternating-subsequence-sum.js)|Medium| +1912|[Design Movie Rental System](./solutions/1912-design-movie-rental-system.js)|Hard| +1913|[Maximum Product Difference Between Two Pairs](./solutions/1913-maximum-product-difference-between-two-pairs.js)|Easy| +1914|[Cyclically Rotating a Grid](./solutions/1914-cyclically-rotating-a-grid.js)|Medium| +1915|[Number of Wonderful Substrings](./solutions/1915-number-of-wonderful-substrings.js)|Medium| +1916|[Count Ways to Build Rooms in an Ant Colony](./solutions/1916-count-ways-to-build-rooms-in-an-ant-colony.js)|Hard| 1920|[Build Array from Permutation](./solutions/1920-build-array-from-permutation.js)|Easy| +1921|[Eliminate Maximum Number of Monsters](./solutions/1921-eliminate-maximum-number-of-monsters.js)|Medium| 1922|[Count Good Numbers](./solutions/1922-count-good-numbers.js)|Medium| +1923|[Longest Common Subpath](./solutions/1923-longest-common-subpath.js)|Hard| +1925|[Count Square Sum Triples](./solutions/1925-count-square-sum-triples.js)|Easy| 1926|[Nearest Exit from Entrance in Maze](./solutions/1926-nearest-exit-from-entrance-in-maze.js)|Medium| +1927|[Sum Game](./solutions/1927-sum-game.js)|Medium| +1928|[Minimum Cost to Reach Destination in Time](./solutions/1928-minimum-cost-to-reach-destination-in-time.js)|Hard| 1929|[Concatenation of Array](./solutions/1929-concatenation-of-array.js)|Easy| 1930|[Unique Length-3 Palindromic Subsequences](./solutions/1930-unique-length-3-palindromic-subsequences.js)|Medium| +1931|[Painting a Grid With Three Different Colors](./solutions/1931-painting-a-grid-with-three-different-colors.js)|Hard| +1932|[Merge BSTs to Create Single BST](./solutions/1932-merge-bsts-to-create-single-bst.js)|Hard| 1935|[Maximum Number of Words You Can Type](./solutions/1935-maximum-number-of-words-you-can-type.js)|Easy| +1936|[Add Minimum Number of Rungs](./solutions/1936-add-minimum-number-of-rungs.js)|Medium| +1937|[Maximum Number of Points with Cost](./solutions/1937-maximum-number-of-points-with-cost.js)|Medium| +1938|[Maximum Genetic Difference Query](./solutions/1938-maximum-genetic-difference-query.js)|Hard| +1941|[Check if All Characters Have Equal Number of Occurrences](./solutions/1941-check-if-all-characters-have-equal-number-of-occurrences.js)|Easy| +1943|[Describe the Painting](./solutions/1943-describe-the-painting.js)|Medium| +1944|[Number of Visible People in a Queue](./solutions/1944-number-of-visible-people-in-a-queue.js)|Hard| +1945|[Sum of Digits of String After Convert](./solutions/1945-sum-of-digits-of-string-after-convert.js)|Easy| +1946|[Largest Number After Mutating Substring](./solutions/1946-largest-number-after-mutating-substring.js)|Medium| +1947|[Maximum Compatibility Score Sum](./solutions/1947-maximum-compatibility-score-sum.js)|Medium| +1948|[Delete Duplicate Folders in System](./solutions/1948-delete-duplicate-folders-in-system.js)|Hard| +1952|[Three Divisors](./solutions/1952-three-divisors.js)|Easy| +1953|[Maximum Number of Weeks for Which You Can Work](./solutions/1953-maximum-number-of-weeks-for-which-you-can-work.js)|Medium| +1954|[Minimum Garden Perimeter to Collect Enough Apples](./solutions/1954-minimum-garden-perimeter-to-collect-enough-apples.js)|Medium| +1955|[Count Number of Special Subsequences](./solutions/1955-count-number-of-special-subsequences.js)|Hard| +1957|[Delete Characters to Make Fancy String](./solutions/1957-delete-characters-to-make-fancy-string.js)|Easy| +1958|[Check if Move is Legal](./solutions/1958-check-if-move-is-legal.js)|Medium| +1959|[Minimum Total Space Wasted With K Resizing Operations](./solutions/1959-minimum-total-space-wasted-with-k-resizing-operations.js)|Medium| +1960|[Maximum Product of the Length of Two Palindromic Substrings](./solutions/1960-maximum-product-of-the-length-of-two-palindromic-substrings.js)|Hard| +1961|[Check If String Is a Prefix of Array](./solutions/1961-check-if-string-is-a-prefix-of-array.js)|Easy| +1963|[Minimum Number of Swaps to Make the String Balanced](./solutions/1963-minimum-number-of-swaps-to-make-the-string-balanced.js)|Medium| +1964|[Find the Longest Valid Obstacle Course at Each Position](./solutions/1964-find-the-longest-valid-obstacle-course-at-each-position.js)|Hard| +1967|[Number of Strings That Appear as Substrings in Word](./solutions/1967-number-of-strings-that-appear-as-substrings-in-word.js)|Easy| +1968|[Array With Elements Not Equal to Average of Neighbors](./solutions/1968-array-with-elements-not-equal-to-average-of-neighbors.js)|Medium| +1969|[Minimum Non-Zero Product of the Array Elements](./solutions/1969-minimum-non-zero-product-of-the-array-elements.js)|Medium| +1970|[Last Day Where You Can Still Cross](./solutions/1970-last-day-where-you-can-still-cross.js)|Hard| +1971|[Find if Path Exists in Graph](./solutions/1971-find-if-path-exists-in-graph.js)|Easy| +1974|[Minimum Time to Type Word Using Special Typewriter](./solutions/1974-minimum-time-to-type-word-using-special-typewriter.js)|Easy| +1975|[Maximum Matrix Sum](./solutions/1975-maximum-matrix-sum.js)|Medium| 1976|[Number of Ways to Arrive at Destination](./solutions/1976-number-of-ways-to-arrive-at-destination.js)|Medium| +1977|[Number of Ways to Separate Numbers](./solutions/1977-number-of-ways-to-separate-numbers.js)|Hard| +1979|[Find Greatest Common Divisor of Array](./solutions/1979-find-greatest-common-divisor-of-array.js)|Easy| 1980|[Find Unique Binary String](./solutions/1980-find-unique-binary-string.js)|Medium| +1981|[Minimize the Difference Between Target and Chosen Elements](./solutions/1981-minimize-the-difference-between-target-and-chosen-elements.js)|Medium| +1982|[Find Array Given Subset Sums](./solutions/1982-find-array-given-subset-sums.js)|Hard| +1984|[Minimum Difference Between Highest and Lowest of K Scores](./solutions/1984-minimum-difference-between-highest-and-lowest-of-k-scores.js)|Easy| 1985|[Find the Kth Largest Integer in the Array](./solutions/1985-find-the-kth-largest-integer-in-the-array.js)|Medium| +1986|[Minimum Number of Work Sessions to Finish the Tasks](./solutions/1986-minimum-number-of-work-sessions-to-finish-the-tasks.js)|Medium| +1987|[Number of Unique Good Subsequences](./solutions/1987-number-of-unique-good-subsequences.js)|Hard| +1991|[Find the Middle Index in Array](./solutions/1991-find-the-middle-index-in-array.js)|Easy| +1992|[Find All Groups of Farmland](./solutions/1992-find-all-groups-of-farmland.js)|Medium| +1993|[Operations on Tree](./solutions/1993-operations-on-tree.js)|Medium| +1994|[The Number of Good Subsets](./solutions/1994-the-number-of-good-subsets.js)|Hard| +1995|[Count Special Quadruplets](./solutions/1995-count-special-quadruplets.js)|Easy| 1996|[The Number of Weak Characters in the Game](./solutions/1996-the-number-of-weak-characters-in-the-game.js)|Medium| +1997|[First Day Where You Have Been in All the Rooms](./solutions/1997-first-day-where-you-have-been-in-all-the-rooms.js)|Medium| +1998|[GCD Sort of an Array](./solutions/1998-gcd-sort-of-an-array.js)|Hard| 2000|[Reverse Prefix of Word](./solutions/2000-reverse-prefix-of-word.js)|Easy| +2001|[Number of Pairs of Interchangeable Rectangles](./solutions/2001-number-of-pairs-of-interchangeable-rectangles.js)|Medium| +2002|[Maximum Product of the Length of Two Palindromic Subsequences](./solutions/2002-maximum-product-of-the-length-of-two-palindromic-subsequences.js)|Medium| +2003|[Smallest Missing Genetic Value in Each Subtree](./solutions/2003-smallest-missing-genetic-value-in-each-subtree.js)|Hard| +2006|[Count Number of Pairs With Absolute Difference K](./solutions/2006-count-number-of-pairs-with-absolute-difference-k.js)|Easy| +2007|[Find Original Array From Doubled Array](./solutions/2007-find-original-array-from-doubled-array.js)|Medium| +2008|[Maximum Earnings From Taxi](./solutions/2008-maximum-earnings-from-taxi.js)|Medium| +2009|[Minimum Number of Operations to Make Array Continuous](./solutions/2009-minimum-number-of-operations-to-make-array-continuous.js)|Hard| 2011|[Final Value of Variable After Performing Operations](./solutions/2011-final-value-of-variable-after-performing-operations.js)|Easy| +2012|[Sum of Beauty in the Array](./solutions/2012-sum-of-beauty-in-the-array.js)|Medium| +2013|[Detect Squares](./solutions/2013-detect-squares.js)|Medium| +2014|[Longest Subsequence Repeated k Times](./solutions/2014-longest-subsequence-repeated-k-times.js)|Hard| 2016|[Maximum Difference Between Increasing Elements](./solutions/2016-maximum-difference-between-increasing-elements.js)|Easy| 2017|[Grid Game](./solutions/2017-grid-game.js)|Medium| +2018|[Check if Word Can Be Placed In Crossword](./solutions/2018-check-if-word-can-be-placed-in-crossword.js)|Medium| +2019|[The Score of Students Solving Math Expression](./solutions/2019-the-score-of-students-solving-math-expression.js)|Hard| +2022|[Convert 1D Array Into 2D Array](./solutions/2022-convert-1d-array-into-2d-array.js)|Easy| +2023|[Number of Pairs of Strings With Concatenation Equal to Target](./solutions/2023-number-of-pairs-of-strings-with-concatenation-equal-to-target.js)|Medium| +2024|[Maximize the Confusion of an Exam](./solutions/2024-maximize-the-confusion-of-an-exam.js)|Medium| +2025|[Maximum Number of Ways to Partition an Array](./solutions/2025-maximum-number-of-ways-to-partition-an-array.js)|Hard| 2027|[Minimum Moves to Convert String](./solutions/2027-minimum-moves-to-convert-string.js)|Easy| +2028|[Find Missing Observations](./solutions/2028-find-missing-observations.js)|Medium| +2029|[Stone Game IX](./solutions/2029-stone-game-ix.js)|Medium| +2030|[Smallest K-Length Subsequence With Occurrences of a Letter](./solutions/2030-smallest-k-length-subsequence-with-occurrences-of-a-letter.js)|Hard| +2032|[Two Out of Three](./solutions/2032-two-out-of-three.js)|Easy| 2033|[Minimum Operations to Make a Uni-Value Grid](./solutions/2033-minimum-operations-to-make-a-uni-value-grid.js)|Medium| +2035|[Partition Array Into Two Arrays to Minimize Sum Difference](./solutions/2035-partition-array-into-two-arrays-to-minimize-sum-difference.js)|Hard| 2037|[Minimum Number of Moves to Seat Everyone](./solutions/2037-minimum-number-of-moves-to-seat-everyone.js)|Easy| +2038|[Remove Colored Pieces if Both Neighbors are the Same Color](./solutions/2038-remove-colored-pieces-if-both-neighbors-are-the-same-color.js)|Medium| +2039|[The Time When the Network Becomes Idle](./solutions/2039-the-time-when-the-network-becomes-idle.js)|Medium| +2040|[Kth Smallest Product of Two Sorted Arrays](./solutions/2040-kth-smallest-product-of-two-sorted-arrays.js)|Hard| +2042|[Check if Numbers Are Ascending in a Sentence](./solutions/2042-check-if-numbers-are-ascending-in-a-sentence.js)|Easy| +2043|[Simple Bank System](./solutions/2043-simple-bank-system.js)|Medium| +2044|[Count Number of Maximum Bitwise-OR Subsets](./solutions/2044-count-number-of-maximum-bitwise-or-subsets.js)|Medium| +2045|[Second Minimum Time to Reach Destination](./solutions/2045-second-minimum-time-to-reach-destination.js)|Hard| 2047|[Number of Valid Words in a Sentence](./solutions/2047-number-of-valid-words-in-a-sentence.js)|Easy| +2048|[Next Greater Numerically Balanced Number](./solutions/2048-next-greater-numerically-balanced-number.js)|Medium| +2049|[Count Nodes With the Highest Score](./solutions/2049-count-nodes-with-the-highest-score.js)|Medium| +2050|[Parallel Courses III](./solutions/2050-parallel-courses-iii.js)|Hard| 2053|[Kth Distinct String in an Array](./solutions/2053-kth-distinct-string-in-an-array.js)|Medium| +2055|[Plates Between Candles](./solutions/2055-plates-between-candles.js)|Medium| +2056|[Number of Valid Move Combinations On Chessboard](./solutions/2056-number-of-valid-move-combinations-on-chessboard.js)|Hard| +2057|[Smallest Index With Equal Value](./solutions/2057-smallest-index-with-equal-value.js)|Easy| +2058|[Find the Minimum and Maximum Number of Nodes Between Critical Points](./solutions/2058-find-the-minimum-and-maximum-number-of-nodes-between-critical-points.js)|Medium| +2059|[Minimum Operations to Convert Number](./solutions/2059-minimum-operations-to-convert-number.js)|Medium| +2060|[Check if an Original String Exists Given Two Encoded Strings](./solutions/2060-check-if-an-original-string-exists-given-two-encoded-strings.js)|Hard| +2062|[Count Vowel Substrings of a String](./solutions/2062-count-vowel-substrings-of-a-string.js)|Easy| +2063|[Vowels of All Substrings](./solutions/2063-vowels-of-all-substrings.js)|Medium| +2064|[Minimized Maximum of Products Distributed to Any Store](./solutions/2064-minimized-maximum-of-products-distributed-to-any-store.js)|Medium| +2065|[Maximum Path Quality of a Graph](./solutions/2065-maximum-path-quality-of-a-graph.js)|Hard| +2068|[Check Whether Two Strings are Almost Equivalent](./solutions/2068-check-whether-two-strings-are-almost-equivalent.js)|Easy| +2069|[Walking Robot Simulation II](./solutions/2069-walking-robot-simulation-ii.js)|Medium| +2070|[Most Beautiful Item for Each Query](./solutions/2070-most-beautiful-item-for-each-query.js)|Medium| +2071|[Maximum Number of Tasks You Can Assign](./solutions/2071-maximum-number-of-tasks-you-can-assign.js)|Hard| +2074|[Reverse Nodes in Even Length Groups](./solutions/2074-reverse-nodes-in-even-length-groups.js)|Medium| +2075|[Decode the Slanted Ciphertext](./solutions/2075-decode-the-slanted-ciphertext.js)|Medium| +2076|[Process Restricted Friend Requests](./solutions/2076-process-restricted-friend-requests.js)|Hard| +2078|[Two Furthest Houses With Different Colors](./solutions/2078-two-furthest-houses-with-different-colors.js)|Easy| +2079|[Watering Plants](./solutions/2079-watering-plants.js)|Medium| +2080|[Range Frequency Queries](./solutions/2080-range-frequency-queries.js)|Medium| +2081|[Sum of k-Mirror Numbers](./solutions/2081-sum-of-k-mirror-numbers.js)|Hard| 2085|[Count Common Words With One Occurrence](./solutions/2085-count-common-words-with-one-occurrence.js)|Easy| +2086|[Minimum Number of Food Buckets to Feed the Hamsters](./solutions/2086-minimum-number-of-food-buckets-to-feed-the-hamsters.js)|Medium| +2087|[Minimum Cost Homecoming of a Robot in a Grid](./solutions/2087-minimum-cost-homecoming-of-a-robot-in-a-grid.js)|Medium| +2088|[Count Fertile Pyramids in a Land](./solutions/2088-count-fertile-pyramids-in-a-land.js)|Hard| +2089|[Find Target Indices After Sorting Array](./solutions/2089-find-target-indices-after-sorting-array.js)|Easy| +2090|[K Radius Subarray Averages](./solutions/2090-k-radius-subarray-averages.js)|Medium| +2091|[Removing Minimum and Maximum From Array](./solutions/2091-removing-minimum-and-maximum-from-array.js)|Medium| +2092|[Find All People With Secret](./solutions/2092-find-all-people-with-secret.js)|Hard| +2094|[Finding 3-Digit Even Numbers](./solutions/2094-finding-3-digit-even-numbers.js)|Easy| 2095|[Delete the Middle Node of a Linked List](./solutions/2095-delete-the-middle-node-of-a-linked-list.js)|Medium| +2096|[Step-By-Step Directions From a Binary Tree Node to Another](./solutions/2096-step-by-step-directions-from-a-binary-tree-node-to-another.js)|Medium| +2097|[Valid Arrangement of Pairs](./solutions/2097-valid-arrangement-of-pairs.js)|Hard| 2099|[Find Subsequence of Length K With the Largest Sum](./solutions/2099-find-subsequence-of-length-k-with-the-largest-sum.js)|Medium| +2100|[Find Good Days to Rob the Bank](./solutions/2100-find-good-days-to-rob-the-bank.js)|Medium| +2101|[Detonate the Maximum Bombs](./solutions/2101-detonate-the-maximum-bombs.js)|Medium| +2103|[Rings and Rods](./solutions/2103-rings-and-rods.js)|Easy| +2104|[Sum of Subarray Ranges](./solutions/2104-sum-of-subarray-ranges.js)|Medium| +2105|[Watering Plants II](./solutions/2105-watering-plants-ii.js)|Medium| +2106|[Maximum Fruits Harvested After at Most K Steps](./solutions/2106-maximum-fruits-harvested-after-at-most-k-steps.js)|Hard| +2108|[Find First Palindromic String in the Array](./solutions/2108-find-first-palindromic-string-in-the-array.js)|Easy| +2109|[Adding Spaces to a String](./solutions/2109-adding-spaces-to-a-string.js)|Medium| +2110|[Number of Smooth Descent Periods of a Stock](./solutions/2110-number-of-smooth-descent-periods-of-a-stock.js)|Medium| +2111|[Minimum Operations to Make the Array K-Increasing](./solutions/2111-minimum-operations-to-make-the-array-k-increasing.js)|Hard| 2114|[Maximum Number of Words Found in Sentences](./solutions/2114-maximum-number-of-words-found-in-sentences.js)|Easy| 2115|[Find All Possible Recipes from Given Supplies](./solutions/2115-find-all-possible-recipes-from-given-supplies.js)|Medium| 2116|[Check if a Parentheses String Can Be Valid](./solutions/2116-check-if-a-parentheses-string-can-be-valid.js)|Medium| +2117|[Abbreviating the Product of a Range](./solutions/2117-abbreviating-the-product-of-a-range.js)|Hard| +2119|[A Number After a Double Reversal](./solutions/2119-a-number-after-a-double-reversal.js)|Easy| +2120|[Execution of All Suffix Instructions Staying in a Grid](./solutions/2120-execution-of-all-suffix-instructions-staying-in-a-grid.js)|Medium| +2121|[Intervals Between Identical Elements](./solutions/2121-intervals-between-identical-elements.js)|Medium| +2122|[Recover the Original Array](./solutions/2122-recover-the-original-array.js)|Hard| +2124|[Check if All A's Appears Before All B's](./solutions/2124-check-if-all-as-appears-before-all-bs.js)|Easy| +2125|[Number of Laser Beams in a Bank](./solutions/2125-number-of-laser-beams-in-a-bank.js)|Medium| +2126|[Destroying Asteroids](./solutions/2126-destroying-asteroids.js)|Medium| 2127|[Maximum Employees to Be Invited to a Meeting](./solutions/2127-maximum-employees-to-be-invited-to-a-meeting.js)|Hard| 2129|[Capitalize the Title](./solutions/2129-capitalize-the-title.js)|Easy| 2130|[Maximum Twin Sum of a Linked List](./solutions/2130-maximum-twin-sum-of-a-linked-list.js)|Medium| +2131|[Longest Palindrome by Concatenating Two Letter Words](./solutions/2131-longest-palindrome-by-concatenating-two-letter-words.js)|Medium| +2132|[Stamping the Grid](./solutions/2132-stamping-the-grid.js)|Hard| +2133|[Check if Every Row and Column Contains All Numbers](./solutions/2133-check-if-every-row-and-column-contains-all-numbers.js)|Easy| +2134|[Minimum Swaps to Group All 1's Together II](./solutions/2134-minimum-swaps-to-group-all-1s-together-ii.js)|Medium| +2135|[Count Words Obtained After Adding a Letter](./solutions/2135-count-words-obtained-after-adding-a-letter.js)|Medium| +2136|[Earliest Possible Day of Full Bloom](./solutions/2136-earliest-possible-day-of-full-bloom.js)|Hard| +2138|[Divide a String Into Groups of Size k](./solutions/2138-divide-a-string-into-groups-of-size-k.js)|Easy| +2139|[Minimum Moves to Reach Target Score](./solutions/2139-minimum-moves-to-reach-target-score.js)|Medium| 2140|[Solving Questions With Brainpower](./solutions/2140-solving-questions-with-brainpower.js)|Medium| +2141|[Maximum Running Time of N Computers](./solutions/2141-maximum-running-time-of-n-computers.js)|Hard| +2144|[Minimum Cost of Buying Candies With Discount](./solutions/2144-minimum-cost-of-buying-candies-with-discount.js)|Easy| 2145|[Count the Hidden Sequences](./solutions/2145-count-the-hidden-sequences.js)|Medium| +2147|[Number of Ways to Divide a Long Corridor](./solutions/2147-number-of-ways-to-divide-a-long-corridor.js)|Hard| +2148|[Count Elements With Strictly Smaller and Greater Elements](./solutions/2148-count-elements-with-strictly-smaller-and-greater-elements.js)|Easy| +2149|[Rearrange Array Elements by Sign](./solutions/2149-rearrange-array-elements-by-sign.js)|Medium| +2150|[Find All Lonely Numbers in the Array](./solutions/2150-find-all-lonely-numbers-in-the-array.js)|Medium| +2151|[Maximum Good People Based on Statements](./solutions/2151-maximum-good-people-based-on-statements.js)|Hard| 2154|[Keep Multiplying Found Values by Two](./solutions/2154-keep-multiplying-found-values-by-two.js)|Easy| +2155|[All Divisions With the Highest Score of a Binary Array](./solutions/2155-all-divisions-with-the-highest-score-of-a-binary-array.js)|Medium| +2156|[Find Substring With Given Hash Value](./solutions/2156-find-substring-with-given-hash-value.js)|Hard| +2157|[Groups of Strings](./solutions/2157-groups-of-strings.js)|Hard| +2160|[Minimum Sum of Four Digit Number After Splitting Digits](./solutions/2160-minimum-sum-of-four-digit-number-after-splitting-digits.js)|Easy| 2161|[Partition Array According to Given Pivot](./solutions/2161-partition-array-according-to-given-pivot.js)|Medium| +2162|[Minimum Cost to Set Cooking Time](./solutions/2162-minimum-cost-to-set-cooking-time.js)|Medium| +2164|[Sort Even and Odd Indices Independently](./solutions/2164-sort-even-and-odd-indices-independently.js)|Easy| +2165|[Smallest Value of the Rearranged Number](./solutions/2165-smallest-value-of-the-rearranged-number.js)|Medium| +2166|[Design Bitset](./solutions/2166-design-bitset.js)|Medium| +2167|[Minimum Time to Remove All Cars Containing Illegal Goods](./solutions/2167-minimum-time-to-remove-all-cars-containing-illegal-goods.js)|Hard| +2169|[Count Operations to Obtain Zero](./solutions/2169-count-operations-to-obtain-zero.js)|Easy| +2170|[Minimum Operations to Make the Array Alternating](./solutions/2170-minimum-operations-to-make-the-array-alternating.js)|Medium| +2171|[Removing Minimum Number of Magic Beans](./solutions/2171-removing-minimum-number-of-magic-beans.js)|Medium| +2172|[Maximum AND Sum of Array](./solutions/2172-maximum-and-sum-of-array.js)|Hard| 2176|[Count Equal and Divisible Pairs in an Array](./solutions/2176-count-equal-and-divisible-pairs-in-an-array.js)|Easy| +2177|[Find Three Consecutive Integers That Sum to a Given Number](./solutions/2177-find-three-consecutive-integers-that-sum-to-a-given-number.js)|Medium| +2178|[Maximum Split of Positive Even Integers](./solutions/2178-maximum-split-of-positive-even-integers.js)|Medium| 2179|[Count Good Triplets in an Array](./solutions/2179-count-good-triplets-in-an-array.js)|Hard| +2180|[Count Integers With Even Digit Sum](./solutions/2180-count-integers-with-even-digit-sum.js)|Easy| +2181|[Merge Nodes in Between Zeros](./solutions/2181-merge-nodes-in-between-zeros.js)|Medium| +2183|[Count Array Pairs Divisible by K](./solutions/2183-count-array-pairs-divisible-by-k.js)|Hard| 2185|[Counting Words With a Given Prefix](./solutions/2185-counting-words-with-a-given-prefix.js)|Easy| +2186|[Minimum Number of Steps to Make Two Strings Anagram II](./solutions/2186-minimum-number-of-steps-to-make-two-strings-anagram-ii.js)|Medium| +2187|[Minimum Time to Complete Trips](./solutions/2187-minimum-time-to-complete-trips.js)|Medium| +2188|[Minimum Time to Finish the Race](./solutions/2188-minimum-time-to-finish-the-race.js)|Hard| +2190|[Most Frequent Number Following Key In an Array](./solutions/2190-most-frequent-number-following-key-in-an-array.js)|Easy| +2191|[Sort the Jumbled Numbers](./solutions/2191-sort-the-jumbled-numbers.js)|Medium| +2192|[All Ancestors of a Node in a Directed Acyclic Graph](./solutions/2192-all-ancestors-of-a-node-in-a-directed-acyclic-graph.js)|Medium| +2193|[Minimum Number of Moves to Make Palindrome](./solutions/2193-minimum-number-of-moves-to-make-palindrome.js)|Hard| +2194|[Cells in a Range on an Excel Sheet](./solutions/2194-cells-in-a-range-on-an-excel-sheet.js)|Easy| +2195|[Append K Integers With Minimal Sum](./solutions/2195-append-k-integers-with-minimal-sum.js)|Medium| +2196|[Create Binary Tree From Descriptions](./solutions/2196-create-binary-tree-from-descriptions.js)|Medium| +2197|[Replace Non-Coprime Numbers in Array](./solutions/2197-replace-non-coprime-numbers-in-array.js)|Hard| +2200|[Find All K-Distant Indices in an Array](./solutions/2200-find-all-k-distant-indices-in-an-array.js)|Easy| +2201|[Count Artifacts That Can Be Extracted](./solutions/2201-count-artifacts-that-can-be-extracted.js)|Medium| +2202|[Maximize the Topmost Element After K Moves](./solutions/2202-maximize-the-topmost-element-after-k-moves.js)|Medium| +2203|[Minimum Weighted Subgraph With the Required Paths](./solutions/2203-minimum-weighted-subgraph-with-the-required-paths.js)|Hard| 2206|[Divide Array Into Equal Pairs](./solutions/2206-divide-array-into-equal-pairs.js)|Easy| +2207|[Maximize Number of Subsequences in a String](./solutions/2207-maximize-number-of-subsequences-in-a-string.js)|Medium| +2209|[Minimum White Tiles After Covering With Carpets](./solutions/2209-minimum-white-tiles-after-covering-with-carpets.js)|Hard| +2210|[Count Hills and Valleys in an Array](./solutions/2210-count-hills-and-valleys-in-an-array.js)|Easy| +2211|[Count Collisions on a Road](./solutions/2211-count-collisions-on-a-road.js)|Medium| +2212|[Maximum Points in an Archery Competition](./solutions/2212-maximum-points-in-an-archery-competition.js)|Medium| +2213|[Longest Substring of One Repeating Character](./solutions/2213-longest-substring-of-one-repeating-character.js)|Hard| 2215|[Find the Difference of Two Arrays](./solutions/2215-find-the-difference-of-two-arrays.js)|Easy| +2216|[Minimum Deletions to Make Array Beautiful](./solutions/2216-minimum-deletions-to-make-array-beautiful.js)|Medium| +2217|[Find Palindrome With Fixed Length](./solutions/2217-find-palindrome-with-fixed-length.js)|Medium| +2218|[Maximum Value of K Coins From Piles](./solutions/2218-maximum-value-of-k-coins-from-piles.js)|Hard| +2220|[Minimum Bit Flips to Convert Number](./solutions/2220-minimum-bit-flips-to-convert-number.js)|Easy| +2221|[Find Triangular Sum of an Array](./solutions/2221-find-triangular-sum-of-an-array.js)|Medium| +2222|[Number of Ways to Select Buildings](./solutions/2222-number-of-ways-to-select-buildings.js)|Medium| +2223|[Sum of Scores of Built Strings](./solutions/2223-sum-of-scores-of-built-strings.js)|Hard| +2224|[Minimum Number of Operations to Convert Time](./solutions/2224-minimum-number-of-operations-to-convert-time.js)|Easy| +2225|[Find Players With Zero or One Losses](./solutions/2225-find-players-with-zero-or-one-losses.js)|Medium| 2226|[Maximum Candies Allocated to K Children](./solutions/2226-maximum-candies-allocated-to-k-children.js)|Medium| +2227|[Encrypt and Decrypt Strings](./solutions/2227-encrypt-and-decrypt-strings.js)|Hard| +2232|[Minimize Result by Adding Parentheses to Expression](./solutions/2232-minimize-result-by-adding-parentheses-to-expression.js)|Medium| +2234|[Maximum Total Beauty of the Gardens](./solutions/2234-maximum-total-beauty-of-the-gardens.js)|Hard| 2235|[Add Two Integers](./solutions/2235-add-two-integers.js)|Easy| +2236|[Root Equals Sum of Children](./solutions/2236-root-equals-sum-of-children.js)|Easy| +2239|[Find Closest Number to Zero](./solutions/2239-find-closest-number-to-zero.js)|Easy| +2240|[Number of Ways to Buy Pens and Pencils](./solutions/2240-number-of-ways-to-buy-pens-and-pencils.js)|Medium| +2241|[Design an ATM Machine](./solutions/2241-design-an-atm-machine.js)|Medium| +2242|[Maximum Score of a Node Sequence](./solutions/2242-maximum-score-of-a-node-sequence.js)|Hard| +2243|[Calculate Digit Sum of a String](./solutions/2243-calculate-digit-sum-of-a-string.js)|Easy| 2244|[Minimum Rounds to Complete All Tasks](./solutions/2244-minimum-rounds-to-complete-all-tasks.js)|Medium| +2245|[Maximum Trailing Zeros in a Cornered Path](./solutions/2245-maximum-trailing-zeros-in-a-cornered-path.js)|Medium| +2246|[Longest Path With Different Adjacent Characters](./solutions/2246-longest-path-with-different-adjacent-characters.js)|Hard| +2248|[Intersection of Multiple Arrays](./solutions/2248-intersection-of-multiple-arrays.js)|Easy| +2249|[Count Lattice Points Inside a Circle](./solutions/2249-count-lattice-points-inside-a-circle.js)|Medium| +2250|[Count Number of Rectangles Containing Each Point](./solutions/2250-count-number-of-rectangles-containing-each-point.js)|Medium| +2251|[Number of Flowers in Full Bloom](./solutions/2251-number-of-flowers-in-full-bloom.js)|Hard| +2255|[Count Prefixes of a Given String](./solutions/2255-count-prefixes-of-a-given-string.js)|Easy| +2256|[Minimum Average Difference](./solutions/2256-minimum-average-difference.js)|Medium| +2257|[Count Unguarded Cells in the Grid](./solutions/2257-count-unguarded-cells-in-the-grid.js)|Medium| +2258|[Escape the Spreading Fire](./solutions/2258-escape-the-spreading-fire.js)|Hard| +2259|[Remove Digit From Number to Maximize Result](./solutions/2259-remove-digit-from-number-to-maximize-result.js)|Easy| +2260|[Minimum Consecutive Cards to Pick Up](./solutions/2260-minimum-consecutive-cards-to-pick-up.js)|Medium| +2261|[K Divisible Elements Subarrays](./solutions/2261-k-divisible-elements-subarrays.js)|Medium| +2262|[Total Appeal of A String](./solutions/2262-total-appeal-of-a-string.js)|Hard| +2264|[Largest 3-Same-Digit Number in String](./solutions/2264-largest-3-same-digit-number-in-string.js)|Easy| +2265|[Count Nodes Equal to Average of Subtree](./solutions/2265-count-nodes-equal-to-average-of-subtree.js)|Medium| +2266|[Count Number of Texts](./solutions/2266-count-number-of-texts.js)|Medium| +2267|[Check if There Is a Valid Parentheses String Path](./solutions/2267-check-if-there-is-a-valid-parentheses-string-path.js)|Hard| +2269|[Find the K-Beauty of a Number](./solutions/2269-find-the-k-beauty-of-a-number.js)|Easy| 2270|[Number of Ways to Split Array](./solutions/2270-number-of-ways-to-split-array.js)|Medium| +2271|[Maximum White Tiles Covered by a Carpet](./solutions/2271-maximum-white-tiles-covered-by-a-carpet.js)|Medium| +2272|[Substring With Largest Variance](./solutions/2272-substring-with-largest-variance.js)|Hard| +2273|[Find Resultant Array After Removing Anagrams](./solutions/2273-find-resultant-array-after-removing-anagrams.js)|Easy| +2274|[Maximum Consecutive Floors Without Special Floors](./solutions/2274-maximum-consecutive-floors-without-special-floors.js)|Medium| +2275|[Largest Combination With Bitwise AND Greater Than Zero](./solutions/2275-largest-combination-with-bitwise-and-greater-than-zero.js)|Medium| +2278|[Percentage of Letter in String](./solutions/2278-percentage-of-letter-in-string.js)|Easy| +2279|[Maximum Bags With Full Capacity of Rocks](./solutions/2279-maximum-bags-with-full-capacity-of-rocks.js)|Medium| +2280|[Minimum Lines to Represent a Line Chart](./solutions/2280-minimum-lines-to-represent-a-line-chart.js)|Medium| +2283|[Check if Number Has Equal Digit Count and Digit Value](./solutions/2283-check-if-number-has-equal-digit-count-and-digit-value.js)|Easy| +2284|[Sender With Largest Word Count](./solutions/2284-sender-with-largest-word-count.js)|Medium| +2287|[Rearrange Characters to Make Target String](./solutions/2287-rearrange-characters-to-make-target-string.js)|Easy| +2288|[Apply Discount to Prices](./solutions/2288-apply-discount-to-prices.js)|Medium| +2293|[Min Max Game](./solutions/2293-min-max-game.js)|Easy| +2294|[Partition Array Such That Maximum Difference Is K](./solutions/2294-partition-array-such-that-maximum-difference-is-k.js)|Medium| +2295|[Replace Elements in an Array](./solutions/2295-replace-elements-in-an-array.js)|Medium| +2296|[Design a Text Editor](./solutions/2296-design-a-text-editor.js)|Hard| +2299|[Strong Password Checker II](./solutions/2299-strong-password-checker-ii.js)|Easy| 2300|[Successful Pairs of Spells and Potions](./solutions/2300-successful-pairs-of-spells-and-potions.js)|Medium| +2301|[Match Substring After Replacement](./solutions/2301-match-substring-after-replacement.js)|Hard| 2302|[Count Subarrays With Score Less Than K](./solutions/2302-count-subarrays-with-score-less-than-k.js)|Hard| +2303|[Calculate Amount Paid in Taxes](./solutions/2303-calculate-amount-paid-in-taxes.js)|Easy| +2304|[Minimum Path Cost in a Grid](./solutions/2304-minimum-path-cost-in-a-grid.js)|Medium| +2305|[Fair Distribution of Cookies](./solutions/2305-fair-distribution-of-cookies.js)|Medium| +2306|[Naming a Company](./solutions/2306-naming-a-company.js)|Hard| +2309|[Greatest English Letter in Upper and Lower Case](./solutions/2309-greatest-english-letter-in-upper-and-lower-case.js)|Easy| +2312|[Selling Pieces of Wood](./solutions/2312-selling-pieces-of-wood.js)|Hard| +2315|[Count Asterisks](./solutions/2315-count-asterisks.js)|Easy| +2316|[Count Unreachable Pairs of Nodes in an Undirected Graph](./solutions/2316-count-unreachable-pairs-of-nodes-in-an-undirected-graph.js)|Medium| +2317|[Maximum XOR After Operations](./solutions/2317-maximum-xor-after-operations.js)|Medium| +2318|[Number of Distinct Roll Sequences](./solutions/2318-number-of-distinct-roll-sequences.js)|Hard| +2319|[Check if Matrix Is X-Matrix](./solutions/2319-check-if-matrix-is-x-matrix.js)|Easy| +2320|[Count Number of Ways to Place Houses](./solutions/2320-count-number-of-ways-to-place-houses.js)|Medium| +2321|[Maximum Score Of Spliced Array](./solutions/2321-maximum-score-of-spliced-array.js)|Hard| +2322|[Minimum Score After Removals on a Tree](./solutions/2322-minimum-score-after-removals-on-a-tree.js)|Hard| +2325|[Decode the Message](./solutions/2325-decode-the-message.js)|Easy| +2326|[Spiral Matrix IV](./solutions/2326-spiral-matrix-iv.js)|Medium| +2328|[Number of Increasing Paths in a Grid](./solutions/2328-number-of-increasing-paths-in-a-grid.js)|Hard| +2331|[Evaluate Boolean Binary Tree](./solutions/2331-evaluate-boolean-binary-tree.js)|Easy| +2334|[Subarray With Elements Greater Than Varying Threshold](./solutions/2334-subarray-with-elements-greater-than-varying-threshold.js)|Hard| 2336|[Smallest Number in Infinite Set](./solutions/2336-smallest-number-in-infinite-set.js)|Medium| +2337|[Move Pieces to Obtain a String](./solutions/2337-move-pieces-to-obtain-a-string.js)|Medium| 2338|[Count the Number of Ideal Arrays](./solutions/2338-count-the-number-of-ideal-arrays.js)|Hard| +2341|[Maximum Number of Pairs in Array](./solutions/2341-maximum-number-of-pairs-in-array.js)|Easy| 2342|[Max Sum of a Pair With Equal Sum of Digits](./solutions/2342-max-sum-of-a-pair-with-equal-sum-of-digits.js)|Medium| +2347|[Best Poker Hand](./solutions/2347-best-poker-hand.js)|Easy| +2348|[Number of Zero-Filled Subarrays](./solutions/2348-number-of-zero-filled-subarrays.js)|Medium| 2349|[Design a Number Container System](./solutions/2349-design-a-number-container-system.js)|Medium| +2350|[Shortest Impossible Sequence of Rolls](./solutions/2350-shortest-impossible-sequence-of-rolls.js)|Hard| +2351|[First Letter to Appear Twice](./solutions/2351-first-letter-to-appear-twice.js)|Easy| 2352|[Equal Row and Column Pairs](./solutions/2352-equal-row-and-column-pairs.js)|Medium| +2354|[Number of Excellent Pairs](./solutions/2354-number-of-excellent-pairs.js)|Hard| +2358|[Maximum Number of Groups Entering a Competition](./solutions/2358-maximum-number-of-groups-entering-a-competition.js)|Medium| +2359|[Find Closest Node to Given Two Nodes](./solutions/2359-find-closest-node-to-given-two-nodes.js)|Medium| +2360|[Longest Cycle in a Graph](./solutions/2360-longest-cycle-in-a-graph.js)|Hard| +2363|[Merge Similar Items](./solutions/2363-merge-similar-items.js)|Easy| 2364|[Count Number of Bad Pairs](./solutions/2364-count-number-of-bad-pairs.js)|Medium| +2365|[Task Scheduler II](./solutions/2365-task-scheduler-ii.js)|Medium| +2366|[Minimum Replacements to Sort the Array](./solutions/2366-minimum-replacements-to-sort-the-array.js)|Hard| +2367|[Number of Arithmetic Triplets](./solutions/2367-number-of-arithmetic-triplets.js)|Easy| +2368|[Reachable Nodes With Restrictions](./solutions/2368-reachable-nodes-with-restrictions.js)|Medium| +2369|[Check if There is a Valid Partition For The Array](./solutions/2369-check-if-there-is-a-valid-partition-for-the-array.js)|Medium| +2370|[Longest Ideal Subsequence](./solutions/2370-longest-ideal-subsequence.js)|Medium| +2373|[Largest Local Values in a Matrix](./solutions/2373-largest-local-values-in-a-matrix.js)|Easy| +2374|[Node With Highest Edge Score](./solutions/2374-node-with-highest-edge-score.js)|Medium| 2375|[Construct Smallest Number From DI String](./solutions/2375-construct-smallest-number-from-di-string.js)|Medium| +2376|[Count Special Integers](./solutions/2376-count-special-integers.js)|Hard| 2379|[Minimum Recolors to Get K Consecutive Black Blocks](./solutions/2379-minimum-recolors-to-get-k-consecutive-black-blocks.js)|Easy| +2380|[Time Needed to Rearrange a Binary String](./solutions/2380-time-needed-to-rearrange-a-binary-string.js)|Medium| 2381|[Shifting Letters II](./solutions/2381-shifting-letters-ii.js)|Medium| +2382|[Maximum Segment Sum After Removals](./solutions/2382-maximum-segment-sum-after-removals.js)|Hard| +2383|[Minimum Hours of Training to Win a Competition](./solutions/2383-minimum-hours-of-training-to-win-a-competition.js)|Easy| +2385|[Amount of Time for Binary Tree to Be Infected](./solutions/2385-amount-of-time-for-binary-tree-to-be-infected.js)|Medium| +2389|[Longest Subsequence With Limited Sum](./solutions/2389-longest-subsequence-with-limited-sum.js)|Easy| 2390|[Removing Stars From a String](./solutions/2390-removing-stars-from-a-string.js)|Medium| +2391|[Minimum Amount of Time to Collect Garbage](./solutions/2391-minimum-amount-of-time-to-collect-garbage.js)|Medium| +2392|[Build a Matrix With Conditions](./solutions/2392-build-a-matrix-with-conditions.js)|Hard| +2395|[Find Subarrays With Equal Sum](./solutions/2395-find-subarrays-with-equal-sum.js)|Easy| 2396|[Strictly Palindromic Number](./solutions/2396-strictly-palindromic-number.js)|Medium| +2397|[Maximum Rows Covered by Columns](./solutions/2397-maximum-rows-covered-by-columns.js)|Medium| +2399|[Check Distances Between Same Letters](./solutions/2399-check-distances-between-same-letters.js)|Easy| 2401|[Longest Nice Subarray](./solutions/2401-longest-nice-subarray.js)|Medium| +2404|[Most Frequent Even Element](./solutions/2404-most-frequent-even-element.js)|Easy| +2405|[Optimal Partition of String](./solutions/2405-optimal-partition-of-string.js)|Medium| +2409|[Count Days Spent Together](./solutions/2409-count-days-spent-together.js)|Easy| +2410|[Maximum Matching of Players With Trainers](./solutions/2410-maximum-matching-of-players-with-trainers.js)|Medium| +2411|[Smallest Subarrays With Maximum Bitwise OR](./solutions/2411-smallest-subarrays-with-maximum-bitwise-or.js)|Medium| +2412|[Minimum Money Required Before Transactions](./solutions/2412-minimum-money-required-before-transactions.js)|Hard| 2413|[Smallest Even Multiple](./solutions/2413-smallest-even-multiple.js)|Easy| +2414|[Length of the Longest Alphabetical Continuous Substring](./solutions/2414-length-of-the-longest-alphabetical-continuous-substring.js)|Medium| +2415|[Reverse Odd Levels of Binary Tree](./solutions/2415-reverse-odd-levels-of-binary-tree.js)|Medium| +2416|[Sum of Prefix Scores of Strings](./solutions/2416-sum-of-prefix-scores-of-strings.js)|Hard| +2418|[Sort the People](./solutions/2418-sort-the-people.js)|Easy| +2419|[Longest Subarray With Maximum Bitwise AND](./solutions/2419-longest-subarray-with-maximum-bitwise-and.js)|Medium| +2420|[Find All Good Indices](./solutions/2420-find-all-good-indices.js)|Medium| +2421|[Number of Good Paths](./solutions/2421-number-of-good-paths.js)|Hard| 2425|[Bitwise XOR of All Pairings](./solutions/2425-bitwise-xor-of-all-pairings.js)|Medium| +2426|[Number of Pairs Satisfying Inequality](./solutions/2426-number-of-pairs-satisfying-inequality.js)|Hard| 2427|[Number of Common Factors](./solutions/2427-number-of-common-factors.js)|Easy| +2428|[Maximum Sum of an Hourglass](./solutions/2428-maximum-sum-of-an-hourglass.js)|Medium| 2429|[Minimize XOR](./solutions/2429-minimize-xor.js)|Medium| +2432|[The Employee That Worked on the Longest Task](./solutions/2432-the-employee-that-worked-on-the-longest-task.js)|Easy| +2433|[Find The Original Array of Prefix Xor](./solutions/2433-find-the-original-array-of-prefix-xor.js)|Medium| +2434|[Using a Robot to Print the Lexicographically Smallest String](./solutions/2434-using-a-robot-to-print-the-lexicographically-smallest-string.js)|Medium| +2435|[Paths in Matrix Whose Sum Is Divisible by K](./solutions/2435-paths-in-matrix-whose-sum-is-divisible-by-k.js)|Hard| +2437|[Number of Valid Clock Times](./solutions/2437-number-of-valid-clock-times.js)|Easy| +2438|[Range Product Queries of Powers](./solutions/2438-range-product-queries-of-powers.js)|Medium| +2439|[Minimize Maximum of Array](./solutions/2439-minimize-maximum-of-array.js)|Medium| +2440|[Create Components With Same Value](./solutions/2440-create-components-with-same-value.js)|Hard| +2441|[Largest Positive Integer That Exists With Its Negative](./solutions/2441-largest-positive-integer-that-exists-with-its-negative.js)|Easy| +2442|[Count Number of Distinct Integers After Reverse Operations](./solutions/2442-count-number-of-distinct-integers-after-reverse-operations.js)|Medium| +2443|[Sum of Number and Its Reverse](./solutions/2443-sum-of-number-and-its-reverse.js)|Medium| 2444|[Count Subarrays With Fixed Bounds](./solutions/2444-count-subarrays-with-fixed-bounds.js)|Hard| +2446|[Determine if Two Events Have Conflict](./solutions/2446-determine-if-two-events-have-conflict.js)|Easy| +2447|[Number of Subarrays With GCD Equal to K](./solutions/2447-number-of-subarrays-with-gcd-equal-to-k.js)|Medium| +2448|[Minimum Cost to Make Array Equal](./solutions/2448-minimum-cost-to-make-array-equal.js)|Hard| +2449|[Minimum Number of Operations to Make Arrays Similar](./solutions/2449-minimum-number-of-operations-to-make-arrays-similar.js)|Hard| +2451|[Odd String Difference](./solutions/2451-odd-string-difference.js)|Easy| +2452|[Words Within Two Edits of Dictionary](./solutions/2452-words-within-two-edits-of-dictionary.js)|Medium| +2453|[Destroy Sequential Targets](./solutions/2453-destroy-sequential-targets.js)|Medium| +2455|[Average Value of Even Numbers That Are Divisible by Three](./solutions/2455-average-value-of-even-numbers-that-are-divisible-by-three.js)|Easy| +2458|[Height of Binary Tree After Subtree Removal Queries](./solutions/2458-height-of-binary-tree-after-subtree-removal-queries.js)|Hard| 2460|[Apply Operations to an Array](./solutions/2460-apply-operations-to-an-array.js)|Easy| +2461|[Maximum Sum of Distinct Subarrays With Length K](./solutions/2461-maximum-sum-of-distinct-subarrays-with-length-k.js)|Medium| 2462|[Total Cost to Hire K Workers](./solutions/2462-total-cost-to-hire-k-workers.js)|Medium| +2463|[Minimum Total Distance Traveled](./solutions/2463-minimum-total-distance-traveled.js)|Hard| +2465|[Number of Distinct Averages](./solutions/2465-number-of-distinct-averages.js)|Easy| +2466|[Count Ways To Build Good Strings](./solutions/2466-count-ways-to-build-good-strings.js)|Medium| 2467|[Most Profitable Path in a Tree](./solutions/2467-most-profitable-path-in-a-tree.js)|Medium| +2468|[Split Message Based on Limit](./solutions/2468-split-message-based-on-limit.js)|Hard| 2469|[Convert the Temperature](./solutions/2469-convert-the-temperature.js)|Easy| +2470|[Number of Subarrays With LCM Equal to K](./solutions/2470-number-of-subarrays-with-lcm-equal-to-k.js)|Medium| +2471|[Minimum Number of Operations to Sort a Binary Tree by Level](./solutions/2471-minimum-number-of-operations-to-sort-a-binary-tree-by-level.js)|Medium| +2472|[Maximum Number of Non-overlapping Palindrome Substrings](./solutions/2472-maximum-number-of-non-overlapping-palindrome-substrings.js)|Hard| +2475|[Number of Unequal Triplets in Array](./solutions/2475-number-of-unequal-triplets-in-array.js)|Easy| +2476|[Closest Nodes Queries in a Binary Search Tree](./solutions/2476-closest-nodes-queries-in-a-binary-search-tree.js)|Medium| +2477|[Minimum Fuel Cost to Report to the Capital](./solutions/2477-minimum-fuel-cost-to-report-to-the-capital.js)|Medium| +2481|[Minimum Cuts to Divide a Circle](./solutions/2481-minimum-cuts-to-divide-a-circle.js)|Easy| 2482|[Difference Between Ones and Zeros in Row and Column](./solutions/2482-difference-between-ones-and-zeros-in-row-and-column.js)|Medium| +2483|[Minimum Penalty for a Shop](./solutions/2483-minimum-penalty-for-a-shop.js)|Medium| +2484|[Count Palindromic Subsequences](./solutions/2484-count-palindromic-subsequences.js)|Hard| +2485|[Find the Pivot Integer](./solutions/2485-find-the-pivot-integer.js)|Easy| +2486|[Append Characters to String to Make Subsequence](./solutions/2486-append-characters-to-string-to-make-subsequence.js)|Medium| +2487|[Remove Nodes From Linked List](./solutions/2487-remove-nodes-from-linked-list.js)|Medium| +2488|[Count Subarrays With Median K](./solutions/2488-count-subarrays-with-median-k.js)|Hard| 2490|[Circular Sentence](./solutions/2490-circular-sentence.js)|Easy| +2491|[Divide Players Into Teams of Equal Skill](./solutions/2491-divide-players-into-teams-of-equal-skill.js)|Medium| +2492|[Minimum Score of a Path Between Two Cities](./solutions/2492-minimum-score-of-a-path-between-two-cities.js)|Medium| 2493|[Divide Nodes Into the Maximum Number of Groups](./solutions/2493-divide-nodes-into-the-maximum-number-of-groups.js)|Hard| +2496|[Maximum Value of a String in an Array](./solutions/2496-maximum-value-of-a-string-in-an-array.js)|Easy| +2498|[Frog Jump II](./solutions/2498-frog-jump-ii.js)|Medium| +2499|[Minimum Total Cost to Make Arrays Unequal](./solutions/2499-minimum-total-cost-to-make-arrays-unequal.js)|Hard| +2501|[Longest Square Streak in an Array](./solutions/2501-longest-square-streak-in-an-array.js)|Medium| +2502|[Design Memory Allocator](./solutions/2502-design-memory-allocator.js)|Medium| 2503|[Maximum Number of Points From Grid Queries](./solutions/2503-maximum-number-of-points-from-grid-queries.js)|Hard| +2506|[Count Pairs Of Similar Strings](./solutions/2506-count-pairs-of-similar-strings.js)|Easy| +2507|[Smallest Value After Replacing With Sum of Prime Factors](./solutions/2507-smallest-value-after-replacing-with-sum-of-prime-factors.js)|Medium| +2509|[Cycle Length Queries in a Tree](./solutions/2509-cycle-length-queries-in-a-tree.js)|Hard| +2511|[Maximum Enemy Forts That Can Be Captured](./solutions/2511-maximum-enemy-forts-that-can-be-captured.js)|Easy| +2515|[Shortest Distance to Target String in a Circular Array](./solutions/2515-shortest-distance-to-target-string-in-a-circular-array.js)|Easy| +2516|[Take K of Each Character From Left and Right](./solutions/2516-take-k-of-each-character-from-left-and-right.js)|Medium| +2517|[Maximum Tastiness of Candy Basket](./solutions/2517-maximum-tastiness-of-candy-basket.js)|Medium| +2520|[Count the Digits That Divide a Number](./solutions/2520-count-the-digits-that-divide-a-number.js)|Easy| +2521|[Distinct Prime Factors of Product of Array](./solutions/2521-distinct-prime-factors-of-product-of-array.js)|Medium| +2522|[Partition String Into Substrings With Values at Most K](./solutions/2522-partition-string-into-substrings-with-values-at-most-k.js)|Medium| 2523|[Closest Prime Numbers in Range](./solutions/2523-closest-prime-numbers-in-range.js)|Medium| +2527|[Find Xor-Beauty of Array](./solutions/2527-find-xor-beauty-of-array.js)|Medium| 2529|[Maximum Count of Positive Integer and Negative Integer](./solutions/2529-maximum-count-of-positive-integer-and-negative-integer.js)|Easy| 2535|[Difference Between Element Sum and Digit Sum of an Array](./solutions/2535-difference-between-element-sum-and-digit-sum-of-an-array.js)|Easy| +2536|[Increment Submatrices by One](./solutions/2536-increment-submatrices-by-one.js)|Medium| 2537|[Count the Number of Good Subarrays](./solutions/2537-count-the-number-of-good-subarrays.js)|Medium| +2540|[Minimum Common Value](./solutions/2540-minimum-common-value.js)|Easy| 2542|[Maximum Subsequence Score](./solutions/2542-maximum-subsequence-score.js)|Medium| +2543|[Check if Point Is Reachable](./solutions/2543-check-if-point-is-reachable.js)|Hard| +2544|[Alternating Digit Sum](./solutions/2544-alternating-digit-sum.js)|Easy| +2545|[Sort the Students by Their Kth Score](./solutions/2545-sort-the-students-by-their-kth-score.js)|Medium| +2546|[Apply Bitwise Operations to Make Strings Equal](./solutions/2546-apply-bitwise-operations-to-make-strings-equal.js)|Medium| +2547|[Minimum Cost to Split an Array](./solutions/2547-minimum-cost-to-split-an-array.js)|Hard| +2549|[Count Distinct Numbers on Board](./solutions/2549-count-distinct-numbers-on-board.js)|Easy| 2551|[Put Marbles in Bags](./solutions/2551-put-marbles-in-bags.js)|Hard| +2553|[Separate the Digits in an Array](./solutions/2553-separate-the-digits-in-an-array.js)|Easy| +2554|[Maximum Number of Integers to Choose From a Range I](./solutions/2554-maximum-number-of-integers-to-choose-from-a-range-i.js)|Medium| 2559|[Count Vowel Strings in Ranges](./solutions/2559-count-vowel-strings-in-ranges.js)|Medium| 2560|[House Robber IV](./solutions/2560-house-robber-iv.js)|Medium| +2562|[Find the Array Concatenation Value](./solutions/2562-find-the-array-concatenation-value.js)|Easy| 2563|[Count the Number of Fair Pairs](./solutions/2563-count-the-number-of-fair-pairs.js)|Medium| +2566|[Maximum Difference by Remapping a Digit](./solutions/2566-maximum-difference-by-remapping-a-digit.js)|Easy| +2567|[Minimum Score by Changing Two Elements](./solutions/2567-minimum-score-by-changing-two-elements.js)|Medium| +2568|[Minimum Impossible OR](./solutions/2568-minimum-impossible-or.js)|Medium| 2570|[Merge Two 2D Arrays by Summing Values](./solutions/2570-merge-two-2d-arrays-by-summing-values.js)|Easy| +2571|[Minimum Operations to Reduce an Integer to 0](./solutions/2571-minimum-operations-to-reduce-an-integer-to-0.js)|Medium| +2574|[Left and Right Sum Differences](./solutions/2574-left-and-right-sum-differences.js)|Easy| +2576|[Find the Maximum Number of Marked Indices](./solutions/2576-find-the-maximum-number-of-marked-indices.js)|Medium| +2578|[Split With Minimum Sum](./solutions/2578-split-with-minimum-sum.js)|Easy| 2579|[Count Total Number of Colored Cells](./solutions/2579-count-total-number-of-colored-cells.js)|Medium| +2581|[Count Number of Possible Root Nodes](./solutions/2581-count-number-of-possible-root-nodes.js)|Hard| +2582|[Pass the Pillow](./solutions/2582-pass-the-pillow.js)|Easy| +2583|[Kth Largest Sum in a Binary Tree](./solutions/2583-kth-largest-sum-in-a-binary-tree.js)|Medium| +2585|[Number of Ways to Earn Points](./solutions/2585-number-of-ways-to-earn-points.js)|Hard| +2586|[Count the Number of Vowel Strings in Range](./solutions/2586-count-the-number-of-vowel-strings-in-range.js)|Easy| +2587|[Rearrange Array to Maximize Prefix Score](./solutions/2587-rearrange-array-to-maximize-prefix-score.js)|Medium| +2588|[Count the Number of Beautiful Subarrays](./solutions/2588-count-the-number-of-beautiful-subarrays.js)|Medium| +2592|[Maximize Greatness of an Array](./solutions/2592-maximize-greatness-of-an-array.js)|Medium| 2594|[Minimum Time to Repair Cars](./solutions/2594-minimum-time-to-repair-cars.js)|Medium| +2595|[Number of Even and Odd Bits](./solutions/2595-number-of-even-and-odd-bits.js)|Easy| +2596|[Check Knight Tour Configuration](./solutions/2596-check-knight-tour-configuration.js)|Medium| +2597|[The Number of Beautiful Subsets](./solutions/2597-the-number-of-beautiful-subsets.js)|Medium| +2598|[Smallest Missing Non-negative Integer After Operations](./solutions/2598-smallest-missing-non-negative-integer-after-operations.js)|Medium| +2600|[K Items With the Maximum Sum](./solutions/2600-k-items-with-the-maximum-sum.js)|Easy| +2601|[Prime Subtraction Operation](./solutions/2601-prime-subtraction-operation.js)|Medium| +2605|[Form Smallest Number From Two Digit Arrays](./solutions/2605-form-smallest-number-from-two-digit-arrays.js)|Easy| +2606|[Find the Substring With Maximum Cost](./solutions/2606-find-the-substring-with-maximum-cost.js)|Medium| +2609|[Find the Longest Balanced Substring of a Binary String](./solutions/2609-find-the-longest-balanced-substring-of-a-binary-string.js)|Easy| +2610|[Convert an Array Into a 2D Array With Conditions](./solutions/2610-convert-an-array-into-a-2d-array-with-conditions.js)|Medium| +2615|[Sum of Distances](./solutions/2615-sum-of-distances.js)|Medium| +2616|[Minimize the Maximum Difference of Pairs](./solutions/2616-minimize-the-maximum-difference-of-pairs.js)|Medium| 2618|[Check if Object Instance of Class](./solutions/2618-check-if-object-instance-of-class.js)|Medium| 2619|[Array Prototype Last](./solutions/2619-array-prototype-last.js)|Easy| 2620|[Counter](./solutions/2620-counter.js)|Easy| @@ -1447,32 +2033,64 @@ 2625|[Flatten Deeply Nested Array](./solutions/2625-flatten-deeply-nested-array.js)|Medium| 2626|[Array Reduce Transformation](./solutions/2626-array-reduce-transformation.js)|Easy| 2627|[Debounce](./solutions/2627-debounce.js)|Medium| +2628|[JSON Deep Equal](./solutions/2628-json-deep-equal.js)|Medium| 2629|[Function Composition](./solutions/2629-function-composition.js)|Easy| 2630|[Memoize II](./solutions/2630-memoize-ii.js)|Hard| 2631|[Group By](./solutions/2631-group-by.js)|Medium| +2632|[Curry](./solutions/2632-curry.js)|Medium| +2633|[Convert Object to JSON String](./solutions/2633-convert-object-to-json-string.js)|Medium| 2634|[Filter Elements from Array](./solutions/2634-filter-elements-from-array.js)|Easy| 2635|[Apply Transform Over Each Element in Array](./solutions/2635-apply-transform-over-each-element-in-array.js)|Easy| +2636|[Promise Pool](./solutions/2636-promise-pool.js)|Medium| 2637|[Promise Time Limit](./solutions/2637-promise-time-limit.js)|Medium| +2639|[Find the Width of Columns of a Grid](./solutions/2639-find-the-width-of-columns-of-a-grid.js)|Easy| +2640|[Find the Score of All Prefixes of an Array](./solutions/2640-find-the-score-of-all-prefixes-of-an-array.js)|Medium| +2641|[Cousins in Binary Tree II](./solutions/2641-cousins-in-binary-tree-ii.js)|Medium| +2643|[Row With Maximum Ones](./solutions/2643-row-with-maximum-ones.js)|Easy| +2644|[Find the Maximum Divisibility Score](./solutions/2644-find-the-maximum-divisibility-score.js)|Easy| +2645|[Minimum Additions to Make Valid String](./solutions/2645-minimum-additions-to-make-valid-string.js)|Medium| +2646|[Minimize the Total Price of the Trips](./solutions/2646-minimize-the-total-price-of-the-trips.js)|Hard| 2648|[Generate Fibonacci Sequence](./solutions/2648-generate-fibonacci-sequence.js)|Easy| 2649|[Nested Array Generator](./solutions/2649-nested-array-generator.js)|Medium| 2650|[Design Cancellable Function](./solutions/2650-design-cancellable-function.js)|Hard| +2651|[Calculate Delayed Arrival Time](./solutions/2651-calculate-delayed-arrival-time.js)|Easy| +2652|[Sum Multiples](./solutions/2652-sum-multiples.js)|Easy| +2656|[Maximum Sum With Exactly K Elements](./solutions/2656-maximum-sum-with-exactly-k-elements.js)|Easy| 2657|[Find the Prefix Common Array of Two Arrays](./solutions/2657-find-the-prefix-common-array-of-two-arrays.js)|Medium| 2658|[Maximum Number of Fish in a Grid](./solutions/2658-maximum-number-of-fish-in-a-grid.js)|Medium| 2661|[First Completely Painted Row or Column](./solutions/2661-first-completely-painted-row-or-column.js)|Medium| 2665|[Counter II](./solutions/2665-counter-ii.js)|Easy| 2666|[Allow One Function Call](./solutions/2666-allow-one-function-call.js)|Easy| 2667|[Create Hello World Function](./solutions/2667-create-hello-world-function.js)|Easy| +2670|[Find the Distinct Difference Array](./solutions/2670-find-the-distinct-difference-array.js)|Easy| +2672|[Number of Adjacent Elements With the Same Color](./solutions/2672-number-of-adjacent-elements-with-the-same-color.js)|Medium| +2673|[Make Costs of Paths Equal in a Binary Tree](./solutions/2673-make-costs-of-paths-equal-in-a-binary-tree.js)|Medium| +2676|[Throttle](./solutions/2676-throttle.js)|Medium| 2677|[Chunk Array](./solutions/2677-chunk-array.js)|Easy| +2678|[Number of Senior Citizens](./solutions/2678-number-of-senior-citizens.js)|Easy| +2680|[Maximum OR](./solutions/2680-maximum-or.js)|Medium| +2682|[Find the Losers of the Circular Game](./solutions/2682-find-the-losers-of-the-circular-game.js)|Easy| 2683|[Neighboring Bitwise XOR](./solutions/2683-neighboring-bitwise-xor.js)|Medium| +2684|[Maximum Number of Moves in a Grid](./solutions/2684-maximum-number-of-moves-in-a-grid.js)|Medium| 2685|[Count the Number of Complete Components](./solutions/2685-count-the-number-of-complete-components.js)|Medium| 2693|[Call Function with Custom Context](./solutions/2693-call-function-with-custom-context.js)|Medium| 2694|[Event Emitter](./solutions/2694-event-emitter.js)|Medium| 2695|[Array Wrapper](./solutions/2695-array-wrapper.js)|Easy| +2696|[Minimum String Length After Removing Substrings](./solutions/2696-minimum-string-length-after-removing-substrings.js)|Easy| +2697|[Lexicographically Smallest Palindrome](./solutions/2697-lexicographically-smallest-palindrome.js)|Easy| 2698|[Find the Punishment Number of an Integer](./solutions/2698-find-the-punishment-number-of-an-integer.js)|Medium| 2703|[Return Length of Arguments Passed](./solutions/2703-return-length-of-arguments-passed.js)|Easy| 2704|[To Be Or Not To Be](./solutions/2704-to-be-or-not-to-be.js)|Easy| 2705|[Compact Object](./solutions/2705-compact-object.js)|Medium| +2706|[Buy Two Chocolates](./solutions/2706-buy-two-chocolates.js)|Easy| +2707|[Extra Characters in a String](./solutions/2707-extra-characters-in-a-string.js)|Medium| +2709|[Greatest Common Divisor Traversal](./solutions/2709-greatest-common-divisor-traversal.js)|Hard| +2710|[Remove Trailing Zeros From a String](./solutions/2710-remove-trailing-zeros-from-a-string.js)|Easy| +2711|[Difference of Number of Distinct Values on Diagonals](./solutions/2711-difference-of-number-of-distinct-values-on-diagonals.js)|Medium| +2712|[Minimum Cost to Make All Characters Equal](./solutions/2712-minimum-cost-to-make-all-characters-equal.js)|Medium| 2715|[Timeout Cancellation](./solutions/2715-timeout-cancellation.js)|Easy| +2716|[Minimize String Length](./solutions/2716-minimize-string-length.js)|Easy| +2717|[Semi-Ordered Permutation](./solutions/2717-semi-ordered-permutation.js)|Easy| 2721|[Execute Asynchronous Functions in Parallel](./solutions/2721-execute-asynchronous-functions-in-parallel.js)|Medium| 2722|[Join Two Arrays by ID](./solutions/2722-join-two-arrays-by-id.js)|Medium| 2723|[Add Two Promises](./solutions/2723-add-two-promises.js)|Easy| @@ -1480,37 +2098,189 @@ 2725|[Interval Cancellation](./solutions/2725-interval-cancellation.js)|Easy| 2726|[Calculator with Method Chaining](./solutions/2726-calculator-with-method-chaining.js)|Easy| 2727|[Is Object Empty](./solutions/2727-is-object-empty.js)|Easy| +2729|[Check if The Number is Fascinating](./solutions/2729-check-if-the-number-is-fascinating.js)|Easy| +2732|[Find a Good Subset of the Matrix](./solutions/2732-find-a-good-subset-of-the-matrix.js)|Hard| +2733|[Neither Minimum nor Maximum](./solutions/2733-neither-minimum-nor-maximum.js)|Easy| +2739|[Total Distance Traveled](./solutions/2739-total-distance-traveled.js)|Easy| +2740|[Find the Value of the Partition](./solutions/2740-find-the-value-of-the-partition.js)|Medium| +2742|[Painting the Walls](./solutions/2742-painting-the-walls.js)|Hard| +2744|[Find Maximum Number of String Pairs](./solutions/2744-find-maximum-number-of-string-pairs.js)|Easy| +2745|[Construct the Longest New String](./solutions/2745-construct-the-longest-new-string.js)|Medium| +2748|[Number of Beautiful Pairs](./solutions/2748-number-of-beautiful-pairs.js)|Easy| +2751|[Robot Collisions](./solutions/2751-robot-collisions.js)|Hard| +2763|[Sum of Imbalance Numbers of All Subarrays](./solutions/2763-sum-of-imbalance-numbers-of-all-subarrays.js)|Hard| +2766|[Relocate Marbles](./solutions/2766-relocate-marbles.js)|Medium| +2767|[Partition String Into Minimum Beautiful Substrings](./solutions/2767-partition-string-into-minimum-beautiful-substrings.js)|Medium| +2769|[Find the Maximum Achievable Number](./solutions/2769-find-the-maximum-achievable-number.js)|Easy| +2778|[Sum of Squares of Special Elements](./solutions/2778-sum-of-squares-of-special-elements.js)|Easy| +2779|[Maximum Beauty of an Array After Applying Operation](./solutions/2779-maximum-beauty-of-an-array-after-applying-operation.js)|Medium| 2780|[Minimum Index of a Valid Split](./solutions/2780-minimum-index-of-a-valid-split.js)|Medium| +2784|[Check if Array is Good](./solutions/2784-check-if-array-is-good.js)|Easy| +2785|[Sort Vowels in a String](./solutions/2785-sort-vowels-in-a-string.js)|Medium| +2788|[Split Strings by Separator](./solutions/2788-split-strings-by-separator.js)|Easy| +2789|[Largest Element in an Array after Merge Operations](./solutions/2789-largest-element-in-an-array-after-merge-operations.js)|Medium| +2791|[Count Paths That Can Form a Palindrome in a Tree](./solutions/2791-count-paths-that-can-form-a-palindrome-in-a-tree.js)|Hard| +2798|[Number of Employees Who Met the Target](./solutions/2798-number-of-employees-who-met-the-target.js)|Easy| 2799|[Count Complete Subarrays in an Array](./solutions/2799-count-complete-subarrays-in-an-array.js)|Medium| +2806|[Account Balance After Rounded Purchase](./solutions/2806-account-balance-after-rounded-purchase.js)|Easy| +2807|[Insert Greatest Common Divisors in Linked List](./solutions/2807-insert-greatest-common-divisors-in-linked-list.js)|Medium| +2810|[Faulty Keyboard](./solutions/2810-faulty-keyboard.js)|Easy| +2815|[Max Pair Sum in an Array](./solutions/2815-max-pair-sum-in-an-array.js)|Easy| +2816|[Double a Number Represented as a Linked List](./solutions/2816-double-a-number-represented-as-a-linked-list.js)|Medium| 2818|[Apply Operations to Maximize Score](./solutions/2818-apply-operations-to-maximize-score.js)|Hard| +2824|[Count Pairs Whose Sum is Less than Target](./solutions/2824-count-pairs-whose-sum-is-less-than-target.js)|Easy| +2825|[Make String a Subsequence Using Cyclic Increments](./solutions/2825-make-string-a-subsequence-using-cyclic-increments.js)|Medium| +2826|[Sorting Three Groups](./solutions/2826-sorting-three-groups.js)|Medium| +2828|[Check if a String Is an Acronym of Words](./solutions/2828-check-if-a-string-is-an-acronym-of-words.js)|Easy| +2829|[Determine the Minimum Sum of a k-avoiding Array](./solutions/2829-determine-the-minimum-sum-of-a-k-avoiding-array.js)|Medium| +2833|[Furthest Point From Origin](./solutions/2833-furthest-point-from-origin.js)|Easy| +2839|[Check if Strings Can be Made Equal With Operations I](./solutions/2839-check-if-strings-can-be-made-equal-with-operations-i.js)|Easy| +2840|[Check if Strings Can be Made Equal With Operations II](./solutions/2840-check-if-strings-can-be-made-equal-with-operations-ii.js)|Medium| +2841|[Maximum Sum of Almost Unique Subarray](./solutions/2841-maximum-sum-of-almost-unique-subarray.js)|Medium| 2843|[Count Symmetric Integers](./solutions/2843-count-symmetric-integers.js)|Easy| 2845|[Count of Interesting Subarrays](./solutions/2845-count-of-interesting-subarrays.js)|Medium| +2846|[Minimum Edge Weight Equilibrium Queries in a Tree](./solutions/2846-minimum-edge-weight-equilibrium-queries-in-a-tree.js)|Hard| +2848|[Points That Intersect With Cars](./solutions/2848-points-that-intersect-with-cars.js)|Easy| +2850|[Minimum Moves to Spread Stones Over Grid](./solutions/2850-minimum-moves-to-spread-stones-over-grid.js)|Medium| +2855|[Minimum Right Shifts to Sort the Array](./solutions/2855-minimum-right-shifts-to-sort-the-array.js)|Easy| +2858|[Minimum Edge Reversals So Every Node Is Reachable](./solutions/2858-minimum-edge-reversals-so-every-node-is-reachable.js)|Hard| +2859|[Sum of Values at Indices With K Set Bits](./solutions/2859-sum-of-values-at-indices-with-k-set-bits.js)|Easy| +2860|[Happy Students](./solutions/2860-happy-students.js)|Medium| +2862|[Maximum Element-Sum of a Complete Subset of Indices](./solutions/2862-maximum-element-sum-of-a-complete-subset-of-indices.js)|Hard| +2864|[Maximum Odd Binary Number](./solutions/2864-maximum-odd-binary-number.js)|Easy| +2865|[Beautiful Towers I](./solutions/2865-beautiful-towers-i.js)|Medium| +2869|[Minimum Operations to Collect Elements](./solutions/2869-minimum-operations-to-collect-elements.js)|Easy| +2870|[Minimum Number of Operations to Make Array Empty](./solutions/2870-minimum-number-of-operations-to-make-array-empty.js)|Medium| +2871|[Split Array Into Maximum Number of Subarrays](./solutions/2871-split-array-into-maximum-number-of-subarrays.js)|Medium| +2872|[Maximum Number of K-Divisible Components](./solutions/2872-maximum-number-of-k-divisible-components.js)|Hard| 2873|[Maximum Value of an Ordered Triplet I](./solutions/2873-maximum-value-of-an-ordered-triplet-i.js)|Easy| 2874|[Maximum Value of an Ordered Triplet II](./solutions/2874-maximum-value-of-an-ordered-triplet-ii.js)|Medium| +2894|[Divisible and Non-divisible Sums Difference](./solutions/2894-divisible-and-non-divisible-sums-difference.js)|Easy| +2895|[Minimum Processing Time](./solutions/2895-minimum-processing-time.js)|Medium| +2897|[Apply Operations on Array to Maximize Sum of Squares](./solutions/2897-apply-operations-on-array-to-maximize-sum-of-squares.js)|Hard| +2899|[Last Visited Integers](./solutions/2899-last-visited-integers.js)|Easy| +2900|[Longest Unequal Adjacent Groups Subsequence I](./solutions/2900-longest-unequal-adjacent-groups-subsequence-i.js)|Easy| +2901|[Longest Unequal Adjacent Groups Subsequence II](./solutions/2901-longest-unequal-adjacent-groups-subsequence-ii.js)|Medium| +2903|[Find Indices With Index and Value Difference I](./solutions/2903-find-indices-with-index-and-value-difference-i.js)|Easy| +2904|[Shortest and Lexicographically Smallest Beautiful String](./solutions/2904-shortest-and-lexicographically-smallest-beautiful-string.js)|Medium| +2908|[Minimum Sum of Mountain Triplets I](./solutions/2908-minimum-sum-of-mountain-triplets-i.js)|Easy| +2909|[Minimum Sum of Mountain Triplets II](./solutions/2909-minimum-sum-of-mountain-triplets-ii.js)|Medium| +2913|[Subarrays Distinct Element Sum of Squares I](./solutions/2913-subarrays-distinct-element-sum-of-squares-i.js)|Easy| +2914|[Minimum Number of Changes to Make Binary String Beautiful](./solutions/2914-minimum-number-of-changes-to-make-binary-string-beautiful.js)|Medium| +2917|[Find the K-or of an Array](./solutions/2917-find-the-k-or-of-an-array.js)|Easy| +2918|[Minimum Equal Sum of Two Arrays After Replacing Zeros](./solutions/2918-minimum-equal-sum-of-two-arrays-after-replacing-zeros.js)|Medium| +2923|[Find Champion I](./solutions/2923-find-champion-i.js)|Easy| +2924|[Find Champion II](./solutions/2924-find-champion-ii.js)|Medium| +2925|[Maximum Score After Applying Operations on a Tree](./solutions/2925-maximum-score-after-applying-operations-on-a-tree.js)|Medium| +2928|[Distribute Candies Among Children I](./solutions/2928-distribute-candies-among-children-i.js)|Easy| +2929|[Distribute Candies Among Children II](./solutions/2929-distribute-candies-among-children-ii.js)|Medium| +2932|[Maximum Strong Pair XOR I](./solutions/2932-maximum-strong-pair-xor-i.js)|Easy| +2933|[High-Access Employees](./solutions/2933-high-access-employees.js)|Medium| +2934|[Minimum Operations to Maximize Last Elements in Arrays](./solutions/2934-minimum-operations-to-maximize-last-elements-in-arrays.js)|Medium| +2937|[Make Three Strings Equal](./solutions/2937-make-three-strings-equal.js)|Easy| +2938|[Separate Black and White Balls](./solutions/2938-separate-black-and-white-balls.js)|Medium| +2942|[Find Words Containing Character](./solutions/2942-find-words-containing-character.js)|Easy| +2946|[Matrix Similarity After Cyclic Shifts](./solutions/2946-matrix-similarity-after-cyclic-shifts.js)|Easy| +2947|[Count Beautiful Substrings I](./solutions/2947-count-beautiful-substrings-i.js)|Medium| 2948|[Make Lexicographically Smallest Array by Swapping Elements](./solutions/2948-make-lexicographically-smallest-array-by-swapping-elements.js)|Medium| +2951|[Find the Peaks](./solutions/2951-find-the-peaks.js)|Easy| +2952|[Minimum Number of Coins to be Added](./solutions/2952-minimum-number-of-coins-to-be-added.js)|Medium| +2956|[Find Common Elements Between Two Arrays](./solutions/2956-find-common-elements-between-two-arrays.js)|Easy| +2957|[Remove Adjacent Almost-Equal Characters](./solutions/2957-remove-adjacent-almost-equal-characters.js)|Medium| +2958|[Length of Longest Subarray With at Most K Frequency](./solutions/2958-length-of-longest-subarray-with-at-most-k-frequency.js)|Medium| +2960|[Count Tested Devices After Test Operations](./solutions/2960-count-tested-devices-after-test-operations.js)|Easy| +2961|[Double Modular Exponentiation](./solutions/2961-double-modular-exponentiation.js)|Medium| +2962|[Count Subarrays Where Max Element Appears at Least K Times](./solutions/2962-count-subarrays-where-max-element-appears-at-least-k-times.js)|Medium| +2963|[Count the Number of Good Partitions](./solutions/2963-count-the-number-of-good-partitions.js)|Hard| 2965|[Find Missing and Repeated Values](./solutions/2965-find-missing-and-repeated-values.js)|Easy| +2966|[Divide Array Into Arrays With Max Difference](./solutions/2966-divide-array-into-arrays-with-max-difference.js)|Medium| +2970|[Count the Number of Incremovable Subarrays I](./solutions/2970-count-the-number-of-incremovable-subarrays-i.js)|Easy| +2971|[Find Polygon With the Largest Perimeter](./solutions/2971-find-polygon-with-the-largest-perimeter.js)|Medium| +2976|[Minimum Cost to Convert String I](./solutions/2976-minimum-cost-to-convert-string-i.js)|Medium| +2980|[Check if Bitwise OR Has Trailing Zeros](./solutions/2980-check-if-bitwise-or-has-trailing-zeros.js)|Easy| +2981|[Find Longest Special Substring That Occurs Thrice I](./solutions/2981-find-longest-special-substring-that-occurs-thrice-i.js)|Medium| +2997|[Minimum Number of Operations to Make Array XOR Equal to K](./solutions/2997-minimum-number-of-operations-to-make-array-xor-equal-to-k.js)|Medium| +2998|[Minimum Number of Operations to Make X and Y Equal](./solutions/2998-minimum-number-of-operations-to-make-x-and-y-equal.js)|Medium| 2999|[Count the Number of Powerful Integers](./solutions/2999-count-the-number-of-powerful-integers.js)|Hard| +3002|[Maximum Size of a Set After Removals](./solutions/3002-maximum-size-of-a-set-after-removals.js)|Medium| +3005|[Count Elements With Maximum Frequency](./solutions/3005-count-elements-with-maximum-frequency.js)|Easy| +3010|[Divide an Array Into Subarrays With Minimum Cost I](./solutions/3010-divide-an-array-into-subarrays-with-minimum-cost-i.js)|Easy| +3011|[Find if Array Can Be Sorted](./solutions/3011-find-if-array-can-be-sorted.js)|Medium| +3014|[Minimum Number of Pushes to Type Word I](./solutions/3014-minimum-number-of-pushes-to-type-word-i.js)|Easy| +3015|[Count the Number of Houses at a Certain Distance I](./solutions/3015-count-the-number-of-houses-at-a-certain-distance-i.js)|Medium| +3016|[Minimum Number of Pushes to Type Word II](./solutions/3016-minimum-number-of-pushes-to-type-word-ii.js)|Medium| +3019|[Number of Changing Keys](./solutions/3019-number-of-changing-keys.js)|Easy| +3021|[Alice and Bob Playing Flower Game](./solutions/3021-alice-and-bob-playing-flower-game.js)|Medium| +3024|[Type of Triangle](./solutions/3024-type-of-triangle.js)|Easy| +3025|[Find the Number of Ways to Place People I](./solutions/3025-find-the-number-of-ways-to-place-people-i.js)|Medium| +3027|[Find the Number of Ways to Place People II](./solutions/3027-find-the-number-of-ways-to-place-people-ii.js)|Hard| +3028|[Ant on the Boundary](./solutions/3028-ant-on-the-boundary.js)|Easy| +3029|[Minimum Time to Revert Word to Initial State I](./solutions/3029-minimum-time-to-revert-word-to-initial-state-i.js)|Medium| +3030|[Find the Grid of Region Average](./solutions/3030-find-the-grid-of-region-average.js)|Medium| +3033|[Modify the Matrix](./solutions/3033-modify-the-matrix.js)|Easy| +3034|[Number of Subarrays That Match a Pattern I](./solutions/3034-number-of-subarrays-that-match-a-pattern-i.js)|Medium| +3035|[Maximum Palindromes After Operations](./solutions/3035-maximum-palindromes-after-operations.js)|Medium| +3038|[Maximum Number of Operations With the Same Score I](./solutions/3038-maximum-number-of-operations-with-the-same-score-i.js)|Easy| +3039|[Apply Operations to Make String Empty](./solutions/3039-apply-operations-to-make-string-empty.js)|Medium| 3042|[Count Prefix and Suffix Pairs I](./solutions/3042-count-prefix-and-suffix-pairs-i.js)|Easy| +3043|[Find the Length of the Longest Common Prefix](./solutions/3043-find-the-length-of-the-longest-common-prefix.js)|Medium| +3044|[Most Frequent Prime](./solutions/3044-most-frequent-prime.js)|Medium| +3046|[Split the Array](./solutions/3046-split-the-array.js)|Easy| +3047|[Find the Largest Area of Square Inside Two Rectangles](./solutions/3047-find-the-largest-area-of-square-inside-two-rectangles.js)|Medium| +3065|[Minimum Operations to Exceed Threshold Value I](./solutions/3065-minimum-operations-to-exceed-threshold-value-i.js)|Easy| 3066|[Minimum Operations to Exceed Threshold Value II](./solutions/3066-minimum-operations-to-exceed-threshold-value-ii.js)|Medium| +3067|[Count Pairs of Connectable Servers in a Weighted Tree Network](./solutions/3067-count-pairs-of-connectable-servers-in-a-weighted-tree-network.js)|Medium| +3068|[Find the Maximum Sum of Node Values](./solutions/3068-find-the-maximum-sum-of-node-values.js)|Hard| +3069|[Distribute Elements Into Two Arrays I](./solutions/3069-distribute-elements-into-two-arrays-i.js)|Easy| +3070|[Count Submatrices with Top-Left Element and Sum Less Than k](./solutions/3070-count-submatrices-with-top-left-element-and-sum-less-than-k.js)|Medium| +3071|[Minimum Operations to Write the Letter Y on a Grid](./solutions/3071-minimum-operations-to-write-the-letter-y-on-a-grid.js)|Medium| +3074|[Apple Redistribution into Boxes](./solutions/3074-apple-redistribution-into-boxes.js)|Easy| +3075|[Maximize Happiness of Selected Children](./solutions/3075-maximize-happiness-of-selected-children.js)|Medium| +3076|[Shortest Uncommon Substring in an Array](./solutions/3076-shortest-uncommon-substring-in-an-array.js)|Medium| +3079|[Find the Sum of Encrypted Integers](./solutions/3079-find-the-sum-of-encrypted-integers.js)|Easy| +3083|[Existence of a Substring in a String and Its Reverse](./solutions/3083-existence-of-a-substring-in-a-string-and-its-reverse.js)|Easy| +3084|[Count Substrings Starting and Ending with Given Character](./solutions/3084-count-substrings-starting-and-ending-with-given-character.js)|Medium| +3085|[Minimum Deletions to Make String K-Special](./solutions/3085-minimum-deletions-to-make-string-k-special.js)|Medium| +3090|[Maximum Length Substring With Two Occurrences](./solutions/3090-maximum-length-substring-with-two-occurrences.js)|Easy| +3091|[Apply Operations to Make Sum of Array Greater Than or Equal to k](./solutions/3091-apply-operations-to-make-sum-of-array-greater-than-or-equal-to-k.js)|Medium| +3095|[Shortest Subarray With OR at Least K I](./solutions/3095-shortest-subarray-with-or-at-least-k-i.js)|Easy| +3097|[Shortest Subarray With OR at Least K II](./solutions/3097-shortest-subarray-with-or-at-least-k-ii.js)|Medium| +3099|[Harshad Number](./solutions/3099-harshad-number.js)|Easy| +3100|[Water Bottles II](./solutions/3100-water-bottles-ii.js)|Medium| 3105|[Longest Strictly Increasing or Strictly Decreasing Subarray](./solutions/3105-longest-strictly-increasing-or-strictly-decreasing-subarray.js)|Easy| 3108|[Minimum Cost Walk in Weighted Graph](./solutions/3108-minimum-cost-walk-in-weighted-graph.js)|Hard| 3110|[Score of a String](./solutions/3110-score-of-a-string.js)|Easy| 3151|[Special Array I](./solutions/3151-special-array-i.js)|Easy| 3160|[Find the Number of Distinct Colors Among the Balls](./solutions/3160-find-the-number-of-distinct-colors-among-the-balls.js)|Medium| 3169|[Count Days Without Meetings](./solutions/3169-count-days-without-meetings.js)|Medium| +3170|[Lexicographically Minimum String After Removing Stars](./solutions/3170-lexicographically-minimum-string-after-removing-stars.js)|Medium| 3174|[Clear Digits](./solutions/3174-clear-digits.js)|Easy| +3178|[Find the Child Who Has the Ball After K Seconds](./solutions/3178-find-the-child-who-has-the-ball-after-k-seconds.js)|Easy| 3191|[Minimum Operations to Make Binary Array Elements Equal to One I](./solutions/3191-minimum-operations-to-make-binary-array-elements-equal-to-one-i.js)|Medium| 3208|[Alternating Groups II](./solutions/3208-alternating-groups-ii.js)|Medium| 3223|[Minimum Length of String After Operations](./solutions/3223-minimum-length-of-string-after-operations.js)|Medium| 3272|[Find the Count of Good Integers](./solutions/3272-find-the-count-of-good-integers.js)|Hard| 3306|[Count of Substrings Containing Every Vowel and K Consonants II](./solutions/3306-count-of-substrings-containing-every-vowel-and-k-consonants-ii.js)|Medium| +3335|[Total Characters in String After Transformations I](./solutions/3335-total-characters-in-string-after-transformations-i.js)|Medium| +3337|[Total Characters in String After Transformations II](./solutions/3337-total-characters-in-string-after-transformations-ii.js)|Hard| +3341|[Find Minimum Time to Reach Last Room I](./solutions/3341-find-minimum-time-to-reach-last-room-i.js)|Medium| +3342|[Find Minimum Time to Reach Last Room II](./solutions/3342-find-minimum-time-to-reach-last-room-ii.js)|Medium| +3343|[Count Number of Balanced Permutations](./solutions/3343-count-number-of-balanced-permutations.js)|Hard| +3355|[Zero Array Transformation I](./solutions/3355-zero-array-transformation-i.js)|Medium| 3356|[Zero Array Transformation II](./solutions/3356-zero-array-transformation-ii.js)|Medium| +3362|[Zero Array Transformation III](./solutions/3362-zero-array-transformation-iii.js)|Medium| +3372|[Maximize the Number of Target Nodes After Connecting Trees I](./solutions/3372-maximize-the-number-of-target-nodes-after-connecting-trees-i.js)|Medium| +3373|[Maximize the Number of Target Nodes After Connecting Trees II](./solutions/3373-maximize-the-number-of-target-nodes-after-connecting-trees-ii.js)|Hard| 3375|[Minimum Operations to Make Array Values Equal to K](./solutions/3375-minimum-operations-to-make-array-values-equal-to-k.js)|Easy| 3392|[Count Subarrays of Length Three With a Condition](./solutions/3392-count-subarrays-of-length-three-with-a-condition.js)|Easy| 3394|[Check if Grid can be Cut into Sections](./solutions/3394-check-if-grid-can-be-cut-into-sections.js)|Medium| 3396|[Minimum Number of Operations to Make Elements in Array Distinct](./solutions/3396-minimum-number-of-operations-to-make-elements-in-array-distinct.js)|Easy| 3397|[Maximum Number of Distinct Elements After Operations](./solutions/3397-maximum-number-of-distinct-elements-after-operations.js)|Medium| 3402|[Minimum Operations to Make Columns Strictly Increasing](./solutions/3402-minimum-operations-to-make-columns-strictly-increasing.js)|Easy| +3403|[Find the Lexicographically Largest String From the Box I](./solutions/3403-find-the-lexicographically-largest-string-from-the-box-i.js)|Medium| +3423|[Maximum Difference Between Adjacent Elements in a Circular Array](./solutions/3423-maximum-difference-between-adjacent-elements-in-a-circular-array.js)|Easy| +3442|[Maximum Difference Between Even and Odd Frequency I](./solutions/3442-maximum-difference-between-even-and-odd-frequency-i.js)|Easy| +3445|[Maximum Difference Between Even and Odd Frequency II](./solutions/3445-maximum-difference-between-even-and-odd-frequency-ii.js)|Hard| 3452|[Sum of Good Numbers](./solutions/3452-sum-of-good-numbers.js)|Easy| 3461|[Check If Digits Are Equal in String After Operations I](./solutions/3461-check-if-digits-are-equal-in-string-after-operations-i.js)|Easy| 3462|[Maximum Sum With at Most K Elements](./solutions/3462-maximum-sum-with-at-most-k-elements.js)|Medium| diff --git a/solutions/0156-binary-tree-upside-down.js b/solutions/0156-binary-tree-upside-down.js new file mode 100644 index 00000000..77bfd8ce --- /dev/null +++ b/solutions/0156-binary-tree-upside-down.js @@ -0,0 +1,39 @@ +/** + * 156. Binary Tree Upside Down + * https://leetcode.com/problems/binary-tree-upside-down/ + * Difficulty: Medium + * + * Given the root of a binary tree, turn the tree upside down and return the new root. + * + * You can turn a binary tree upside down with the following steps: + * - The original left child becomes the new root. + * - The original root becomes the new right child. + * - The original right child becomes the new left child. + * + * The mentioned steps are done level by level. It is guaranteed that every right node has + * a sibling (a left node with the same parent) and has no children. + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {TreeNode} root + * @return {TreeNode} + */ +var upsideDownBinaryTree = function(root) { + if (!root || !root.left) return root; + + const newRoot = upsideDownBinaryTree(root.left); + root.left.left = root.right; + root.left.right = root; + root.left = null; + root.right = null; + + return newRoot; +}; diff --git a/solutions/0157-read-n-characters-given-read4.js b/solutions/0157-read-n-characters-given-read4.js new file mode 100644 index 00000000..0074fec8 --- /dev/null +++ b/solutions/0157-read-n-characters-given-read4.js @@ -0,0 +1,48 @@ +/** + * 157. Read N Characters Given Read4 + * https://leetcode.com/problems/read-n-characters-given-read4/ + * Difficulty: Easy + * + * Given a file and assume that you can only read the file using a given method read4, implement + * a method to read n characters. + * + * Method read4: + * - The API read4 reads four consecutive characters from file, then writes those characters into + * the buffer array buf4. + * + * The return value is the number of actual characters read. + * + * Note that read4() has its own file pointer, much like FILE *fp in C. + */ + +/** + * @param {function} read4() + * @return {function} + */ +var solution = function(read4) { + let cache = []; + let cacheIndex = 0; + let cacheSize = 0; + + /** + * @param {character[]} buf Destination buffer + * @param {number} n Number of characters to read + * @return {number} The number of actual characters read + */ + return function(buf, n) { + let charsRead = 0; + + while (charsRead < n) { + if (cacheIndex >= cacheSize) { + cache = new Array(4); + cacheSize = read4(cache); + cacheIndex = 0; + if (cacheSize === 0) break; + } + + buf[charsRead++] = cache[cacheIndex++]; + } + + return charsRead; + }; +}; diff --git a/solutions/0158-read-n-characters-given-read4-ii-call-multiple-times.js b/solutions/0158-read-n-characters-given-read4-ii-call-multiple-times.js new file mode 100644 index 00000000..9fdd7b54 --- /dev/null +++ b/solutions/0158-read-n-characters-given-read4-ii-call-multiple-times.js @@ -0,0 +1,48 @@ +/** + * 158. Read N Characters Given read4 II - Call Multiple Times + * https://leetcode.com/problems/read-n-characters-given-read4-ii-call-multiple-times/ + * Difficulty: Hard + * + * Given a file and assume that you can only read the file using a given method read4, implement + * a method read to read n characters. Your method read may be called multiple times. + * + * Method read4: + * - The API read4 reads four consecutive characters from file, then writes those characters into + * the buffer array buf4. + * + * The return value is the number of actual characters read. + * + * Note that read4() has its own file pointer, much like FILE *fp in C. + */ + +/** + * @param {function} read4() + * @return {function} + */ +var solution = function(read4) { + let cache = []; + let cacheIndex = 0; + let cacheSize = 0; + + /** + * @param {character[]} buf Destination buffer + * @param {number} n Number of characters to read + * @return {number} The number of actual characters read + */ + return function(buf, n) { + let charsRead = 0; + + while (charsRead < n) { + if (cacheIndex >= cacheSize) { + cache = new Array(4); + cacheSize = read4(cache); + cacheIndex = 0; + if (cacheSize === 0) break; + } + + buf[charsRead++] = cache[cacheIndex++]; + } + + return charsRead; + }; +}; diff --git a/solutions/0159-longest-substring-with-at-most-two-distinct-characters.js b/solutions/0159-longest-substring-with-at-most-two-distinct-characters.js new file mode 100644 index 00000000..8e023114 --- /dev/null +++ b/solutions/0159-longest-substring-with-at-most-two-distinct-characters.js @@ -0,0 +1,34 @@ +/** + * 159. Longest Substring with At Most Two Distinct Characters + * https://leetcode.com/problems/longest-substring-with-at-most-two-distinct-characters/ + * Difficulty: Medium + * + * Given a string s, return the length of the longest substring that contains at most two + * distinct characters. + */ + +/** + * @param {string} s + * @return {number} + */ +var lengthOfLongestSubstringTwoDistinct = function(s) { + const map = new Map(); + let maxLength = 0; + let start = 0; + + for (let end = 0; end < s.length; end++) { + map.set(s[end], (map.get(s[end]) || 0) + 1); + + while (map.size > 2) { + map.set(s[start], map.get(s[start]) - 1); + if (map.get(s[start]) === 0) { + map.delete(s[start]); + } + start++; + } + + maxLength = Math.max(maxLength, end - start + 1); + } + + return maxLength; +}; diff --git a/solutions/0161-one-edit-distance.js b/solutions/0161-one-edit-distance.js new file mode 100644 index 00000000..cb69f9ec --- /dev/null +++ b/solutions/0161-one-edit-distance.js @@ -0,0 +1,36 @@ +/** + * 161. One Edit Distance + * https://leetcode.com/problems/one-edit-distance/ + * Difficulty: Medium + * + * Given two strings s and t, return true if they are both one edit distance apart, otherwise + * return false. + * + * A string s is said to be one distance apart from a string t if you can: + * - Insert exactly one character into s to get t. + * - Delete exactly one character from s to get t. + * - Replace exactly one character of s with a different character to get t. + */ + +/** + * @param {string} s + * @param {string} t + * @return {boolean} + */ +var isOneEditDistance = function(s, t) { + if (s === t) return false; + const sLength = s.length; + const tLength = t.length; + if (Math.abs(sLength - tLength) > 1) return false; + + if (sLength > tLength) return isOneEditDistance(t, s); + + let i = 0; + while (i < sLength && s[i] === t[i]) i++; + + if (sLength === tLength) { + return i < sLength && s.slice(i + 1) === t.slice(i + 1); + } + + return s.slice(i) === t.slice(i + 1); +}; diff --git a/solutions/0163-missing-ranges.js b/solutions/0163-missing-ranges.js new file mode 100644 index 00000000..717b6edb --- /dev/null +++ b/solutions/0163-missing-ranges.js @@ -0,0 +1,35 @@ +/** + * 163. Missing Ranges + * https://leetcode.com/problems/missing-ranges/ + * Difficulty: Easy + * + * You are given an inclusive range [lower, upper] and a sorted unique integer array nums, + * where all elements are within the inclusive range. + * + * A number x is considered missing if x is in the range [lower, upper] and x is not in nums. + * + * Return the shortest sorted list of ranges that exactly covers all the missing numbers. + * That is, no element of nums is included in any of the ranges, and each missing number + * is covered by one of the ranges. + */ + +/** + * @param {number[]} nums + * @param {number} lower + * @param {number} upper + * @return {number[][]} + */ +var findMissingRanges = function(nums, lower, upper) { + const result = []; + let prev = lower - 1; + + for (let i = 0; i <= nums.length; i++) { + const curr = i < nums.length ? nums[i] : upper + 1; + if (curr - prev > 1) { + result.push([prev + 1, curr - 1]); + } + prev = curr; + } + + return result; +}; diff --git a/solutions/0170-two-sum-iii-data-structure-design.js b/solutions/0170-two-sum-iii-data-structure-design.js new file mode 100644 index 00000000..f0cd8777 --- /dev/null +++ b/solutions/0170-two-sum-iii-data-structure-design.js @@ -0,0 +1,42 @@ +/** + * 170. Two Sum III - Data structure design + * https://leetcode.com/problems/two-sum-iii-data-structure-design/ + * Difficulty: Easy + * + * Design a data structure that accepts a stream of integers and checks if it has a pair of + * integers that sum up to a particular value. + * + * Implement the TwoSum class: + * - TwoSum() Initializes the TwoSum object, with an empty array initially. + * - void add(int number) Adds number to the data structure. + * - boolean find(int value) Returns true if there exists any pair of numbers whose sum is equal + * to value, otherwise, it returns false. + */ + +var TwoSum = function() { + this.numCount = new Map(); +}; + +/** + * @param {number} number + * @return {void} + */ +TwoSum.prototype.add = function(number) { + this.numCount.set(number, (this.numCount.get(number) || 0) + 1); +}; + +/** + * @param {number} value + * @return {boolean} + */ +TwoSum.prototype.find = function(value) { + for (const num of this.numCount.keys()) { + const complement = value - num; + if (complement === num) { + if (this.numCount.get(num) > 1) return true; + } else if (this.numCount.has(complement)) { + return true; + } + } + return false; +}; diff --git a/solutions/0186-reverse-words-in-a-string-ii.js b/solutions/0186-reverse-words-in-a-string-ii.js new file mode 100644 index 00000000..ebc713fa --- /dev/null +++ b/solutions/0186-reverse-words-in-a-string-ii.js @@ -0,0 +1,40 @@ +/** + * 186. Reverse Words in a String II + * https://leetcode.com/problems/reverse-words-in-a-string-ii/ + * Difficulty: Medium + * + * Given a character array s, reverse the order of the words. + * + * A word is defined as a sequence of non-space characters. The words in s will be separated + * by a single space. + * + * Your code must solve the problem in-place, i.e. without allocating extra space. + */ + +/** + * @param {character[]} s + * @return {void} Do not return anything, modify s in-place instead. + */ +var reverseWords = function(s) { + let left = 0; + let right = s.length - 1; + + while (left < right) { + [s[left], s[right]] = [s[right], s[left]]; + left++; + right--; + } + + left = 0; + for (let i = 0; i <= s.length; i++) { + if (i === s.length || s[i] === ' ') { + right = i - 1; + while (left < right) { + [s[left], s[right]] = [s[right], s[left]]; + left++; + right--; + } + left = i + 1; + } + } +}; diff --git a/solutions/0243-shortest-word-distance.js b/solutions/0243-shortest-word-distance.js new file mode 100644 index 00000000..d05ac820 --- /dev/null +++ b/solutions/0243-shortest-word-distance.js @@ -0,0 +1,36 @@ +/** + * 243. Shortest Word Distance + * https://leetcode.com/problems/shortest-word-distance/ + * Difficulty: Easy + * + * Given an array of strings wordsDict and two different strings that already exist in the array + * word1 and word2, return the shortest distance between these two words in the list. + */ + +/** + * @param {string[]} wordsDict + * @param {string} word1 + * @param {string} word2 + * @return {number} + */ +var shortestDistance = function(wordsDict, word1, word2) { + let result = Infinity; + let index1 = -1; + let index2 = -1; + + for (let i = 0; i < wordsDict.length; i++) { + if (wordsDict[i] === word1) { + index1 = i; + if (index2 !== -1) { + result = Math.min(result, index1 - index2); + } + } else if (wordsDict[i] === word2) { + index2 = i; + if (index1 !== -1) { + result = Math.min(result, index2 - index1); + } + } + } + + return result; +}; diff --git a/solutions/0244-shortest-word-distance-ii.js b/solutions/0244-shortest-word-distance-ii.js new file mode 100644 index 00000000..3d66d604 --- /dev/null +++ b/solutions/0244-shortest-word-distance-ii.js @@ -0,0 +1,50 @@ +/** + * 244. Shortest Word Distance II + * https://leetcode.com/problems/shortest-word-distance-ii/ + * Difficulty: Medium + * + * Design a data structure that will be initialized with a string array, and then it should + * answer queries of the shortest distance between two different strings from the array. + * + * Implement the WordDistance class: + * - WordDistance(String[] wordsDict) initializes the object with the strings array wordsDict. + * - int shortest(String word1, String word2) returns the shortest distance between word1 and + * word2 in the array wordsDict. + */ + +/** + * @param {string[]} wordsDict + */ +var WordDistance = function(wordsDict) { + this.wordIndices = new Map(); + for (let i = 0; i < wordsDict.length; i++) { + if (!this.wordIndices.has(wordsDict[i])) { + this.wordIndices.set(wordsDict[i], []); + } + this.wordIndices.get(wordsDict[i]).push(i); + } +}; + +/** + * @param {string} word1 + * @param {string} word2 + * @return {number} + */ +WordDistance.prototype.shortest = function(word1, word2) { + const indices1 = this.wordIndices.get(word1); + const indices2 = this.wordIndices.get(word2); + let minDistance = Infinity; + let i = 0; + let j = 0; + + while (i < indices1.length && j < indices2.length) { + minDistance = Math.min(minDistance, Math.abs(indices1[i] - indices2[j])); + if (indices1[i] < indices2[j]) { + i++; + } else { + j++; + } + } + + return minDistance; +}; diff --git a/solutions/0245-shortest-word-distance-iii.js b/solutions/0245-shortest-word-distance-iii.js new file mode 100644 index 00000000..0e1c24f5 --- /dev/null +++ b/solutions/0245-shortest-word-distance-iii.js @@ -0,0 +1,46 @@ +/** + * 245. Shortest Word Distance III + * https://leetcode.com/problems/shortest-word-distance-iii/ + * Difficulty: Medium + * + * Given an array of strings wordsDict and two strings that already exist in the array word1 + * and word2, return the shortest distance between the occurrence of these two words in the list. + * + * Note that word1 and word2 may be the same. It is guaranteed that they represent two individual + * words in the list. + */ + +/** + * @param {string[]} wordsDict + * @param {string} word1 + * @param {string} word2 + * @return {number} + */ +var shortestWordDistance = function(wordsDict, word1, word2) { + let result = Infinity; + let lastWord1Index = -1; + let lastWord2Index = -1; + const areSameWords = word1 === word2; + + for (let index = 0; index < wordsDict.length; index++) { + const currentWord = wordsDict[index]; + + if (currentWord === word1) { + if (areSameWords) { + if (lastWord1Index !== -1) { + result = Math.min(result, index - lastWord1Index); + } + } else if (lastWord2Index !== -1) { + result = Math.min(result, index - lastWord2Index); + } + lastWord1Index = index; + } else if (!areSameWords && currentWord === word2) { + if (lastWord1Index !== -1) { + result = Math.min(result, index - lastWord1Index); + } + lastWord2Index = index; + } + } + + return result; +}; diff --git a/solutions/0246-strobogrammatic-number.js b/solutions/0246-strobogrammatic-number.js new file mode 100644 index 00000000..19c3ab46 --- /dev/null +++ b/solutions/0246-strobogrammatic-number.js @@ -0,0 +1,40 @@ +/** + * 246. Strobogrammatic Number + * https://leetcode.com/problems/strobogrammatic-number/ + * Difficulty: Easy + * + * Given a string num which represents an integer, return true if num is a strobogrammatic number. + * + * A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at + * upside down). + */ + +/** + * @param {string} num + * @return {boolean} + */ +var isStrobogrammatic = function(num) { + const validPairs = new Map([ + ['0', '0'], + ['1', '1'], + ['6', '9'], + ['8', '8'], + ['9', '6'] + ]); + let left = 0; + let right = num.length - 1; + + while (left <= right) { + const leftDigit = num[left]; + const rightDigit = num[right]; + + if (!validPairs.has(leftDigit) || validPairs.get(leftDigit) !== rightDigit) { + return false; + } + + left++; + right--; + } + + return true; +}; diff --git a/solutions/0247-strobogrammatic-number-ii.js b/solutions/0247-strobogrammatic-number-ii.js new file mode 100644 index 00000000..d8ebf09a --- /dev/null +++ b/solutions/0247-strobogrammatic-number-ii.js @@ -0,0 +1,43 @@ +/** + * 247. Strobogrammatic Number II + * https://leetcode.com/problems/strobogrammatic-number-ii/ + * Difficulty: Medium + * + * Given an integer n, return all the strobogrammatic numbers that are of length n. You may + * return the answer in any order. + * + * A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked + * at upside down). + */ + +/** + * @param {number} n + * @return {string[]} + */ +var findStrobogrammatic = function(n) { + const pairs = [ + ['0', '0'], + ['1', '1'], + ['6', '9'], + ['8', '8'], + ['9', '6'] + ]; + + return generateStrobogrammatic(n, n); + + function generateStrobogrammatic(length, finalLength) { + if (length === 0) return ['']; + if (length === 1) return ['0', '1', '8']; + + const result = []; + const subNumbers = generateStrobogrammatic(length - 2, finalLength); + for (const [left, right] of pairs) { + for (const sub of subNumbers) { + if (length === finalLength && left === '0') continue; + result.push(left + sub + right); + } + } + + return result; + } +}; diff --git a/solutions/0248-strobogrammatic-number-iii.js b/solutions/0248-strobogrammatic-number-iii.js new file mode 100644 index 00000000..d20b8dda --- /dev/null +++ b/solutions/0248-strobogrammatic-number-iii.js @@ -0,0 +1,65 @@ +/** + * 248. Strobogrammatic Number III + * https://leetcode.com/problems/strobogrammatic-number-iii/ + * Difficulty: Hard + * + * Given two strings low and high that represent two integers low and high where low <= high, + * return the number of strobogrammatic numbers in the range [low, high]. + * + * A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked + * at upside down). + */ + +/** + * @param {string} low + * @param {string} high + * @return {number} + */ +var strobogrammaticInRange = function(low, high) { + const pairs = [ + ['0', '0'], + ['1', '1'], + ['6', '9'], + ['8', '8'], + ['9', '6'] + ]; + + function generateStrobogrammatic(length, isOuter) { + if (length === 0) return ['']; + if (length === 1) return ['0', '1', '8']; + + const result = []; + const subNumbers = generateStrobogrammatic(length - 2, false); + + for (const [left, right] of pairs) { + for (const sub of subNumbers) { + if (isOuter && left === '0') continue; + result.push(left + sub + right); + } + } + + return result; + } + + function countInRange(num, lowVal, highVal) { + if (num.length < lowVal.length || num.length > highVal.length) return false; + if (num.length === lowVal.length && num < lowVal) return false; + if (num.length === highVal.length && num > highVal) return false; + return true; + } + + let count = 0; + const lowLength = low.length; + const highLength = high.length; + + for (let len = lowLength; len <= highLength; len++) { + const numbers = generateStrobogrammatic(len, true); + for (const num of numbers) { + if (countInRange(num, low, high)) { + count++; + } + } + } + + return count; +}; diff --git a/solutions/0249-group-shifted-strings.js b/solutions/0249-group-shifted-strings.js new file mode 100644 index 00000000..cbcfaf26 --- /dev/null +++ b/solutions/0249-group-shifted-strings.js @@ -0,0 +1,49 @@ +/** + * 249. Group Shifted Strings + * https://leetcode.com/problems/group-shifted-strings/ + * Difficulty: Medium + * + * Perform the following shift operations on a string: + * - Right shift: Replace every letter with the successive letter of the English alphabet, where + * 'z' is replaced by 'a'. For example, "abc" can be right-shifted to "bcd" or "xyz" can be + * right-shifted to "yza". + * - Left shift: Replace every letter with the preceding letter of the English alphabet, where + * 'a' is replaced by 'z'. For example, "bcd" can be left-shifted to "abc" or "yza" can be + * left-shifted to "xyz". + * + * We can keep shifting the string in both directions to form an endless shifting sequence. + * - For example, shift "abc" to form the sequence: ... <-> "abc" <-> "bcd" <-> ... <-> "xyz" + * <-> "yza" <-> .... <-> "zab" <-> "abc" <-> ... + * + * You are given an array of strings strings, group together all strings[i] that belong to the same + * shifting sequence. You may return the answer in any order. + */ + +/** + * @param {string[]} strings + * @return {string[][]} + */ +var groupStrings = function(strings) { + const groups = new Map(); + + for (const str of strings) { + const key = getShiftKey(str); + if (!groups.has(key)) { + groups.set(key, []); + } + groups.get(key).push(str); + } + + return Array.from(groups.values()); + + function getShiftKey(str) { + if (str.length === 1) return 'single'; + const key = []; + for (let i = 1; i < str.length; i++) { + let diff = str.charCodeAt(i) - str.charCodeAt(i - 1); + if (diff < 0) diff += 26; + key.push(diff); + } + return key.join(','); + } +}; diff --git a/solutions/0250-count-univalue-subtrees.js b/solutions/0250-count-univalue-subtrees.js new file mode 100644 index 00000000..8a8e14ff --- /dev/null +++ b/solutions/0250-count-univalue-subtrees.js @@ -0,0 +1,44 @@ +/** + * 250. Count Univalue Subtrees + * https://leetcode.com/problems/count-univalue-subtrees/ + * Difficulty: Medium + * + * Given the root of a binary tree, return the number of uni-value subtrees. + * + * A uni-value subtree means all nodes of the subtree have the same value. + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {TreeNode} root + * @return {number} + */ +var countUnivalSubtrees = function(root) { + let count = 0; + traverse(root); + return count; + + function isUnival(node, value) { + if (!node) return true; + + if (node.val !== value) return false; + + return isUnival(node.left, value) && isUnival(node.right, value); + } + + function traverse(node) { + if (!node) return; + + if (isUnival(node, node.val)) count++; + + traverse(node.left); + traverse(node.right); + } +}; diff --git a/solutions/0251-flatten-2d-vector.js b/solutions/0251-flatten-2d-vector.js new file mode 100644 index 00000000..612cc921 --- /dev/null +++ b/solutions/0251-flatten-2d-vector.js @@ -0,0 +1,44 @@ +/** + * 251. Flatten 2D Vector + * https://leetcode.com/problems/flatten-2d-vector/ + * Difficulty: Medium + * + * Design an iterator to flatten a 2D vector. It should support the next and hasNext operations. + * + * Implement the Vector2D class: + * - Vector2D(int[][] vec) initializes the object with the 2D vector vec. + * - next() returns the next element from the 2D vector and moves the pointer one step forward. + * You may assume that all the calls to next are valid. + * - hasNext() returns true if there are still some elements in the vector, and false otherwise. + */ + +/** + * @param {number[][]} vec + */ +var Vector2D = function(vec) { + this.vector = vec; + this.row = 0; + this.col = 0; +}; + +/** + * @return {number} + */ +Vector2D.prototype.next = function() { + while (this.row < this.vector.length && this.col >= this.vector[this.row].length) { + this.row++; + this.col = 0; + } + return this.vector[this.row][this.col++]; +}; + +/** + * @return {boolean} + */ +Vector2D.prototype.hasNext = function() { + while (this.row < this.vector.length && this.col >= this.vector[this.row].length) { + this.row++; + this.col = 0; + } + return this.row < this.vector.length; +}; diff --git a/solutions/0252-meeting-rooms.js b/solutions/0252-meeting-rooms.js new file mode 100644 index 00000000..09045654 --- /dev/null +++ b/solutions/0252-meeting-rooms.js @@ -0,0 +1,24 @@ +/** + * 252. Meeting Rooms + * https://leetcode.com/problems/meeting-rooms/ + * Difficulty: Easy + * + * Given an array of meeting time intervals where intervals[i] = [starti, endi], determine + * if a person could attend all meetings. + */ + +/** + * @param {number[][]} intervals + * @return {boolean} + */ +var canAttendMeetings = function(intervals) { + intervals.sort((a, b) => a[0] - b[0]); + + for (let i = 1; i < intervals.length; i++) { + if (intervals[i][0] < intervals[i - 1][1]) { + return false; + } + } + + return true; +}; diff --git a/solutions/0253-meeting-rooms-ii.js b/solutions/0253-meeting-rooms-ii.js new file mode 100644 index 00000000..2c08e7e3 --- /dev/null +++ b/solutions/0253-meeting-rooms-ii.js @@ -0,0 +1,34 @@ +/** + * 253. Meeting Rooms II + * https://leetcode.com/problems/meeting-rooms-ii/ + * Difficulty: Medium + * + * Given an array of meeting time intervals intervals where intervals[i] = [starti, endi], + * return the minimum number of conference rooms required. + */ + +/** + * @param {number[][]} intervals + * @return {number} + */ +var minMeetingRooms = function(intervals) { + const starts = intervals.map(([start]) => start).sort((a, b) => a - b); + const ends = intervals.map(([, end]) => end).sort((a, b) => a - b); + let rooms = 0; + let startIndex = 0; + let endIndex = 0; + let result = 0; + + while (startIndex < intervals.length) { + if (starts[startIndex] < ends[endIndex]) { + rooms++; + result = Math.max(result, rooms); + startIndex++; + } else { + rooms--; + endIndex++; + } + } + + return result; +}; diff --git a/solutions/0254-factor-combinations.js b/solutions/0254-factor-combinations.js new file mode 100644 index 00000000..ab66abba --- /dev/null +++ b/solutions/0254-factor-combinations.js @@ -0,0 +1,36 @@ +/** + * 254. Factor Combinations + * https://leetcode.com/problems/factor-combinations/ + * Difficulty: Medium + * + * Numbers can be regarded as the product of their factors. + * + * For example, 8 = 2 x 2 x 2 = 2 x 4. + * + * Given an integer n, return all possible combinations of its factors. You may return the + * answer in any order. + * + * Note that the factors should be in the range [2, n - 1]. + */ + +/** + * @param {number} n + * @return {number[][]} + */ +var getFactors = function(n) { + const result = []; + findFactors(n, 2, []); + return result; + + function findFactors(currentNum, start, combination) { + for (let i = start; i * i <= currentNum; i++) { + if (currentNum % i === 0) { + const nextNum = currentNum / i; + if (nextNum >= i && nextNum < currentNum) { + result.push([...combination, i, nextNum]); + findFactors(nextNum, i, [...combination, i]); + } + } + } + } +}; diff --git a/solutions/0255-verify-preorder-sequence-in-binary-search-tree.js b/solutions/0255-verify-preorder-sequence-in-binary-search-tree.js new file mode 100644 index 00000000..2e502211 --- /dev/null +++ b/solutions/0255-verify-preorder-sequence-in-binary-search-tree.js @@ -0,0 +1,27 @@ +/** + * 255. Verify Preorder Sequence in Binary Search Tree + * https://leetcode.com/problems/verify-preorder-sequence-in-binary-search-tree/ + * Difficulty: Medium + * + * Given an array of unique integers preorder, return true if it is the correct preorder + * traversal sequence of a binary search tree. + */ + +/** + * @param {number[]} preorder + * @return {boolean} + */ +var verifyPreorder = function(preorder) { + let minLimit = -Infinity; + const stack = []; + + for (const value of preorder) { + while (stack.length && stack[stack.length - 1] < value) { + minLimit = stack.pop(); + } + if (value <= minLimit) return false; + stack.push(value); + } + + return true; +}; diff --git a/solutions/0256-paint-house.js b/solutions/0256-paint-house.js new file mode 100644 index 00000000..c37cc991 --- /dev/null +++ b/solutions/0256-paint-house.js @@ -0,0 +1,34 @@ +/** + * 256. Paint House + * https://leetcode.com/problems/paint-house/ + * Difficulty: Medium + * + * There is a row of n houses, where each house can be painted one of three colors: red, blue, + * or green. The cost of painting each house with a certain color is different. You have to + * paint all the houses such that no two adjacent houses have the same color. + * + * The cost of painting each house with a certain color is represented by an n x 3 cost matrix + * costs. + * - For example, costs[0][0] is the cost of painting house 0 with the color red; costs[1][2] + * is the cost of painting house 1 with color green, and so on... + * + * Return the minimum cost to paint all houses. + */ + +/** + * @param {number[][]} costs + * @return {number} + */ +var minCost = function(costs) { + let prev = [...costs[0]]; + + for (let i = 1; i < costs.length; i++) { + prev = [ + costs[i][0] + Math.min(prev[1], prev[2]), + costs[i][1] + Math.min(prev[0], prev[2]), + costs[i][2] + Math.min(prev[0], prev[1]) + ]; + } + + return Math.min(...prev); +}; diff --git a/solutions/0259-3sum-smaller.js b/solutions/0259-3sum-smaller.js new file mode 100644 index 00000000..89e0d4b5 --- /dev/null +++ b/solutions/0259-3sum-smaller.js @@ -0,0 +1,36 @@ +/** + * 259. 3Sum Smaller + * https://leetcode.com/problems/3sum-smaller/ + * Difficulty: Medium + * + * Given an array of n integers nums and an integer target, find the number of index triplets + * i, j, k with 0 <= i < j < k < n that satisfy the condition nums[i] + nums[j] + nums[k] < target. + */ + +/** + * @param {number[]} nums + * @param {number} target + * @return {number} + */ +var threeSumSmaller = function(nums, target) { + nums.sort((a, b) => a - b); + const n = nums.length; + let result = 0; + + for (let i = 0; i < n - 2; i++) { + let left = i + 1; + let right = n - 1; + + while (left < right) { + const sum = nums[i] + nums[left] + nums[right]; + if (sum < target) { + result += right - left; + left++; + } else { + right--; + } + } + } + + return result; +}; diff --git a/solutions/0261-graph-valid-tree.js b/solutions/0261-graph-valid-tree.js new file mode 100644 index 00000000..483b2345 --- /dev/null +++ b/solutions/0261-graph-valid-tree.js @@ -0,0 +1,45 @@ +/** + * 261. Graph Valid Tree + * https://leetcode.com/problems/graph-valid-tree/ + * Difficulty: Medium + * + * You have a graph of n nodes labeled from 0 to n - 1. You are given an integer n and a list of + * edges where edges[i] = [ai, bi] indicates that there is an undirected edge between nodes ai + * and bi in the graph. + * + * Return true if the edges of the given graph make up a valid tree, and false otherwise. + */ + +/** + * @param {number} n + * @param {number[][]} edges + * @return {boolean} + */ +var validTree = function(n, edges) { + const parent = new Array(n).fill(-1); + + for (const [u, v] of edges) { + if (!union(u, v)) return false; + } + + let components = 0; + for (let i = 0; i < n; i++) { + if (parent[i] === -1) components++; + if (components > 1) return false; + } + + return edges.length === n - 1; + + function find(x) { + if (parent[x] === -1) return x; + return parent[x] = find(parent[x]); + } + + function union(x, y) { + const rootX = find(x); + const rootY = find(y); + if (rootX === rootY) return false; + parent[rootX] = rootY; + return true; + } +}; diff --git a/solutions/0265-paint-house-ii.js b/solutions/0265-paint-house-ii.js new file mode 100644 index 00000000..6a883f10 --- /dev/null +++ b/solutions/0265-paint-house-ii.js @@ -0,0 +1,51 @@ +/** + * 265. Paint House II + * https://leetcode.com/problems/paint-house-ii/ + * Difficulty: Hard + * + * There are a row of n houses, each house can be painted with one of the k colors. The cost of + * painting each house with a certain color is different. You have to paint all the houses such + * that no two adjacent houses have the same color. + * + * The cost of painting each house with a certain color is represented by an n x k cost matrix + * costs. + * - For example, costs[0][0] is the cost of painting house 0 with color 0; costs[1][2] is the + * cost of painting house 1 with color 2, and so on... + * + * Return the minimum cost to paint all houses. + */ + +/** + * @param {number[][]} costs + * @return {number} + */ +var minCostII = function(costs) { + const n = costs.length; + const k = costs[0].length; + let prev = [...costs[0]]; + + for (let i = 1; i < n; i++) { + const curr = new Array(k); + let min1 = Infinity; + let min2 = Infinity; + let index = -1; + + for (let j = 0; j < k; j++) { + if (prev[j] < min1) { + min2 = min1; + min1 = prev[j]; + index = j; + } else if (prev[j] < min2) { + min2 = prev[j]; + } + } + + for (let j = 0; j < k; j++) { + curr[j] = costs[i][j] + (j === index ? min2 : min1); + } + + prev = curr; + } + + return Math.min(...prev); +}; diff --git a/solutions/0266-palindrome-permutation.js b/solutions/0266-palindrome-permutation.js new file mode 100644 index 00000000..9f710d28 --- /dev/null +++ b/solutions/0266-palindrome-permutation.js @@ -0,0 +1,28 @@ +/** + * 266. Palindrome Permutation + * https://leetcode.com/problems/palindrome-permutation/ + * Difficulty: Easy + * + * Given a string s, return true if a permutation of the string could form a palindrome + * and false otherwise. + */ + +/** + * @param {string} s + * @return {boolean} + */ +var canPermutePalindrome = function(s) { + const map = new Map(); + + for (const char of s) { + map.set(char, (map.get(char) || 0) + 1); + } + + let oddCount = 0; + for (const count of map.values()) { + if (count % 2 !== 0) oddCount++; + if (oddCount > 1) return false; + } + + return true; +}; diff --git a/solutions/0267-palindrome-permutation-ii.js b/solutions/0267-palindrome-permutation-ii.js new file mode 100644 index 00000000..6f1127c0 --- /dev/null +++ b/solutions/0267-palindrome-permutation-ii.js @@ -0,0 +1,62 @@ +/** + * 267. Palindrome Permutation II + * https://leetcode.com/problems/palindrome-permutation-ii/ + * Difficulty: Medium + * + * Given a string s, return all the palindromic permutations (without duplicates) of it. + * + * You may return the answer in any order. If s has no palindromic permutation, return an + * empty list. + */ + +/** + * @param {string} s + * @return {string[]} + */ +var generatePalindromes = function(s) { + const map = new Map(); + for (const char of s) { + map.set(char, (map.get(char) || 0) + 1); + } + + let oddChar = ''; + const half = []; + let oddCount = 0; + + for (const [char, count] of map) { + if (count % 2) { + oddCount++; + oddChar = char; + } + for (let i = 0; i < Math.floor(count / 2); i++) { + half.push(char); + } + } + + if (oddCount > 1) return []; + + const result = new Set(); + + half.sort(); + permute(half, [], new Array(half.length).fill(false)); + return Array.from(result); + + function permute(chars, current, used) { + if (current.length === chars.length) { + const palindrome = current.join('') + oddChar + current.reverse().join(''); + result.add(palindrome); + current.reverse(); + return; + } + + for (let i = 0; i < chars.length; i++) { + if (!used[i] && (i === 0 || chars[i] !== chars[i - 1] || used[i - 1])) { + used[i] = true; + current.push(chars[i]); + permute(chars, current, used); + current.pop(); + used[i] = false; + } + } + } +}; diff --git a/solutions/0269-alien-dictionary.js b/solutions/0269-alien-dictionary.js new file mode 100644 index 00000000..00e19ca3 --- /dev/null +++ b/solutions/0269-alien-dictionary.js @@ -0,0 +1,73 @@ +/** + * 269. Alien Dictionary + * https://leetcode.com/problems/alien-dictionary/ + * Difficulty: Hard + * + * There is a new alien language that uses the English alphabet. However, the order of the + * letters is unknown to you. + * + * You are given a list of strings words from the alien language's dictionary. Now it is + * claimed that the strings in words are sorted lexicographically by the rules of this new + * language. + * + * If this claim is incorrect, and the given arrangement of string in words cannot correspond + * to any order of letters, return "". + * + * Otherwise, return a string of the unique letters in the new alien language sorted in + * lexicographically increasing order by the new language's rules. If there are multiple + * solutions, return any of them. + */ + +/** + * @param {string[]} words + * @return {string} + */ +var alienOrder = function(words) { + const graph = new Map(); + const inDegree = new Map(); + + for (const word of words) { + for (const char of word) { + if (!graph.has(char)) { + graph.set(char, new Set()); + inDegree.set(char, 0); + } + } + } + + for (let i = 1; i < words.length; i++) { + const prev = words[i - 1]; + const curr = words[i]; + const minLen = Math.min(prev.length, curr.length); + + if (prev.length > curr.length && prev.startsWith(curr)) return ''; + + for (let j = 0; j < minLen; j++) { + if (prev[j] !== curr[j]) { + if (!graph.get(prev[j]).has(curr[j])) { + graph.get(prev[j]).add(curr[j]); + inDegree.set(curr[j], inDegree.get(curr[j]) + 1); + } + break; + } + } + } + + const queue = []; + for (const [char, degree] of inDegree) { + if (degree === 0) queue.push(char); + } + + let result = ''; + while (queue.length) { + const char = queue.shift(); + result += char; + + for (const next of graph.get(char)) { + inDegree.set(next, inDegree.get(next) - 1); + if (inDegree.get(next) === 0) queue.push(next); + } + } + + return result.length === graph.size ? result : ''; +}; diff --git a/solutions/0270-closest-binary-search-tree-value.js b/solutions/0270-closest-binary-search-tree-value.js new file mode 100644 index 00000000..b0e78a8e --- /dev/null +++ b/solutions/0270-closest-binary-search-tree-value.js @@ -0,0 +1,36 @@ +/** + * 270. Closest Binary Search Tree Value + * https://leetcode.com/problems/closest-binary-search-tree-value/ + * Difficulty: Easy + * + * Given the root of a binary search tree and a target value, return the value in the BST that + * is closest to the target. If there are multiple answers, print the smallest. + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {TreeNode} root + * @param {number} target + * @return {number} + */ +var closestValue = function(root, target) { + let closest = root.val; + + while (root) { + closest = Math.abs(root.val - target) < Math.abs(closest - target) + || (Math.abs(root.val - target) === Math.abs(closest - target) && root.val < closest) + ? root.val + : closest; + + root = target < root.val ? root.left : root.right; + } + + return closest; +}; diff --git a/solutions/0271-encode-and-decode-strings.js b/solutions/0271-encode-and-decode-strings.js new file mode 100644 index 00000000..e32296b3 --- /dev/null +++ b/solutions/0271-encode-and-decode-strings.js @@ -0,0 +1,58 @@ +/** + * 271. Encode and Decode Strings + * https://leetcode.com/problems/encode-and-decode-strings/ + * Difficulty: Medium + * + * Design an algorithm to encode a list of strings to a string. The encoded string is then sent over + * the network and is decoded back to the original list of strings. + * + * Machine 1 (sender) has the function: + * string encode(vector strs) { + * // ... your code + * return encoded_string; + * } + * Machine 2 (receiver) has the function: + * vector decode(string s) { + * //... your code + * return strs; + * } + * So Machine 1 does: + * string encoded_string = encode(strs); + * and Machine 2 does: + * vector strs2 = decode(encoded_string); + * strs2 in Machine 2 should be the same as strs in Machine 1. + * + * Implement the encode and decode methods. + * + * You are not allowed to solve the problem using any serialize methods (such as eval). + */ + +/** + * Encodes a list of strings to a single string. + * + * @param {string[]} strs + * @return {string} + */ +var encode = function(strs) { + return strs.map(str => `${str.length}:${str}`).join(''); +}; + +/** + * Decodes a single string to a list of strings. + * + * @param {string} s + * @return {string[]} + */ +var decode = function(s) { + const result = []; + let i = 0; + + while (i < s.length) { + const colon = s.indexOf(':', i); + const len = parseInt(s.slice(i, colon)); + result.push(s.slice(colon + 1, colon + 1 + len)); + i = colon + 1 + len; + } + + return result; +}; diff --git a/solutions/0272-closest-binary-search-tree-value-ii.js b/solutions/0272-closest-binary-search-tree-value-ii.js new file mode 100644 index 00000000..b3a6b27b --- /dev/null +++ b/solutions/0272-closest-binary-search-tree-value-ii.js @@ -0,0 +1,41 @@ +/** + * 272. Closest Binary Search Tree Value II + * https://leetcode.com/problems/closest-binary-search-tree-value-ii/ + * Difficulty: Hard + * + * Given the root of a binary search tree, a target value, and an integer k, return the k values + * in the BST that are closest to the target. You may return the answer in any order. + * + * You are guaranteed to have only one unique set of k values in the BST that are closest to the + * target. + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {TreeNode} root + * @param {number} target + * @param {number} k + * @return {number[]} + */ +var closestKValues = function(root, target, k) { + const values = []; + + inOrder(root); + + values.sort((a, b) => Math.abs(a - target) - Math.abs(b - target)); + return values.slice(0, k); + + function inOrder(node) { + if (!node) return; + inOrder(node.left); + values.push(node.val); + inOrder(node.right); + } +}; diff --git a/solutions/0276-paint-fence.js b/solutions/0276-paint-fence.js new file mode 100644 index 00000000..c19bb08a --- /dev/null +++ b/solutions/0276-paint-fence.js @@ -0,0 +1,33 @@ +/** + * 276. Paint Fence + * https://leetcode.com/problems/paint-fence/ + * Difficulty: Medium + * + * You are painting a fence of n posts with k different colors. You must paint the posts following + * these rules: + * - Every post must be painted exactly one color. + * - There cannot be three or more consecutive posts with the same color. + * + * Given the two integers n and k, return the number of ways you can paint the fence. + */ + +/** + * @param {number} n + * @param {number} k + * @return {number} + */ +var numWays = function(n, k) { + if (n === 1) return k; + if (n === 2) return k * k; + + let same = k; + let diff = k * (k - 1); + + for (let i = 3; i <= n; i++) { + const prevSame = same; + same = diff; + diff = (prevSame + diff) * (k - 1); + } + + return same + diff; +}; diff --git a/solutions/0277-find-the-celebrity.js b/solutions/0277-find-the-celebrity.js new file mode 100644 index 00000000..ad6f71a4 --- /dev/null +++ b/solutions/0277-find-the-celebrity.js @@ -0,0 +1,53 @@ +/** + * 277. Find the Celebrity + * https://leetcode.com/problems/find-the-celebrity/ + * Difficulty: Medium + * + * Suppose you are at a party with n people labeled from 0 to n - 1 and among them, there may + * exist one celebrity. The definition of a celebrity is that all the other n - 1 people know + * the celebrity, but the celebrity does not know any of them. + * + * Now you want to find out who the celebrity is or verify that there is not one. You are only + * allowed to ask questions like: "Hi, A. Do you know B?" to get information about whether A + * knows B. You need to find out the celebrity (or verify there is not one) by asking as few + * questions as possible (in the asymptotic sense). + * + * You are given an integer n and a helper function bool knows(a, b) that tells you whether a + * knows b. Implement a function int findCelebrity(n). There will be exactly one celebrity if + * they are at the party. + * + * Return the celebrity's label if there is a celebrity at the party. If there is no celebrity, + * return -1. + * + * Note that the n x n 2D array graph given as input is not directly available to you, and + * instead only accessible through the helper function knows. graph[i][j] == 1 represents + * person i knows person j, wherease graph[i][j] == 0 represents person j does not know person i. + */ + +/** + * @param {function} knows() + * @return {function} + */ +var solution = function(knows) { + /** + * @param {integer} n Total people + * @return {integer} The celebrity + */ + return function(n) { + let candidate = 0; + + for (let i = 1; i < n; i++) { + if (knows(candidate, i)) { + candidate = i; + } + } + + for (let i = 0; i < n; i++) { + if (i !== candidate && (knows(candidate, i) || !knows(i, candidate))) { + return -1; + } + } + + return candidate; + }; +}; diff --git a/solutions/0280-wiggle-sort.js b/solutions/0280-wiggle-sort.js new file mode 100644 index 00000000..2f2aee91 --- /dev/null +++ b/solutions/0280-wiggle-sort.js @@ -0,0 +1,25 @@ +/** + * 280. Wiggle Sort + * https://leetcode.com/problems/wiggle-sort/ + * Difficulty: Medium + * + * Given an integer array nums, reorder it such that nums[0] <= nums[1] >= nums[2] <= nums[3].... + * + * You may assume the input array always has a valid answer. + */ + +/** + * @param {number[]} nums + * @return {void} Do not return anything, modify nums in-place instead. + */ +var wiggleSort = function(nums) { + const n = nums.length; + + for (let i = 0; i < n - 1; i++) { + if (i % 2 === 0 && nums[i] > nums[i + 1]) { + [nums[i], nums[i + 1]] = [nums[i + 1], nums[i]]; + } else if (i % 2 === 1 && nums[i] < nums[i + 1]) { + [nums[i], nums[i + 1]] = [nums[i + 1], nums[i]]; + } + } +}; diff --git a/solutions/0281-zigzag-iterator.js b/solutions/0281-zigzag-iterator.js new file mode 100644 index 00000000..ce71c1d5 --- /dev/null +++ b/solutions/0281-zigzag-iterator.js @@ -0,0 +1,49 @@ +/** + * 281. Zigzag Iterator + * https://leetcode.com/problems/zigzag-iterator/ + * Difficulty: Medium + * + * Given two vectors of integers v1 and v2, implement an iterator to return their elements + * alternately. + * + * Implement the ZigzagIterator class: + * - ZigzagIterator(List v1, List v2) initializes the object with the two vectors + * v1 and v2. + * - boolean hasNext() returns true if the iterator still has elements, and false otherwise. + * - int next() returns the current element of the iterator and moves the iterator to the + * next element. + */ + +/** + * @constructor + * @param {Integer[]} v1 + * @param {Integer[]} v2 + */ +var ZigzagIterator = function ZigzagIterator(v1, v2) { + this.queue = []; + if (v1.length) this.queue.push([v1, 0]); + if (v2.length) this.queue.push([v2, 0]); +}; + +/** + * @this ZigzagIterator + * @returns {boolean} + */ +ZigzagIterator.prototype.hasNext = function hasNext() { + return this.queue.length > 0; +}; + +/** + * @this ZigzagIterator + * @returns {integer} + */ +ZigzagIterator.prototype.next = function next() { + const [vector, index] = this.queue.shift(); + const value = vector[index]; + + if (index + 1 < vector.length) { + this.queue.push([vector, index + 1]); + } + + return value; +}; diff --git a/solutions/0285-inorder-successor-in-bst.js b/solutions/0285-inorder-successor-in-bst.js new file mode 100644 index 00000000..d589f0e4 --- /dev/null +++ b/solutions/0285-inorder-successor-in-bst.js @@ -0,0 +1,35 @@ +/** + * 285. Inorder Successor in BST + * https://leetcode.com/problems/inorder-successor-in-bst/ + * Difficulty: Medium + * + * Given the root of a binary search tree and a node p in it, return the in-order successor of + * that node in the BST. If the given node has no in-order successor in the tree, return null. + * + * The successor of a node p is the node with the smallest key greater than p.val. + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @param {TreeNode} p + * @return {TreeNode} + */ +var inorderSuccessor = function(root, p) { + let successor = null; + while (root) { + if (p.val < root.val) { + successor = root; + root = root.left; + } else { + root = root.right; + } + } + return successor; +}; diff --git a/solutions/0286-walls-and-gates.js b/solutions/0286-walls-and-gates.js new file mode 100644 index 00000000..13440941 --- /dev/null +++ b/solutions/0286-walls-and-gates.js @@ -0,0 +1,49 @@ +/** + * 286. Walls and Gates + * https://leetcode.com/problems/walls-and-gates/ + * Difficulty: Medium + * + * You are given an m x n grid rooms initialized with these three possible values. + * - -1 A wall or an obstacle. + * - 0 A gate. + * - INF Infinity means an empty room. We use the value 231 - 1 = 2147483647 to represent INF + * as you may assume that the distance to a gate is less than 2147483647. + * + * Fill each empty room with the distance to its nearest gate. If it is impossible to reach + * a gate, it should be filled with INF. + */ + +/** + * @param {number[][]} rooms + * @return {void} Do not return anything, modify rooms in-place instead. + */ +var wallsAndGates = function(rooms) { + const rows = rooms.length; + const cols = rooms[0].length; + const queue = []; + const INF = 2147483647; + + for (let i = 0; i < rows; i++) { + for (let j = 0; j < cols; j++) { + if (rooms[i][j] === 0) { + queue.push([i, j]); + } + } + } + + const directions = [[0, 1], [1, 0], [0, -1], [-1, 0]]; + while (queue.length) { + const [row, col] = queue.shift(); + + for (const [dr, dc] of directions) { + const newRow = row + dr; + const newCol = col + dc; + + if (newRow >= 0 && newRow < rows && newCol >= 0 && newCol < cols + && rooms[newRow][newCol] === INF) { + rooms[newRow][newCol] = rooms[row][col] + 1; + queue.push([newRow, newCol]); + } + } + } +}; diff --git a/solutions/0288-unique-word-abbreviation.js b/solutions/0288-unique-word-abbreviation.js new file mode 100644 index 00000000..886f3b29 --- /dev/null +++ b/solutions/0288-unique-word-abbreviation.js @@ -0,0 +1,57 @@ +/** + * 288. Unique Word Abbreviation + * https://leetcode.com/problems/unique-word-abbreviation/ + * Difficulty: Medium + * + * The abbreviation of a word is a concatenation of its first letter, the number of characters + * between the first and last letter, and its last letter. If a word has only two characters, + * then it is an abbreviation of itself. + * + * For example: + * - dog --> d1g because there is one letter between the first letter 'd' and the last letter 'g'. + * - internationalization --> i18n because there are 18 letters between the first letter 'i' and + * the last letter 'n'. + * - it --> it because any word with only two characters is an abbreviation of itself. + * + * Implement the ValidWordAbbr class: + * - ValidWordAbbr(String[] dictionary) Initializes the object with a dictionary of words. + * - boolean isUnique(string word) Returns true if either of the following conditions are met + * (otherwise returns false): + * - There is no word in dictionary whose abbreviation is equal to word's abbreviation. + * - For any word in dictionary whose abbreviation is equal to word's abbreviation, that word + * and word are the same. + */ + +/** + * @param {string[]} dictionary + */ +var ValidWordAbbr = function(dictionary) { + this.abbrMap = new Map(); + + for (const word of dictionary) { + const abbr = this.getAbbreviation(word); + if (!this.abbrMap.has(abbr)) { + this.abbrMap.set(abbr, new Set()); + } + this.abbrMap.get(abbr).add(word); + } +}; + +/** + * @param {string} word + * @return {string} + */ +ValidWordAbbr.prototype.getAbbreviation = function(word) { + if (word.length <= 2) return word; + return word[0] + (word.length - 2) + word[word.length - 1]; +}; + +/** + * @param {string} word + * @return {boolean} + */ +ValidWordAbbr.prototype.isUnique = function(word) { + const abbr = this.getAbbreviation(word); + const words = this.abbrMap.get(abbr); + return !words || (words.size === 1 && words.has(word)); +}; diff --git a/solutions/0291-word-pattern-ii.js b/solutions/0291-word-pattern-ii.js new file mode 100644 index 00000000..83e7eca5 --- /dev/null +++ b/solutions/0291-word-pattern-ii.js @@ -0,0 +1,51 @@ +/** + * 291. Word Pattern II + * https://leetcode.com/problems/word-pattern-ii/ + * Difficulty: Medium + * + * Given a pattern and a string s, return true if s matches the pattern. + * + * A string s matches a pattern if there is some bijective mapping of single characters to + * non-empty strings such that if each character in pattern is replaced by the string it + * maps to, then the resulting string is s. A bijective mapping means that no two characters + * map to the same string, and no character maps to two different strings. + */ + +/** + * @param {string} pattern + * @param {string} s + * @return {boolean} + */ +var wordPatternMatch = function(pattern, s) { + const charToWord = new Map(); + const usedWords = new Set(); + + return backtrack(0, 0); + + function backtrack(patIndex, strIndex) { + if (patIndex === pattern.length && strIndex === s.length) return true; + if (patIndex >= pattern.length || strIndex >= s.length) return false; + + const char = pattern[patIndex]; + if (charToWord.has(char)) { + const word = charToWord.get(char); + if (!s.startsWith(word, strIndex)) return false; + return backtrack(patIndex + 1, strIndex + word.length); + } + + for (let i = strIndex + 1; i <= s.length; i++) { + const word = s.slice(strIndex, i); + if (usedWords.has(word)) continue; + + charToWord.set(char, word); + usedWords.add(word); + + if (backtrack(patIndex + 1, strIndex + word.length)) return true; + + charToWord.delete(char); + usedWords.delete(word); + } + + return false; + } +}; diff --git a/solutions/0293-flip-game.js b/solutions/0293-flip-game.js new file mode 100644 index 00000000..8fe0485a --- /dev/null +++ b/solutions/0293-flip-game.js @@ -0,0 +1,32 @@ +/** + * 293. Flip Game + * https://leetcode.com/problems/flip-game/ + * Difficulty: Easy + * + * You are playing a Flip Game with your friend. + * + * You are given a string currentState that contains only '+' and '-'. You and your friend take + * turns to flip two consecutive "++" into "--". The game ends when a person can no longer make + * a move, and therefore the other person will be the winner. + * + * Return all possible states of the string currentState after one valid move. You may return + * the answer in any order. If there is no valid move, return an empty list []. + */ + +/** + * @param {string} currentState + * @return {string[]} + */ +var generatePossibleNextMoves = function(currentState) { + const results = []; + + for (let i = 0; i < currentState.length - 1; i++) { + if (currentState[i] === '+' && currentState[i + 1] === '+') { + results.push( + currentState.slice(0, i) + '--' + currentState.slice(i + 2) + ); + } + } + + return results; +}; diff --git a/solutions/0294-flip-game-ii.js b/solutions/0294-flip-game-ii.js new file mode 100644 index 00000000..d4baf073 --- /dev/null +++ b/solutions/0294-flip-game-ii.js @@ -0,0 +1,40 @@ +/** + * 294. Flip Game II + * https://leetcode.com/problems/flip-game-ii/ + * Difficulty: Medium + * + * You are playing a Flip Game with your friend. + * + * You are given a string currentState that contains only '+' and '-'. You and your friend take + * turns to flip two consecutive "++" into "--". The game ends when a person can no longer make + * a move, and therefore the other person will be the winner. + * + * Return true if the starting player can guarantee a win, and false otherwise. + */ + +/** + * @param {string} currentState + * @return {boolean} + */ +var canWin = function(currentState) { + const map = new Map(); + + return canWinFrom(currentState); + + function canWinFrom(state) { + if (map.has(state)) return map.get(state); + + for (let i = 0; i < state.length - 1; i++) { + if (state[i] === '+' && state[i + 1] === '+') { + const nextState = state.slice(0, i) + '--' + state.slice(i + 2); + if (!canWinFrom(nextState)) { + map.set(state, true); + return true; + } + } + } + + map.set(state, false); + return false; + } +}; diff --git a/solutions/0296-best-meeting-point.js b/solutions/0296-best-meeting-point.js new file mode 100644 index 00000000..d31e660b --- /dev/null +++ b/solutions/0296-best-meeting-point.js @@ -0,0 +1,42 @@ +/** + * 296. Best Meeting Point + * https://leetcode.com/problems/best-meeting-point/ + * Difficulty: Hard + * + * Given an m x n binary grid grid where each 1 marks the home of one friend, return the minimal + * total travel distance. + * + * The total travel distance is the sum of the distances between the houses of the friends and + * the meeting point. + * + * The distance is calculated using Manhattan Distance, where + * distance(p1, p2) = |p2.x - p1.x| + |p2.y - p1.y|. + */ + +/** + * @param {number[][]} grid + * @return {number} + */ +var minTotalDistance = function(grid) { + const rows = []; + const cols = []; + + for (let i = 0; i < grid.length; i++) { + for (let j = 0; j < grid[0].length; j++) { + if (grid[i][j] === 1) { + rows.push(i); + cols.push(j); + } + } + } + + rows.sort((a, b) => a - b); + cols.sort((a, b) => a - b); + + let result = 0; + for (let i = 0; i < rows.length; i++) { + result += Math.abs(rows[i] - rows[Math.floor(rows.length / 2)]); + result += Math.abs(cols[i] - cols[Math.floor(cols.length / 2)]); + } + return result; +}; diff --git a/solutions/0298-binary-tree-longest-consecutive-sequence.js b/solutions/0298-binary-tree-longest-consecutive-sequence.js new file mode 100644 index 00000000..642f88bc --- /dev/null +++ b/solutions/0298-binary-tree-longest-consecutive-sequence.js @@ -0,0 +1,40 @@ +/** + * 298. Binary Tree Longest Consecutive Sequence + * https://leetcode.com/problems/binary-tree-longest-consecutive-sequence/ + * Difficulty: Medium + * + * Given the root of a binary tree, return the length of the longest consecutive sequence path. + * + * A consecutive sequence path is a path where the values increase by one along the path. + * + * Note that the path can start at any node in the tree, and you cannot go from a node to its + * parent in the path. + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {TreeNode} root + * @return {number} + */ +var longestConsecutive = function(root) { + let result = 0; + traverse(root, root.val - 1, 0); + return result; + + function traverse(node, parentValue, length) { + if (!node) return; + + const currentLength = parentValue + 1 === node.val ? length + 1 : 1; + result = Math.max(result, currentLength); + + traverse(node.left, node.val, currentLength); + traverse(node.right, node.val, currentLength); + } +}; diff --git a/solutions/0302-smallest-rectangle-enclosing-black-pixels.js b/solutions/0302-smallest-rectangle-enclosing-black-pixels.js new file mode 100644 index 00000000..76de7a6e --- /dev/null +++ b/solutions/0302-smallest-rectangle-enclosing-black-pixels.js @@ -0,0 +1,63 @@ +/** + * 302. Smallest Rectangle Enclosing Black Pixels + * https://leetcode.com/problems/smallest-rectangle-enclosing-black-pixels/ + * Difficulty: Hard + * + * You are given an m x n binary matrix image where 0 represents a white pixel and 1 represents + * a black pixel. + * + * The black pixels are connected (i.e., there is only one black region). Pixels are connected + * horizontally and vertically. + * + * Given two integers x and y that represents the location of one of the black pixels, return + * the area of the smallest (axis-aligned) rectangle that encloses all black pixels. + * + * You must write an algorithm with less than O(mn) runtime complexity + */ + +/** + * @param {character[][]} image + * @param {number} x + * @param {number} y + * @return {number} + */ +var minArea = function(image, x, y) { + const rows = image.length; + const cols = image[0].length; + const top = binarySearch(0, x, true, true); + const bottom = binarySearch(x, rows - 1, true, false); + const left = binarySearch(0, y, false, true); + const right = binarySearch(y, cols - 1, false, false); + + return (bottom - top + 1) * (right - left + 1); + + function binarySearch(start, end, isRow, isMin) { + let result = isMin ? end : start; + while (start <= end) { + const mid = Math.floor((start + end) / 2); + let hasBlack = false; + for (let i = 0; i < (isRow ? cols : rows); i++) { + const pixel = isRow ? image[mid][i] : image[i][mid]; + if (pixel === '1') { + hasBlack = true; + break; + } + } + if (hasBlack) { + result = mid; + if (isMin) { + end = mid - 1; + } else { + start = mid + 1; + } + } else { + if (isMin) { + start = mid + 1; + } else { + end = mid - 1; + } + } + } + return result; + } +}; diff --git a/solutions/0305-number-of-islands-ii.js b/solutions/0305-number-of-islands-ii.js new file mode 100644 index 00000000..e5f5cd28 --- /dev/null +++ b/solutions/0305-number-of-islands-ii.js @@ -0,0 +1,86 @@ +/** + * 305. Number of Islands II + * https://leetcode.com/problems/number-of-islands-ii/ + * Difficulty: Hard + * + * You are given an empty 2D binary grid grid of size m x n. The grid represents a map where 0's + * represent water and 1's represent land. Initially, all the cells of grid are water cells + * (i.e., all the cells are 0's). + * + * We may perform an add land operation which turns the water at position into a land. You are + * given an array positions where positions[i] = [ri, ci] is the position (ri, ci) at which we + * should operate the ith operation. + * + * Return an array of integers answer where answer[i] is the number of islands after turning + * the cell (ri, ci) into a land. + * + * An island is surrounded by water and is formed by connecting adjacent lands horizontally + * or vertically. You may assume all four edges of the grid are all surrounded by water. + */ + +/** + * @param {number} m + * @param {number} n + * @param {number[][]} positions + * @return {number[]} + */ +var numIslands2 = function(m, n, positions) { + const parent = new Map(); + const rank = new Map(); + const result = []; + const directions = [[-1, 0], [1, 0], [0, -1], [0, 1]]; + let islandCount = 0; + + for (const [row, col] of positions) { + const current = row * n + col; + if (parent.has(current)) { + result.push(islandCount); + continue; + } + islandCount++; + parent.set(current, current); + rank.set(current, 0); + + for (const [dr, dc] of directions) { + const newRow = row + dr; + const newCol = col + dc; + if (newRow >= 0 && newRow < m && newCol >= 0 && newCol < n) { + const neighbor = newRow * n + newCol; + if (parent.has(neighbor)) { + union(current, neighbor); + } + } + } + result.push(islandCount); + } + + return result; + + function find(node) { + if (!parent.has(node)) { + parent.set(node, node); + rank.set(node, 0); + } + if (parent.get(node) !== node) { + parent.set(node, find(parent.get(node))); + } + return parent.get(node); + } + + function union(node1, node2) { + const root1 = find(node1); + const root2 = find(node2); + if (root1 === root2) return; + const rank1 = rank.get(root1); + const rank2 = rank.get(root2); + if (rank1 < rank2) { + parent.set(root1, root2); + } else if (rank1 > rank2) { + parent.set(root2, root1); + } else { + parent.set(root2, root1); + rank.set(root1, rank1 + 1); + } + islandCount--; + } +}; diff --git a/solutions/0308-range-sum-query-2d-mutable.js b/solutions/0308-range-sum-query-2d-mutable.js new file mode 100644 index 00000000..670caca6 --- /dev/null +++ b/solutions/0308-range-sum-query-2d-mutable.js @@ -0,0 +1,94 @@ +/** + * 308. Range Sum Query 2D - Mutable + * https://leetcode.com/problems/range-sum-query-2d-mutable/ + * Difficulty: Medium + * + * Given a 2D matrix matrix, handle multiple queries of the following types: + * 1. Update the value of a cell in matrix. + * 2. Calculate the sum of the elements of matrix inside the rectangle defined by its upper left + * corner (row1, col1) and lower right corner (row2, col2). + * + * Implement the NumMatrix class: + * - NumMatrix(int[][] matrix) Initializes the object with the integer matrix matrix. + * - void update(int row, int col, int val) Updates the value of matrix[row][col] to be val. + * - int sumRegion(int row1, int col1, int row2, int col2) Returns the sum of the elements of + * matrix inside the rectangle defined by its upper left corner (row1, col1) and lower right + * corner (row2, col2). + */ + +/** + * @param {number[][]} matrix + */ +var NumMatrix = function(matrix) { + this.rows = matrix.length; + this.cols = matrix[0].length; + this.matrix = matrix; + this.tree = new Array(this.rows + 1).fill().map(() => new Array(this.cols + 1).fill(0)); + + for (let i = 0; i < this.rows; i++) { + for (let j = 0; j < this.cols; j++) { + this.updateTree(i + 1, j + 1, matrix[i][j]); + } + } +}; + +/** + * @param {number} row + * @param {number} col + * @param {number} val + * @return {void} + */ +NumMatrix.prototype.updateTree = function(row, col, val) { + while (row <= this.rows) { + let c = col; + while (c <= this.cols) { + this.tree[row][c] += val; + c += c & (-c); + } + row += row & (-row); + } +}; + +/** + * @param {number} row + * @param {number} col + * @return {number} + */ +NumMatrix.prototype.getSum = function(row, col) { + let sum = 0; + while (row > 0) { + let c = col; + while (c > 0) { + sum += this.tree[row][c]; + c -= c & (-c); + } + row -= row & (-row); + } + return sum; +}; + +/** + * @param {number} row + * @param {number} col + * @param {number} val + * @return {void} + */ +NumMatrix.prototype.update = function(row, col, val) { + const diff = val - this.matrix[row][col]; + this.matrix[row][col] = val; + this.updateTree(row + 1, col + 1, diff); +}; + +/** + * @param {number} row1 + * @param {number} col1 + * @param {number} row2 + * @param {number} col2 + * @return {number} + */ +NumMatrix.prototype.sumRegion = function(row1, col1, row2, col2) { + return this.getSum(row2 + 1, col2 + 1) + - this.getSum(row2 + 1, col1) + - this.getSum(row1, col2 + 1) + + this.getSum(row1, col1); +}; diff --git a/solutions/0311-sparse-matrix-multiplication.js b/solutions/0311-sparse-matrix-multiplication.js new file mode 100644 index 00000000..7a69dca2 --- /dev/null +++ b/solutions/0311-sparse-matrix-multiplication.js @@ -0,0 +1,34 @@ +/** + * 311. Sparse Matrix Multiplication + * https://leetcode.com/problems/sparse-matrix-multiplication/ + * Difficulty: Medium + * + * Given two sparse matrices mat1 of size m x k and mat2 of size k x n, return the result of + * mat1 x mat2. You may assume that multiplication is always possible. + */ + +/** + * @param {number[][]} mat1 + * @param {number[][]} mat2 + * @return {number[][]} + */ +var multiply = function(mat1, mat2) { + const m = mat1.length; + const k = mat1[0].length; + const n = mat2[0].length; + const result = new Array(m).fill().map(() => new Array(n).fill(0)); + + for (let i = 0; i < m; i++) { + for (let j = 0; j < k; j++) { + if (mat1[i][j] !== 0) { + for (let l = 0; l < n; l++) { + if (mat2[j][l] !== 0) { + result[i][l] += mat1[i][j] * mat2[j][l]; + } + } + } + } + } + + return result; +}; diff --git a/solutions/0314-binary-tree-vertical-order-traversal.js b/solutions/0314-binary-tree-vertical-order-traversal.js new file mode 100644 index 00000000..e93b1b43 --- /dev/null +++ b/solutions/0314-binary-tree-vertical-order-traversal.js @@ -0,0 +1,53 @@ +/** + * 314. Binary Tree Vertical Order Traversal + * https://leetcode.com/problems/binary-tree-vertical-order-traversal/ + * Difficulty: Medium + * + * Given the root of a binary tree, return the vertical order traversal of its nodes' values. + * (i.e., from top to bottom, column by column). + * + * If two nodes are in the same row and column, the order should be from left to right. + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {TreeNode} root + * @return {number[][]} + */ +var verticalOrder = function(root) { + if (!root) return []; + + const columns = new Map(); + const queue = [[root, 0]]; + let minCol = 0; + let maxCol = 0; + + while (queue.length) { + const [node, col] = queue.shift(); + if (!columns.has(col)) columns.set(col, []); + columns.get(col).push(node.val); + + if (node.left) { + queue.push([node.left, col - 1]); + minCol = Math.min(minCol, col - 1); + } + if (node.right) { + queue.push([node.right, col + 1]); + maxCol = Math.max(maxCol, col + 1); + } + } + + const result = []; + for (let col = minCol; col <= maxCol; col++) { + if (columns.has(col)) result.push(columns.get(col)); + } + + return result; +}; diff --git a/solutions/0317-shortest-distance-from-all-buildings.js b/solutions/0317-shortest-distance-from-all-buildings.js new file mode 100644 index 00000000..f699b1b0 --- /dev/null +++ b/solutions/0317-shortest-distance-from-all-buildings.js @@ -0,0 +1,80 @@ +/** + * 317. Shortest Distance from All Buildings + * https://leetcode.com/problems/shortest-distance-from-all-buildings/ + * Difficulty: Hard + * + * You are given an m x n grid grid of values 0, 1, or 2, where: + * - each 0 marks an empty land that you can pass by freely, + * - each 1 marks a building that you cannot pass through, and + * - each 2 marks an obstacle that you cannot pass through. + * + * You want to build a house on an empty land that reaches all buildings in the shortest total + * travel distance. You can only move up, down, left, and right. + * + * Return the shortest travel distance for such a house. If it is not possible to build such + * a house according to the above rules, return -1. + * + * The total travel distance is the sum of the distances between the houses of the friends and + * the meeting point. + */ + +/** + * @param {number[][]} grid + * @return {number} + */ +var shortestDistance = function(grid) { + const rows = grid.length; + const cols = grid[0].length; + const distances = new Array(rows).fill().map(() => new Array(cols).fill(0)); + const reachCounts = new Array(rows).fill().map(() => new Array(cols).fill(0)); + let buildingCount = 0; + + function bfs(startRow, startCol) { + const queue = [[startRow, startCol]]; + const visited = new Array(rows).fill().map(() => new Array(cols).fill(false)); + visited[startRow][startCol] = true; + let distance = 0; + + const directions = [[-1, 0], [1, 0], [0, -1], [0, 1]]; + + while (queue.length) { + const size = queue.length; + distance++; + for (let i = 0; i < size; i++) { + const [row, col] = queue.shift(); + for (const [dr, dc] of directions) { + const newRow = row + dr; + const newCol = col + dc; + if (newRow >= 0 && newRow < rows && newCol >= 0 && newCol < cols + && !visited[newRow][newCol] && grid[newRow][newCol] !== 1 + && grid[newRow][newCol] !== 2) { + queue.push([newRow, newCol]); + visited[newRow][newCol] = true; + distances[newRow][newCol] += distance; + reachCounts[newRow][newCol]++; + } + } + } + } + } + + for (let i = 0; i < rows; i++) { + for (let j = 0; j < cols; j++) { + if (grid[i][j] === 1) { + buildingCount++; + bfs(i, j); + } + } + } + + let minDistance = Infinity; + for (let i = 0; i < rows; i++) { + for (let j = 0; j < cols; j++) { + if (grid[i][j] === 0 && reachCounts[i][j] === buildingCount) { + minDistance = Math.min(minDistance, distances[i][j]); + } + } + } + + return minDistance === Infinity ? -1 : minDistance; +}; diff --git a/solutions/0320-generalized-abbreviation.js b/solutions/0320-generalized-abbreviation.js new file mode 100644 index 00000000..96ab102d --- /dev/null +++ b/solutions/0320-generalized-abbreviation.js @@ -0,0 +1,41 @@ +/** + * 320. Generalized Abbreviation + * https://leetcode.com/problems/generalized-abbreviation/ + * Difficulty: Medium + * + * A word's generalized abbreviation can be constructed by taking any number of non-overlapping + * and non-adjacent substrings and replacing them with their respective lengths. + * - For example, "abcde" can be abbreviated into: + * - "a3e" ("bcd" turned into "3") + * - "1bcd1" ("a" and "e" both turned into "1") + * - "5" ("abcde" turned into "5") + * - "abcde" (no substrings replaced) + * - However, these abbreviations are invalid: + * - "23" ("ab" turned into "2" and "cde" turned into "3") is invalid as the substrings + * chosen are adjacent. + * - "22de" ("ab" turned into "2" and "bc" turned into "2") is invalid as the substring + * chosen overlap. + * + * Given a string word, return a list of all the possible generalized abbreviations of word. + * Return the answer in any order. + */ + +/** + * @param {string} word + * @return {string[]} + */ +var generateAbbreviations = function(word) { + const result = []; + backtrack('', 0, 0); + return result; + + function backtrack(current, pos, count) { + if (pos === word.length) { + result.push(current + (count > 0 ? count : '')); + return; + } + + backtrack(current + (count > 0 ? count : '') + word[pos], pos + 1, 0); + backtrack(current, pos + 1, count + 1); + } +}; diff --git a/solutions/0323-number-of-connected-components-in-an-undirected-graph.js b/solutions/0323-number-of-connected-components-in-an-undirected-graph.js new file mode 100644 index 00000000..ba679b5f --- /dev/null +++ b/solutions/0323-number-of-connected-components-in-an-undirected-graph.js @@ -0,0 +1,42 @@ +/** + * 323. Number of Connected Components in an Undirected Graph + * https://leetcode.com/problems/number-of-connected-components-in-an-undirected-graph/ + * Difficulty: Medium + * + * You have a graph of n nodes. You are given an integer n and an array edges where + * edges[i] = [ai, bi] indicates that there is an edge between ai and bi in the graph. + * + * Return the number of connected components in the graph. + */ + +/** + * @param {number} n + * @param {number[][]} edges + * @return {number} + */ +var countComponents = function(n, edges) { + const parent = new Array(n).fill().map((_, i) => i); + let components = n; + + for (const [node1, node2] of edges) { + union(node1, node2); + } + + return components; + + function find(node) { + if (parent[node] !== node) { + parent[node] = find(parent[node]); + } + return parent[node]; + } + + function union(node1, node2) { + const root1 = find(node1); + const root2 = find(node2); + if (root1 !== root2) { + parent[root1] = root2; + components--; + } + } +}; diff --git a/solutions/0325-maximum-size-subarray-sum-equals-k.js b/solutions/0325-maximum-size-subarray-sum-equals-k.js new file mode 100644 index 00000000..697c3a73 --- /dev/null +++ b/solutions/0325-maximum-size-subarray-sum-equals-k.js @@ -0,0 +1,31 @@ +/** + * 325. Maximum Size Subarray Sum Equals k + * https://leetcode.com/problems/maximum-size-subarray-sum-equals-k/ + * Difficulty: Medium + * + * Given an integer array nums and an integer k, return the maximum length of a subarray that + * sums to k. If there is not one, return 0 instead. + */ + +/** + * @param {number[]} nums + * @param {number} k + * @return {number} + */ +var maxSubArrayLen = function(nums, k) { + const sumIndex = new Map([[0, -1]]); + let currentSum = 0; + let result = 0; + + for (let i = 0; i < nums.length; i++) { + currentSum += nums[i]; + if (sumIndex.has(currentSum - k)) { + result = Math.max(result, i - sumIndex.get(currentSum - k)); + } + if (!sumIndex.has(currentSum)) { + sumIndex.set(currentSum, i); + } + } + + return result; +}; diff --git a/solutions/0333-largest-bst-subtree.js b/solutions/0333-largest-bst-subtree.js new file mode 100644 index 00000000..30c83e84 --- /dev/null +++ b/solutions/0333-largest-bst-subtree.js @@ -0,0 +1,52 @@ +/** + * 333. Largest BST Subtree + * https://leetcode.com/problems/largest-bst-subtree/ + * Difficulty: Medium + * + * Given the root of a binary tree, find the largest subtree, which is also a Binary Search + * Tree (BST), where the largest means subtree has the largest number of nodes. + * + * A Binary Search Tree (BST) is a tree in which all the nodes follow the below-mentioned + * properties: + * - The left subtree values are less than the value of their parent (root) node's value. + * - The right subtree values are greater than the value of their parent (root) node's value. + * + * Note: A subtree must include all of its descendants. + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {TreeNode} root + * @return {number} + */ +var largestBSTSubtree = function(root) { + let maxSize = 0; + traverse(root); + return maxSize; + + function traverse(node) { + if (!node) return { isBST: true, size: 0, min: Infinity, max: -Infinity }; + + const left = traverse(node.left); + const right = traverse(node.right); + if (left.isBST && right.isBST && node.val > left.max && node.val < right.min) { + const size = left.size + right.size + 1; + maxSize = Math.max(maxSize, size); + return { + isBST: true, + size, + min: Math.min(left.min, node.val), + max: Math.max(right.max, node.val) + }; + } + + return { isBST: false, size: 0, min: 0, max: 0 }; + } +}; diff --git a/solutions/0339-nested-list-weight-sum.js b/solutions/0339-nested-list-weight-sum.js new file mode 100644 index 00000000..2ca1b16b --- /dev/null +++ b/solutions/0339-nested-list-weight-sum.js @@ -0,0 +1,33 @@ +/** + * 339. Nested List Weight Sum + * https://leetcode.com/problems/nested-list-weight-sum/ + * Difficulty: Medium + * + * You are given a nested list of integers nestedList. Each element is either an integer or + * a list whose elements may also be integers or other lists. + * + * The depth of an integer is the number of lists that it is inside of. For example, the nested + * list [1,[2,2],[[3],2],1] has each integer's value set to its depth. + * + * Return the sum of each integer in nestedList multiplied by its depth. + */ + +/** + * @param {NestedInteger[]} nestedList + * @return {number} + */ +var depthSum = function(nestedList) { + return calculateDepth(nestedList, 1); + + function calculateDepth(list, depth) { + let total = 0; + for (const element of list) { + if (element.isInteger()) { + total += element.getInteger() * depth; + } else { + total += calculateDepth(element.getList(), depth + 1); + } + } + return total; + } +}; diff --git a/solutions/0340-longest-substring-with-at-most-k-distinct-characters.js b/solutions/0340-longest-substring-with-at-most-k-distinct-characters.js new file mode 100644 index 00000000..dfd6a5c3 --- /dev/null +++ b/solutions/0340-longest-substring-with-at-most-k-distinct-characters.js @@ -0,0 +1,35 @@ +/** + * 340. Longest Substring with At Most K Distinct Characters + * https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/ + * Difficulty: Medium + * + * Given a string s and an integer k, return the length of the longest substring of s that + * contains at most k distinct characters. + */ + +/** + * @param {string} s + * @param {number} k + * @return {number} + */ +var lengthOfLongestSubstringKDistinct = function(s, k) { + const map = new Map(); + let result = 0; + let left = 0; + + for (let right = 0; right < s.length; right++) { + map.set(s[right], (map.get(s[right]) || 0) + 1); + + while (map.size > k) { + map.set(s[left], map.get(s[left]) - 1); + if (map.get(s[left]) === 0) { + map.delete(s[left]); + } + left++; + } + + result = Math.max(result, right - left + 1); + } + + return result; +}; diff --git a/solutions/0346-moving-average-from-data-stream.js b/solutions/0346-moving-average-from-data-stream.js new file mode 100644 index 00000000..6c2981a8 --- /dev/null +++ b/solutions/0346-moving-average-from-data-stream.js @@ -0,0 +1,36 @@ +/** + * 346. Moving Average from Data Stream + * https://leetcode.com/problems/moving-average-from-data-stream/ + * Difficulty: Easy + * + * Given a stream of integers and a window size, calculate the moving average of all integers + * in the sliding window. + * + * Implement the MovingAverage class: + * - MovingAverage(int size) Initializes the object with the size of the window size. + * - double next(int val) Returns the moving average of the last size values of the stream. + */ + +/** + * @param {number} size + */ +var MovingAverage = function(size) { + this.window = []; + this.maxSize = size; + this.sum = 0; +}; + +/** + * @param {number} val + * @return {number} + */ +MovingAverage.prototype.next = function(val) { + this.window.push(val); + this.sum += val; + + if (this.window.length > this.maxSize) { + this.sum -= this.window.shift(); + } + + return this.sum / this.window.length; +}; diff --git a/solutions/0348-design-tic-tac-toe.js b/solutions/0348-design-tic-tac-toe.js new file mode 100644 index 00000000..9b517913 --- /dev/null +++ b/solutions/0348-design-tic-tac-toe.js @@ -0,0 +1,59 @@ +/** + * 348. Design Tic-Tac-Toe + * https://leetcode.com/problems/design-tic-tac-toe/ + * Difficulty: Medium + * + * Assume the following rules are for the tic-tac-toe game on an n x n board between two players: + * 1. A move is guaranteed to be valid and is placed on an empty block. + * 2. Once a winning condition is reached, no more moves are allowed. + * 3. A player who succeeds in placing n of their marks in a horizontal, vertical, or diagonal + * row wins the game. + * + * Implement the TicTacToe class: + * - TicTacToe(int n) Initializes the object the size of the board n. + * - int move(int row, int col, int player) Indicates that the player with id player plays at the + * cell (row, col) of the board. The move is guaranteed to be a valid move, and the two players + * alternate in making moves. Return + * - 0 if there is no winner after the move, + * - 1 if player 1 is the winner after the move, or + * - 2 if player 2 is the winner after the move. + */ + +/** + * @param {number} n + */ +var TicTacToe = function(n) { + this.size = n; + this.rows = new Array(n).fill(0); + this.cols = new Array(n).fill(0); + this.diagonal = 0; + this.antiDiagonal = 0; +}; + +/** + * @param {number} row + * @param {number} col + * @param {number} player + * @return {number} + */ +TicTacToe.prototype.move = function(row, col, player) { + const value = player === 1 ? 1 : -1; + + this.rows[row] += value; + this.cols[col] += value; + + if (row === col) { + this.diagonal += value; + } + + if (row + col === this.size - 1) { + this.antiDiagonal += value; + } + + if (Math.abs(this.rows[row]) === this.size || Math.abs(this.cols[col]) === this.size + || Math.abs(this.diagonal) === this.size || Math.abs(this.antiDiagonal) === this.size) { + return player; + } + + return 0; +}; diff --git a/solutions/0351-android-unlock-patterns.js b/solutions/0351-android-unlock-patterns.js new file mode 100644 index 00000000..ef71439d --- /dev/null +++ b/solutions/0351-android-unlock-patterns.js @@ -0,0 +1,68 @@ +/** + * 351. Android Unlock Patterns + * https://leetcode.com/problems/android-unlock-patterns/ + * Difficulty: Medium + * + * Android devices have a special lock screen with a 3 x 3 grid of dots. Users can set an + * "unlock pattern" by connecting the dots in a specific sequence, forming a series of joined + * line segments where each segment's endpoints are two consecutive dots in the sequence. + * A sequence of k dots is a valid unlock pattern if both of the following are true: + * - All the dots in the sequence are distinct. + * - If the line segment connecting two consecutive dots in the sequence passes through the + * center of any other dot, the other dot must have previously appeared in the sequence. + * No jumps through the center non-selected dots are allowed. + * - For example, connecting dots 2 and 9 without dots 5 or 6 appearing beforehand is valid + * because the line from dot 2 to dot 9 does not pass through the center of either dot 5 or 6. + * - However, connecting dots 1 and 3 without dot 2 appearing beforehand is invalid because + * the line from dot 1 to dot 3 passes through the center of dot 2. + * + * Here are some example valid and invalid unlock patterns: + */ + +/** + * @param {number} m + * @param {number} n + * @return {number} + */ +var numberOfPatterns = function(m, n) { + const jumps = new Array(10).fill().map(() => new Array(10).fill(0)); + jumps[1][3] = jumps[3][1] = 2; + jumps[1][7] = jumps[7][1] = 4; + jumps[3][9] = jumps[9][3] = 6; + jumps[7][9] = jumps[9][7] = 8; + jumps[1][9] = jumps[9][1] = jumps[2][8] = jumps[8][2] = jumps[3][7] + = jumps[7][3] = jumps[4][6] = jumps[6][4] = 5; + + function backtrack(current, visited, length) { + if (length > n) return 0; + let count = length >= m ? 1 : 0; + if (length === n) return count; + + for (let next = 1; next <= 9; next++) { + if (!visited.has(next)) { + const jump = jumps[current][next]; + if (jump === 0 || visited.has(jump)) { + visited.add(next); + count += backtrack(next, visited, length + 1); + visited.delete(next); + } + } + } + return count; + } + + let total = 0; + const visited = new Set(); + visited.add(1); + total += backtrack(1, visited, 1) * 4; + visited.delete(1); + + visited.add(2); + total += backtrack(2, visited, 1) * 4; + visited.delete(2); + + visited.add(5); + total += backtrack(5, visited, 1); + + return total; +}; diff --git a/solutions/0353-design-snake-game.js b/solutions/0353-design-snake-game.js new file mode 100644 index 00000000..4f615906 --- /dev/null +++ b/solutions/0353-design-snake-game.js @@ -0,0 +1,82 @@ +/** + * 353. Design Snake Game + * https://leetcode.com/problems/design-snake-game/ + * Difficulty: Medium + * + * Design a Snake game that is played on a device with screen size height x width. Play the + * game online if you are not familiar with the game. + * + * The snake is initially positioned at the top left corner (0, 0) with a length of 1 unit. + * + * You are given an array food where food[i] = (ri, ci) is the row and column position of a + * piece of food that the snake can eat. When a snake eats a piece of food, its length and + * the game's score both increase by 1. + * + * Each piece of food appears one by one on the screen, meaning the second piece of food will + * not appear until the snake eats the first piece of food. + * + * When a piece of food appears on the screen, it is guaranteed that it will not appear on a + * block occupied by the snake. + * + * The game is over if the snake goes out of bounds (hits a wall) or if its head occupies a + * space that its body occupies after moving (i.e. a snake of length 4 cannot run into itself). + * + * Implement the SnakeGame class: + * - SnakeGame(int width, int height, int[][] food) Initializes the object with a screen of size + * height x width and the positions of the food. + * - int move(String direction) Returns the score of the game after applying one direction move + * by the snake. If the game is over, return -1. + */ + +/** + * @param {number} width + * @param {number} height + * @param {number[][]} food + */ +var SnakeGame = function(width, height, food) { + this.width = width; + this.height = height; + this.food = food; + this.foodIndex = 0; + this.score = 0; + this.snake = [[0, 0]]; + this.bodySet = new Set(['0,0']); +}; + +/** + * @param {string} direction + * @return {number} + */ +SnakeGame.prototype.move = function(direction) { + const head = [...this.snake[0]]; + + if (direction === 'U') head[0]--; + else if (direction === 'D') head[0]++; + else if (direction === 'L') head[1]--; + else if (direction === 'R') head[1]++; + + if (head[0] < 0 || head[0] >= this.height || head[1] < 0 || head[1] >= this.width) { + return -1; + } + + const tail = this.snake.pop(); + this.bodySet.delete(`${tail[0]},${tail[1]}`); + + const headKey = `${head[0]},${head[1]}`; + if (this.bodySet.has(headKey)) { + return -1; + } + + this.snake.unshift(head); + this.bodySet.add(headKey); + + if (this.foodIndex < this.food.length && head[0] === this.food[this.foodIndex][0] + && head[1] === this.food[this.foodIndex][1]) { + this.snake.push(tail); + this.bodySet.add(`${tail[0]},${tail[1]}`); + this.foodIndex++; + this.score++; + } + + return this.score; +}; diff --git a/solutions/0356-line-reflection.js b/solutions/0356-line-reflection.js new file mode 100644 index 00000000..76722159 --- /dev/null +++ b/solutions/0356-line-reflection.js @@ -0,0 +1,37 @@ +/** + * 356. Line Reflection + * https://leetcode.com/problems/line-reflection/ + * Difficulty: Medium + * + * Given n points on a 2D plane, find if there is such a line parallel to the y-axis that reflects + * the given points symmetrically. + * + * In other words, answer whether or not if there exists a line that after reflecting all points + * over the given line, the original points' set is the same as the reflected ones. + * + * Note that there can be repeated points. + */ + +/** + * @param {number[][]} points + * @return {boolean} + */ +var isReflected = function(points) { + const pointSet = new Set(points.map(([x, y]) => `${x},${y}`)); + let minX = Infinity; + let maxX = -Infinity; + + for (const [x] of points) { + minX = Math.min(minX, x); + maxX = Math.max(maxX, x); + } + + const sum = minX + maxX; + for (const [x, y] of points) { + if (!pointSet.has(`${sum - x},${y}`)) { + return false; + } + } + + return true; +}; diff --git a/solutions/0358-rearrange-string-k-distance-apart.js b/solutions/0358-rearrange-string-k-distance-apart.js new file mode 100644 index 00000000..9d498ae4 --- /dev/null +++ b/solutions/0358-rearrange-string-k-distance-apart.js @@ -0,0 +1,65 @@ +/** + * 358. Rearrange String k Distance Apart + * https://leetcode.com/problems/rearrange-string-k-distance-apart/ + * Difficulty: Hard + * + * Given a string s and an integer k, rearrange s such that the same characters are at least + * distance k from each other. If it is not possible to rearrange the string, return an empty + * string "". + */ + +/** + * @param {string} s + * @param {number} k + * @return {string} + */ +var rearrangeString = function(s, k) { + if (k <= 1) return s; + + const charCount = new Array(26).fill(0); + for (const char of s) { + charCount[char.charCodeAt(0) - 97]++; + } + + const maxHeap = []; + for (let i = 0; i < 26; i++) { + if (charCount[i] > 0) { + maxHeap.push([charCount[i], String.fromCharCode(i + 97)]); + } + } + maxHeap.sort((a, b) => b[0] - a[0]); + + const maxFreq = maxHeap[0] ? maxHeap[0][0] : 0; + if (maxFreq > Math.ceil(s.length / k)) return ''; + + const result = new Array(s.length).fill(''); + let index = 0; + + while (maxHeap.length) { + const temp = []; + for (let i = 0; i < k && maxHeap.length; i++) { + const [count, char] = maxHeap.shift(); + while (index < s.length && result[index] !== '') { + index++; + } + if (index >= s.length) index = 0; + result[index] = char; + index++; + if (count > 1) temp.push([count - 1, char]); + } + + temp.sort((a, b) => b[0] - a[0]); + maxHeap.push(...temp); + maxHeap.sort((a, b) => b[0] - a[0]); + } + + for (let i = 0; i <= s.length - k; i++) { + const seen = new Set(); + for (let j = i; j < i + k; j++) { + if (seen.has(result[j])) return ''; + seen.add(result[j]); + } + } + + return result.join(''); +}; diff --git a/solutions/0359-logger-rate-limiter.js b/solutions/0359-logger-rate-limiter.js new file mode 100644 index 00000000..9dacbd78 --- /dev/null +++ b/solutions/0359-logger-rate-limiter.js @@ -0,0 +1,35 @@ +/** + * 359. Logger Rate Limiter + * https://leetcode.com/problems/logger-rate-limiter/ + * Difficulty: Easy + * + * Design a logger system that receives a stream of messages along with their timestamps. + * Each unique message should only be printed at most every 10 seconds (i.e. a message + * printed at timestamp t will prevent other identical messages from being printed until + * timestamp t + 10). + * + * All messages will come in chronological order. Several messages may arrive at the same timestamp. + * + * Implement the Logger class: + * - Logger() Initializes the logger object. + * - bool shouldPrintMessage(int timestamp, string message) Returns true if the message should + * be printed in the given timestamp, otherwise returns false. + */ + +var Logger = function() { + this.messageTimestamps = new Map(); +}; + +/** + * @param {number} timestamp + * @param {string} message + * @return {boolean} + */ +Logger.prototype.shouldPrintMessage = function(timestamp, message) { + const nextAllowed = this.messageTimestamps.get(message) || 0; + if (timestamp >= nextAllowed) { + this.messageTimestamps.set(message, timestamp + 10); + return true; + } + return false; +}; diff --git a/solutions/0360-sort-transformed-array.js b/solutions/0360-sort-transformed-array.js new file mode 100644 index 00000000..30badca3 --- /dev/null +++ b/solutions/0360-sort-transformed-array.js @@ -0,0 +1,52 @@ +/** + * 360. Sort Transformed Array + * https://leetcode.com/problems/sort-transformed-array/ + * Difficulty: Medium + * + * Given a sorted integer array nums and three integers a, b and c, apply a quadratic function + * of the form f(x) = ax2 + bx + c to each element nums[i] in the array, and return the array + * in a sorted order. + */ + +/** + * @param {number[]} nums + * @param {number} a + * @param {number} b + * @param {number} c + * @return {number[]} + */ +var sortTransformedArray = function(nums, a, b, c) { + const result = new Array(nums.length); + let left = 0; + let right = nums.length - 1; + let index = a >= 0 ? nums.length - 1 : 0; + + while (left <= right) { + const leftVal = transform(nums[left]); + const rightVal = transform(nums[right]); + + if (a >= 0) { + if (leftVal > rightVal) { + result[index--] = leftVal; + left++; + } else { + result[index--] = rightVal; + right--; + } + } else { + if (leftVal < rightVal) { + result[index++] = leftVal; + left++; + } else { + result[index++] = rightVal; + right--; + } + } + } + + return result; + + function transform(x) { + return a * x * x + b * x + c; + } +}; diff --git a/solutions/0361-bomb-enemy.js b/solutions/0361-bomb-enemy.js new file mode 100644 index 00000000..ffa279e8 --- /dev/null +++ b/solutions/0361-bomb-enemy.js @@ -0,0 +1,46 @@ +/** + * 361. Bomb Enemy + * https://leetcode.com/problems/bomb-enemy/ + * Difficulty: Medium + * + * Given an m x n matrix grid where each cell is either a wall 'W', an enemy 'E' or empty '0', + * return the maximum enemies you can kill using one bomb. You can only place the bomb in an + * empty cell. + * + * The bomb kills all the enemies in the same row and column from the planted point until it + * hits the wall since it is too strong to be destroyed. + */ + +/** + * @param {character[][]} grid + * @return {number} + */ +var maxKilledEnemies = function(grid) { + const rows = grid.length; + const cols = grid[0].length; + const colHits = new Array(cols).fill(0); + let rowHits = 0; + let result = 0; + + for (let i = 0; i < rows; i++) { + for (let j = 0; j < cols; j++) { + if (j === 0 || grid[i][j-1] === 'W') { + rowHits = 0; + for (let k = j; k < cols && grid[i][k] !== 'W'; k++) { + if (grid[i][k] === 'E') rowHits++; + } + } + if (i === 0 || grid[i-1][j] === 'W') { + colHits[j] = 0; + for (let k = i; k < rows && grid[k][j] !== 'W'; k++) { + if (grid[k][j] === 'E') colHits[j]++; + } + } + if (grid[i][j] === '0') { + result = Math.max(result, rowHits + colHits[j]); + } + } + } + + return result; +}; diff --git a/solutions/0362-design-hit-counter.js b/solutions/0362-design-hit-counter.js new file mode 100644 index 00000000..ebe1aeef --- /dev/null +++ b/solutions/0362-design-hit-counter.js @@ -0,0 +1,43 @@ +/** + * 362. Design Hit Counter + * https://leetcode.com/problems/design-hit-counter/ + * Difficulty: Medium + * + * Design a hit counter which counts the number of hits received in the past 5 minutes + * (i.e., the past 300 seconds). + * + * Your system should accept a timestamp parameter (in seconds granularity), and you may + * assume that calls are being made to the system in chronological order (i.e., timestamp + * is monotonically increasing). Several hits may arrive roughly at the same time. + * + * Implement the HitCounter class: + * - HitCounter() Initializes the object of the hit counter system. + * - void hit(int timestamp) Records a hit that happened at timestamp (in seconds). Several + * hits may happen at the same timestamp. + * - int getHits(int timestamp) Returns the number of hits in the past 5 minutes from timestamp + * (i.e., the past 300 seconds). + */ + +var HitCounter = function() { + this.hits = []; +}; + +/** + * @param {number} timestamp + * @return {void} + */ +HitCounter.prototype.hit = function(timestamp) { + this.hits.push(timestamp); +}; + +/** + * @param {number} timestamp + * @return {number} + */ +HitCounter.prototype.getHits = function(timestamp) { + const threshold = timestamp - 300; + while (this.hits.length && this.hits[0] <= threshold) { + this.hits.shift(); + } + return this.hits.length; +}; diff --git a/solutions/0364-nested-list-weight-sum-ii.js b/solutions/0364-nested-list-weight-sum-ii.js new file mode 100644 index 00000000..dea3ecd0 --- /dev/null +++ b/solutions/0364-nested-list-weight-sum-ii.js @@ -0,0 +1,47 @@ +/** + * 364. Nested List Weight Sum II + * https://leetcode.com/problems/nested-list-weight-sum-ii/ + * Difficulty: Medium + * + * You are given a nested list of integers nestedList. Each element is either an integer or + * a list whose elements may also be integers or other lists. + * + * The depth of an integer is the number of lists that it is inside of. For example, the + * nested list [1,[2,2],[[3],2],1] has each integer's value set to its depth. Let maxDepth + * be the maximum depth of any integer. + * + * The weight of an integer is maxDepth - (the depth of the integer) + 1. + * + * Return the sum of each integer in nestedList multiplied by its weight. + */ + +/** + * @param {NestedInteger[]} nestedList + * @return {number} + */ +var depthSumInverse = function(nestedList) { + const maxDepth = findMaxDepth(nestedList, 1); + return calculateSum(nestedList, 1, maxDepth); + + function findMaxDepth(list, depth) { + let maxDepth = depth; + for (const element of list) { + if (!element.isInteger()) { + maxDepth = Math.max(maxDepth, findMaxDepth(element.getList(), depth + 1)); + } + } + return maxDepth; + } + + function calculateSum(list, depth, maxDepth) { + let total = 0; + for (const element of list) { + if (element.isInteger()) { + total += element.getInteger() * (maxDepth - depth + 1); + } else { + total += calculateSum(element.getList(), depth + 1, maxDepth); + } + } + return total; + } +}; diff --git a/solutions/0366-find-leaves-of-binary-tree.js b/solutions/0366-find-leaves-of-binary-tree.js new file mode 100644 index 00000000..45159fed --- /dev/null +++ b/solutions/0366-find-leaves-of-binary-tree.js @@ -0,0 +1,43 @@ +/** + * 366. Find Leaves of Binary Tree + * https://leetcode.com/problems/find-leaves-of-binary-tree/ + * Difficulty: Medium + * + * Given the root of a binary tree, collect a tree's nodes as if you were doing this: + * - Collect all the leaf nodes. + * - Remove all the leaf nodes. + * - Repeat until the tree is empty. + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {TreeNode} root + * @return {number[][]} + */ +var findLeaves = function(root) { + const levels = []; + getHeight(root); + return levels; + + function getHeight(node) { + if (!node) return -1; + + const leftHeight = getHeight(node.left); + const rightHeight = getHeight(node.right); + const height = Math.max(leftHeight, rightHeight) + 1; + + if (levels.length <= height) { + levels.push([]); + } + levels[height].push(node.val); + + return height; + } +}; diff --git a/solutions/0369-plus-one-linked-list.js b/solutions/0369-plus-one-linked-list.js new file mode 100644 index 00000000..0dbb048d --- /dev/null +++ b/solutions/0369-plus-one-linked-list.js @@ -0,0 +1,40 @@ +/** + * 369. Plus One Linked List + * https://leetcode.com/problems/plus-one-linked-list/ + * Difficulty: Medium + * + * Given a non-negative integer represented as a linked list of digits, plus one to the integer. + * + * The digits are stored such that the most significant digit is at the head of the list. + */ + +/** + * Definition for singly-linked list. + * function ListNode(val, next) { + * this.val = (val===undefined ? 0 : val) + * this.next = (next===undefined ? null : next) + * } + */ +/** + * @param {ListNode} head + * @return {ListNode} + */ +var plusOne = function(head) { + const list = new ListNode(0, head); + let notNine = list; + + while (head) { + if (head.val !== 9) notNine = head; + head = head.next; + } + + notNine.val++; + notNine = notNine.next; + + while (notNine) { + notNine.val = 0; + notNine = notNine.next; + } + + return list.val === 0 ? list.next : list; +}; diff --git a/solutions/0370-range-addition.js b/solutions/0370-range-addition.js new file mode 100644 index 00000000..b10a3991 --- /dev/null +++ b/solutions/0370-range-addition.js @@ -0,0 +1,34 @@ +/** + * 370. Range Addition + * https://leetcode.com/problems/range-addition/ + * Difficulty: Medium + * + * You are given an integer length and an array updates where + * updates[i] = [startIdxi, endIdxi, inci]. + * + * You have an array arr of length length with all zeros, and you have some operation + * to apply on arr. In the ith operation, you should increment all the elements + * arr[startIdxi], arr[startIdxi + 1], ..., arr[endIdxi] by inci. + * + * Return arr after applying all the updates. + */ + +/** + * @param {number} length + * @param {number[][]} updates + * @return {number[]} + */ +var getModifiedArray = function(length, updates) { + const result = new Array(length).fill(0); + + for (const [start, end, inc] of updates) { + result[start] += inc; + if (end + 1 < length) result[end + 1] -= inc; + } + + for (let i = 1; i < length; i++) { + result[i] += result[i - 1]; + } + + return result; +}; diff --git a/solutions/0379-design-phone-directory.js b/solutions/0379-design-phone-directory.js new file mode 100644 index 00000000..4973efa9 --- /dev/null +++ b/solutions/0379-design-phone-directory.js @@ -0,0 +1,64 @@ +/** + * 379. Design Phone Directory + * https://leetcode.com/problems/design-phone-directory/ + * Difficulty: Medium + * + * Design a phone directory that initially has maxNumbers empty slots that can store numbers. + * The directory should store numbers, check if a certain slot is empty or not, and empty a + * given slot. + * + * Implement the PhoneDirectory class: + * - PhoneDirectory(int maxNumbers) Initializes the phone directory with the number of + * available slots maxNumbers. + * - int get() Provides a number that is not assigned to anyone. Returns -1 if no number + * is available. + * - bool check(int number) Returns true if the slot number is available and false otherwise. + * - void release(int number) Recycles or releases the slot number. + */ + +/** + * @param {number} maxNumbers + */ +var PhoneDirectory = function(maxNumbers) { + this.available = new Set(); + this.released = []; + this.max = maxNumbers; + for (let i = 0; i < maxNumbers; i++) { + this.available.add(i); + } +}; + +/** + * @return {number} + */ +PhoneDirectory.prototype.get = function() { + if (this.available.size === 0 && this.released.length === 0) return -1; + let number; + if (this.released.length > 0) { + number = this.released.pop(); + } else { + number = this.available.values().next().value; + this.available.delete(number); + } + return number; +}; + +/** + * @param {number} number + * @return {boolean} + */ +PhoneDirectory.prototype.check = function(number) { + return number >= 0 && number < this.max + && (this.available.has(number) || this.released.includes(number)); +}; + +/** + * @param {number} number + * @return {void} + */ +PhoneDirectory.prototype.release = function(number) { + if (number >= 0 && number < this.max + && !this.available.has(number) && !this.released.includes(number)) { + this.released.push(number); + } +}; diff --git a/solutions/0408-valid-word-abbreviation.js b/solutions/0408-valid-word-abbreviation.js new file mode 100644 index 00000000..9dde3f72 --- /dev/null +++ b/solutions/0408-valid-word-abbreviation.js @@ -0,0 +1,55 @@ +/** + * 408. Valid Word Abbreviation + * https://leetcode.com/problems/valid-word-abbreviation/ + * Difficulty: Easy + * + * A string can be abbreviated by replacing any number of non-adjacent, non-empty substrings + * with their lengths. The lengths should not have leading zeros. + * + * For example, a string such as "substitution" could be abbreviated as (but not limited to): + * - "s10n" ("s ubstitutio n") + * - "sub4u4" ("sub stit u tion") + * - "12" ("substitution") + * - "su3i1u2on" ("su bst i t u ti on") + * - "substitution" (no substrings replaced) + * + * The following are not valid abbreviations: + * - "s55n" ("s ubsti tutio n", the replaced substrings are adjacent) + * - "s010n" (has leading zeros) + * - "s0ubstitution" (replaces an empty substring) + * + * Given a string word and an abbreviation abbr, return whether the string matches the given + * abbreviation. + * + * A substring is a contiguous non-empty sequence of characters within a string. + */ + +/** + * @param {string} word + * @param {string} abbr + * @return {boolean} + */ +var validWordAbbreviation = function(word, abbr) { + let wordIndex = 0; + let abbrIndex = 0; + + while (wordIndex < word.length && abbrIndex < abbr.length) { + if (word[wordIndex] === abbr[abbrIndex]) { + wordIndex++; + abbrIndex++; + continue; + } + + if (abbr[abbrIndex] < '0' || abbr[abbrIndex] > '9') return false; + if (abbr[abbrIndex] === '0') return false; + + let num = 0; + while (abbrIndex < abbr.length && /[0-9]/.test(abbr[abbrIndex])) { + num = num * 10 + Number(abbr[abbrIndex]); + abbrIndex++; + } + wordIndex += num; + } + + return wordIndex === word.length && abbrIndex === abbr.length; +}; diff --git a/solutions/0411-minimum-unique-word-abbreviation.js b/solutions/0411-minimum-unique-word-abbreviation.js new file mode 100644 index 00000000..f595afd4 --- /dev/null +++ b/solutions/0411-minimum-unique-word-abbreviation.js @@ -0,0 +1,97 @@ +/** + * 411. Minimum Unique Word Abbreviation + * https://leetcode.com/problems/minimum-unique-word-abbreviation/ + * Difficulty: Hard + * + * A string can be abbreviated by replacing any number of non-adjacent substrings with their + * lengths. For example, a string such as "substitution" could be abbreviated as (but not + * limited to): + * - "s10n" ("s ubstitutio n") + * - "sub4u4" ("sub stit u tion") + * - "12" ("substitution") + * - "su3i1u2on" ("su bst i t u ti on") + * - "substitution" (no substrings replaced) + * + * Note that "s55n" ("s ubsti tutio n") is not a valid abbreviation of "substitution" because + * the replaced substrings are adjacent. + * + * The length of an abbreviation is the number of letters that were not replaced plus the + * number of substrings that were replaced. For example, the abbreviation "s10n" has a length + * of 3 (2 letters + 1 substring) and "su3i1u2on" has a length of 9 (6 letters + 3 substrings). + * + * Given a target string target and an array of strings dictionary, return an abbreviation + * of target with the shortest possible length such that it is not an abbreviation of any + * string in dictionary. If there are multiple shortest abbreviations, return any of them. + */ + +/** + * @param {string} target + * @param {string[]} dictionary + * @return {string} + */ +var minAbbreviation = function(target, dictionary) { + let minLength = target.length; + let result = target; + const validDict = dictionary.filter(word => word.length === target.length); + + for (let mask = 0; mask < (1 << target.length); mask++) { + const abbr = getAbbr(target, mask); + if (abbr.length <= minLength) { + let isValid = true; + for (const word of validDict) { + if (conflicts(abbr, word)) { + isValid = false; + break; + } + } + if (isValid) { + if (abbr.length < minLength) { + minLength = abbr.length; + result = abbr; + } else if (abbr.length === minLength && abbr < result) { + result = abbr; + } + } + } + } + + return result; + + function getAbbr(str, mask) { + let abbr = ''; + let count = 0; + for (let i = 0; i < str.length; i++) { + if (mask & (1 << i)) { + if (count) { + abbr += count; + count = 0; + } + abbr += str[i]; + } else { + count++; + } + } + if (count) abbr += count; + return abbr; + } + + function conflicts(abbr, word) { + let i = 0; + let j = 0; + while (i < abbr.length && j < word.length) { + if (i < abbr.length && j < word.length && abbr[i] === word[j]) { + i++; + j++; + } else if (i < abbr.length && /\d/.test(abbr[i])) { + let num = 0; + while (i < abbr.length && /\d/.test(abbr[i])) { + num = num * 10 + Number(abbr[i++]); + } + j += num; + } else { + return false; + } + } + return i === abbr.length && j === word.length; + } +}; diff --git a/solutions/1737-change-minimum-characters-to-satisfy-one-of-three-conditions.js b/solutions/1737-change-minimum-characters-to-satisfy-one-of-three-conditions.js new file mode 100644 index 00000000..3a084982 --- /dev/null +++ b/solutions/1737-change-minimum-characters-to-satisfy-one-of-three-conditions.js @@ -0,0 +1,59 @@ +/** + * 1737. Change Minimum Characters to Satisfy One of Three Conditions + * https://leetcode.com/problems/change-minimum-characters-to-satisfy-one-of-three-conditions/ + * Difficulty: Medium + * + * You are given two strings a and b that consist of lowercase letters. In one operation, you can + * change any character in a or b to any lowercase letter. + * + * Your goal is to satisfy one of the following three conditions: + * - Every letter in a is strictly less than every letter in b in the alphabet. + * - Every letter in b is strictly less than every letter in a in the alphabet. + * - Both a and b consist of only one distinct letter. + * + * Return the minimum number of operations needed to achieve your goal. + */ + +/** + * @param {string} a + * @param {string} b + * @return {number} + */ +var minCharacters = function(a, b) { + const aFreq = getFrequency(a); + const bFreq = getFrequency(b); + + const condition1 = operationsForCondition1(aFreq, bFreq); + const condition2 = operationsForCondition1(bFreq, aFreq); + const condition3 = operationsForCondition3(aFreq, bFreq); + + return Math.min(condition1, condition2, condition3); + + function getFrequency(str) { + const freq = Array(26).fill(0); + for (const char of str) { + freq[char.charCodeAt(0) - 97]++; + } + return freq; + } + + function operationsForCondition1(aFreq, bFreq) { + let minOps = Infinity; + for (let i = 0; i < 25; i++) { + let ops = 0; + for (let j = 0; j <= i; j++) ops += aFreq[j]; + for (let j = i + 1; j < 26; j++) ops += bFreq[j]; + minOps = Math.min(minOps, ops); + } + return minOps; + } + + function operationsForCondition3(aFreq, bFreq) { + let minOps = Infinity; + for (let i = 0; i < 26; i++) { + const ops = a.length + b.length - aFreq[i] - bFreq[i]; + minOps = Math.min(minOps, ops); + } + return minOps; + } +}; diff --git a/solutions/1738-find-kth-largest-xor-coordinate-value.js b/solutions/1738-find-kth-largest-xor-coordinate-value.js new file mode 100644 index 00000000..383d4166 --- /dev/null +++ b/solutions/1738-find-kth-largest-xor-coordinate-value.js @@ -0,0 +1,37 @@ +/** + * 1738. Find Kth Largest XOR Coordinate Value + * https://leetcode.com/problems/find-kth-largest-xor-coordinate-value/ + * Difficulty: Medium + * + * You are given a 2D matrix of size m x n, consisting of non-negative integers. You are also + * given an integer k. + * + * The value of coordinate (a, b) of the matrix is the XOR of all matrix[i][j] where + * 0 <= i <= a < m and 0 <= j <= b < n (0-indexed). + * + * Find the kth largest value (1-indexed) of all the coordinates of matrix. + */ + +/** + * @param {number[][]} matrix + * @param {number} k + * @return {number} + */ +var kthLargestValue = function(matrix, k) { + const rows = matrix.length; + const cols = matrix[0].length; + const xorValues = new Array(rows * cols); + const prefixXor = Array.from({ length: rows + 1 }, () => Array(cols + 1).fill(0)); + + let index = 0; + for (let i = 1; i <= rows; i++) { + for (let j = 1; j <= cols; j++) { + prefixXor[i][j] = prefixXor[i-1][j] ^ prefixXor[i][j-1] + ^ prefixXor[i-1][j-1] ^ matrix[i-1][j-1]; + xorValues[index++] = prefixXor[i][j]; + } + } + + xorValues.sort((a, b) => b - a); + return xorValues[k-1]; +}; diff --git a/solutions/1739-building-boxes.js b/solutions/1739-building-boxes.js new file mode 100644 index 00000000..0a80282a --- /dev/null +++ b/solutions/1739-building-boxes.js @@ -0,0 +1,38 @@ +/** + * 1739. Building Boxes + * https://leetcode.com/problems/building-boxes/ + * Difficulty: Hard + * + * You have a cubic storeroom where the width, length, and height of the room are all equal to n + * units. You are asked to place n boxes in this room where each box is a cube of unit side + * length. There are however some rules to placing the boxes: + * - You can place the boxes anywhere on the floor. + * - If box x is placed on top of the box y, then each side of the four vertical sides of the box + * y must either be adjacent to another box or to a wall. + * + * Given an integer n, return the minimum possible number of boxes touching the floor. + */ + +/** + * @param {number} n + * @return {number} + */ +var minimumBoxes = function(n) { + if (n < 4) return n; + + let baseSize = 0; + let totalBoxes = 0; + const triangular = k => k * (k + 1) / 2; + + while (totalBoxes + triangular(baseSize + 1) <= n) { + baseSize++; + totalBoxes += triangular(baseSize); + } + + const remaining = n - totalBoxes; + let extraFloor = 0; + + while (triangular(extraFloor) < remaining) extraFloor++; + + return triangular(baseSize) + extraFloor; +}; diff --git a/solutions/1742-maximum-number-of-balls-in-a-box.js b/solutions/1742-maximum-number-of-balls-in-a-box.js new file mode 100644 index 00000000..e16d7ae5 --- /dev/null +++ b/solutions/1742-maximum-number-of-balls-in-a-box.js @@ -0,0 +1,44 @@ +/** + * 1742. Maximum Number of Balls in a Box + * https://leetcode.com/problems/maximum-number-of-balls-in-a-box/ + * Difficulty: Easy + * + * You are working in a ball factory where you have n balls numbered from lowLimit up to + * highLimit inclusive (i.e., n == highLimit - lowLimit + 1), and an infinite number of + * boxes numbered from 1 to infinity. + * + * Your job at this factory is to put each ball in the box with a number equal to the sum + * of digits of the ball's number. For example, the ball number 321 will be put in the + * box number 3 + 2 + 1 = 6 and the ball number 10 will be put in the box number 1 + 0 = 1. + * + * Given two integers lowLimit and highLimit, return the number of balls in the box with + * the most balls. + */ + +/** + * @param {number} lowLimit + * @param {number} highLimit + * @return {number} + */ +var countBalls = function(lowLimit, highLimit) { + const boxCounts = new Map(); + let result = 0; + + for (let ball = lowLimit; ball <= highLimit; ball++) { + const box = sumDigits(ball); + const count = (boxCounts.get(box) || 0) + 1; + boxCounts.set(box, count); + result = Math.max(result, count); + } + + return result; + + function sumDigits(num) { + let sum = 0; + while (num > 0) { + sum += num % 10; + num = Math.floor(num / 10); + } + return sum; + } +}; diff --git a/solutions/1743-restore-the-array-from-adjacent-pairs.js b/solutions/1743-restore-the-array-from-adjacent-pairs.js new file mode 100644 index 00000000..f7cdbb9f --- /dev/null +++ b/solutions/1743-restore-the-array-from-adjacent-pairs.js @@ -0,0 +1,51 @@ +/** + * 1743. Restore the Array From Adjacent Pairs + * https://leetcode.com/problems/restore-the-array-from-adjacent-pairs/ + * Difficulty: Medium + * + * There is an integer array nums that consists of n unique elements, but you have + * forgotten it. However, you do remember every pair of adjacent elements in nums. + * + * You are given a 2D integer array adjacentPairs of size n - 1 where each + * adjacentPairs[i] = [ui, vi] indicates that the elements ui and vi are adjacent in nums. + * + * It is guaranteed that every adjacent pair of elements nums[i] and nums[i+1] will exist in + * adjacentPairs, either as [nums[i], nums[i+1]] or [nums[i+1], nums[i]]. The pairs can appear + * in any order. + * + * Return the original array nums. If there are multiple solutions, return any of them. + */ + +/** + * @param {number[][]} adjacentPairs + * @return {number[]} + */ +var restoreArray = function(adjacentPairs) { + const graph = new Map(); + for (const [u, v] of adjacentPairs) { + graph.set(u, (graph.get(u) || []).concat(v)); + graph.set(v, (graph.get(v) || []).concat(u)); + } + + let start; + for (const [node, neighbors] of graph) { + if (neighbors.length === 1) { + start = node; + break; + } + } + + const result = [start]; + let prev = start; + let curr = graph.get(start)[0]; + + while (graph.get(curr).length > 1) { + result.push(curr); + const next = graph.get(curr).find(n => n !== prev); + prev = curr; + curr = next; + } + result.push(curr); + + return result; +}; diff --git a/solutions/1744-can-you-eat-your-favorite-candy-on-your-favorite-day.js b/solutions/1744-can-you-eat-your-favorite-candy-on-your-favorite-day.js new file mode 100644 index 00000000..ac72e529 --- /dev/null +++ b/solutions/1744-can-you-eat-your-favorite-candy-on-your-favorite-day.js @@ -0,0 +1,45 @@ +/** + * 1744. Can You Eat Your Favorite Candy on Your Favorite Day? + * https://leetcode.com/problems/can-you-eat-your-favorite-candy-on-your-favorite-day/ + * Difficulty: Medium + * + * You are given a (0-indexed) array of positive integers candiesCount where candiesCount[i] + * represents the number of candies of the ith type you have. You are also given a 2D array + * queries where queries[i] = [favoriteTypei, favoriteDayi, dailyCapi]. + * + * You play a game with the following rules: + * - You start eating candies on day 0. + * - You cannot eat any candy of type i unless you have eaten all candies of type i - 1. + * - You must eat at least one candy per day until you have eaten all the candies. + * + * Construct a boolean array answer such that answer.length == queries.length and answer[i] is + * true if you can eat a candy of type favoriteTypei on day favoriteDayi without eating more + * than dailyCapi candies on any day, and false otherwise. Note that you can eat different + * types of candy on the same day, provided that you follow rule 2. + * + * Return the constructed array answer. + */ + +/** + * @param {number[]} candiesCount + * @param {number[][]} queries + * @return {boolean[]} + */ +var canEat = function(candiesCount, queries) { + const prefixSums = [0]; + for (const count of candiesCount) { + prefixSums.push(prefixSums.at(-1) + count); + } + + const result = new Array(queries.length); + for (let i = 0; i < queries.length; i++) { + const [type, day, cap] = queries[i]; + const minCandies = day; + const maxCandies = (day + 1) * cap; + const typeStart = prefixSums[type]; + const typeEnd = prefixSums[type + 1] - 1; + result[i] = maxCandies > typeStart && minCandies <= typeEnd; + } + + return result; +}; diff --git a/solutions/1745-palindrome-partitioning-iv.js b/solutions/1745-palindrome-partitioning-iv.js new file mode 100644 index 00000000..7fefea0f --- /dev/null +++ b/solutions/1745-palindrome-partitioning-iv.js @@ -0,0 +1,37 @@ +/** + * 1745. Palindrome Partitioning IV + * https://leetcode.com/problems/palindrome-partitioning-iv/ + * Difficulty: Hard + * + * Given a string s, return true if it is possible to split the string s into three non-empty + * palindromic substrings. Otherwise, return false. + * + * A string is said to be palindrome if it the same string when reversed. + */ + +/** + * @param {string} s + * @return {boolean} + */ +var checkPartitioning = function(s) { + const n = s.length; + const isPalindrome = Array.from({ length: n }, () => Array(n).fill(false)); + + for (let i = n - 1; i >= 0; i--) { + for (let j = i; j < n; j++) { + if (s[i] === s[j] && (j - i <= 2 || isPalindrome[i + 1][j - 1])) { + isPalindrome[i][j] = true; + } + } + } + + for (let i = 1; i < n - 1; i++) { + for (let j = i; j < n - 1; j++) { + if (isPalindrome[0][i - 1] && isPalindrome[i][j] && isPalindrome[j + 1][n - 1]) { + return true; + } + } + } + + return false; +}; diff --git a/solutions/1750-minimum-length-of-string-after-deleting-similar-ends.js b/solutions/1750-minimum-length-of-string-after-deleting-similar-ends.js new file mode 100644 index 00000000..c8cdb813 --- /dev/null +++ b/solutions/1750-minimum-length-of-string-after-deleting-similar-ends.js @@ -0,0 +1,33 @@ +/** + * 1750. Minimum Length of String After Deleting Similar Ends + * https://leetcode.com/problems/minimum-length-of-string-after-deleting-similar-ends/ + * Difficulty: Medium + * + * Given a string s consisting only of characters 'a', 'b', and 'c'. You are asked to apply the + * following algorithm on the string any number of times: + * 1. Pick a non-empty prefix from the string s where all the characters in the prefix are equal. + * 2. Pick a non-empty suffix from the string s where all the characters in this suffix are equal. + * 3. The prefix and the suffix should not intersect at any index. + * 4. The characters from the prefix and suffix must be the same. + * 5. Delete both the prefix and the suffix. + * + * Return the minimum length of s after performing the above operation any number of times + * (possibly zero times). + */ + +/** + * @param {string} s + * @return {number} + */ +var minimumLength = function(s) { + let left = 0; + let right = s.length - 1; + + while (left < right && s[left] === s[right]) { + const char = s[left]; + while (left <= right && s[left] === char) left++; + while (left <= right && s[right] === char) right--; + } + + return Math.max(0, right - left + 1); +}; diff --git a/solutions/1751-maximum-number-of-events-that-can-be-attended-ii.js b/solutions/1751-maximum-number-of-events-that-can-be-attended-ii.js new file mode 100644 index 00000000..74cd6ee3 --- /dev/null +++ b/solutions/1751-maximum-number-of-events-that-can-be-attended-ii.js @@ -0,0 +1,54 @@ +/** + * 1751. Maximum Number of Events That Can Be Attended II + * https://leetcode.com/problems/maximum-number-of-events-that-can-be-attended-ii/ + * Difficulty: Hard + * + * You are given an array of events where events[i] = [startDayi, endDayi, valuei]. The ith event + * starts at startDayi and ends at endDayi, and if you attend this event, you will receive a value + * of valuei. You are also given an integer k which represents the maximum number of events you can + * attend. + * + * You can only attend one event at a time. If you choose to attend an event, you must attend the + * entire event. Note that the end day is inclusive: that is, you cannot attend two events where + * one of them starts and the other ends on the same day. + * + * Return the maximum sum of values that you can receive by attending events. + */ + +/** + * @param {number[][]} events + * @param {number} k + * @return {number} + */ +var maxValue = function(events, k) { + events.sort((a, b) => a[0] - b[0]); + const n = events.length; + const dp = Array.from({ length: k + 1 }, () => new Array(n + 1).fill(-1)); + + return maximize(0, k); + + function findNext(index, end) { + let left = index; + let right = n; + while (left < right) { + const mid = Math.floor((left + right) / 2); + if (events[mid][0] > end) { + right = mid; + } else { + left = mid + 1; + } + } + return left; + } + + function maximize(index, remaining) { + if (index >= n || remaining === 0) return 0; + if (dp[remaining][index] !== -1) return dp[remaining][index]; + + const nextIndex = findNext(index + 1, events[index][1]); + const take = events[index][2] + maximize(nextIndex, remaining - 1); + const skip = maximize(index + 1, remaining); + + return dp[remaining][index] = Math.max(take, skip); + } +}; diff --git a/solutions/1753-maximum-score-from-removing-stones.js b/solutions/1753-maximum-score-from-removing-stones.js new file mode 100644 index 00000000..24dfa2f0 --- /dev/null +++ b/solutions/1753-maximum-score-from-removing-stones.js @@ -0,0 +1,32 @@ +/** + * 1753. Maximum Score From Removing Stones + * https://leetcode.com/problems/maximum-score-from-removing-stones/ + * Difficulty: Medium + * + * You are playing a solitaire game with three piles of stones of sizes a, b, and c respectively. + * Each turn you choose two different non-empty piles, take one stone from each, and add 1 point + * to your score. The game stops when there are fewer than two non-empty piles (meaning there are + * no more available moves). + * + * Given three integers a, b, and c return the maximum score you can get. + */ + +/** + * @param {number} a + * @param {number} b + * @param {number} c + * @return {number} + */ +var maximumScore = function(a, b, c) { + const piles = [a, b, c].sort((x, y) => y - x); + let score = 0; + + while (piles[0] > 0 && piles[1] > 0) { + piles[0]--; + piles[1]--; + score++; + piles.sort((x, y) => y - x); + } + + return score; +}; diff --git a/solutions/1754-largest-merge-of-two-strings.js b/solutions/1754-largest-merge-of-two-strings.js new file mode 100644 index 00000000..0ba08bd4 --- /dev/null +++ b/solutions/1754-largest-merge-of-two-strings.js @@ -0,0 +1,44 @@ +/** + * 1754. Largest Merge Of Two Strings + * https://leetcode.com/problems/largest-merge-of-two-strings/ + * Difficulty: Medium + * + * You are given two strings word1 and word2. You want to construct a string merge in the + * following way: while either word1 or word2 are non-empty, choose one of the following + * options: + * - If word1 is non-empty, append the first character in word1 to merge and delete it from word1. + * - For example, if word1 = "abc" and merge = "dv", then after choosing this operation, + * word1 = "bc" and merge = "dva". + * - If word2 is non-empty, append the first character in word2 to merge and delete it from word2. + * - For example, if word2 = "abc" and merge = "", then after choosing this operation, + * word2 = "bc" and merge = "a". + * + * Return the lexicographically largest merge you can construct. + * + * A string a is lexicographically larger than a string b (of the same length) if in the first + * position where a and b differ, a has a character strictly larger than the corresponding + * character in b. For example, "abcd" is lexicographically larger than "abcc" because the + * first position they differ is at the fourth character, and d is greater than c. + */ + +/** + * @param {string} word1 + * @param {string} word2 + * @return {string} + */ +var largestMerge = function(word1, word2) { + let merge = ''; + let i = 0; + let j = 0; + + while (i < word1.length && j < word2.length) { + if (word1.slice(i) >= word2.slice(j)) { + merge += word1[i++]; + } else { + merge += word2[j++]; + } + } + + merge += word1.slice(i) + word2.slice(j); + return merge; +}; diff --git a/solutions/1755-closest-subsequence-sum.js b/solutions/1755-closest-subsequence-sum.js new file mode 100644 index 00000000..bad15f92 --- /dev/null +++ b/solutions/1755-closest-subsequence-sum.js @@ -0,0 +1,63 @@ +/** + * 1755. Closest Subsequence Sum + * https://leetcode.com/problems/closest-subsequence-sum/ + * Difficulty: Hard + * + * You are given an integer array nums and an integer goal. + * + * You want to choose a subsequence of nums such that the sum of its elements is the closest + * possible to goal. That is, if the sum of the subsequence's elements is sum, then you want + * to minimize the absolute difference abs(sum - goal). + * + * Return the minimum possible value of abs(sum - goal). + * + * Note that a subsequence of an array is an array formed by removing some elements (possibly + * all or none) of the original array. + */ + +/** + * @param {number[]} nums + * @param {number} goal + * @return {number} + */ +var minAbsDifference = function(nums, goal) { + const n = nums.length; + const half = Math.floor(n / 2); + const leftSums = new Set(); + const rightSums = new Set(); + + generateSums(0, half, leftSums); + generateSums(half, n, rightSums); + + const rightArray = [...rightSums].sort((a, b) => a - b); + let minDiff = Infinity; + + for (const leftSum of leftSums) { + const target = goal - leftSum; + let left = 0; + let right = rightArray.length - 1; + + while (left <= right) { + const mid = Math.floor((left + right) / 2); + const sum = leftSum + rightArray[mid]; + minDiff = Math.min(minDiff, Math.abs(sum - goal)); + + if (sum < goal) { + left = mid + 1; + } else { + right = mid - 1; + } + } + } + + return minDiff; + + function generateSums(start, end, sums, current = 0) { + if (start === end) { + sums.add(current); + return; + } + generateSums(start + 1, end, sums, current); + generateSums(start + 1, end, sums, current + nums[start]); + } +}; diff --git a/solutions/1758-minimum-changes-to-make-alternating-binary-string.js b/solutions/1758-minimum-changes-to-make-alternating-binary-string.js new file mode 100644 index 00000000..dad5e376 --- /dev/null +++ b/solutions/1758-minimum-changes-to-make-alternating-binary-string.js @@ -0,0 +1,31 @@ +/** + * 1758. Minimum Changes To Make Alternating Binary String + * https://leetcode.com/problems/minimum-changes-to-make-alternating-binary-string/ + * Difficulty: Easy + * + * You are given a string s consisting only of the characters '0' and '1'. In one operation, you can + * change any '0' to '1' or vice versa. + * + * The string is called alternating if no two adjacent characters are equal. For example, the string + * "010" is alternating, while the string "0100" is not. + * + * Return the minimum number of operations needed to make s alternating. + */ + +/** + * @param {string} s + * @return {number} + */ +var minOperations = function(s) { + let changesToZeroStart = 0; + let changesToOneStart = 0; + + for (let i = 0; i < s.length; i++) { + const expectedZeroStart = i % 2 === 0 ? '0' : '1'; + const expectedOneStart = i % 2 === 0 ? '1' : '0'; + if (s[i] !== expectedZeroStart) changesToZeroStart++; + if (s[i] !== expectedOneStart) changesToOneStart++; + } + + return Math.min(changesToZeroStart, changesToOneStart); +}; diff --git a/solutions/1759-count-number-of-homogenous-substrings.js b/solutions/1759-count-number-of-homogenous-substrings.js new file mode 100644 index 00000000..b6fb8fbc --- /dev/null +++ b/solutions/1759-count-number-of-homogenous-substrings.js @@ -0,0 +1,35 @@ +/** + * 1759. Count Number of Homogenous Substrings + * https://leetcode.com/problems/count-number-of-homogenous-substrings/ + * Difficulty: Medium + * + * Given a string s, return the number of homogenous substrings of s. Since the answer may be + * too large, return it modulo 109 + 7. + * + * A string is homogenous if all the characters of the string are the same. + * + * A substring is a contiguous sequence of characters within a string. + */ + +/** + * @param {string} s + * @return {number} + */ +var countHomogenous = function(s) { + const mod = 1e9 + 7; + let result = 0; + let streak = 1; + + for (let i = 1; i < s.length; i++) { + if (s[i] === s[i - 1]) { + streak++; + } else { + result = (result + (streak * (streak + 1) / 2)) % mod; + streak = 1; + } + } + + result = (result + (streak * (streak + 1) / 2)) % mod; + + return result; +}; diff --git a/solutions/1760-minimum-limit-of-balls-in-a-bag.js b/solutions/1760-minimum-limit-of-balls-in-a-bag.js new file mode 100644 index 00000000..f8ff3efa --- /dev/null +++ b/solutions/1760-minimum-limit-of-balls-in-a-bag.js @@ -0,0 +1,45 @@ +/** + * 1760. Minimum Limit of Balls in a Bag + * https://leetcode.com/problems/minimum-limit-of-balls-in-a-bag/ + * Difficulty: Medium + * + * You are given an integer array nums where the ith bag contains nums[i] balls. You are also + * given an integer maxOperations. + * + * You can perform the following operation at most maxOperations times: + * - Take any bag of balls and divide it into two new bags with a positive number of balls. + * - For example, a bag of 5 balls can become two new bags of 1 and 4 balls, or two new bags + * of 2 and 3 balls. + * + * Your penalty is the maximum number of balls in a bag. You want to minimize your penalty after + * the operations. + * + * Return the minimum possible penalty after performing the operations. + */ + +/** + * @param {number[]} nums + * @param {number} maxOperations + * @return {number} + */ +var minimumSize = function(nums, maxOperations) { + let left = 1; + let right = Math.max(...nums); + + while (left < right) { + const mid = Math.floor((left + right) / 2); + let operations = 0; + + for (const num of nums) { + operations += Math.ceil(num / mid) - 1; + } + + if (operations <= maxOperations) { + right = mid; + } else { + left = mid + 1; + } + } + + return left; +}; diff --git a/solutions/1761-minimum-degree-of-a-connected-trio-in-a-graph.js b/solutions/1761-minimum-degree-of-a-connected-trio-in-a-graph.js new file mode 100644 index 00000000..d913b953 --- /dev/null +++ b/solutions/1761-minimum-degree-of-a-connected-trio-in-a-graph.js @@ -0,0 +1,49 @@ +/** + * 1761. Minimum Degree of a Connected Trio in a Graph + * https://leetcode.com/problems/minimum-degree-of-a-connected-trio-in-a-graph/ + * Difficulty: Hard + * + * You are given an undirected graph. You are given an integer n which is the number of nodes in + * the graph and an array edges, where each edges[i] = [ui, vi] indicates that there is an + * undirected edge between ui and vi. + * + * A connected trio is a set of three nodes where there is an edge between every pair of them. + * + * The degree of a connected trio is the number of edges where one endpoint is in the trio, and + * the other is not. + * + * Return the minimum degree of a connected trio in the graph, or -1 if the graph has no + * connected trios. + */ + +/** + * @param {number} n + * @param {number[][]} edges + * @return {number} + */ +var minTrioDegree = function(n, edges) { + const graph = Array.from({ length: n + 1 }, () => new Set()); + const degrees = Array(n + 1).fill(0); + + for (const [u, v] of edges) { + graph[u].add(v); + graph[v].add(u); + degrees[u]++; + degrees[v]++; + } + + let minDegree = Infinity; + + for (let i = 1; i <= n; i++) { + for (const j of graph[i]) { + for (const k of graph[j]) { + if (graph[k].has(i)) { + const trioDegree = degrees[i] + degrees[j] + degrees[k] - 6; + minDegree = Math.min(minDegree, trioDegree); + } + } + } + } + + return minDegree === Infinity ? -1 : minDegree; +}; diff --git a/solutions/1763-longest-nice-substring.js b/solutions/1763-longest-nice-substring.js new file mode 100644 index 00000000..00495b99 --- /dev/null +++ b/solutions/1763-longest-nice-substring.js @@ -0,0 +1,38 @@ +/** + * 1763. Longest Nice Substring + * https://leetcode.com/problems/longest-nice-substring/ + * Difficulty: Easy + * + * A string s is nice if, for every letter of the alphabet that s contains, it appears both + * in uppercase and lowercase. For example, "abABB" is nice because 'A' and 'a' appear, + * and 'B' and 'b' appear. However, "abA" is not because 'b' appears, but 'B' does not. + * + * Given a string s, return the longest substring of s that is nice. If there are multiple, + * return the substring of the earliest occurrence. If there are none, return an empty string. + */ + +/** + * @param {string} s + * @return {string} + */ +var longestNiceSubstring = function(s) { + let longest = ''; + + for (let i = 0; i < s.length; i++) { + for (let j = i; j < s.length; j++) { + const substr = s.slice(i, j + 1); + if (substr.length <= longest.length) continue; + const chars = new Set(substr.toLowerCase().split('')); + let isNice = true; + for (const char of chars) { + if (!substr.includes(char.toLowerCase()) || !substr.includes(char.toUpperCase())) { + isNice = false; + break; + } + } + if (isNice) longest = substr; + } + } + + return longest; +}; diff --git a/solutions/1766-tree-of-coprimes.js b/solutions/1766-tree-of-coprimes.js new file mode 100644 index 00000000..31ec7f8d --- /dev/null +++ b/solutions/1766-tree-of-coprimes.js @@ -0,0 +1,76 @@ +/** + * 1766. Tree of Coprimes + * https://leetcode.com/problems/tree-of-coprimes/ + * Difficulty: Hard + * + * There is a tree (i.e., a connected, undirected graph that has no cycles) consisting of n nodes + * numbered from 0 to n - 1 and exactly n - 1 edges. Each node has a value associated with it, + * and the root of the tree is node 0. + * + * To represent this tree, you are given an integer array nums and a 2D array edges. Each nums[i] + * represents the ith node's value, and each edges[j] = [uj, vj] represents an edge between nodes + * uj and vj in the tree. + * + * Two values x and y are coprime if gcd(x, y) == 1 where gcd(x, y) is the greatest common divisor + * of x and y. + * + * An ancestor of a node i is any other node on the shortest path from node i to the root. A node + * is not considered an ancestor of itself. + * + * Return an array ans of size n, where ans[i] is the closest ancestor to node i such that + * nums[i] and nums[ans[i]] are coprime, or -1 if there is no such ancestor. + */ + +/** + * @param {number[]} nums + * @param {number[][]} edges + * @return {number[]} + */ +var getCoprimes = function(nums, edges) { + const n = nums.length; + const graph = Array.from({ length: n }, () => []); + for (const [u, v] of edges) { + graph[u].push(v); + graph[v].push(u); + } + + const result = Array(n).fill(-1); + const valueDepth = Array(51).fill().map(() => []); + const visited = new Set(); + + dfs(0, 0, -1); + return result; + + function dfs(node, depth, parent) { + const val = nums[node]; + let maxDepth = -1; + let closestAncestor = -1; + + for (let i = 1; i <= 50; i++) { + if (gcd(val, i) === 1 && valueDepth[i].length) { + const [ancestor, d] = valueDepth[i].at(-1); + if (d > maxDepth) { + maxDepth = d; + closestAncestor = ancestor; + } + } + } + + result[node] = closestAncestor; + valueDepth[val].push([node, depth]); + visited.add(node); + + for (const neighbor of graph[node]) { + if (!visited.has(neighbor)) { + dfs(neighbor, depth + 1, node); + } + } + + valueDepth[val].pop(); + } + + function gcd(a, b) { + while (b) [a, b] = [b, a % b]; + return a; + } +}; diff --git a/solutions/1770-maximum-score-from-performing-multiplication-operations.js b/solutions/1770-maximum-score-from-performing-multiplication-operations.js new file mode 100644 index 00000000..73ec2746 --- /dev/null +++ b/solutions/1770-maximum-score-from-performing-multiplication-operations.js @@ -0,0 +1,39 @@ +/** + * 1770. Maximum Score from Performing Multiplication Operations + * https://leetcode.com/problems/maximum-score-from-performing-multiplication-operations/ + * Difficulty: Hard + * + * You are given two 0-indexed integer arrays nums and multipliers of size n and m respectively, + * where n >= m. + * + * You begin with a score of 0. You want to perform exactly m operations. On the ith operation + * (0-indexed) you will: + * - Choose one integer x from either the start or the end of the array nums. + * - Add multipliers[i] * x to your score. + * - Note that multipliers[0] corresponds to the first operation, multipliers[1] to the second + * operation, and so on. + * - Remove x from nums. + * + * Return the maximum score after performing m operations. + */ + +/** + * @param {number[]} nums + * @param {number[]} multipliers + * @return {number} + */ +var maximumScore = function(nums, multipliers) { + const m = multipliers.length; + const dp = Array.from({ length: m + 1 }, () => Array(m + 1).fill(0)); + + for (let op = m - 1; op >= 0; op--) { + for (let left = op; left >= 0; left--) { + const right = nums.length - 1 - (op - left); + const takeLeft = multipliers[op] * nums[left] + dp[op + 1][left + 1]; + const takeRight = multipliers[op] * nums[right] + dp[op + 1][left]; + dp[op][left] = Math.max(takeLeft, takeRight); + } + } + + return dp[0][0]; +}; diff --git a/solutions/1771-maximize-palindrome-length-from-subsequences.js b/solutions/1771-maximize-palindrome-length-from-subsequences.js new file mode 100644 index 00000000..f24d48c9 --- /dev/null +++ b/solutions/1771-maximize-palindrome-length-from-subsequences.js @@ -0,0 +1,47 @@ +/** + * 1771. Maximize Palindrome Length From Subsequences + * https://leetcode.com/problems/maximize-palindrome-length-from-subsequences/ + * Difficulty: Hard + * + * You are given two strings, word1 and word2. You want to construct a string in the following + * manner: + * - Choose some non-empty subsequence subsequence1 from word1. + * - Choose some non-empty subsequence subsequence2 from word2. + * - Concatenate the subsequences: subsequence1 + subsequence2, to make the string. + * + * Return the length of the longest palindrome that can be constructed in the described manner. + * If no palindromes can be constructed, return 0. + * + * A subsequence of a string s is a string that can be made by deleting some (possibly none) + * characters from s without changing the order of the remaining characters. + * + * A palindrome is a string that reads the same forward as well as backward. + */ + +/** + * @param {string} word1 + * @param {string} word2 + * @return {number} + */ +var longestPalindrome = function(word1, word2) { + const s = word1 + word2; + const n = s.length; + const dp = Array.from({ length: n }, () => Array(n).fill(0)); + let result = 0; + + for (let i = n - 1; i >= 0; i--) { + dp[i][i] = 1; + for (let j = i + 1; j < n; j++) { + if (s[i] === s[j]) { + dp[i][j] = dp[i + 1][j - 1] + 2; + if (i < word1.length && j >= word1.length) { + result = Math.max(result, dp[i][j]); + } + } else { + dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]); + } + } + } + + return result; +}; diff --git a/solutions/1773-count-items-matching-a-rule.js b/solutions/1773-count-items-matching-a-rule.js new file mode 100644 index 00000000..528c7169 --- /dev/null +++ b/solutions/1773-count-items-matching-a-rule.js @@ -0,0 +1,35 @@ +/** + * 1773. Count Items Matching a Rule + * https://leetcode.com/problems/count-items-matching-a-rule/ + * Difficulty: Easy + * + * You are given an array items, where each items[i] = [typei, colori, namei] describes the type, + * color, and name of the ith item. You are also given a rule represented by two strings, + * ruleKey and ruleValue. + * + * The ith item is said to match the rule if one of the following is true: + * - ruleKey == "type" and ruleValue == typei. + * - ruleKey == "color" and ruleValue == colori. + * - ruleKey == "name" and ruleValue == namei. + * + * Return the number of items that match the given rule. + */ + +/** + * @param {string[][]} items + * @param {string} ruleKey + * @param {string} ruleValue + * @return {number} + */ +var countMatches = function(items, ruleKey, ruleValue) { + const keyIndex = { type: 0, color: 1, name: 2 }; + let result = 0; + + for (const item of items) { + if (item[keyIndex[ruleKey]] === ruleValue) { + result++; + } + } + + return result; +}; diff --git a/solutions/1774-closest-dessert-cost.js b/solutions/1774-closest-dessert-cost.js new file mode 100644 index 00000000..707d1812 --- /dev/null +++ b/solutions/1774-closest-dessert-cost.js @@ -0,0 +1,55 @@ +/** + * 1774. Closest Dessert Cost + * https://leetcode.com/problems/closest-dessert-cost/ + * Difficulty: Medium + * + * You would like to make dessert and are preparing to buy the ingredients. You have n ice + * cream base flavors and m types of toppings to choose from. You must follow these rules + * when making your dessert: + * - There must be exactly one ice cream base. + * - You can add one or more types of topping or have no toppings at all. + * - There are at most two of each type of topping. + * + * You are given three inputs: + * - baseCosts, an integer array of length n, where each baseCosts[i] represents the price of + * the ith ice cream base flavor. + * - toppingCosts, an integer array of length m, where each toppingCosts[i] is the price of + * one of the ith topping. + * - target, an integer representing your target price for dessert. + * + * You want to make a dessert with a total cost as close to target as possible. + * + * Return the closest possible cost of the dessert to target. If there are multiple, return + * the lower one. + */ + +/** + * @param {number[]} baseCosts + * @param {number[]} toppingCosts + * @param {number} target + * @return {number} + */ +var closestCost = function(baseCosts, toppingCosts, target) { + let result = Infinity; + + for (const base of baseCosts) { + exploreToppings(0, base); + } + + return result; + + function exploreToppings(index, currentCost) { + const diff = Math.abs(currentCost - target); + const prevDiff = Math.abs(result - target); + + if (diff < prevDiff || (diff === prevDiff && currentCost < result)) { + result = currentCost; + } + + if (index >= toppingCosts.length || currentCost > target) return; + + exploreToppings(index + 1, currentCost); + exploreToppings(index + 1, currentCost + toppingCosts[index]); + exploreToppings(index + 1, currentCost + 2 * toppingCosts[index]); + } +}; diff --git a/solutions/1775-equal-sum-arrays-with-minimum-number-of-operations.js b/solutions/1775-equal-sum-arrays-with-minimum-number-of-operations.js new file mode 100644 index 00000000..8c2f068f --- /dev/null +++ b/solutions/1775-equal-sum-arrays-with-minimum-number-of-operations.js @@ -0,0 +1,65 @@ +/** + * 1775. Equal Sum Arrays With Minimum Number of Operations + * https://leetcode.com/problems/equal-sum-arrays-with-minimum-number-of-operations/ + * Difficulty: Medium + * + * You are given two arrays of integers nums1 and nums2, possibly of different lengths. The values + * in the arrays are between 1 and 6, inclusive. + * + * In one operation, you can change any integer's value in any of the arrays to any value between + * 1 and 6, inclusive. + * + * Return the minimum number of operations required to make the sum of values in nums1 equal to + * the sum of values in nums2. Return -1 if it is not possible to make the sum of the two arrays + * equal. + */ + +/** + * @param {number[]} nums1 + * @param {number[]} nums2 + * @return {number} + */ +var minOperations = function(nums1, nums2) { + let sum1 = nums1.reduce((a, b) => a + b, 0); + let sum2 = nums2.reduce((a, b) => a + b, 0); + + if (sum1 < sum2) { + [nums1, nums2, sum1, sum2] = [nums2, nums1, sum2, sum1]; + } + + const maxSum1 = nums1.length * 6; + const minSum1 = nums1.length; + const maxSum2 = nums2.length * 6; + const minSum2 = nums2.length; + + if (maxSum1 < minSum2 || maxSum2 < minSum1) return -1; + + let result = 0; + const gains = []; + const losses = []; + + for (const num of nums1) { + losses.push(num - 1); + } + for (const num of nums2) { + gains.push(6 - num); + } + + losses.sort((a, b) => b - a); + gains.sort((a, b) => b - a); + + let i = 0; + let j = 0; + let diff = sum1 - sum2; + + while (diff > 0 && (i < losses.length || j < gains.length)) { + const change = i < losses.length && (j >= gains.length || losses[i] >= gains[j]) + ? losses[i++] + : gains[j++]; + const take = Math.min(diff, change); + diff -= take; + result++; + } + + return result; +}; diff --git a/solutions/1776-car-fleet-ii.js b/solutions/1776-car-fleet-ii.js new file mode 100644 index 00000000..176303c5 --- /dev/null +++ b/solutions/1776-car-fleet-ii.js @@ -0,0 +1,56 @@ +/** + * 1776. Car Fleet II + * https://leetcode.com/problems/car-fleet-ii/ + * Difficulty: Hard + * + * There are n cars traveling at different speeds in the same direction along a one-lane road. + * You are given an array cars of length n, where cars[i] = [positioni, speedi] represents: + * - positioni is the distance between the ith car and the beginning of the road in meters. + * It is guaranteed that positioni < positioni+1. + * - speedi is the initial speed of the ith car in meters per second. + * + * For simplicity, cars can be considered as points moving along the number line. Two cars + * collide when they occupy the same position. Once a car collides with another car, they + * unite and form a single car fleet. The cars in the formed fleet will have the same position + * and the same speed, which is the initial speed of the slowest car in the fleet. + * + * Return an array answer, where answer[i] is the time, in seconds, at which the ith car + * collides with the next car, or -1 if the car does not collide with the next car. Answers + * within 10-5 of the actual answers are accepted. + */ + +/** + * @param {number[][]} cars + * @return {number[]} + */ +var getCollisionTimes = function(cars) { + const n = cars.length; + const stack = []; + const collisionTimes = Array(n).fill(-1); + + for (let i = n - 1; i >= 0; i--) { + const [pos, speed] = cars[i]; + + while (stack.length > 0) { + const j = stack[stack.length - 1]; + const [nextPos, nextSpeed] = cars[j]; + + if (speed <= nextSpeed || (collisionTimes[j] > 0 + && (nextPos - pos) / (speed - nextSpeed) >= collisionTimes[j])) { + stack.pop(); + } else { + break; + } + } + + if (stack.length > 0) { + const j = stack[stack.length - 1]; + const [nextPos, nextSpeed] = cars[j]; + collisionTimes[i] = (nextPos - pos) / (speed - nextSpeed); + } + + stack.push(i); + } + + return collisionTimes; +}; diff --git a/solutions/1779-find-nearest-point-that-has-the-same-x-or-y-coordinate.js b/solutions/1779-find-nearest-point-that-has-the-same-x-or-y-coordinate.js new file mode 100644 index 00000000..faf1f1b2 --- /dev/null +++ b/solutions/1779-find-nearest-point-that-has-the-same-x-or-y-coordinate.js @@ -0,0 +1,40 @@ +/** + * 1779. Find Nearest Point That Has the Same X or Y Coordinate + * https://leetcode.com/problems/find-nearest-point-that-has-the-same-x-or-y-coordinate/ + * Difficulty: Easy + * + * You are given two integers, x and y, which represent your current location on a Cartesian + * grid: (x, y). You are also given an array points where each points[i] = [ai, bi] represents + * that a point exists at (ai, bi). A point is valid if it shares the same x-coordinate or the + * same y-coordinate as your location. + * + * Return the index (0-indexed) of the valid point with the smallest Manhattan distance from + * your current location. If there are multiple, return the valid point with the smallest index. + * If there are no valid points, return -1. + * + * The Manhattan distance between two points (x1, y1) and (x2, y2) is abs(x1 - x2) + abs(y1 - y2). + */ + +/** + * @param {number} x + * @param {number} y + * @param {number[][]} points + * @return {number} + */ +var nearestValidPoint = function(x, y, points) { + let minDistance = Infinity; + let result = -1; + + for (let i = 0; i < points.length; i++) { + const [px, py] = points[i]; + if (px === x || py === y) { + const distance = Math.abs(px - x) + Math.abs(py - y); + if (distance < minDistance) { + minDistance = distance; + result = i; + } + } + } + + return result; +}; diff --git a/solutions/1781-sum-of-beauty-of-all-substrings.js b/solutions/1781-sum-of-beauty-of-all-substrings.js new file mode 100644 index 00000000..6c561b33 --- /dev/null +++ b/solutions/1781-sum-of-beauty-of-all-substrings.js @@ -0,0 +1,35 @@ +/** + * 1781. Sum of Beauty of All Substrings + * https://leetcode.com/problems/sum-of-beauty-of-all-substrings/ + * Difficulty: Medium + * + * The beauty of a string is the difference in frequencies between the most frequent and + * least frequent characters. + * - For example, the beauty of "abaacc" is 3 - 1 = 2. + * + * Given a string s, return the sum of beauty of all of its substrings. + */ + +/** + * @param {string} s + * @return {number} + */ +var beautySum = function(s) { + let result = 0; + + for (let i = 0; i < s.length; i++) { + const freq = new Map(); + for (let j = i; j < s.length; j++) { + freq.set(s[j], (freq.get(s[j]) || 0) + 1); + let maxFreq = 0; + let minFreq = Infinity; + for (const count of freq.values()) { + maxFreq = Math.max(maxFreq, count); + minFreq = Math.min(minFreq, count); + } + result += maxFreq - minFreq; + } + } + + return result; +}; diff --git a/solutions/1782-count-pairs-of-nodes.js b/solutions/1782-count-pairs-of-nodes.js new file mode 100644 index 00000000..d0e4f00c --- /dev/null +++ b/solutions/1782-count-pairs-of-nodes.js @@ -0,0 +1,68 @@ +/** + * 1782. Count Pairs Of Nodes + * https://leetcode.com/problems/count-pairs-of-nodes/ + * Difficulty: Hard + * + * You are given an undirected graph defined by an integer n, the number of nodes, and a 2D + * integer array edges, the edges in the graph, where edges[i] = [ui, vi] indicates that there + * is an undirected edge between ui and vi. You are also given an integer array queries. + * + * Let incident(a, b) be defined as the number of edges that are connected to either node a or b. + * + * The answer to the jth query is the number of pairs of nodes (a, b) that satisfy both of the + * following conditions: + * - a < b + * - incident(a, b) > queries[j] + * + * Return an array answers such that answers.length == queries.length and answers[j] is the + * answer of the jth query. + * + * Note that there can be multiple edges between the same two nodes. + */ + +/** + * @param {number} n + * @param {number[][]} edges + * @param {number[]} queries + * @return {number[]} + */ +var countPairs = function(n, edges, queries) { + const degrees = Array(n + 1).fill(0); + const edgeCounts = new Map(); + + for (const [u, v] of edges) { + degrees[u]++; + degrees[v]++; + const key = u < v ? `${u},${v}` : `${v},${u}`; + edgeCounts.set(key, (edgeCounts.get(key) || 0) + 1); + } + + const sortedDegrees = [...degrees].slice(1).sort((a, b) => a - b); + const result = Array(queries.length).fill(0); + + for (let q = 0; q < queries.length; q++) { + let total = 0; + let left = 0; + let right = n - 1; + + while (left < right) { + if (sortedDegrees[left] + sortedDegrees[right] > queries[q]) { + total += right - left; + right--; + } else { + left++; + } + } + + for (const [key, count] of edgeCounts) { + const [u, v] = key.split(',').map(Number); + if (degrees[u] + degrees[v] > queries[q] && degrees[u] + degrees[v] - count <= queries[q]) { + total--; + } + } + + result[q] = total; + } + + return result; +}; diff --git a/solutions/1784-check-if-binary-string-has-at-most-one-segment-of-ones.js b/solutions/1784-check-if-binary-string-has-at-most-one-segment-of-ones.js new file mode 100644 index 00000000..4f3e3fb9 --- /dev/null +++ b/solutions/1784-check-if-binary-string-has-at-most-one-segment-of-ones.js @@ -0,0 +1,26 @@ +/** + * 1784. Check if Binary String Has at Most One Segment of Ones + * https://leetcode.com/problems/check-if-binary-string-has-at-most-one-segment-of-ones/ + * Difficulty: Easy + * + * Given a binary string s without leading zeros, return true if s contains at most one + * contiguous segment of ones. Otherwise, return false. + */ + +/** + * @param {string} s + * @return {boolean} + */ +var checkOnesSegment = function(s) { + let seenZero = false; + + for (let i = 1; i < s.length; i++) { + if (s[i] === '0') { + seenZero = true; + } else if (seenZero) { + return false; + } + } + + return true; +}; diff --git a/solutions/1785-minimum-elements-to-add-to-form-a-given-sum.js b/solutions/1785-minimum-elements-to-add-to-form-a-given-sum.js new file mode 100644 index 00000000..7b27b2c7 --- /dev/null +++ b/solutions/1785-minimum-elements-to-add-to-form-a-given-sum.js @@ -0,0 +1,25 @@ +/** + * 1785. Minimum Elements to Add to Form a Given Sum + * https://leetcode.com/problems/minimum-elements-to-add-to-form-a-given-sum/ + * Difficulty: Medium + * + * You are given an integer array nums and two integers limit and goal. The array nums has + * an interesting property that abs(nums[i]) <= limit. + * + * Return the minimum number of elements you need to add to make the sum of the array equal + * to goal. The array must maintain its property that abs(nums[i]) <= limit. + * + * Note that abs(x) equals x if x >= 0, and -x otherwise. + */ + +/** + * @param {number[]} nums + * @param {number} limit + * @param {number} goal + * @return {number} + */ +var minElements = function(nums, limit, goal) { + const currentSum = nums.reduce((sum, num) => sum + num, 0); + const difference = Math.abs(goal - currentSum); + return Math.ceil(difference / limit); +}; diff --git a/solutions/1786-number-of-restricted-paths-from-first-to-last-node.js b/solutions/1786-number-of-restricted-paths-from-first-to-last-node.js new file mode 100644 index 00000000..e55ddab4 --- /dev/null +++ b/solutions/1786-number-of-restricted-paths-from-first-to-last-node.js @@ -0,0 +1,80 @@ +/** + * 1786. Number of Restricted Paths From First to Last Node + * https://leetcode.com/problems/number-of-restricted-paths-from-first-to-last-node/ + * Difficulty: Medium + * + * There is an undirected weighted connected graph. You are given a positive integer n which + * denotes that the graph has n nodes labeled from 1 to n, and an array edges where each + * edges[i] = [ui, vi, weighti] denotes that there is an edge between nodes ui and vi with + * weight equal to weighti. + * + * A path from node start to node end is a sequence of nodes [z0, z1, z2, ..., zk] such that + * z0 = start and zk = end and there is an edge between zi and zi+1 where 0 <= i <= k-1. + * + * The distance of a path is the sum of the weights on the edges of the path. Let + * distanceToLastNode(x) denote the shortest distance of a path between node n and node x. + * A restricted path is a path that also satisfies that + * distanceToLastNode(zi) > distanceToLastNode(zi+1) where 0 <= i <= k-1. + * + * Return the number of restricted paths from node 1 to node n. Since that number may be too + * large, return it modulo 109 + 7. + */ + +/** + * @param {number} n + * @param {number[][]} edges + * @return {number} + */ +var countRestrictedPaths = function(n, edges) { + const MODULO = 1e9 + 7; + const graph = {}; + for (const [u, v, weight] of edges) { + (graph[u] ??= []).push({ edge: v, weight }); + (graph[v] ??= []).push({ edge: u, weight }); + } + + const distances = new Array(n + 1).fill(Number.MAX_SAFE_INTEGER); + distances[n] = 0; + + const NOT_VISITED = 0; + const VISITED = 1; + const IN_QUEUE = 2; + const states = new Array(n + 1).fill(NOT_VISITED); + const queue = [n]; + + while (queue.length) { + const node = queue.shift(); + states[node] = IN_QUEUE; + + for (const { edge, weight } of graph[node]) { + if (distances[node] + weight >= distances[edge]) continue; + + distances[edge] = distances[node] + weight; + + if (states[edge] === NOT_VISITED) { + queue.push(edge); + states[edge] = VISITED; + } else if (states[edge] === IN_QUEUE) { + queue.unshift(edge); + } + } + } + + const memo = new Map([[n, 1]]); + + return countPaths(1); + + function countPaths(node) { + if (memo.has(node)) return memo.get(node); + + let count = 0; + for (const { edge } of graph[node]) { + if (distances[edge] < distances[node]) { + count = (count + countPaths(edge)) % MODULO; + } + } + + memo.set(node, count); + return count; + } +}; diff --git a/solutions/1787-make-the-xor-of-all-segments-equal-to-zero.js b/solutions/1787-make-the-xor-of-all-segments-equal-to-zero.js new file mode 100644 index 00000000..7817c120 --- /dev/null +++ b/solutions/1787-make-the-xor-of-all-segments-equal-to-zero.js @@ -0,0 +1,51 @@ +/** + * 1787. Make the XOR of All Segments Equal to Zero + * https://leetcode.com/problems/make-the-xor-of-all-segments-equal-to-zero/ + * Difficulty: Hard + * + * You are given an array nums and an integer k. The XOR of a segment [left, right] where + * left <= right is the XOR of all the elements with indices between left and right, + * inclusive: nums[left] XOR nums[left+1] XOR ... XOR nums[right]. + * + * Return the minimum number of elements to change in the array such that the XOR of all + * segments of size k is equal to zero. + */ + +/** + * @param {number[]} nums + * @param {number} k + * @return {number} + */ +var minChanges = function(nums, k) { + const n = nums.length; + const maxVal = 1 << 10; + const groups = new Array(k).fill().map(() => new Map()); + + for (let i = 0; i < n; i++) { + groups[i % k].set(nums[i], (groups[i % k].get(nums[i]) || 0) + 1); + } + + const dp = new Array(maxVal).fill(n); + dp[0] = 0; + + for (let pos = 0; pos < k; pos++) { + const prevDp = [...dp]; + dp.fill(n); + const groupSize = Math.floor(n / k) + (pos < n % k ? 1 : 0); + const minPrev = Math.min(...prevDp); + + for (let xor = 0; xor < maxVal; xor++) { + if (prevDp[xor] === n) continue; + for (const [val, count] of groups[pos]) { + const newXor = xor ^ val; + dp[newXor] = Math.min(dp[newXor], prevDp[xor] + groupSize - count); + } + } + + for (let xor = 0; xor < maxVal; xor++) { + dp[xor] = Math.min(dp[xor], minPrev + groupSize); + } + } + + return dp[0]; +}; diff --git a/solutions/1792-maximum-average-pass-ratio.js b/solutions/1792-maximum-average-pass-ratio.js new file mode 100644 index 00000000..3ff9c5b3 --- /dev/null +++ b/solutions/1792-maximum-average-pass-ratio.js @@ -0,0 +1,107 @@ +/** + * 1792. Maximum Average Pass Ratio + * https://leetcode.com/problems/maximum-average-pass-ratio/ + * Difficulty: Medium + * + * There is a school that has classes of students and each class will be having a final exam. + * You are given a 2D integer array classes, where classes[i] = [passi, totali]. You know + * beforehand that in the ith class, there are totali total students, but only passi number + * of students will pass the exam. + * + * You are also given an integer extraStudents. There are another extraStudents brilliant + * students that are guaranteed to pass the exam of any class they are assigned to. You want + * to assign each of the extraStudents students to a class in a way that maximizes the average + * pass ratio across all the classes. + * + * The pass ratio of a class is equal to the number of students of the class that will pass + * the exam divided by the total number of students of the class. The average pass ratio is + * the sum of pass ratios of all the classes divided by the number of the classes. + * + * Return the maximum possible average pass ratio after assigning the extraStudents students. + * Answers within 10-5 of the actual answer will be accepted. + */ + +/** +* @param {number[][]} classes +* @param {number} extraStudents +* @return {number} +*/ +var maxAverageRatio = function(classes, extraStudents) { + const maxHeap = []; + + for (const [pass, total] of classes) { + const profit = getProfit(pass, total); + maxHeap.push([profit, pass, total]); + } + + heapify(); + + for (let i = 0; i < extraStudents; i++) { + const [_, pass, total] = extractMax(); + const newPass = pass + 1; + const newTotal = total + 1; + const newProfit = getProfit(newPass, newTotal); + insert([newProfit, newPass, newTotal]); + } + + let sumRatio = 0; + for (const [_, pass, total] of maxHeap) { + sumRatio += pass / total; + } + + return sumRatio / classes.length; + + function getProfit(pass, total) { + return (pass + 1) / (total + 1) - pass / total; + } + + function heapify() { + for (let i = Math.floor(maxHeap.length / 2) - 1; i >= 0; i--) { + siftDown(i); + } + } + + function siftDown(i) { + const left = 2 * i + 1; + const right = 2 * i + 2; + let largest = i; + + if (left < maxHeap.length && maxHeap[left][0] > maxHeap[largest][0]) { + largest = left; + } + + if (right < maxHeap.length && maxHeap[right][0] > maxHeap[largest][0]) { + largest = right; + } + + if (largest !== i) { + [maxHeap[i], maxHeap[largest]] = [maxHeap[largest], maxHeap[i]]; + siftDown(largest); + } + } + + function extractMax() { + const max = maxHeap[0]; + const last = maxHeap.pop(); + + if (maxHeap.length > 0) { + maxHeap[0] = last; + siftDown(0); + } + + return max; + } + + function insert(item) { + maxHeap.push(item); + + let i = maxHeap.length - 1; + let parent = Math.floor((i - 1) / 2); + + while (i > 0 && maxHeap[i][0] > maxHeap[parent][0]) { + [maxHeap[i], maxHeap[parent]] = [maxHeap[parent], maxHeap[i]]; + i = parent; + parent = Math.floor((i - 1) / 2); + } + } +}; diff --git a/solutions/1793-maximum-score-of-a-good-subarray.js b/solutions/1793-maximum-score-of-a-good-subarray.js new file mode 100644 index 00000000..9a662c67 --- /dev/null +++ b/solutions/1793-maximum-score-of-a-good-subarray.js @@ -0,0 +1,42 @@ +/** + * 1793. Maximum Score of a Good Subarray + * https://leetcode.com/problems/maximum-score-of-a-good-subarray/ + * Difficulty: Hard + * + * You are given an array of integers nums (0-indexed) and an integer k. + * + * The score of a subarray (i, j) is defined as min(nums[i], nums[i+1], ..., nums[j]) * + * (j - i + 1). A good subarray is a subarray where i <= k <= j. + * + * Return the maximum possible score of a good subarray. + */ + +/** + * @param {number[]} nums + * @param {number} k + * @return {number} + */ +var maximumScore = function(nums, k) { + let result = nums[k]; + let minimum = nums[k]; + let left = k; + let right = k; + const length = nums.length; + + while (left > 0 || right < length - 1) { + const leftValue = left > 0 ? nums[left - 1] : 0; + const rightValue = right < length - 1 ? nums[right + 1] : 0; + + if (leftValue >= rightValue) { + left--; + minimum = Math.min(minimum, leftValue); + } else { + right++; + minimum = Math.min(minimum, rightValue); + } + + result = Math.max(result, minimum * (right - left + 1)); + } + + return result; +}; diff --git a/solutions/1796-second-largest-digit-in-a-string.js b/solutions/1796-second-largest-digit-in-a-string.js new file mode 100644 index 00000000..196ba422 --- /dev/null +++ b/solutions/1796-second-largest-digit-in-a-string.js @@ -0,0 +1,33 @@ +/** + * 1796. Second Largest Digit in a String + * https://leetcode.com/problems/second-largest-digit-in-a-string/ + * Difficulty: Easy + * + * Given an alphanumeric string s, return the second largest numerical digit that appears in + * s, or -1 if it does not exist. + * + * An alphanumeric string is a string consisting of lowercase English letters and digits. + */ + +/** + * @param {string} s + * @return {number} + */ +var secondHighest = function(s) { + let largest = -1; + let result = -1; + + for (const char of s) { + if (/\d/.test(char)) { + const digit = parseInt(char); + if (digit > largest) { + result = largest; + largest = digit; + } else if (digit < largest && digit > result) { + result = digit; + } + } + } + + return result; +}; diff --git a/solutions/1797-design-authentication-manager.js b/solutions/1797-design-authentication-manager.js new file mode 100644 index 00000000..e631c416 --- /dev/null +++ b/solutions/1797-design-authentication-manager.js @@ -0,0 +1,68 @@ +/** + * 1797. Design Authentication Manager + * https://leetcode.com/problems/design-authentication-manager/ + * Difficulty: Medium + * + * There is an authentication system that works with authentication tokens. For each session, + * the user will receive a new authentication token that will expire timeToLive seconds after + * the currentTime. If the token is renewed, the expiry time will be extended to expire + * timeToLive seconds after the (potentially different) currentTime. + * + * Implement the AuthenticationManager class: + * - AuthenticationManager(int timeToLive) constructs the AuthenticationManager and sets the + * timeToLive. + * - generate(string tokenId, int currentTime) generates a new token with the given tokenId + * at the given currentTime in seconds. + * - renew(string tokenId, int currentTime) renews the unexpired token with the given tokenId + * at the given currentTime in seconds. If there are no unexpired tokens with the given + * tokenId, the request is ignored, and nothing happens. + * - countUnexpiredTokens(int currentTime) returns the number of unexpired tokens at the + * given currentTime. + * + * Note that if a token expires at time t, and another action happens on time t (renew or + * countUnexpiredTokens), the expiration takes place before the other actions. + */ + +/** + * @param {number} timeToLive + */ +var AuthenticationManager = function(timeToLive) { + this.timeToLive = timeToLive; + this.tokens = new Map(); +}; + +/** + * @param {string} tokenId + * @param {number} currentTime + * @return {void} + */ +AuthenticationManager.prototype.generate = function(tokenId, currentTime) { + this.tokens.set(tokenId, currentTime + this.timeToLive); +}; + +/** + * @param {string} tokenId + * @param {number} currentTime + * @return {void} + */ +AuthenticationManager.prototype.renew = function(tokenId, currentTime) { + if (this.tokens.has(tokenId) && this.tokens.get(tokenId) > currentTime) { + this.tokens.set(tokenId, currentTime + this.timeToLive); + } +}; + +/** + * @param {number} currentTime + * @return {number} + */ +AuthenticationManager.prototype.countUnexpiredTokens = function(currentTime) { + let count = 0; + for (const [tokenId, expiry] of this.tokens) { + if (expiry > currentTime) { + count++; + } else { + this.tokens.delete(tokenId); + } + } + return count; +}; diff --git a/solutions/1798-maximum-number-of-consecutive-values-you-can-make.js b/solutions/1798-maximum-number-of-consecutive-values-you-can-make.js new file mode 100644 index 00000000..0c91d2de --- /dev/null +++ b/solutions/1798-maximum-number-of-consecutive-values-you-can-make.js @@ -0,0 +1,30 @@ +/** + * 1798. Maximum Number of Consecutive Values You Can Make + * https://leetcode.com/problems/maximum-number-of-consecutive-values-you-can-make/ + * Difficulty: Medium + * + * You are given an integer array coins of length n which represents the n coins that you + * own. The value of the ith coin is coins[i]. You can make some value x if you can choose + * some of your n coins such that their values sum up to x. + * + * Return the maximum number of consecutive integer values that you can make with your coins + * starting from and including 0. + * + * Note that you may have multiple coins of the same value. + */ + +/** + * @param {number[]} coins + * @return {number} + */ +var getMaximumConsecutive = function(coins) { + let maxReachable = 0; + + coins.sort((a, b) => a - b); + for (const coin of coins) { + if (coin > maxReachable + 1) break; + maxReachable += coin; + } + + return maxReachable + 1; +}; diff --git a/solutions/1799-maximize-score-after-n-operations.js b/solutions/1799-maximize-score-after-n-operations.js new file mode 100644 index 00000000..eb7a2e3b --- /dev/null +++ b/solutions/1799-maximize-score-after-n-operations.js @@ -0,0 +1,59 @@ +/** + * 1799. Maximize Score After N Operations + * https://leetcode.com/problems/maximize-score-after-n-operations/ + * Difficulty: Hard + * + * You are given nums, an array of positive integers of size 2 * n. You must perform n operations + * on this array. + * + * In the ith operation (1-indexed), you will: + * - Choose two elements, x and y. + * - Receive a score of i * gcd(x, y). + * - Remove x and y from nums. + * + * Return the maximum score you can receive after performing n operations. + * + * The function gcd(x, y) is the greatest common divisor of x and y. + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var maxScore = function(nums) { + const n = nums.length; + const pairsGcd = Array(n).fill().map(() => Array(n).fill(0)); + for (let i = 0; i < n; i++) { + for (let j = i + 1; j < n; j++) { + pairsGcd[i][j] = gcd(nums[i], nums[j]); + } + } + + return solve(1, 0, {}, pairsGcd); + + function gcd(a, b) { + while (b) { + a %= b; + [a, b] = [b, a]; + } + return a; + } + + function solve(operations, mask, memo, pairsGcd) { + if (operations > nums.length / 2) return 0; + if (memo[mask] !== undefined) return memo[mask]; + + let maxScore = 0; + for (let i = 0; i < nums.length; i++) { + if (mask & (1 << i)) continue; + for (let j = i + 1; j < nums.length; j++) { + if (mask & (1 << j)) continue; + const newMask = mask | (1 << i) | (1 << j); + const score = operations * pairsGcd[i][j] + solve(operations + 1, newMask, memo, pairsGcd); + maxScore = Math.max(maxScore, score); + } + } + + return memo[mask] = maxScore; + } +}; diff --git a/solutions/1801-number-of-orders-in-the-backlog.js b/solutions/1801-number-of-orders-in-the-backlog.js new file mode 100644 index 00000000..1c9501c0 --- /dev/null +++ b/solutions/1801-number-of-orders-in-the-backlog.js @@ -0,0 +1,73 @@ +/** + * 1801. Number of Orders in the Backlog + * https://leetcode.com/problems/number-of-orders-in-the-backlog/ + * Difficulty: Medium + * + * You are given a 2D integer array orders, where each orders[i] = [pricei, amounti, orderTypei] + * denotes that amounti orders have been placed of type orderTypei at the price pricei. + * The orderTypei is: + * - 0 if it is a batch of buy orders, or + * - 1 if it is a batch of sell orders. + * + * Note that orders[i] represents a batch of amounti independent orders with the same price and + * order type. All orders represented by orders[i] will be placed before all orders represented + * by orders[i+1] for all valid i. + * + * There is a backlog that consists of orders that have not been executed. The backlog is initially + * empty. When an order is placed, the following happens: + * - If the order is a buy order, you look at the sell order with the smallest price in the backlog. + * If that sell order's price is smaller than or equal to the current buy order's price, they will + * match and be executed, and that sell order will be removed from the backlog. Else, the buy + * order is added to the backlog. + * - Vice versa, if the order is a sell order, you look at the buy order with the largest price in + * the backlog. If that buy order's price is larger than or equal to the current sell order's + * price, they will match and be executed, and that buy order will be removed from the backlog. + * Else, the sell order is added to the backlog. + * + * Return the total amount of orders in the backlog after placing all the orders from the input. + * Since this number can be large, return it modulo 109 + 7. + */ + +/** + * @param {number[][]} orders + * @return {number} + */ +var getNumberOfBacklogOrders = function(orders) { + const MOD = 1e9 + 7; + const buyOrders = new MinPriorityQueue(); + const sellOrders = new MinPriorityQueue(); + + for (let [price, amount, type] of orders) { + if (type === 0) { + const order = { price: -price, amount, originalPrice: price, valueOf: () => -price }; + while (amount > 0 && !sellOrders.isEmpty() && sellOrders.front().price <= price) { + const sellOrder = sellOrders.dequeue(); + const matchAmount = Math.min(amount, sellOrder.amount); + amount -= matchAmount; + sellOrder.amount -= matchAmount; + if (sellOrder.amount > 0) sellOrders.enqueue(sellOrder); + } + if (amount > 0) buyOrders.enqueue({ ...order, amount }); + } else { + const order = { price, amount, valueOf: () => price }; + while (amount > 0 && !buyOrders.isEmpty() && buyOrders.front().originalPrice >= price) { + const buyOrder = buyOrders.dequeue(); + const matchAmount = Math.min(amount, buyOrder.amount); + amount -= matchAmount; + buyOrder.amount -= matchAmount; + if (buyOrder.amount > 0) buyOrders.enqueue(buyOrder); + } + if (amount > 0) sellOrders.enqueue({ ...order, amount }); + } + } + + let total = 0; + while (!buyOrders.isEmpty()) { + total = (total + buyOrders.dequeue().amount) % MOD; + } + while (!sellOrders.isEmpty()) { + total = (total + sellOrders.dequeue().amount) % MOD; + } + + return total; +}; diff --git a/solutions/1802-maximum-value-at-a-given-index-in-a-bounded-array.js b/solutions/1802-maximum-value-at-a-given-index-in-a-bounded-array.js new file mode 100644 index 00000000..bc7fba1a --- /dev/null +++ b/solutions/1802-maximum-value-at-a-given-index-in-a-bounded-array.js @@ -0,0 +1,51 @@ +/** + * 1802. Maximum Value at a Given Index in a Bounded Array + * https://leetcode.com/problems/maximum-value-at-a-given-index-in-a-bounded-array/ + * Difficulty: Medium + * + * You are given three positive integers: n, index, and maxSum. You want to construct an array + * nums (0-indexed) that satisfies the following conditions: + * - nums.length == n + * - nums[i] is a positive integer where 0 <= i < n. + * - abs(nums[i] - nums[i+1]) <= 1 where 0 <= i < n-1. + * - The sum of all the elements of nums does not exceed maxSum. + * - nums[index] is maximized. + * + * Return nums[index] of the constructed array. + * + * Note that abs(x) equals x if x >= 0, and -x otherwise. + */ + +/** + * @param {number} n + * @param {number} index + * @param {number} maxSum + * @return {number} + */ +var maxValue = function(n, index, maxSum) { + function minSumRequired(peak) { + const leftCount = Math.min(index, peak - 1); + const rightCount = Math.min(n - index - 1, peak - 1); + let sum = peak; + sum += (peak - 1 + peak - leftCount) * leftCount / 2; + sum += (peak - 1 + peak - rightCount) * rightCount / 2; + sum += (index - leftCount) + (n - index - 1 - rightCount); + return sum; + } + + let low = 1; + let high = maxSum; + let result = 1; + + while (low <= high) { + const mid = Math.floor((low + high) / 2); + if (minSumRequired(mid) <= maxSum) { + result = mid; + low = mid + 1; + } else { + high = mid - 1; + } + } + + return result; +}; diff --git a/solutions/1803-count-pairs-with-xor-in-a-range.js b/solutions/1803-count-pairs-with-xor-in-a-range.js new file mode 100644 index 00000000..1912bf08 --- /dev/null +++ b/solutions/1803-count-pairs-with-xor-in-a-range.js @@ -0,0 +1,67 @@ +/** + * 1803. Count Pairs With XOR in a Range + * https://leetcode.com/problems/count-pairs-with-xor-in-a-range/ + * Difficulty: Hard + * + * Given a (0-indexed) integer array nums and two integers low and high, return the number + * of nice pairs. + * + * A nice pair is a pair (i, j) where 0 <= i < j < nums.length and low <= (nums[i] XOR + * nums[j]) <= high. + */ + +/** + * @param {number[]} nums + * @param {number} low + * @param {number} high + * @return {number} + */ +var countPairs = function(nums, low, high) { + const root = new TrieNode(); + let total = 0; + + for (const num of nums) { + total += countPairsInRange(num, high, root) - countPairsInRange(num, low - 1, root); + insert(num, root); + } + + return total; +}; + +class TrieNode { + constructor() { + this.children = [null, null]; + this.count = 0; + } +} + +function countPairsInRange(num, limit, root, depth = 14) { + let count = 0; + let node = root; + for (let i = depth; i >= 0 && node; i--) { + const numBit = (num >> i) & 1; + const limitBit = (limit >> i) & 1; + if (limitBit === 0) { + node = node.children[numBit]; + } else { + if (node.children[numBit]) { + count += node.children[numBit].count; + } + node = node.children[numBit ^ 1]; + } + } + return count + (node ? node.count : 0); +} + +function insert(num, root) { + let node = root; + for (let i = 14; i >= 0; i--) { + const bit = (num >> i) & 1; + if (!node.children[bit]) { + node.children[bit] = new TrieNode(); + } + node = node.children[bit]; + node.count++; + } +} + diff --git a/solutions/1805-number-of-different-integers-in-a-string.js b/solutions/1805-number-of-different-integers-in-a-string.js new file mode 100644 index 00000000..61b6f693 --- /dev/null +++ b/solutions/1805-number-of-different-integers-in-a-string.js @@ -0,0 +1,40 @@ +/** + * 1805. Number of Different Integers in a String + * https://leetcode.com/problems/number-of-different-integers-in-a-string/ + * Difficulty: Easy + * + * You are given a string word that consists of digits and lowercase English letters. + * + * You will replace every non-digit character with a space. For example, "a123bc34d8ef34" + * will become " 123 34 8 34". Notice that you are left with some integers that are + * separated by at least one space: "123", "34", "8", and "34". + * + * Return the number of different integers after performing the replacement operations on word. + * + * Two integers are considered different if their decimal representations without any leading + * zeros are different. + */ + +/** + * @param {string} word + * @return {number} + */ +var numDifferentIntegers = function(word) { + const uniqueIntegers = new Set(); + let currentNum = ''; + + for (const char of word) { + if (/\d/.test(char)) { + currentNum += char; + } else if (currentNum) { + uniqueIntegers.add(String(BigInt(currentNum))); + currentNum = ''; + } + } + + if (currentNum) { + uniqueIntegers.add(String(BigInt(currentNum))); + } + + return uniqueIntegers.size; +}; diff --git a/solutions/1806-minimum-number-of-operations-to-reinitialize-a-permutation.js b/solutions/1806-minimum-number-of-operations-to-reinitialize-a-permutation.js new file mode 100644 index 00000000..5ba88490 --- /dev/null +++ b/solutions/1806-minimum-number-of-operations-to-reinitialize-a-permutation.js @@ -0,0 +1,37 @@ +/** + * 1806. Minimum Number of Operations to Reinitialize a Permutation + * https://leetcode.com/problems/minimum-number-of-operations-to-reinitialize-a-permutation/ + * Difficulty: Medium + * + * You are given an even integer n. You initially have a permutation perm of size n where + * perm[i] == i (0-indexed). + * + * In one operation, you will create a new array arr, and for each i: + * - If i % 2 == 0, then arr[i] = perm[i / 2]. + * - If i % 2 == 1, then arr[i] = perm[n / 2 + (i - 1) / 2]. + * + * You will then assign arr to perm. + * + * Return the minimum non-zero number of operations you need to perform on perm to return the + * permutation to its initial value. + */ + +/** + * @param {number} n + * @return {number} + */ +var reinitializePermutation = function(n) { + let currentIndex = 1; + let result = 0; + + do { + if (currentIndex % 2 === 0) { + currentIndex = currentIndex / 2; + } else { + currentIndex = n / 2 + (currentIndex - 1) / 2; + } + result++; + } while (currentIndex !== 1); + + return result; +}; diff --git a/solutions/1807-evaluate-the-bracket-pairs-of-a-string.js b/solutions/1807-evaluate-the-bracket-pairs-of-a-string.js new file mode 100644 index 00000000..7fffdc33 --- /dev/null +++ b/solutions/1807-evaluate-the-bracket-pairs-of-a-string.js @@ -0,0 +1,51 @@ +/** + * 1807. Evaluate the Bracket Pairs of a String + * https://leetcode.com/problems/evaluate-the-bracket-pairs-of-a-string/ + * Difficulty: Medium + * + * You are given a string s that contains some bracket pairs, with each pair containing + * a non-empty key. + * + * - For example, in the string "(name)is(age)yearsold", there are two bracket pairs that contain + * the keys "name" and "age". + * + * You know the values of a wide range of keys. This is represented by a 2D string array knowledge + * where each knowledge[i] = [keyi, valuei] indicates that key keyi has a value of valuei. + * + * You are tasked to evaluate all of the bracket pairs. When you evaluate a bracket pair that + * contains some key keyi, you will: + * - Replace keyi and the bracket pair with the key's corresponding valuei. + * - If you do not know the value of the key, you will replace keyi and the bracket pair with a + * question mark "?" (without the quotation marks). + * + * Each key will appear at most once in your knowledge. There will not be any nested brackets in s. + * + * Return the resulting string after evaluating all of the bracket pairs. + */ + +/** + * @param {string} s + * @param {string[][]} knowledge + * @return {string} + */ +var evaluate = function(s, knowledge) { + const keyValueMap = new Map(knowledge); + let result = ''; + let i = 0; + + while (i < s.length) { + if (s[i] === '(') { + i++; + let key = ''; + while (i < s.length && s[i] !== ')') { + key += s[i++]; + } + result += keyValueMap.get(key) || '?'; + i++; + } else { + result += s[i++]; + } + } + + return result; +}; diff --git a/solutions/1808-maximize-number-of-nice-divisors.js b/solutions/1808-maximize-number-of-nice-divisors.js new file mode 100644 index 00000000..49f3697a --- /dev/null +++ b/solutions/1808-maximize-number-of-nice-divisors.js @@ -0,0 +1,48 @@ +/** + * 1808. Maximize Number of Nice Divisors + * https://leetcode.com/problems/maximize-number-of-nice-divisors/ + * Difficulty: Hard + * + * You are given a positive integer primeFactors. You are asked to construct a positive + * integer n that satisfies the following conditions: + * - The number of prime factors of n (not necessarily distinct) is at most primeFactors. + * - The number of nice divisors of n is maximized. Note that a divisor of n is nice if it + * is divisible by every prime factor of n. For example, if n = 12, then its prime factors + * are [2,2,3], then 6 and 12 are nice divisors, while 3 and 4 are not. + * + * Return the number of nice divisors of n. Since that number can be too large, return it + * modulo 109 + 7. + * + * Note that a prime number is a natural number greater than 1 that is not a product of two + * smaller natural numbers. The prime factors of a number n is a list of prime numbers such + * that their product equals n. + */ + +/** + * @param {number} primeFactors + * @return {number} + */ +var maxNiceDivisors = function(primeFactors) { + const MOD = 1e9 + 7; + + if (primeFactors <= 3) return primeFactors; + + const quotient = Math.floor(primeFactors / 3); + const remainder = primeFactors % 3; + + if (remainder === 0) return power(3, quotient); + if (remainder === 1) return (power(3, quotient - 1) * 4) % MOD; + + return (power(3, quotient) * 2) % MOD; + + function power(base, exponent) { + let result = BigInt(1); + base = BigInt(base); + while (exponent > 0) { + if (exponent & 1) result = (result * base) % BigInt(MOD); + base = (base * base) % BigInt(MOD); + exponent >>= 1; + } + return Number(result); + } +}; diff --git a/solutions/1813-sentence-similarity-iii.js b/solutions/1813-sentence-similarity-iii.js new file mode 100644 index 00000000..872cea74 --- /dev/null +++ b/solutions/1813-sentence-similarity-iii.js @@ -0,0 +1,46 @@ +/** + * 1813. Sentence Similarity III + * https://leetcode.com/problems/sentence-similarity-iii/ + * Difficulty: Medium + * + * You are given two strings sentence1 and sentence2, each representing a sentence composed of + * words. A sentence is a list of words that are separated by a single space with no leading + * or trailing spaces. Each word consists of only uppercase and lowercase English characters. + * + * Two sentences s1 and s2 are considered similar if it is possible to insert an arbitrary + * sentence (possibly empty) inside one of these sentences such that the two sentences become + * equal. Note that the inserted sentence must be separated from existing words by spaces. + * + * For example: + * - s1 = "Hello Jane" and s2 = "Hello my name is Jane" can be made equal by inserting "my name is" + * between "Hello" and "Jane" in s1. + * - s1 = "Frog cool" and s2 = "Frogs are cool" are not similar, since although there is a sentence + * "s are" inserted into s1, it is not separated from "Frog" by a space. + * + * Given two sentences sentence1 and sentence2, return true if sentence1 and sentence2 are + * similar. Otherwise, return false. + */ + +/** + * @param {string} sentence1 + * @param {string} sentence2 + * @return {boolean} + */ +var areSentencesSimilar = function(sentence1, sentence2) { + let words1 = sentence1.split(' '); + let words2 = sentence2.split(' '); + if (words1.length < words2.length) [words1, words2] = [words2, words1]; + + let prefixLength = 0; + while (prefixLength < words2.length && words1[prefixLength] === words2[prefixLength]) { + prefixLength++; + } + + let suffixLength = 0; + while (suffixLength < words2.length - prefixLength + && words1[words1.length - 1 - suffixLength] === words2[words2.length - 1 - suffixLength]) { + suffixLength++; + } + + return prefixLength + suffixLength >= words2.length; +}; diff --git a/solutions/1814-count-nice-pairs-in-an-array.js b/solutions/1814-count-nice-pairs-in-an-array.js new file mode 100644 index 00000000..f8db6cc5 --- /dev/null +++ b/solutions/1814-count-nice-pairs-in-an-array.js @@ -0,0 +1,37 @@ +/** + * 1814. Count Nice Pairs in an Array + * https://leetcode.com/problems/count-nice-pairs-in-an-array/ + * Difficulty: Medium + * + * You are given an array nums that consists of non-negative integers. Let us define rev(x) + * as the reverse of the non-negative integer x. For example, rev(123) = 321, and rev(120) = 21. + * A pair of indices (i, j) is nice if it satisfies all of the following conditions: + * - 0 <= i < j < nums.length + * - nums[i] + rev(nums[j]) == nums[j] + rev(nums[i]) + * + * Return the number of nice pairs of indices. Since that number can be too large, return it + * modulo 109 + 7. + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var countNicePairs = function(nums) { + const MOD = 1e9 + 7; + const map = new Map(); + let result = 0; + + for (const num of nums) { + const diff = num - reverseNumber(num); + const count = map.get(diff) || 0; + result = (result + count) % MOD; + map.set(diff, count + 1); + } + + return result; + + function reverseNumber(num) { + return Number(String(num).split('').reverse().join('')); + } +}; diff --git a/solutions/1815-maximum-number-of-groups-getting-fresh-donuts.js b/solutions/1815-maximum-number-of-groups-getting-fresh-donuts.js new file mode 100644 index 00000000..fcd73dc8 --- /dev/null +++ b/solutions/1815-maximum-number-of-groups-getting-fresh-donuts.js @@ -0,0 +1,59 @@ +/** + * 1815. Maximum Number of Groups Getting Fresh Donuts + * https://leetcode.com/problems/maximum-number-of-groups-getting-fresh-donuts/ + * Difficulty: Hard + * + * There is a donuts shop that bakes donuts in batches of batchSize. They have a rule where they + * must serve all of the donuts of a batch before serving any donuts of the next batch. You are + * given an integer batchSize and an integer array groups, where groups[i] denotes that there is + * a group of groups[i] customers that will visit the shop. Each customer will get exactly one + * donut. + * + * When a group visits the shop, all customers of the group must be served before serving any + * of the following groups. A group will be happy if they all get fresh donuts. That is, the + * first customer of the group does not receive a donut that was left over from the previous group. + * + * You can freely rearrange the ordering of the groups. Return the maximum possible number of + * happy groups after rearranging the groups. + */ + +/** + * @param {number} batchSize + * @param {number[]} groups + * @return {number} + */ +var maxHappyGroups = function(batchSize, groups) { + const remainders = new Array(batchSize).fill(0); + let result = 0; + + for (const size of groups) { + remainders[size % batchSize]++; + } + + result += remainders[0]; + remainders[0] = 0; + + return result + findMaxHappy(remainders, 0); + + function findMaxHappy(remainders, leftover, memo = new Map()) { + const key = remainders.join(',') + ',' + leftover; + if (memo.has(key)) return memo.get(key); + + let maxHappy = 0; + for (let i = 1; i < batchSize; i++) { + if (remainders[i] === 0) continue; + remainders[i]--; + + let current = 0; + if (leftover === 0) current = 1; + maxHappy = Math.max( + maxHappy, current + findMaxHappy(remainders, (leftover + i) % batchSize, memo) + ); + + remainders[i]++; + } + + memo.set(key, maxHappy); + return maxHappy; + } +}; diff --git a/solutions/1816-truncate-sentence.js b/solutions/1816-truncate-sentence.js new file mode 100644 index 00000000..d0d91e32 --- /dev/null +++ b/solutions/1816-truncate-sentence.js @@ -0,0 +1,22 @@ +/** + * 1816. Truncate Sentence + * https://leetcode.com/problems/truncate-sentence/ + * Difficulty: Easy + * + * A sentence is a list of words that are separated by a single space with no leading or + * trailing spaces. Each of the words consists of only uppercase and lowercase English + * letters (no punctuation). + * - For example, "Hello World", "HELLO", and "hello world hello world" are all sentences. + * + * You are given a sentence s and an integer k. You want to truncate s such that it contains + * only the first k words. Return s after truncating it. + */ + +/** + * @param {string} s + * @param {number} k + * @return {string} + */ +var truncateSentence = function(s, k) { + return s.split(' ').slice(0, k).join(' '); +}; diff --git a/solutions/1818-minimum-absolute-sum-difference.js b/solutions/1818-minimum-absolute-sum-difference.js new file mode 100644 index 00000000..fb1cc1dc --- /dev/null +++ b/solutions/1818-minimum-absolute-sum-difference.js @@ -0,0 +1,51 @@ +/** + * 1818. Minimum Absolute Sum Difference + * https://leetcode.com/problems/minimum-absolute-sum-difference/ + * Difficulty: Medium + * + * You are given two positive integer arrays nums1 and nums2, both of length n. + * + * The absolute sum difference of arrays nums1 and nums2 is defined as the sum of + * |nums1[i] - nums2[i]| for each 0 <= i < n (0-indexed). + * + * You can replace at most one element of nums1 with any other element in nums1 to minimize + * the absolute sum difference. + * + * Return the minimum absolute sum difference after replacing at most one element in the + * array nums1. Since the answer may be large, return it modulo 109 + 7. + * + * |x| is defined as: + * - x if x >= 0, or + * - -x if x < 0. + */ + +/** + * @param {number[]} nums1 + * @param {number[]} nums2 + * @return {number} + */ +var minAbsoluteSumDiff = function(nums1, nums2) { + const MOD = 1e9 + 7; + const sortedNums1 = [...nums1].sort((a, b) => a - b); + let totalDiff = 0; + let maxReduction = 0; + + for (let i = 0; i < nums1.length; i++) { + const currentDiff = Math.abs(nums1[i] - nums2[i]); + totalDiff = (totalDiff + currentDiff) % MOD; + + let left = 0; + let right = nums1.length - 1; + while (left <= right) { + const mid = Math.floor((left + right) / 2); + const newDiff = Math.abs(sortedNums1[mid] - nums2[i]); + const reduction = currentDiff - newDiff; + maxReduction = Math.max(maxReduction, reduction); + + if (sortedNums1[mid] < nums2[i]) left = mid + 1; + else right = mid - 1; + } + } + + return (totalDiff - maxReduction + MOD) % MOD; +}; diff --git a/solutions/1819-number-of-different-subsequences-gcds.js b/solutions/1819-number-of-different-subsequences-gcds.js new file mode 100644 index 00000000..04842fef --- /dev/null +++ b/solutions/1819-number-of-different-subsequences-gcds.js @@ -0,0 +1,48 @@ +/** + * 1819. Number of Different Subsequences GCDs + * https://leetcode.com/problems/number-of-different-subsequences-gcds/ + * Difficulty: Hard + * + * You are given an array nums that consists of positive integers. + * + * The GCD of a sequence of numbers is defined as the greatest integer that divides all the + * numbers in the sequence evenly. + * - For example, the GCD of the sequence [4,6,16] is 2. + * + * A subsequence of an array is a sequence that can be formed by removing some elements (possibly + * none) of the array. + * - For example, [2,5,10] is a subsequence of [1,2,1,2,4,1,5,10]. + * + * Return the number of different GCDs among all non-empty subsequences of nums. + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var countDifferentSubsequenceGCDs = function(nums) { + const maxNum = Math.max(...nums); + const exists = new Array(maxNum + 1).fill(false); + let result = 0; + + function gcd(a, b) { + while (b) [a, b] = [b, a % b]; + return a; + } + + for (const num of nums) { + exists[num] = true; + } + + for (let i = 1; i <= maxNum; i++) { + let currentGcd = 0; + for (let j = i; j <= maxNum; j += i) { + if (exists[j]) { + currentGcd = currentGcd ? gcd(currentGcd, j) : j; + } + } + if (currentGcd === i) result++; + } + + return result; +}; diff --git a/solutions/1822-sign-of-the-product-of-an-array.js b/solutions/1822-sign-of-the-product-of-an-array.js new file mode 100644 index 00000000..f235ea51 --- /dev/null +++ b/solutions/1822-sign-of-the-product-of-an-array.js @@ -0,0 +1,29 @@ +/** + * 1822. Sign of the Product of an Array + * https://leetcode.com/problems/sign-of-the-product-of-an-array/ + * Difficulty: Easy + * + * Implement a function signFunc(x) that returns: + * - 1 if x is positive. + * - -1 if x is negative. + * - 0 if x is equal to 0. + * + * You are given an integer array nums. Let product be the product of all values in the array nums. + * + * Return signFunc(product). + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var arraySign = function(nums) { + let negativeCount = 0; + + for (const num of nums) { + if (num === 0) return 0; + if (num < 0) negativeCount++; + } + + return negativeCount % 2 === 0 ? 1 : -1; +}; diff --git a/solutions/1823-find-the-winner-of-the-circular-game.js b/solutions/1823-find-the-winner-of-the-circular-game.js new file mode 100644 index 00000000..3138d5bb --- /dev/null +++ b/solutions/1823-find-the-winner-of-the-circular-game.js @@ -0,0 +1,36 @@ +/** + * 1823. Find the Winner of the Circular Game + * https://leetcode.com/problems/find-the-winner-of-the-circular-game/ + * Difficulty: Medium + * + * There are n friends that are playing a game. The friends are sitting in a circle and are + * numbered from 1 to n in clockwise order. More formally, moving clockwise from the ith + * friend brings you to the (i+1)th friend for 1 <= i < n, and moving clockwise from the + * nth friend brings you to the 1st friend. + * + * The rules of the game are as follows: + * 1. Start at the 1st friend. + * 2. Count the next k friends in the clockwise direction including the friend you started at. + * The counting wraps around the circle and may count some friends more than once. + * 3. The last friend you counted leaves the circle and loses the game. + * 4. If there is still more than one friend in the circle, go back to step 2 starting from the + * friend immediately clockwise of the friend who just lost and repeat. + * 5. Else, the last friend in the circle wins the game. + * + * Given the number of friends, n, and an integer k, return the winner of the game. + */ + +/** + * @param {number} n + * @param {number} k + * @return {number} + */ +var findTheWinner = function(n, k) { + let winner = 0; + + for (let i = 1; i <= n; i++) { + winner = (winner + k) % i; + } + + return winner + 1; +}; diff --git a/solutions/1824-minimum-sideway-jumps.js b/solutions/1824-minimum-sideway-jumps.js new file mode 100644 index 00000000..e4eb60d3 --- /dev/null +++ b/solutions/1824-minimum-sideway-jumps.js @@ -0,0 +1,55 @@ +/** + * 1824. Minimum Sideway Jumps + * https://leetcode.com/problems/minimum-sideway-jumps/ + * Difficulty: Medium + * + * There is a 3 lane road of length n that consists of n + 1 points labeled from 0 to n. A frog + * starts at point 0 in the second lane and wants to jump to point n. However, there could be + * obstacles along the way. + * + * You are given an array obstacles of length n + 1 where each obstacles[i] (ranging from 0 to 3) + * describes an obstacle on the lane obstacles[i] at point i. If obstacles[i] == 0, there are no + * obstacles at point i. There will be at most one obstacle in the 3 lanes at each point. + * - For example, if obstacles[2] == 1, then there is an obstacle on lane 1 at point 2. + * + * The frog can only travel from point i to point i + 1 on the same lane if there is not an obstacle + * on the lane at point i + 1. To avoid obstacles, the frog can also perform a side jump to jump + * to another lane (even if they are not adjacent) at the same point if there is no obstacle on + * the new lane. + * - For example, the frog can jump from lane 3 at point 3 to lane 1 at point 3. + * + * Return the minimum number of side jumps the frog needs to reach any lane at point n starting + * from lane 2 at point 0. + * + * Note: There will be no obstacles on points 0 and n. + */ + +/** + * @param {number[]} obstacles + * @return {number} + */ +var minSideJumps = function(obstacles) { + const n = obstacles.length; + let dp = [1, 0, 1]; + + for (let i = 1; i < n; i++) { + const currentObstacle = obstacles[i]; + const nextDp = [Infinity, Infinity, Infinity]; + + for (let lane = 1; lane <= 3; lane++) { + if (lane === currentObstacle) continue; + + nextDp[lane - 1] = dp[lane - 1]; + + for (let fromLane = 1; fromLane <= 3; fromLane++) { + if (fromLane !== lane && fromLane !== currentObstacle) { + nextDp[lane - 1] = Math.min(nextDp[lane - 1], dp[fromLane - 1] + 1); + } + } + } + + dp = nextDp; + } + + return Math.min(...dp); +}; diff --git a/solutions/1825-finding-mk-average.js b/solutions/1825-finding-mk-average.js new file mode 100644 index 00000000..ddc2b83e --- /dev/null +++ b/solutions/1825-finding-mk-average.js @@ -0,0 +1,93 @@ +/** + * 1825. Finding MK Average + * https://leetcode.com/problems/finding-mk-average/ + * Difficulty: Hard + * + * You are given two integers, m and k, and a stream of integers. You are tasked to implement a data + * structure that calculates the MKAverage for the stream. + * + * The MKAverage can be calculated using these steps: + * - If the number of the elements in the stream is less than m you should consider the MKAverage to + * be -1. Otherwise, copy the last m elements of the stream to a separate container. + * - Remove the smallest k elements and the largest k elements from the container. + * - Calculate the average value for the rest of the elements rounded down to the nearest integer. + * + * Implement the MKAverage class: + * - MKAverage(int m, int k) Initializes the MKAverage object with an empty stream and the two + * integers m and k. + * - void addElement(int num) Inserts a new element num into the stream. + * - int calculateMKAverage() Calculates and returns the MKAverage for the current stream rounded + * down to the nearest integer. + */ + +/** + * @param {number} m + * @param {number} k + */ +var MKAverage = function(m, k) { + this.m = m; + this.k = k; + this.stream = []; + this.sortedStream = []; + this.sum = 0; +}; + +/** + * @param {number} num + * @return {void} + */ +MKAverage.prototype.addElement = function(num) { + this.stream.push(num); + + const insertIndex = this.findInsertPosition(num); + this.sortedStream.splice(insertIndex, 0, num); + this.sum += num; + + if (this.stream.length > this.m) { + const oldestElement = this.stream.shift(); + const oldestIndex = this.sortedStream.indexOf(oldestElement); + this.sortedStream.splice(oldestIndex, 1); + this.sum -= oldestElement; + } +}; + +/** + * @return {number} + */ +MKAverage.prototype.calculateMKAverage = function() { + if (this.stream.length < this.m) { + return -1; + } + + let adjustedSum = this.sum; + + for (let i = 0; i < this.k; i++) { + adjustedSum -= this.sortedStream[i]; + } + for (let i = this.sortedStream.length - this.k; i < this.sortedStream.length; i++) { + adjustedSum -= this.sortedStream[i]; + } + + return Math.floor(adjustedSum / (this.m - 2 * this.k)); +}; + +/** + * Helper method to find insert position using binary search + * @param {number} num + * @return {number} + */ +MKAverage.prototype.findInsertPosition = function(num) { + let left = 0; + let right = this.sortedStream.length - 1; + + while (left <= right) { + const mid = Math.floor((left + right) / 2); + if (this.sortedStream[mid] < num) { + left = mid + 1; + } else { + right = mid - 1; + } + } + + return left; +}; diff --git a/solutions/1827-minimum-operations-to-make-the-array-increasing.js b/solutions/1827-minimum-operations-to-make-the-array-increasing.js new file mode 100644 index 00000000..5eef57d6 --- /dev/null +++ b/solutions/1827-minimum-operations-to-make-the-array-increasing.js @@ -0,0 +1,35 @@ +/** + * 1827. Minimum Operations to Make the Array Increasing + * https://leetcode.com/problems/minimum-operations-to-make-the-array-increasing/ + * Difficulty: Easy + * + * You are given an integer array nums (0-indexed). In one operation, you can choose an + * element of the array and increment it by 1. + * - For example, if nums = [1,2,3], you can choose to increment nums[1] to make nums = [1,3,3]. + * + * Return the minimum number of operations needed to make nums strictly increasing. + * + * An array nums is strictly increasing if nums[i] < nums[i+1] for all 0 <= i < nums.length - 1. + * An array of length 1 is trivially strictly increasing. + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var minOperations = function(nums) { + let result = 0; + let previousValue = nums[0]; + + for (let i = 1; i < nums.length; i++) { + if (nums[i] <= previousValue) { + const requiredValue = previousValue + 1; + result += requiredValue - nums[i]; + previousValue = requiredValue; + } else { + previousValue = nums[i]; + } + } + + return result; +}; diff --git a/solutions/1828-queries-on-number-of-points-inside-a-circle.js b/solutions/1828-queries-on-number-of-points-inside-a-circle.js new file mode 100644 index 00000000..bfc1e4b8 --- /dev/null +++ b/solutions/1828-queries-on-number-of-points-inside-a-circle.js @@ -0,0 +1,38 @@ +/** + * 1828. Queries on Number of Points Inside a Circle + * https://leetcode.com/problems/queries-on-number-of-points-inside-a-circle/ + * Difficulty: Medium + * + * You are given an array points where points[i] = [xi, yi] is the coordinates of the ith + * point on a 2D plane. Multiple points can have the same coordinates. + * + * You are also given an array queries where queries[j] = [xj, yj, rj] describes a circle + * centered at (xj, yj) with a radius of rj. + * + * For each query queries[j], compute the number of points inside the jth circle. Points on + * the border of the circle are considered inside. + * + * Return an array answer, where answer[j] is the answer to the jth query. + */ + +/** + * @param {number[][]} points + * @param {number[][]} queries + * @return {number[]} + */ +var countPoints = function(points, queries) { + const result = []; + + for (const [centerX, centerY, radius] of queries) { + let pointsInside = 0; + for (const [pointX, pointY] of points) { + const distance = Math.sqrt((centerX - pointX) ** 2 + (centerY - pointY) ** 2); + if (distance <= radius) { + pointsInside++; + } + } + result.push(pointsInside); + } + + return result; +}; diff --git a/solutions/1829-maximum-xor-for-each-query.js b/solutions/1829-maximum-xor-for-each-query.js new file mode 100644 index 00000000..43a867f6 --- /dev/null +++ b/solutions/1829-maximum-xor-for-each-query.js @@ -0,0 +1,36 @@ +/** + * 1829. Maximum XOR for Each Query + * https://leetcode.com/problems/maximum-xor-for-each-query/ + * Difficulty: Medium + * + * You are given a sorted array nums of n non-negative integers and an integer maximumBit. + * You want to perform the following query n times: + * - Find a non-negative integer k < 2maximumBit such that nums[0] XOR nums[1] XOR ... XOR + * nums[nums.length-1] XOR k is maximized. k is the answer to the ith query. + * - Remove the last element from the current array nums. + * + * Return an array answer, where answer[i] is the answer to the ith query. + */ + +/** + * @param {number[]} nums + * @param {number} maximumBit + * @return {number[]} + */ +var getMaximumXor = function(nums, maximumBit) { + const result = []; + let currentXor = 0; + const maxValue = (1 << maximumBit) - 1; + + for (const num of nums) { + currentXor ^= num; + } + + for (let i = nums.length - 1; i >= 0; i--) { + const optimalK = currentXor ^ maxValue; + result.push(optimalK); + currentXor ^= nums[i]; + } + + return result; +}; diff --git a/solutions/1830-minimum-number-of-operations-to-make-string-sorted.js b/solutions/1830-minimum-number-of-operations-to-make-string-sorted.js new file mode 100644 index 00000000..51cbb535 --- /dev/null +++ b/solutions/1830-minimum-number-of-operations-to-make-string-sorted.js @@ -0,0 +1,71 @@ +/** + * 1830. Minimum Number of Operations to Make String Sorted + * https://leetcode.com/problems/minimum-number-of-operations-to-make-string-sorted/ + * Difficulty: Hard + * + * You are given a string s (0-indexed). You are asked to perform the following operation on + * s until you get a sorted string: + * 1. Find the largest index i such that 1 <= i < s.length and s[i] < s[i - 1]. + * 2. Find the largest index j such that i <= j < s.length and s[k] < s[i - 1] for all the + * possible values of k in the range [i, j] inclusive. + * 3. Swap the two characters at indices i - 1 and j. + * 4. Reverse the suffix starting at index i. + * + * Return the number of operations needed to make the string sorted. Since the answer can be too + * large, return it modulo 109 + 7. + */ + +/** + * @param {string} s + * @return {number} + */ +var makeStringSorted = function(s) { + const MOD = 1e9 + 7; + const length = s.length; + const factorials = new Array(length + 1).fill(1n); + const inverses = new Array(length + 1).fill(1n); + + for (let i = 2; i <= length; i++) { + factorials[i] = (factorials[i - 1] * BigInt(i)) % BigInt(MOD); + } + + for (let i = 1; i <= length; i++) { + inverses[i] = modInverse(factorials[i], BigInt(MOD)); + } + + let result = 0n; + const charCounts = new Array(26).fill(0); + for (let i = length - 1; i >= 0; i--) { + const charIndex = s.charCodeAt(i) - 97; + charCounts[charIndex]++; + let smallerChars = 0; + for (let j = 0; j < charIndex; j++) { + smallerChars += charCounts[j]; + } + let totalPermutations = factorials[length - i - 1]; + for (const count of charCounts) { + totalPermutations = (totalPermutations * inverses[count]) % BigInt(MOD); + } + result = (result + BigInt(smallerChars) * totalPermutations) % BigInt(MOD); + } + + return Number(result); + + function modInverse(a, m) { + const m0 = m; + let q; + let x0 = 0n; + let x1 = 1n; + while (a > 1n) { + q = a / m; + [a, m] = [m, a % m]; + [x0, x1] = [x1 - q * x0, x0]; + } + return x1 < 0n ? x1 + m0 : x1; + } + + function combinations(n, k) { + if (k < 0 || k > n) return 0n; + return (factorials[n] * inverses[k] % BigInt(MOD)) * inverses[n - k] % BigInt(MOD); + } +}; diff --git a/solutions/1834-single-threaded-cpu.js b/solutions/1834-single-threaded-cpu.js new file mode 100644 index 00000000..e07dd7dc --- /dev/null +++ b/solutions/1834-single-threaded-cpu.js @@ -0,0 +1,51 @@ +/** + * 1834. Single-Threaded CPU + * https://leetcode.com/problems/single-threaded-cpu/ + * Difficulty: Medium + * + * You are given n tasks labeled from 0 to n - 1 represented by a 2D integer array tasks, + * where tasks[i] = [enqueueTimei, processingTimei] means that the ith task will be available + * to process at enqueueTimei and will take processingTimei to finish processing. + * + * You have a single-threaded CPU that can process at most one task at a time and will act in + * the following way: + * - If the CPU is idle and there are no available tasks to process, the CPU remains idle. + * - If the CPU is idle and there are available tasks, the CPU will choose the one with the shortest + * processing time. If multiple tasks have the same shortest processing time, it will choose the + * task with the smallest index. + * - Once a task is started, the CPU will process the entire task without stopping. + * - The CPU can finish a task then start a new one instantly. + * + * Return the order in which the CPU will process the tasks. + */ + +/** + * @param {number[][]} tasks + * @return {number[]} + */ +var getOrder = function(tasks) { + const indexedTasks = tasks.map(([enqueue, process], index) => ({ enqueue, process, index })) + .sort((a, b) => a.enqueue - b.enqueue); + + const result = []; + const availableTasks = new PriorityQueue((a, b) => a.process - b.process || a.index - b.index); + let currentTime = indexedTasks[0].enqueue; + let taskIndex = 0; + + while (result.length < tasks.length) { + while (taskIndex < tasks.length && indexedTasks[taskIndex].enqueue <= currentTime) { + availableTasks.push(indexedTasks[taskIndex]); + taskIndex++; + } + + if (availableTasks.size() > 0) { + const task = availableTasks.pop(); + result.push(task.index); + currentTime += task.process; + } else { + currentTime = indexedTasks[taskIndex].enqueue; + } + } + + return result; +}; diff --git a/solutions/1835-find-xor-sum-of-all-pairs-bitwise-and.js b/solutions/1835-find-xor-sum-of-all-pairs-bitwise-and.js new file mode 100644 index 00000000..f57b405d --- /dev/null +++ b/solutions/1835-find-xor-sum-of-all-pairs-bitwise-and.js @@ -0,0 +1,37 @@ +/** + * 1835. Find XOR Sum of All Pairs Bitwise AND + * https://leetcode.com/problems/find-xor-sum-of-all-pairs-bitwise-and/ + * Difficulty: Hard + * + * The XOR sum of a list is the bitwise XOR of all its elements. If the list only contains one + * element, then its XOR sum will be equal to this element. + * - For example, the XOR sum of [1,2,3,4] is equal to 1 XOR 2 XOR 3 XOR 4 = 4, and the XOR + * sum of [3] is equal to 3. + * + * You are given two 0-indexed arrays arr1 and arr2 that consist only of non-negative integers. + * + * Consider the list containing the result of arr1[i] AND arr2[j] (bitwise AND) for every (i, j) + * pair where 0 <= i < arr1.length and 0 <= j < arr2.length. + * + * Return the XOR sum of the aforementioned list. + */ + +/** + * @param {number[]} arr1 + * @param {number[]} arr2 + * @return {number} + */ +var getXORSum = function(arr1, arr2) { + let xor1 = 0; + let xor2 = 0; + + for (const num of arr1) { + xor1 ^= num; + } + + for (const num of arr2) { + xor2 ^= num; + } + + return xor1 & xor2; +}; diff --git a/solutions/1837-sum-of-digits-in-base-k.js b/solutions/1837-sum-of-digits-in-base-k.js new file mode 100644 index 00000000..48223a4d --- /dev/null +++ b/solutions/1837-sum-of-digits-in-base-k.js @@ -0,0 +1,27 @@ +/** + * 1837. Sum of Digits in Base K + * https://leetcode.com/problems/sum-of-digits-in-base-k/ + * Difficulty: Easy + * + * Given an integer n (in base 10) and a base k, return the sum of the digits of n after + * converting n from base 10 to base k. + * + * After converting, each digit should be interpreted as a base 10 number, and the sum should + * be returned in base 10. + */ + +/** + * @param {number} n + * @param {number} k + * @return {number} + */ +var sumBase = function(n, k) { + let digitSum = 0; + + while (n > 0) { + digitSum += n % k; + n = Math.floor(n / k); + } + + return digitSum; +}; diff --git a/solutions/1838-frequency-of-the-most-frequent-element.js b/solutions/1838-frequency-of-the-most-frequent-element.js new file mode 100644 index 00000000..d13b8eb2 --- /dev/null +++ b/solutions/1838-frequency-of-the-most-frequent-element.js @@ -0,0 +1,36 @@ +/** + * 1838. Frequency of the Most Frequent Element + * https://leetcode.com/problems/frequency-of-the-most-frequent-element/ + * Difficulty: Medium + * + * The frequency of an element is the number of times it occurs in an array. + * + * You are given an integer array nums and an integer k. In one operation, you can choose + * an index of nums and increment the element at that index by 1. + * + * Return the maximum possible frequency of an element after performing at most k operations. + */ + +/** + * @param {number[]} nums + * @param {number} k + * @return {number} + */ +var maxFrequency = function(nums, k) { + nums.sort((a, b) => a - b); + + let result = 0; + let currentSum = 0; + let left = 0; + + for (let right = 0; right < nums.length; right++) { + currentSum += nums[right]; + while (currentSum + k < nums[right] * (right - left + 1)) { + currentSum -= nums[left]; + left++; + } + result = Math.max(result, right - left + 1); + } + + return result; +}; diff --git a/solutions/1839-longest-substring-of-all-vowels-in-order.js b/solutions/1839-longest-substring-of-all-vowels-in-order.js new file mode 100644 index 00000000..343f0279 --- /dev/null +++ b/solutions/1839-longest-substring-of-all-vowels-in-order.js @@ -0,0 +1,43 @@ +/** + * 1839. Longest Substring Of All Vowels in Order + * https://leetcode.com/problems/longest-substring-of-all-vowels-in-order/ + * Difficulty: Medium + * + * A string is considered beautiful if it satisfies the following conditions: + * - Each of the 5 English vowels ('a', 'e', 'i', 'o', 'u') must appear at least once in it. + * - The letters must be sorted in alphabetical order (i.e. all 'a's before 'e's, all 'e's + * before 'i's, etc.). + * + * For example, strings "aeiou" and "aaaaaaeiiiioou" are considered beautiful, but "uaeio", "aeoiu", + * and "aaaeeeooo" are not beautiful. + * + * Given a string word consisting of English vowels, return the length of the longest beautiful + * substring of word. If no such substring exists, return 0. + * + * A substring is a contiguous sequence of characters in a string. + */ + +/** + * @param {string} word + * @return {number} + */ +var longestBeautifulSubstring = function(word) { + let result = 0; + let start = 0; + let vowelCount = 1; + + for (let i = 1; i < word.length; i++) { + if (word[i] < word[i - 1]) { + start = i; + vowelCount = 1; + } else if (word[i] > word[i - 1]) { + vowelCount++; + } + + if (vowelCount === 5) { + result = Math.max(result, i - start + 1); + } + } + + return result; +}; diff --git a/solutions/1840-maximum-building-height.js b/solutions/1840-maximum-building-height.js new file mode 100644 index 00000000..d77cdd46 --- /dev/null +++ b/solutions/1840-maximum-building-height.js @@ -0,0 +1,60 @@ +/** + * 1840. Maximum Building Height + * https://leetcode.com/problems/maximum-building-height/ + * Difficulty: Hard + * + * You want to build n new buildings in a city. The new buildings will be built in a line + * and are labeled from 1 to n. + * + * However, there are city restrictions on the heights of the new buildings: + * - The height of each building must be a non-negative integer. + * - The height of the first building must be 0. + * - The height difference between any two adjacent buildings cannot exceed 1. + * + * Additionally, there are city restrictions on the maximum height of specific buildings. + * These restrictions are given as a 2D integer array restrictions where + * restrictions[i] = [idi, maxHeighti] indicates that building idi must have a height + * less than or equal to maxHeighti. + * + * It is guaranteed that each building will appear at most once in restrictions, and building + * 1 will not be in restrictions. + * + * Return the maximum possible height of the tallest building. + */ + +/** + * @param {number} n + * @param {number[][]} restrictions + * @return {number} + */ +var maxBuilding = function(n, restrictions) { + restrictions.push([1, 0], [n, n - 1]); + restrictions.sort((a, b) => a[0] - b[0]); + + const length = restrictions.length; + + for (let i = 1; i < length; i++) { + const [currId, currHeight] = restrictions[i]; + const [prevId, prevHeight] = restrictions[i - 1]; + restrictions[i][1] = Math.min(currHeight, prevHeight + (currId - prevId)); + } + + for (let i = length - 2; i >= 0; i--) { + const [currId, currHeight] = restrictions[i]; + const [nextId, nextHeight] = restrictions[i + 1]; + restrictions[i][1] = Math.min(currHeight, nextHeight + (nextId - currId)); + } + + let maxHeight = 0; + + for (let i = 1; i < length; i++) { + const [leftId, leftHeight] = restrictions[i - 1]; + const [rightId, rightHeight] = restrictions[i]; + const distance = rightId - leftId; + const heightDiff = Math.abs(rightHeight - leftHeight); + const peakHeight = Math.max(leftHeight, rightHeight) + Math.floor((distance - heightDiff) / 2); + maxHeight = Math.max(maxHeight, peakHeight); + } + + return maxHeight; +}; diff --git a/solutions/1844-replace-all-digits-with-characters.js b/solutions/1844-replace-all-digits-with-characters.js new file mode 100644 index 00000000..c5efb48c --- /dev/null +++ b/solutions/1844-replace-all-digits-with-characters.js @@ -0,0 +1,39 @@ +/** + * 1844. Replace All Digits with Characters + * https://leetcode.com/problems/replace-all-digits-with-characters/ + * Difficulty: Easy + * + * You are given a 0-indexed string s that has lowercase English letters in its even indices and + * digits in its odd indices. + * + * You must perform an operation shift(c, x), where c is a character and x is a digit, that returns + * the xth character after c. + * - For example, shift('a', 5) = 'f' and shift('x', 0) = 'x'. + * + * For every odd index i, you want to replace the digit s[i] with the result of the + * shift(s[i-1], s[i]) operation. + * + * Return s after replacing all digits. It is guaranteed that shift(s[i-1], s[i]) will never + * exceed 'z'. + * + * Note that shift(c, x) is not a preloaded function, but an operation to be implemented as part + * of the solution. + */ + +/** + * @param {string} s + * @return {string} + */ +var replaceDigits = function(s) { + const result = s.split(''); + + for (let i = 1; i < s.length; i += 2) { + result[i] = shiftChar(s[i - 1], s[i]); + } + + return result.join(''); + + function shiftChar(char, shift) { + return String.fromCharCode(char.charCodeAt(0) + parseInt(shift)); + } +}; diff --git a/solutions/1845-seat-reservation-manager.js b/solutions/1845-seat-reservation-manager.js new file mode 100644 index 00000000..53bc7edd --- /dev/null +++ b/solutions/1845-seat-reservation-manager.js @@ -0,0 +1,44 @@ +/** + * 1845. Seat Reservation Manager + * https://leetcode.com/problems/seat-reservation-manager/ + * Difficulty: Medium + * + * Design a system that manages the reservation state of n seats that are numbered from 1 to n. + * + * Implement the SeatManager class: + * - SeatManager(int n) Initializes a SeatManager object that will manage n seats numbered from + * 1 to n. All seats are initially available. + * - int reserve() Fetches the smallest-numbered unreserved seat, reserves it, and returns its + * number. + * - void unreserve(int seatNumber) Unreserves the seat with the given seatNumber. + */ + +/** + * @param {number} n + */ +var SeatManager = function(n) { + this.nextAvailable = 1; + this.unreservedSeats = new Set(); +}; + +/** + * @return {number} + */ +SeatManager.prototype.reserve = function() { + if (this.unreservedSeats.size > 0) { + const minSeat = Math.min(...this.unreservedSeats); + if (minSeat < this.nextAvailable) { + this.unreservedSeats.delete(minSeat); + return minSeat; + } + } + return this.nextAvailable++; +}; + +/** + * @param {number} seatNumber + * @return {void} + */ +SeatManager.prototype.unreserve = function(seatNumber) { + this.unreservedSeats.add(seatNumber); +}; diff --git a/solutions/1846-maximum-element-after-decreasing-and-rearranging.js b/solutions/1846-maximum-element-after-decreasing-and-rearranging.js new file mode 100644 index 00000000..266a8dc1 --- /dev/null +++ b/solutions/1846-maximum-element-after-decreasing-and-rearranging.js @@ -0,0 +1,36 @@ +/** + * 1846. Maximum Element After Decreasing and Rearranging + * https://leetcode.com/problems/maximum-element-after-decreasing-and-rearranging/ + * Difficulty: Medium + * + * You are given an array of positive integers arr. Perform some operations (possibly none) on + * arr so that it satisfies these conditions: + * - The value of the first element in arr must be 1. + * - The absolute difference between any 2 adjacent elements must be less than or equal to 1. + * In other words, abs(arr[i] - arr[i - 1]) <= 1 for each i where 1 <= i < arr.length + * (0-indexed). abs(x) is the absolute value of x. + * + * There are 2 types of operations that you can perform any number of times: + * - Decrease the value of any element of arr to a smaller positive integer. + * - Rearrange the elements of arr to be in any order. + * + * Return the maximum possible value of an element in arr after performing the operations to + * satisfy the conditions. + */ + +/** + * @param {number[]} arr + * @return {number} + */ +var maximumElementAfterDecrementingAndRearranging = function(arr) { + arr.sort((a, b) => a - b); + let maxPossible = 1; + + for (let i = 1; i < arr.length; i++) { + if (arr[i] > maxPossible) { + maxPossible++; + } + } + + return maxPossible; +}; diff --git a/solutions/1847-closest-room.js b/solutions/1847-closest-room.js new file mode 100644 index 00000000..49963145 --- /dev/null +++ b/solutions/1847-closest-room.js @@ -0,0 +1,83 @@ +/** + * 1847. Closest Room + * https://leetcode.com/problems/closest-room/ + * Difficulty: Hard + * + * There is a hotel with n rooms. The rooms are represented by a 2D integer array rooms where + * rooms[i] = [roomIdi, sizei] denotes that there is a room with room number roomIdi and size + * equal to sizei. Each roomIdi is guaranteed to be unique. + * + * You are also given k queries in a 2D array queries where queries[j] = [preferredj, minSizej]. + * The answer to the jth query is the room number id of a room such that: + * - The room has a size of at least minSizej, and + * - abs(id - preferredj) is minimized, where abs(x) is the absolute value of x. + * + * If there is a tie in the absolute difference, then use the room with the smallest such id. + * If there is no such room, the answer is -1. + * + * Return an array answer of length k where answer[j] contains the answer to the jth query. + */ + +/** + * @param {number[][]} rooms + * @param {number[][]} queries + * @return {number[]} + */ +var closestRoom = function(rooms, queries) { + rooms.sort((a, b) => b[1] - a[1]); + const sortedQueries = queries + .map((q, i) => [q[0], q[1], i]) + .sort((a, b) => b[1] - a[1]); + + const result = new Array(queries.length).fill(-1); + const roomIds = []; + let roomIndex = 0; + + for (const [preferred, minSize, queryIndex] of sortedQueries) { + while (roomIndex < rooms.length && rooms[roomIndex][1] >= minSize) { + insertSorted(rooms[roomIndex][0]); + roomIndex++; + } + + result[queryIndex] = findClosestId(preferred); + } + + return result; + + function insertSorted(id) { + let left = 0; + let right = roomIds.length; + while (left < right) { + const mid = Math.floor((left + right) / 2); + if (roomIds[mid] < id) left = mid + 1; + else right = mid; + } + roomIds.splice(left, 0, id); + } + + function findClosestId(target) { + if (!roomIds.length) return -1; + + let left = 0; + let right = roomIds.length - 1; + let closest = roomIds[0]; + let minDiff = Math.abs(closest - target); + + while (left <= right) { + const mid = Math.floor((left + right) / 2); + const id = roomIds[mid]; + const diff = Math.abs(id - target); + + if (diff < minDiff || (diff === minDiff && id < closest)) { + minDiff = diff; + closest = id; + } + + if (id < target) left = mid + 1; + else if (id > target) right = mid - 1; + else break; + } + + return closest; + } +}; diff --git a/solutions/1848-minimum-distance-to-the-target-element.js b/solutions/1848-minimum-distance-to-the-target-element.js new file mode 100644 index 00000000..567427d2 --- /dev/null +++ b/solutions/1848-minimum-distance-to-the-target-element.js @@ -0,0 +1,32 @@ +/** + * 1848. Minimum Distance to the Target Element + * https://leetcode.com/problems/minimum-distance-to-the-target-element/ + * Difficulty: Easy + * + * Given an integer array nums (0-indexed) and two integers target and start, find an index i + * such that nums[i] == target and abs(i - start) is minimized. Note that abs(x) is the absolute + * value of x. + * + * Return abs(i - start). + * + * It is guaranteed that target exists in nums. + */ + +/** + * @param {number[]} nums + * @param {number} target + * @param {number} start + * @return {number} + */ +var getMinDistance = function(nums, target, start) { + let result = Infinity; + + for (let i = 0; i < nums.length; i++) { + if (nums[i] === target) { + const distance = Math.abs(i - start); + result = Math.min(result, distance); + } + } + + return result; +}; diff --git a/solutions/1849-splitting-a-string-into-descending-consecutive-values.js b/solutions/1849-splitting-a-string-into-descending-consecutive-values.js new file mode 100644 index 00000000..d993db28 --- /dev/null +++ b/solutions/1849-splitting-a-string-into-descending-consecutive-values.js @@ -0,0 +1,50 @@ +/** + * 1849. Splitting a String Into Descending Consecutive Values + * https://leetcode.com/problems/splitting-a-string-into-descending-consecutive-values/ + * Difficulty: Medium + * + * You are given a string s that consists of only digits. + * + * Check if we can split s into two or more non-empty substrings such that the numerical values of + * the substrings are in descending order and the difference between numerical values of every two + * adjacent substrings is equal to 1. + * - For example, the string s = "0090089" can be split into ["0090", "089"] with numerical values + * [90,89]. The values are in descending order and adjacent values differ by 1, so this way is + * valid. + * - Another example, the string s = "001" can be split into ["0", "01"], ["00", "1"], or + * ["0", "0", "1"]. However all the ways are invalid because they have numerical values + * [0,1], [0,1], and [0,0,1] respectively, all of which are not in descending order. + * + * Return true if it is possible to split s as described above, or false otherwise. + * + * A substring is a contiguous sequence of characters in a string. + */ + +/** + * @param {string} s + * @return {boolean} + */ +var splitString = function(s) { + let firstValue = 0; + for (let i = 0; i < s.length - 1; i++) { + firstValue = firstValue * 10 + parseInt(s[i]); + if (trySplit(i + 1, firstValue)) return true; + } + + return false; + + function trySplit(index, prevValue) { + if (index === s.length) return true; + + let currentValue = 0; + for (let i = index; i < s.length; i++) { + currentValue = currentValue * 10 + parseInt(s[i]); + if (currentValue >= prevValue) break; + if (prevValue - currentValue === 1 && trySplit(i + 1, currentValue)) { + return true; + } + } + + return false; + } +}; diff --git a/solutions/1850-minimum-adjacent-swaps-to-reach-the-kth-smallest-number.js b/solutions/1850-minimum-adjacent-swaps-to-reach-the-kth-smallest-number.js new file mode 100644 index 00000000..d4853138 --- /dev/null +++ b/solutions/1850-minimum-adjacent-swaps-to-reach-the-kth-smallest-number.js @@ -0,0 +1,70 @@ +/** + * 1850. Minimum Adjacent Swaps to Reach the Kth Smallest Number + * https://leetcode.com/problems/minimum-adjacent-swaps-to-reach-the-kth-smallest-number/ + * Difficulty: Medium + * + * You are given a string num, representing a large integer, and an integer k. + * + * We call some integer wonderful if it is a permutation of the digits in num and is greater in + * value than num. There can be many wonderful integers. However, we only care about the + * smallest-valued ones. + * - For example, when num = "5489355142": + * - The 1st smallest wonderful integer is "5489355214". + * - The 2nd smallest wonderful integer is "5489355241". + * - The 3rd smallest wonderful integer is "5489355412". + * - The 4th smallest wonderful integer is "5489355421". + * + * Return the minimum number of adjacent digit swaps that needs to be applied to num to reach + * the kth smallest wonderful integer. + * + * The tests are generated in such a way that kth smallest wonderful integer exists. + */ + +/** + * @param {string} num + * @param {number} k + * @return {number} + */ +var getMinSwaps = function(num, k) { + const original = num.split(''); + const target = num.split(''); + + for (let i = 0; i < k; i++) { + nextPermutation(target); + } + + let result = 0; + for (let i = 0; i < original.length; i++) { + if (original[i] !== target[i]) { + let j = i + 1; + while (j < original.length && original[j] !== target[i]) j++; + while (j > i) { + [original[j], original[j - 1]] = [original[j - 1], original[j]]; + result++; + j--; + } + } + } + + return result; + + function nextPermutation(arr) { + let i = arr.length - 2; + while (i >= 0 && arr[i] >= arr[i + 1]) i--; + if (i < 0) return false; + + let j = arr.length - 1; + while (arr[j] <= arr[i]) j--; + + [arr[i], arr[j]] = [arr[j], arr[i]]; + + let left = i + 1; + let right = arr.length - 1; + while (left < right) { + [arr[left], arr[right]] = [arr[right], arr[left]]; + left++; + right--; + } + return true; + } +}; diff --git a/solutions/1851-minimum-interval-to-include-each-query.js b/solutions/1851-minimum-interval-to-include-each-query.js new file mode 100644 index 00000000..a81d82ea --- /dev/null +++ b/solutions/1851-minimum-interval-to-include-each-query.js @@ -0,0 +1,49 @@ +/** + * 1851. Minimum Interval to Include Each Query + * https://leetcode.com/problems/minimum-interval-to-include-each-query/ + * Difficulty: Hard + * + * You are given a 2D integer array intervals, where intervals[i] = [lefti, righti] describes + * the ith interval starting at lefti and ending at righti (inclusive). The size of an interval + * is defined as the number of integers it contains, or more formally righti - lefti + 1. + * + * You are also given an integer array queries. The answer to the jth query is the size of the + * smallest interval i such that lefti <= queries[j] <= righti. If no such interval exists, + * the answer is -1. + * + * Return an array containing the answers to the queries. + */ + +/** + * @param {number[][]} intervals + * @param {number[]} queries + * @return {number[]} + */ +var minInterval = function(intervals, queries) { + intervals.sort((a, b) => a[0] - b[0]); + const sortedQueries = queries + .map((q, i) => [q, i]) + .sort((a, b) => a[0] - b[0]); + + const activeIntervals = new PriorityQueue((a, b) => a[0] - b[0]); + const result = new Array(queries.length).fill(-1); + let intervalIndex = 0; + + for (const [queryValue, queryIndex] of sortedQueries) { + while (intervalIndex < intervals.length && intervals[intervalIndex][0] <= queryValue) { + const [start, end] = intervals[intervalIndex]; + activeIntervals.enqueue([end - start + 1, end]); + intervalIndex++; + } + + while (!activeIntervals.isEmpty() && activeIntervals.front()?.[1] < queryValue) { + activeIntervals.dequeue(); + } + + if (!activeIntervals.isEmpty()) { + result[queryIndex] = activeIntervals.front()[0]; + } + } + + return result; +}; diff --git a/solutions/1854-maximum-population-year.js b/solutions/1854-maximum-population-year.js new file mode 100644 index 00000000..9ea9aec0 --- /dev/null +++ b/solutions/1854-maximum-population-year.js @@ -0,0 +1,42 @@ +/** + * 1854. Maximum Population Year + * https://leetcode.com/problems/maximum-population-year/ + * Difficulty: Easy + * + * You are given a 2D integer array logs where each logs[i] = [birthi, deathi] indicates the + * birth and death years of the ith person. + * + * The population of some year x is the number of people alive during that year. The ith person + * is counted in year x's population if x is in the inclusive range [birthi, deathi - 1]. Note + * that the person is not counted in the year that they die. + * + * Return the earliest year with the maximum population. + */ + +/** + * @param {number[][]} logs + * @return {number} + */ +var maximumPopulation = function(logs) { + const populationChanges = new Array(101).fill(0); + const baseYear = 1950; + + for (const [birth, death] of logs) { + populationChanges[birth - baseYear]++; + populationChanges[death - baseYear]--; + } + + let maxPopulation = 0; + let currentPopulation = 0; + let result = baseYear; + + for (let i = 0; i < populationChanges.length; i++) { + currentPopulation += populationChanges[i]; + if (currentPopulation > maxPopulation) { + maxPopulation = currentPopulation; + result = baseYear + i; + } + } + + return result; +}; diff --git a/solutions/1855-maximum-distance-between-a-pair-of-values.js b/solutions/1855-maximum-distance-between-a-pair-of-values.js new file mode 100644 index 00000000..d94af4d5 --- /dev/null +++ b/solutions/1855-maximum-distance-between-a-pair-of-values.js @@ -0,0 +1,35 @@ +/** + * 1855. Maximum Distance Between a Pair of Values + * https://leetcode.com/problems/maximum-distance-between-a-pair-of-values/ + * Difficulty: Medium + * + * You are given two non-increasing 0-indexed integer arrays nums2 and nums2. + * + * A pair of indices (i, j), where 0 <= i < nums1.length and 0 <= j < nums2.length, + * is valid if both i <= j and nums1[i] <= nums2[j]. The distance of the pair is j - i. + * + * Return the maximum distance of any valid pair (i, j). If there are no valid pairs, return 0. + * + * An array arr is non-increasing if arr[i-1] >= arr[i] for every 1 <= i < arr.length. + */ + +/** + * @param {number[]} nums1 + * @param {number[]} nums2 + * @return {number} + */ +var maxDistance = function(nums1, nums2) { + let result = 0; + let left = 0; + + for (let right = 0; right < nums2.length; right++) { + while (left < nums1.length && nums1[left] > nums2[right]) { + left++; + } + if (left <= right && left < nums1.length) { + result = Math.max(result, right - left); + } + } + + return result; +}; diff --git a/solutions/1856-maximum-subarray-min-product.js b/solutions/1856-maximum-subarray-min-product.js new file mode 100644 index 00000000..02a5f6bc --- /dev/null +++ b/solutions/1856-maximum-subarray-min-product.js @@ -0,0 +1,47 @@ +/** + * 1856. Maximum Subarray Min-Product + * https://leetcode.com/problems/maximum-subarray-min-product/ + * Difficulty: Medium + * + * The min-product of an array is equal to the minimum value in the array multiplied by + * the array's sum. + * - For example, the array [3,2,5] (minimum value is 2) has a min-product of + * 2 * (3+2+5) = 2 * 10 = 20. + * + * Given an array of integers nums, return the maximum min-product of any non-empty + * subarray of nums. Since the answer may be large, return it modulo 109 + 7. + * + * Note that the min-product should be maximized before performing the modulo operation. + * Testcases are generated such that the maximum min-product without modulo will fit in + * a 64-bit signed integer. + * + * A subarray is a contiguous part of an array. + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var maxSumMinProduct = function(nums) { + const modulo = 1000000007n; + const stack = []; + const prefixSums = [0n]; + let maxMinProduct = 0n; + + for (let i = 0; i < nums.length; i++) { + prefixSums.push(prefixSums[i] + BigInt(nums[i])); + } + + for (let right = 0; right <= nums.length; right++) { + const current = right < nums.length ? BigInt(nums[right]) : 0n; + while (stack.length && stack[stack.length - 1].value > current) { + const { index, value } = stack.pop(); + const left = stack.length ? stack[stack.length - 1].index + 1 : 0; + const subarraySum = prefixSums[right] - prefixSums[left]; + maxMinProduct = maxMinProduct > value * subarraySum ? maxMinProduct : value * subarraySum; + } + stack.push({ index: right, value: current }); + } + + return Number(maxMinProduct % modulo); +}; diff --git a/solutions/1857-largest-color-value-in-a-directed-graph.js b/solutions/1857-largest-color-value-in-a-directed-graph.js new file mode 100644 index 00000000..c592996b --- /dev/null +++ b/solutions/1857-largest-color-value-in-a-directed-graph.js @@ -0,0 +1,60 @@ +/** + * 1857. Largest Color Value in a Directed Graph + * https://leetcode.com/problems/largest-color-value-in-a-directed-graph/ + * Difficulty: Hard + * + * There is a directed graph of n colored nodes and m edges. The nodes are numbered from 0 to n - 1. + * + * You are given a string colors where colors[i] is a lowercase English letter representing the + * color of the ith node in this graph (0-indexed). You are also given a 2D array edges where + * edges[j] = [aj, bj] indicates that there is a directed edge from node aj to node bj. + * + * A valid path in the graph is a sequence of nodes x1 -> x2 -> x3 -> ... -> xk such that there + * is a directed edge from xi to xi+1 for every 1 <= i < k. The color value of the path is the + * number of nodes that are colored the most frequently occurring color along that path. + * + * Return the largest color value of any valid path in the given graph, or -1 if the graph + * contains a cycle. + */ + +/** + * @param {string} colors + * @param {number[][]} edges + * @return {number} + */ +var largestPathValue = function(colors, edges) { + const nodeCount = colors.length; + const adjacencyList = Array.from({ length: nodeCount }, () => []); + const inDegree = new Array(nodeCount).fill(0); + const colorCounts = Array.from({ length: nodeCount }, () => new Array(26).fill(0)); + const queue = []; + let maxColorValue = 0; + let processedNodes = 0; + + for (const [from, to] of edges) { + adjacencyList[from].push(to); + inDegree[to]++; + } + + for (let i = 0; i < nodeCount; i++) { + if (inDegree[i] === 0) queue.push(i); + } + + while (queue.length) { + const current = queue.shift(); + processedNodes++; + const colorIndex = colors.charCodeAt(current) - 97; + colorCounts[current][colorIndex]++; + + for (const next of adjacencyList[current]) { + for (let i = 0; i < 26; i++) { + colorCounts[next][i] = Math.max(colorCounts[next][i], colorCounts[current][i]); + } + if (--inDegree[next] === 0) queue.push(next); + } + + maxColorValue = Math.max(maxColorValue, ...colorCounts[current]); + } + + return processedNodes === nodeCount ? maxColorValue : -1; +}; diff --git a/solutions/1859-sorting-the-sentence.js b/solutions/1859-sorting-the-sentence.js new file mode 100644 index 00000000..d2d9c81f --- /dev/null +++ b/solutions/1859-sorting-the-sentence.js @@ -0,0 +1,32 @@ +/** + * 1859. Sorting the Sentence + * https://leetcode.com/problems/sorting-the-sentence/ + * Difficulty: Easy + * + * A sentence is a list of words that are separated by a single space with no leading or trailing + * spaces. Each word consists of lowercase and uppercase English letters. + * + * A sentence can be shuffled by appending the 1-indexed word position to each word then rearranging + * the words in the sentence. + * - For example, the sentence "This is a sentence" can be shuffled as "sentence4 a3 is2 This1" or + * "is2 sentence4 This1 a3". + * + * Given a shuffled sentence s containing no more than 9 words, reconstruct and return the original + * sentence. + */ + +/** + * @param {string} s + * @return {string} + */ +var sortSentence = function(s) { + const words = s.split(' '); + const sortedWords = new Array(words.length); + + for (const word of words) { + const position = parseInt(word.slice(-1)) - 1; + sortedWords[position] = word.slice(0, -1); + } + + return sortedWords.join(' '); +}; diff --git a/solutions/1860-incremental-memory-leak.js b/solutions/1860-incremental-memory-leak.js new file mode 100644 index 00000000..fd72b849 --- /dev/null +++ b/solutions/1860-incremental-memory-leak.js @@ -0,0 +1,41 @@ +/** + * 1860. Incremental Memory Leak + * https://leetcode.com/problems/incremental-memory-leak/ + * Difficulty: Medium + * + * You are given two integers memory1 and memory2 representing the available memory in bits on + * two memory sticks. There is currently a faulty program running that consumes an increasing + * amount of memory every second. + * + * At the ith second (starting from 1), i bits of memory are allocated to the stick with more + * available memory (or from the first memory stick if both have the same available memory). + * If neither stick has at least i bits of available memory, the program crashes. + * + * Return an array containing [crashTime, memory1crash, memory2crash], where crashTime is the + * time (in seconds) when the program crashed and memory1crash and memory2crash are the + * available bits of memory in the first and second sticks respectively. + */ + +/** + * @param {number} memory1 + * @param {number} memory2 + * @return {number[]} + */ +var memLeak = function(memory1, memory2) { + let time = 1; + let stick1 = memory1; + let stick2 = memory2; + + while (time <= stick1 || time <= stick2) { + if (stick1 >= stick2) { + if (stick1 < time) break; + stick1 -= time; + } else { + if (stick2 < time) break; + stick2 -= time; + } + time++; + } + + return [time, stick1, stick2]; +}; diff --git a/solutions/1861-rotating-the-box.js b/solutions/1861-rotating-the-box.js new file mode 100644 index 00000000..0b874c74 --- /dev/null +++ b/solutions/1861-rotating-the-box.js @@ -0,0 +1,46 @@ +/** + * 1861. Rotating the Box + * https://leetcode.com/problems/rotating-the-box/ + * Difficulty: Medium + * + * You are given an m x n matrix of characters boxGrid representing a side-view of a box. + * Each cell of the box is one of the following: + * - A stone '#' + * - A stationary obstacle '*' + * - Empty '.' + * + * The box is rotated 90 degrees clockwise, causing some of the stones to fall due to gravity. + * Each stone falls down until it lands on an obstacle, another stone, or the bottom of the box. + * Gravity does not affect the obstacles' positions, and the inertia from the box's rotation + * does not affect the stones' horizontal positions. + * + * It is guaranteed that each stone in boxGrid rests on an obstacle, another stone, or the + * bottom of the box. + * + * Return an n x m matrix representing the box after the rotation described above. + */ + +/** + * @param {character[][]} boxGrid + * @return {character[][]} + */ +var rotateTheBox = function(boxGrid) { + const rows = boxGrid.length; + const cols = boxGrid[0].length; + const result = Array.from({ length: cols }, () => new Array(rows).fill('.')); + + for (let row = 0; row < rows; row++) { + let freePosition = cols - 1; + for (let col = cols - 1; col >= 0; col--) { + if (boxGrid[row][col] === '*') { + result[col][rows - 1 - row] = '*'; + freePosition = col - 1; + } else if (boxGrid[row][col] === '#') { + result[freePosition][rows - 1 - row] = '#'; + freePosition--; + } + } + } + + return result; +}; diff --git a/solutions/1862-sum-of-floored-pairs.js b/solutions/1862-sum-of-floored-pairs.js new file mode 100644 index 00000000..4d470c3c --- /dev/null +++ b/solutions/1862-sum-of-floored-pairs.js @@ -0,0 +1,44 @@ +/** + * 1862. Sum of Floored Pairs + * https://leetcode.com/problems/sum-of-floored-pairs/ + * Difficulty: Hard + * + * Given an integer array nums, return the sum of floor(nums[i] / nums[j]) for all pairs of + * indices 0 <= i, j < nums.length in the array. Since the answer may be too large, return + * it modulo 109 + 7. + * + * The floor() function returns the integer part of the division. + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var sumOfFlooredPairs = function(nums) { + const modulo = 1e9 + 7; + const maxValue = Math.max(...nums); + const frequency = new Array(maxValue + 1).fill(0); + const prefixSum = new Array(maxValue + 1).fill(0); + let result = 0; + + for (const num of nums) { + frequency[num]++; + } + + for (let i = 1; i <= maxValue; i++) { + prefixSum[i] = prefixSum[i - 1] + frequency[i]; + } + + for (let i = 1; i <= maxValue; i++) { + if (frequency[i] === 0) continue; + for (let divisor = i; divisor <= maxValue; divisor += i) { + const quotient = Math.floor(divisor / i); + const count = ( + prefixSum[Math.min(maxValue, divisor + i - 1)] - prefixSum[divisor - 1] + ) % modulo; + result = (result + quotient * frequency[i] * count) % modulo; + } + } + + return result; +}; diff --git a/solutions/1864-minimum-number-of-swaps-to-make-the-binary-string-alternating.js b/solutions/1864-minimum-number-of-swaps-to-make-the-binary-string-alternating.js new file mode 100644 index 00000000..28378e0b --- /dev/null +++ b/solutions/1864-minimum-number-of-swaps-to-make-the-binary-string-alternating.js @@ -0,0 +1,49 @@ +/** + * 1864. Minimum Number of Swaps to Make the Binary String Alternating + * https://leetcode.com/problems/minimum-number-of-swaps-to-make-the-binary-string-alternating/ + * Difficulty: Medium + * + * Given a binary string s, return the minimum number of character swaps to make it alternating, + * or -1 if it is impossible. + * + * The string is called alternating if no two adjacent characters are equal. For example, the + * strings "010" and "1010" are alternating, while the string "0100" is not. + * + * Any two characters may be swapped, even if they are not adjacent. + */ + +/** + * @param {string} s + * @return {number} + */ +var minSwaps = function(s) { + const length = s.length; + let ones = 0; + let zeros = 0; + + for (const char of s) { + if (char === '1') ones++; + else zeros++; + } + + if (Math.abs(ones - zeros) > 1) return -1; + + let mismatchesStartWithZero = 0; + let mismatchesStartWithOne = 0; + + for (let i = 0; i < length; i++) { + if (i % 2 === 0) { + if (s[i] !== '0') mismatchesStartWithZero++; + if (s[i] !== '1') mismatchesStartWithOne++; + } else { + if (s[i] !== '1') mismatchesStartWithZero++; + if (s[i] !== '0') mismatchesStartWithOne++; + } + } + + if (ones === zeros) { + return Math.min(mismatchesStartWithZero, mismatchesStartWithOne) >> 1; + } + + return (ones > zeros ? mismatchesStartWithOne : mismatchesStartWithZero) >> 1; +}; diff --git a/solutions/1865-finding-pairs-with-a-certain-sum.js b/solutions/1865-finding-pairs-with-a-certain-sum.js new file mode 100644 index 00000000..9a100a1b --- /dev/null +++ b/solutions/1865-finding-pairs-with-a-certain-sum.js @@ -0,0 +1,60 @@ +/** + * 1865. Finding Pairs With a Certain Sum + * https://leetcode.com/problems/finding-pairs-with-a-certain-sum/ + * Difficulty: Medium + * + * You are given two integer arrays nums1 and nums2. You are tasked to implement a data structure + * that supports queries of two types: + * 1. Add a positive integer to an element of a given index in the array nums2. + * 2. Count the number of pairs (i, j) such that nums1[i] + nums2[j] equals a given + * value (0 <= i < nums1.length and 0 <= j < nums2.length). + * + * Implement the FindSumPairs class: + * - FindSumPairs(int[] nums1, int[] nums2) Initializes the FindSumPairs object with two integer + * arrays nums1 and nums2. + * - void add(int index, int val) Adds val to nums2[index], i.e., apply nums2[index] += val. + * - int count(int tot) Returns the number of pairs (i, j) such that nums1[i] + nums2[j] == tot. + */ + +/** + * @param {number[]} nums1 + * @param {number[]} nums2 + */ +var FindSumPairs = function(nums1, nums2) { + this.firstArray = nums1; + this.secondArray = nums2; + this.frequency = new Map(); + + for (const num of nums2) { + this.frequency.set(num, (this.frequency.get(num) || 0) + 1); + } +}; + +/** + * @param {number} index + * @param {number} val + * @return {void} + */ +FindSumPairs.prototype.add = function(index, val) { + const oldValue = this.secondArray[index]; + this.secondArray[index] += val; + const newValue = this.secondArray[index]; + + this.frequency.set(oldValue, this.frequency.get(oldValue) - 1); + this.frequency.set(newValue, (this.frequency.get(newValue) || 0) + 1); +}; + +/** + * @param {number} tot + * @return {number} + */ +FindSumPairs.prototype.count = function(tot) { + let result = 0; + + for (const num of this.firstArray) { + const complement = tot - num; + result += this.frequency.get(complement) || 0; + } + + return result; +}; diff --git a/solutions/1866-number-of-ways-to-rearrange-sticks-with-k-sticks-visible.js b/solutions/1866-number-of-ways-to-rearrange-sticks-with-k-sticks-visible.js new file mode 100644 index 00000000..3a2ffed6 --- /dev/null +++ b/solutions/1866-number-of-ways-to-rearrange-sticks-with-k-sticks-visible.js @@ -0,0 +1,37 @@ +/** + * 1866. Number of Ways to Rearrange Sticks With K Sticks Visible + * https://leetcode.com/problems/number-of-ways-to-rearrange-sticks-with-k-sticks-visible/ + * Difficulty: Hard + * + * There are n uniquely-sized sticks whose lengths are integers from 1 to n. You want to arrange + * the sticks such that exactly k sticks are visible from the left. A stick is visible from the + * left if there are no longer sticks to the left of it. + * - For example, if the sticks are arranged [1,3,2,5,4], then the sticks with lengths 1, 3, + * and 5 are visible from the left. + * + * Given n and k, return the number of such arrangements. Since the answer may be large, return + * it modulo 109 + 7. + */ + +/** + * @param {number} n + * @param {number} k + * @return {number} + */ +var rearrangeSticks = function(n, k) { + const modulo = 1e9 + 7; + const dp = Array.from({ length: n + 1 }, () => new Array(k + 1).fill(0)); + dp[0][0] = 1; + + for (let sticks = 1; sticks <= n; sticks++) { + for (let visible = 0; visible <= k; visible++) { + if (visible > sticks) continue; + if (visible > 0) { + dp[sticks][visible] = (dp[sticks][visible] + dp[sticks - 1][visible - 1]) % modulo; + } + dp[sticks][visible] = (dp[sticks][visible] + dp[sticks - 1][visible] * (sticks - 1)) % modulo; + } + } + + return dp[n][k]; +}; diff --git a/solutions/1869-longer-contiguous-segments-of-ones-than-zeros.js b/solutions/1869-longer-contiguous-segments-of-ones-than-zeros.js new file mode 100644 index 00000000..bc6acf26 --- /dev/null +++ b/solutions/1869-longer-contiguous-segments-of-ones-than-zeros.js @@ -0,0 +1,38 @@ +/** + * 1869. Longer Contiguous Segments of Ones than Zeros + * https://leetcode.com/problems/longer-contiguous-segments-of-ones-than-zeros/ + * Difficulty: Easy + * + * Given a binary string s, return true if the longest contiguous segment of 1's is strictly + * longer than the longest contiguous segment of 0's in s, or return false otherwise. + * - For example, in s = "110100010" the longest continuous segment of 1s has length 2, and the + * longest continuous segment of 0s has length 3. + * + * Note that if there are no 0's, then the longest continuous segment of 0's is considered to + * have a length 0. The same applies if there is no 1's. + */ + +/** + * @param {string} s + * @return {boolean} + */ +var checkZeroOnes = function(s) { + let maxOnes = 0; + let maxZeros = 0; + let currentOnes = 0; + let currentZeros = 0; + + for (const char of s) { + if (char === '1') { + currentOnes++; + currentZeros = 0; + maxOnes = Math.max(maxOnes, currentOnes); + } else { + currentZeros++; + currentOnes = 0; + maxZeros = Math.max(maxZeros, currentZeros); + } + } + + return maxOnes > maxZeros; +}; diff --git a/solutions/1870-minimum-speed-to-arrive-on-time.js b/solutions/1870-minimum-speed-to-arrive-on-time.js new file mode 100644 index 00000000..fd7633a5 --- /dev/null +++ b/solutions/1870-minimum-speed-to-arrive-on-time.js @@ -0,0 +1,54 @@ +/** + * 1870. Minimum Speed to Arrive on Time + * https://leetcode.com/problems/minimum-speed-to-arrive-on-time/ + * Difficulty: Medium + * + * You are given a floating-point number hour, representing the amount of time you have to reach + * the office. To commute to the office, you must take n trains in sequential order. You are also + * given an integer array dist of length n, where dist[i] describes the distance (in kilometers) + * of the ith train ride. + * + * Each train can only depart at an integer hour, so you may need to wait in between each train + * ride. + * - For example, if the 1st train ride takes 1.5 hours, you must wait for an additional 0.5 hours + * before you can depart on the 2nd train ride at the 2 hour mark. + * + * Return the minimum positive integer speed (in kilometers per hour) that all the trains must + * travel at for you to reach the office on time, or -1 if it is impossible to be on time. + * + * Tests are generated such that the answer will not exceed 107 and hour will have at most two + * digits after the decimal point. + */ + +/** + * @param {number[]} dist + * @param {number} hour + * @return {number} + */ +var minSpeedOnTime = function(dist, hour) { + const trainCount = dist.length; + if (Math.ceil(trainCount - 1) > hour) return -1; + + let minSpeed = 1; + let maxSpeed = 10000000; + let result = -1; + + while (minSpeed <= maxSpeed) { + const midSpeed = (minSpeed + maxSpeed) >> 1; + let totalTime = 0; + + for (let i = 0; i < trainCount - 1; i++) { + totalTime += Math.ceil(dist[i] / midSpeed); + } + totalTime += dist[trainCount - 1] / midSpeed; + + if (totalTime <= hour) { + result = midSpeed; + maxSpeed = midSpeed - 1; + } else { + minSpeed = midSpeed + 1; + } + } + + return result; +}; diff --git a/solutions/1871-jump-game-vii.js b/solutions/1871-jump-game-vii.js new file mode 100644 index 00000000..92a47cc2 --- /dev/null +++ b/solutions/1871-jump-game-vii.js @@ -0,0 +1,44 @@ +/** + * 1871. Jump Game VII + * https://leetcode.com/problems/jump-game-vii/ + * Difficulty: Medium + * + * You are given a 0-indexed binary string s and two integers minJump and maxJump. In the + * beginning, you are standing at index 0, which is equal to '0'. You can move from index + * i to index j if the following conditions are fulfilled: + * - i + minJump <= j <= min(i + maxJump, s.length - 1), and + * - s[j] == '0'. + * + * Return true if you can reach index s.length - 1 in s, or false otherwise. + */ + +/** + * @param {string} s + * @param {number} minJump + * @param {number} maxJump + * @return {boolean} + */ +var canReach = function(s, minJump, maxJump) { + const length = s.length; + const reachable = new Array(length).fill(false); + reachable[0] = true; + const queue = [0]; + let farthest = 0; + + while (queue.length) { + const current = queue.shift(); + const start = current + minJump; + const end = Math.min(current + maxJump, length - 1); + + for (let next = Math.max(start, farthest + 1); next <= end; next++) { + if (s[next] === '0' && !reachable[next]) { + reachable[next] = true; + queue.push(next); + if (next === length - 1) return true; + } + } + farthest = Math.max(farthest, end); + } + + return false; +}; diff --git a/solutions/1872-stone-game-viii.js b/solutions/1872-stone-game-viii.js new file mode 100644 index 00000000..c8e74328 --- /dev/null +++ b/solutions/1872-stone-game-viii.js @@ -0,0 +1,42 @@ +/** + * 1872. Stone Game VIII + * https://leetcode.com/problems/stone-game-viii/ + * Difficulty: Hard + * + * Alice and Bob take turns playing a game, with Alice starting first. + * + * There are n stones arranged in a row. On each player's turn, while the number of stones is more + * than one, they will do the following: + * 1. Choose an integer x > 1, and remove the leftmost x stones from the row. + * 2. Add the sum of the removed stones' values to the player's score. + * 3. Place a new stone, whose value is equal to that sum, on the left side of the row. + * + * The game stops when only one stone is left in the row. + * + * The score difference between Alice and Bob is (Alice's score - Bob's score). Alice's goal is to + * maximize the score difference, and Bob's goal is the minimize the score difference. + * + * Given an integer array stones of length n where stones[i] represents the value of the ith stone + * from the left, return the score difference between Alice and Bob if they both play optimally. + */ + +/** + * @param {number[]} stones + * @return {number} + */ +var stoneGameVIII = function(stones) { + const length = stones.length; + const prefixSums = new Array(length).fill(0); + prefixSums[0] = stones[0]; + + for (let i = 1; i < length; i++) { + prefixSums[i] = prefixSums[i - 1] + stones[i]; + } + + let result = prefixSums[length - 1]; + for (let i = length - 2; i >= 1; i--) { + result = Math.max(result, prefixSums[i] - result); + } + + return result; +}; diff --git a/solutions/1876-substrings-of-size-three-with-distinct-characters.js b/solutions/1876-substrings-of-size-three-with-distinct-characters.js new file mode 100644 index 00000000..cbe56e47 --- /dev/null +++ b/solutions/1876-substrings-of-size-three-with-distinct-characters.js @@ -0,0 +1,41 @@ +/** + * 1876. Substrings of Size Three with Distinct Characters + * https://leetcode.com/problems/substrings-of-size-three-with-distinct-characters/ + * Difficulty: Easy + * + * A string is good if there are no repeated characters. + * + * Given a string s, return the number of good substrings of length three in s. + * + * Note that if there are multiple occurrences of the same substring, every occurrence should + * be counted. + * + * A substring is a contiguous sequence of characters in a string. + */ + +/** + * @param {string} s + * @return {number} + */ +var countGoodSubstrings = function(s) { + if (s.length < 3) return 0; + + let result = 0; + const charCount = new Map(); + + for (let i = 0; i < 3; i++) { + charCount.set(s[i], (charCount.get(s[i]) || 0) + 1); + } + if (charCount.size === 3) result++; + + for (let i = 3; i < s.length; i++) { + const oldChar = s[i - 3]; + charCount.set(oldChar, charCount.get(oldChar) - 1); + if (charCount.get(oldChar) === 0) charCount.delete(oldChar); + + charCount.set(s[i], (charCount.get(s[i]) || 0) + 1); + if (charCount.size === 3) result++; + } + + return result; +}; diff --git a/solutions/1877-minimize-maximum-pair-sum-in-array.js b/solutions/1877-minimize-maximum-pair-sum-in-array.js new file mode 100644 index 00000000..264d9569 --- /dev/null +++ b/solutions/1877-minimize-maximum-pair-sum-in-array.js @@ -0,0 +1,35 @@ +/** + * 1877. Minimize Maximum Pair Sum in Array + * https://leetcode.com/problems/minimize-maximum-pair-sum-in-array/ + * Difficulty: Medium + * + * The pair sum of a pair (a,b) is equal to a + b. The maximum pair sum is the largest pair sum + * in a list of pairs. + * - For example, if we have pairs (1,5), (2,3), and (4,4), the maximum pair sum would be + * max(1+5, 2+3, 4+4) = max(6, 5, 8) = 8. + * + * Given an array nums of even length n, pair up the elements of nums into n / 2 pairs such that: + * - Each element of nums is in exactly one pair, and + * - The maximum pair sum is minimized. + * + * Return the minimized maximum pair sum after optimally pairing up the elements. + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var minPairSum = function(nums) { + nums.sort((a, b) => a - b); + let result = 0; + let left = 0; + let right = nums.length - 1; + + while (left < right) { + result = Math.max(result, nums[left] + nums[right]); + left++; + right--; + } + + return result; +}; diff --git a/solutions/1878-get-biggest-three-rhombus-sums-in-a-grid.js b/solutions/1878-get-biggest-three-rhombus-sums-in-a-grid.js new file mode 100644 index 00000000..f10c1b56 --- /dev/null +++ b/solutions/1878-get-biggest-three-rhombus-sums-in-a-grid.js @@ -0,0 +1,46 @@ +/** + * 1878. Get Biggest Three Rhombus Sums in a Grid + * https://leetcode.com/problems/get-biggest-three-rhombus-sums-in-a-grid/ + * Difficulty: Medium + * + * You are given an m x n integer matrix grid. + * + * A rhombus sum is the sum of the elements that form the border of a regular rhombus shape in + * grid. The rhombus must have the shape of a square rotated 45 degrees with each of the corners + * centered in a grid cell. Below is an image of four valid rhombus shapes with the corresponding + * colored cells that should be included in each rhombus sum. + * + * Note that the rhombus can have an area of 0, which is depicted by the purple rhombus in the + * bottom right corner. + * + * Return the biggest three distinct rhombus sums in the grid in descending order. If there are + * less than three distinct values, return all of them. + */ + +/** + * @param {number[][]} grid + * @return {number[]} + */ +var getBiggestThree = function(grid) { + const rows = grid.length; + const cols = grid[0].length; + const sums = new Set(); + + for (let i = 0; i < rows; i++) { + for (let j = 0; j < cols; j++) { + sums.add(grid[i][j]); + for (let size = 1; size <= Math.min(i, rows - 1 - i, j, cols - 1 - j); size++) { + let rhombusSum = 0; + rhombusSum += grid[i - size][j] + grid[i + size][j] + grid[i][j - size] + grid[i][j + size]; + for (let offset = 1; offset < size; offset++) { + rhombusSum += grid[i - size + offset][j + offset] + grid[i + size - offset][j + offset]; + rhombusSum += grid[i - size + offset][j - offset] + grid[i + size - offset][j - offset]; + } + sums.add(rhombusSum); + } + } + } + + const sortedSums = [...sums].sort((a, b) => b - a); + return sortedSums.slice(0, Math.min(3, sortedSums.length)); +}; diff --git a/solutions/1879-minimum-xor-sum-of-two-arrays.js b/solutions/1879-minimum-xor-sum-of-two-arrays.js new file mode 100644 index 00000000..2f7c4f61 --- /dev/null +++ b/solutions/1879-minimum-xor-sum-of-two-arrays.js @@ -0,0 +1,39 @@ +/** + * 1879. Minimum XOR Sum of Two Arrays + * https://leetcode.com/problems/minimum-xor-sum-of-two-arrays/ + * Difficulty: Hard + * + * You are given two integer arrays nums1 and nums2 of length n. + * + * The XOR sum of the two integer arrays is (nums1[0] XOR nums2[0]) + (nums1[1] XOR nums2[1]) + * + ... + (nums1[n - 1] XOR nums2[n - 1]) (0-indexed). + * - For example, the XOR sum of [1,2,3] and [3,2,1] is equal to (1 XOR 3) + (2 XOR 2) + + * (3 XOR 1) = 2 + 0 + 2 = 4. + * + * Rearrange the elements of nums2 such that the resulting XOR sum is minimized. + * + * Return the XOR sum after the rearrangement. + */ + +/** + * @param {number[]} nums1 + * @param {number[]} nums2 + * @return {number} + */ +var minimumXORSum = function(nums1, nums2) { + const n = nums1.length; + const dp = new Array(1 << n).fill(Infinity); + dp[0] = 0; + + for (let mask = 0; mask < (1 << n); mask++) { + const usedCount = mask.toString(2).split('1').length - 1; + for (let j = 0; j < n; j++) { + if (!(mask & (1 << j))) { + const newMask = mask | (1 << j); + dp[newMask] = Math.min(dp[newMask], dp[mask] + (nums1[usedCount] ^ nums2[j])); + } + } + } + + return dp[(1 << n) - 1]; +}; diff --git a/solutions/1881-maximum-value-after-insertion.js b/solutions/1881-maximum-value-after-insertion.js new file mode 100644 index 00000000..4ba804d7 --- /dev/null +++ b/solutions/1881-maximum-value-after-insertion.js @@ -0,0 +1,46 @@ +/** + * 1881. Maximum Value after Insertion + * https://leetcode.com/problems/maximum-value-after-insertion/ + * Difficulty: Medium + * + * You are given a very large integer n, represented as a string, and an integer digit x. + * The digits in n and the digit x are in the inclusive range [1, 9], and n may represent + * a negative number. + * + * You want to maximize n's numerical value by inserting x anywhere in the decimal representation + * of n. You cannot insert x to the left of the negative sign. + * - For example, if n = 73 and x = 6, it would be best to insert it between 7 and 3, making + * n = 763. + * - If n = -55 and x = 2, it would be best to insert it before the first 5, making n = -255. + * + * Return a string representing the maximum value of n after the insertion. + */ + +/** + * @param {string} n + * @param {number} x + * @return {string} + */ +var maxValue = function(n, x) { + const isNegative = n[0] === '-'; + const digits = n.slice(isNegative ? 1 : 0); + let result = ''; + + if (isNegative) { + for (let i = 0; i <= digits.length; i++) { + if (i === digits.length || x < parseInt(digits[i])) { + result = '-' + digits.slice(0, i) + x + digits.slice(i); + break; + } + } + } else { + for (let i = 0; i <= digits.length; i++) { + if (i === digits.length || x > parseInt(digits[i])) { + result = digits.slice(0, i) + x + digits.slice(i); + break; + } + } + } + + return result; +}; diff --git a/solutions/1882-process-tasks-using-servers.js b/solutions/1882-process-tasks-using-servers.js new file mode 100644 index 00000000..e82ad99f --- /dev/null +++ b/solutions/1882-process-tasks-using-servers.js @@ -0,0 +1,71 @@ +/** + * 1882. Process Tasks Using Servers + * https://leetcode.com/problems/process-tasks-using-servers/ + * Difficulty: Medium + * + * You are given two 0-indexed integer arrays servers and tasks of lengths n and m respectively. + * servers[i] is the weight of the ith server, and tasks[j] is the time needed to process the + * jth task in seconds. + * + * Tasks are assigned to the servers using a task queue. Initially, all servers are free, and + * the queue is empty. + * + * At second j, the jth task is inserted into the queue (starting with the 0th task being inserted + * at second 0). As long as there are free servers and the queue is not empty, the task in the front + * of the queue will be assigned to a free server with the smallest weight, and in case of a tie, + * it is assigned to a free server with the smallest index. + * + * If there are no free servers and the queue is not empty, we wait until a server becomes free + * and immediately assign the next task. If multiple servers become free at the same time, then + * multiple tasks from the queue will be assigned in order of insertion following the weight and + * index priorities above. + * + * A server that is assigned task j at second t will be free again at second t + tasks[j]. + * + * Build an array ans of length m, where ans[j] is the index of the server the jth task will + * be assigned to. + * + * Return the array ans. + */ + +/** + * @param {number[]} servers + * @param {number[]} tasks + * @return {number[]} + */ +var assignTasks = function(servers, tasks) { + const serverHeap = new PriorityQueue((a, b) => a[0] * 1000000 + a[1] - (b[0] * 1000000 + b[1])); + const busyHeap = new PriorityQueue((a, b) => a[0] - b[0]); + const result = new Array(tasks.length); + + for (let i = 0; i < servers.length; i++) { + serverHeap.enqueue([servers[i], i]); + } + + let time = 0; + let taskIndex = 0; + + while (taskIndex < tasks.length) { + time = Math.max(time, taskIndex); + + while (!busyHeap.isEmpty() && busyHeap.front()[0] <= time) { + const [, weight, index] = busyHeap.dequeue(); + serverHeap.enqueue([weight, index]); + } + + while (serverHeap.size() && taskIndex < tasks.length && taskIndex <= time) { + const [weight, index] = serverHeap.dequeue(); + result[taskIndex] = index; + busyHeap.enqueue([time + tasks[taskIndex], weight, index]); + taskIndex++; + } + + if (serverHeap.isEmpty() && taskIndex < tasks.length) { + const [freeTime, weight, index] = busyHeap.dequeue(); + time = freeTime; + serverHeap.enqueue([weight, index]); + } + } + + return result; +}; diff --git a/solutions/1883-minimum-skips-to-arrive-at-meeting-on-time.js b/solutions/1883-minimum-skips-to-arrive-at-meeting-on-time.js new file mode 100644 index 00000000..23d83b18 --- /dev/null +++ b/solutions/1883-minimum-skips-to-arrive-at-meeting-on-time.js @@ -0,0 +1,66 @@ +/** + * 1883. Minimum Skips to Arrive at Meeting On Time + * https://leetcode.com/problems/minimum-skips-to-arrive-at-meeting-on-time/ + * Difficulty: Hard + * + * You are given an integer hoursBefore, the number of hours you have to travel to your meeting. + * To arrive at your meeting, you have to travel through n roads. The road lengths are given as + * an integer array dist of length n, where dist[i] describes the length of the ith road in + * kilometers. In addition, you are given an integer speed, which is the speed (in km/h) you + * will travel at. + * + * After you travel road i, you must rest and wait for the next integer hour before you can begin + * traveling on the next road. Note that you do not have to rest after traveling the last road + * because you are already at the meeting. + * - For example, if traveling a road takes 1.4 hours, you must wait until the 2 hour mark before + * traveling the next road. If traveling a road takes exactly 2 hours, you do not need to wait. + * + * However, you are allowed to skip some rests to be able to arrive on time, meaning you do not + * need to wait for the next integer hour. Note that this means you may finish traveling future + * roads at different hour marks. + * - For example, suppose traveling the first road takes 1.4 hours and traveling the second road + * takes 0.6 hours. Skipping the rest after the first road will mean you finish traveling the + * second road right at the 2 hour mark, letting you start traveling the third road immediately. + * + * Return the minimum number of skips required to arrive at the meeting on time, or -1 if it is + * impossible. + */ + +/** + * @param {number[]} dist + * @param {number} speed + * @param {number} hoursBefore + * @return {number} + */ +var minSkips = function(dist, speed, hoursBefore) { + const n = dist.length; + const dp = Array.from({ length: n + 1 }, () => new Array(n + 1).fill(Infinity)); + dp[0][0] = 0; + + for (let i = 1; i <= n; i++) { + for (let skips = 0; skips <= i; skips++) { + if (skips < i) { + const prevTime = dp[i - 1][skips]; + if (prevTime !== Infinity) { + const time = prevTime + dist[i - 1]; + dp[i][skips] = Math.min(dp[i][skips], Math.ceil(time / speed) * speed); + } + } + if (skips > 0) { + const prevTime = dp[i - 1][skips - 1]; + if (prevTime !== Infinity) { + dp[i][skips] = Math.min(dp[i][skips], prevTime + dist[i - 1]); + } + } + } + } + + const targetTime = hoursBefore * speed; + for (let skips = 0; skips <= n; skips++) { + if (dp[n][skips] <= targetTime) { + return skips; + } + } + + return -1; +}; diff --git a/solutions/1884-egg-drop-with-2-eggs-and-n-floors.js b/solutions/1884-egg-drop-with-2-eggs-and-n-floors.js new file mode 100644 index 00000000..4b5ccb3f --- /dev/null +++ b/solutions/1884-egg-drop-with-2-eggs-and-n-floors.js @@ -0,0 +1,42 @@ +/** + * 1884. Egg Drop With 2 Eggs and N Floors + * https://leetcode.com/problems/egg-drop-with-2-eggs-and-n-floors/ + * Difficulty: Medium + * + * You are given two identical eggs and you have access to a building with n floors labeled + * from 1 to n. + * + * You know that there exists a floor f where 0 <= f <= n such that any egg dropped at a floor + * higher than f will break, and any egg dropped at or below floor f will not break. + * + * In each move, you may take an unbroken egg and drop it from any floor x (where 1 <= x <= n). + * If the egg breaks, you can no longer use it. However, if the egg does not break, you may + * reuse it in future moves. + * + * Return the minimum number of moves that you need to determine with certainty what the value + * of f is. + */ + +/** + * @param {number} n + * @return {number} + */ +var twoEggDrop = function(n) { + const dp = Array.from({ length: 3 }, () => new Array(n + 1).fill(Infinity)); + dp[0][0] = 0; + dp[1][0] = 0; + dp[2][0] = 0; + + for (let floors = 1; floors <= n; floors++) { + dp[1][floors] = floors; + for (let eggs = 2; eggs <= 2; eggs++) { + for (let k = 1; k <= floors; k++) { + const breaks = dp[eggs - 1][k - 1]; + const survives = dp[eggs][floors - k]; + dp[eggs][floors] = Math.min(dp[eggs][floors], 1 + Math.max(breaks, survives)); + } + } + } + + return dp[2][n]; +}; diff --git a/solutions/1887-reduction-operations-to-make-the-array-elements-equal.js b/solutions/1887-reduction-operations-to-make-the-array-elements-equal.js new file mode 100644 index 00000000..d6672d7b --- /dev/null +++ b/solutions/1887-reduction-operations-to-make-the-array-elements-equal.js @@ -0,0 +1,34 @@ +/** + * 1887. Reduction Operations to Make the Array Elements Equal + * https://leetcode.com/problems/reduction-operations-to-make-the-array-elements-equal/ + * Difficulty: Medium + * + * Given an integer array nums, your goal is to make all elements in nums equal. To complete one + * operation, follow these steps: + * 1. Find the largest value in nums. Let its index be i (0-indexed) and its value be largest. + * If there are multiple elements with the largest value, pick the smallest i. + * 2. Find the next largest value in nums strictly smaller than largest. Let its value be + * nextLargest. + * 3. Reduce nums[i] to nextLargest. + * + * Return the number of operations to make all elements in nums equal. + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var reductionOperations = function(nums) { + nums.sort((a, b) => a - b); + let result = 0; + let count = 0; + + for (let i = 1; i < nums.length; i++) { + if (nums[i] !== nums[i - 1]) { + count++; + } + result += count; + } + + return result; +}; diff --git a/solutions/1888-minimum-number-of-flips-to-make-the-binary-string-alternating.js b/solutions/1888-minimum-number-of-flips-to-make-the-binary-string-alternating.js new file mode 100644 index 00000000..24795a9f --- /dev/null +++ b/solutions/1888-minimum-number-of-flips-to-make-the-binary-string-alternating.js @@ -0,0 +1,47 @@ +/** + * 1888. Minimum Number of Flips to Make the Binary String Alternating + * https://leetcode.com/problems/minimum-number-of-flips-to-make-the-binary-string-alternating/ + * Difficulty: Medium + * + * You are given a binary string s. You are allowed to perform two types of operations on the + * string in any sequence: + * - Type-1: Remove the character at the start of the string s and append it to the end of + * the string. + * - Type-2: Pick any character in s and flip its value, i.e., if its value is '0' it becomes + * '1' and vice-versa. + * + * Return the minimum number of type-2 operations you need to perform such that s becomes + * alternating. + * + * The string is called alternating if no two adjacent characters are equal. + * + * For example, the strings "010" and "1010" are alternating, while the string "0100" is not. + */ + +/** + * @param {string} s + * @return {number} + */ +var minFlips = function(s) { + const n = s.length; + let result = n; + let flipsZeroStart = 0; + let flipsOneStart = 0; + + for (let i = 0; i < n; i++) { + if (s[i] !== (i % 2 === 0 ? '0' : '1')) flipsZeroStart++; + if (s[i] !== (i % 2 === 0 ? '1' : '0')) flipsOneStart++; + } + + result = Math.min(flipsZeroStart, flipsOneStart); + + for (let i = 0; i < n - 1; i++) { + if (s[i] !== (i % 2 === 0 ? '0' : '1')) flipsZeroStart--; + if (s[i] !== (i % 2 === 0 ? '1' : '0')) flipsOneStart--; + if (s[i] !== ((n + i) % 2 === 0 ? '0' : '1')) flipsZeroStart++; + if (s[i] !== ((n + i) % 2 === 0 ? '1' : '0')) flipsOneStart++; + result = Math.min(result, flipsZeroStart, flipsOneStart); + } + + return result; +}; diff --git a/solutions/1889-minimum-space-wasted-from-packaging.js b/solutions/1889-minimum-space-wasted-from-packaging.js new file mode 100644 index 00000000..de010d0f --- /dev/null +++ b/solutions/1889-minimum-space-wasted-from-packaging.js @@ -0,0 +1,82 @@ +/** + * 1889. Minimum Space Wasted From Packaging + * https://leetcode.com/problems/minimum-space-wasted-from-packaging/ + * Difficulty: Hard + * + * You have n packages that you are trying to place in boxes, one package in each box. There are + * m suppliers that each produce boxes of different sizes (with infinite supply). A package can + * be placed in a box if the size of the package is less than or equal to the size of the box. + * + * The package sizes are given as an integer array packages, where packages[i] is the size of the + * ith package. The suppliers are given as a 2D integer array boxes, where boxes[j] is an array + * of box sizes that the jth supplier produces. + * + * You want to choose a single supplier and use boxes from them such that the total wasted space + * is minimized. For each package in a box, we define the space wasted to be size of the box - size + * of the package. The total wasted space is the sum of the space wasted in all the boxes. + * - For example, if you have to fit packages with sizes [2,3,5] and the supplier offers boxes of + * sizes [4,8], you can fit the packages of size-2 and size-3 into two boxes of size-4 and the + * package with size-5 into a box of size-8. This would result in a waste + * of (4-2) + (4-3) + (8-5) = 6. + * + * Return the minimum total wasted space by choosing the box supplier optimally, or -1 if it is + * impossible to fit all the packages inside boxes. Since the answer may be large, return it + * modulo 109 + 7. + */ + +/** + * @param {number[]} packages + * @param {number[][]} boxes + * @return {number} + */ +var minWastedSpace = function(packages, boxes) { + const modulo = 1e9 + 7; + packages.sort((a, b) => a - b); + let minWaste = BigInt(2) ** BigInt(60); + const n = packages.length; + + const prefixSums = new Array(n + 1).fill(BigInt(0)); + for (let i = 0; i < n; i++) { + prefixSums[i + 1] = prefixSums[i] + BigInt(packages[i]); + } + + for (const supplier of boxes) { + supplier.sort((a, b) => a - b); + if (supplier[supplier.length - 1] < packages[n - 1]) continue; + + let waste = BigInt(0); + let packageIndex = 0; + + for (const box of supplier) { + if (packageIndex >= n) break; + const upperBound = binarySearch(packages, box, packageIndex); + if (upperBound > packageIndex) { + const count = BigInt(upperBound - packageIndex); + waste += count * BigInt(box) - (prefixSums[upperBound] - prefixSums[packageIndex]); + packageIndex = upperBound; + } + } + + if (packageIndex === n) { + minWaste = minWaste < waste ? minWaste : waste; + } + } + + return minWaste === BigInt(2) ** BigInt(60) ? -1 : Number(minWaste % BigInt(modulo)); +}; + +function binarySearch(arr, target, start) { + let left = start; + let right = arr.length; + + while (left < right) { + const mid = (left + right) >> 1; + if (arr[mid] <= target) { + left = mid + 1; + } else { + right = mid; + } + } + + return left; +} diff --git a/solutions/1893-check-if-all-the-integers-in-a-range-are-covered.js b/solutions/1893-check-if-all-the-integers-in-a-range-are-covered.js new file mode 100644 index 00000000..def56b8c --- /dev/null +++ b/solutions/1893-check-if-all-the-integers-in-a-range-are-covered.js @@ -0,0 +1,35 @@ +/** + * 1893. Check if All the Integers in a Range Are Covered + * https://leetcode.com/problems/check-if-all-the-integers-in-a-range-are-covered/ + * Difficulty: Easy + * + * You are given a 2D integer array ranges and two integers left and right. Each + * ranges[i] = [starti, endi] represents an inclusive interval between starti and endi. + * + * Return true if each integer in the inclusive range [left, right] is covered by at least + * one interval in ranges. Return false otherwise. + * + * An integer x is covered by an interval ranges[i] = [starti, endi] if starti <= x <= endi. + */ + +/** + * @param {number[][]} ranges + * @param {number} left + * @param {number} right + * @return {boolean} + */ +var isCovered = function(ranges, left, right) { + const covered = new Array(51).fill(false); + + for (const [start, end] of ranges) { + for (let i = start; i <= end; i++) { + covered[i] = true; + } + } + + for (let i = left; i <= right; i++) { + if (!covered[i]) return false; + } + + return true; +}; diff --git a/solutions/1894-find-the-student-that-will-replace-the-chalk.js b/solutions/1894-find-the-student-that-will-replace-the-chalk.js new file mode 100644 index 00000000..387fd854 --- /dev/null +++ b/solutions/1894-find-the-student-that-will-replace-the-chalk.js @@ -0,0 +1,38 @@ +/** + * 1894. Find the Student that Will Replace the Chalk + * https://leetcode.com/problems/find-the-student-that-will-replace-the-chalk/ + * Difficulty: Medium + * + * There are n students in a class numbered from 0 to n - 1. The teacher will give each student + * a problem starting with the student number 0, then the student number 1, and so on until the + * teacher reaches the student number n - 1. After that, the teacher will restart the process, + * starting with the student number 0 again. + * + * You are given a 0-indexed integer array chalk and an integer k. There are initially k pieces + * of chalk. When the student number i is given a problem to solve, they will use chalk[i] + * pieces of chalk to solve that problem. However, if the current number of chalk pieces is + * strictly less than chalk[i], then the student number i will be asked to replace the chalk. + * + * Return the index of the student that will replace the chalk pieces. + */ + +/** + * @param {number[]} chalk + * @param {number} k + * @return {number} + */ +var chalkReplacer = function(chalk, k) { + let totalChalk = 0; + for (const amount of chalk) { + totalChalk += amount; + } + + k = k % totalChalk; + + for (let i = 0; i < chalk.length; i++) { + if (k < chalk[i]) return i; + k -= chalk[i]; + } + + return 0; +}; diff --git a/solutions/1895-largest-magic-square.js b/solutions/1895-largest-magic-square.js new file mode 100644 index 00000000..e23a71cc --- /dev/null +++ b/solutions/1895-largest-magic-square.js @@ -0,0 +1,71 @@ +/** + * 1895. Largest Magic Square + * https://leetcode.com/problems/largest-magic-square/ + * Difficulty: Medium + * + * A k x k magic square is a k x k grid filled with integers such that every row sum, every + * column sum, and both diagonal sums are all equal. The integers in the magic square do not + * have to be distinct. Every 1 x 1 grid is trivially a magic square. + * + * Given an m x n integer grid, return the size (i.e., the side length k) of the largest magic + * square that can be found within this grid. + */ + +/** + * @param {number[][]} grid + * @return {number} + */ +var largestMagicSquare = function(grid) { + const rows = grid.length; + const cols = grid[0].length; + const rowSums = Array.from({ length: rows + 1 }, () => new Array(cols + 1).fill(0)); + const colSums = Array.from({ length: rows + 1 }, () => new Array(cols + 1).fill(0)); + + for (let i = 1; i <= rows; i++) { + for (let j = 1; j <= cols; j++) { + rowSums[i][j] = rowSums[i][j - 1] + grid[i - 1][j - 1]; + colSums[i][j] = colSums[i - 1][j] + grid[i - 1][j - 1]; + } + } + + const maxSize = 1; + for (let size = Math.min(rows, cols); size >= 2; size--) { + for (let i = size; i <= rows; i++) { + for (let j = size; j <= cols; j++) { + const rowSum = rowSums[i][j] - rowSums[i][j - size]; + let isMagic = true; + + for (let k = 1; k < size; k++) { + if (rowSums[i - k][j] - rowSums[i - k][j - size] !== rowSum) { + isMagic = false; + break; + } + } + + if (!isMagic) continue; + + for (let k = 0; k < size; k++) { + if (colSums[i][j - k] - colSums[i - size][j - k] !== rowSum) { + isMagic = false; + break; + } + } + + if (!isMagic) continue; + + let diagSum1 = 0; + let diagSum2 = 0; + for (let k = 0; k < size; k++) { + diagSum1 += grid[i - size + k][j - size + k]; + diagSum2 += grid[i - size + k][j - 1 - k]; + } + + if (diagSum1 === rowSum && diagSum2 === rowSum) { + return size; + } + } + } + } + + return maxSize; +}; diff --git a/solutions/1896-minimum-cost-to-change-the-final-value-of-expression.js b/solutions/1896-minimum-cost-to-change-the-final-value-of-expression.js new file mode 100644 index 00000000..1e430149 --- /dev/null +++ b/solutions/1896-minimum-cost-to-change-the-final-value-of-expression.js @@ -0,0 +1,113 @@ +/** + * 1896. Minimum Cost to Change the Final Value of Expression + * https://leetcode.com/problems/minimum-cost-to-change-the-final-value-of-expression/ + * Difficulty: Hard + * + * You are given a valid boolean expression as a string expression consisting of the + * characters '1','0','&' (bitwise AND operator),'|' (bitwise OR operator),'(', and ')'. + * - For example, "()1|1" and "(1)&()" are not valid while "1", "(((1))|(0))", and "1|(0&(1))" + * are valid expressions. + * + * Return the minimum cost to change the final value of the expression. + * - For example, if expression = "1|1|(0&0)&1", its value is + * 1|1|(0&0)&1 = 1|1|0&1 = 1|0&1 = 1&1 = 1. We want to apply operations so that the new + * expression evaluates to 0. + * + * The cost of changing the final value of an expression is the number of operations performed + * on the expression. The types of operations are described as follows: + * - Turn a '1' into a '0'. + * - Turn a '0' into a '1'. + * - Turn a '&' into a '|'. + * - Turn a '|' into a '&'. + * + * Note: '&' does not take precedence over '|' in the order of calculation. Evaluate parentheses + * first, then in left-to-right order. + */ + +/** + * @param {string} expression + * @return {number} + */ +var minOperationsToFlip = function(expression) { + const stack = []; + for (const char of expression) { + if (char === ')') { + const values = []; + while (stack.length && stack[stack.length - 1][0] !== '(') { + values.push(stack.pop()); + } + stack.pop(); + let [val1, cost1] = values.pop(); + while (values.length) { + const [op] = values.pop(); + const [val2, cost2] = values.pop(); + if (op === '&') { + if (val1 === 1 && val2 === 1) { + val1 = 1; + cost1 = Math.min(cost1, cost2); + } else if (val1 === 0 && val2 === 0) { + val1 = 0; + cost1 = Math.min(cost1 + 1, cost2 + 1); + } else { + val1 = 0; + cost1 = Math.min(cost1 + cost2, 1); + } + } else { + if (val1 === 1 && val2 === 1) { + val1 = 1; + cost1 = Math.min(cost1 + 1, cost2 + 1); + } else if (val1 === 0 && val2 === 0) { + val1 = 0; + cost1 = Math.min(cost1, cost2); + } else { + val1 = 1; + cost1 = Math.min(cost1 + cost2, 1); + } + } + } + stack.push([val1, cost1]); + } else if (char === '1') { + stack.push([1, 1]); + } else if (char === '0') { + stack.push([0, 1]); + } else { + stack.push([char]); + } + } + + const values = []; + while (stack.length) { + values.push(stack.pop()); + } + + let [val1, cost1] = values.pop(); + while (values.length) { + const [op] = values.pop(); + const [val2, cost2] = values.pop(); + if (op === '&') { + if (val1 === 1 && val2 === 1) { + val1 = 1; + cost1 = Math.min(cost1, cost2); + } else if (val1 === 0 && val2 === 0) { + val1 = 0; + cost1 = Math.min(cost1 + 1, cost2 + 1); + } else { + val1 = 0; + cost1 = Math.min(cost1 + cost2, 1); + } + } else { + if (val1 === 1 && val2 === 1) { + val1 = 1; + cost1 = Math.min(cost1 + 1, cost2 + 1); + } else if (val1 === 0 && val2 === 0) { + val1 = 0; + cost1 = Math.min(cost1, cost2); + } else { + val1 = 1; + cost1 = Math.min(cost1 + cost2, 1); + } + } + } + + return cost1; +}; diff --git a/solutions/1897-redistribute-characters-to-make-all-strings-equal.js b/solutions/1897-redistribute-characters-to-make-all-strings-equal.js new file mode 100644 index 00000000..b58b05ba --- /dev/null +++ b/solutions/1897-redistribute-characters-to-make-all-strings-equal.js @@ -0,0 +1,34 @@ +/** + * 1897. Redistribute Characters to Make All Strings Equal + * https://leetcode.com/problems/redistribute-characters-to-make-all-strings-equal/ + * Difficulty: Easy + * + * You are given an array of strings words (0-indexed). + * + * In one operation, pick two distinct indices i and j, where words[i] is a non-empty string, + * and move any character from words[i] to any position in words[j]. + * + * Return true if you can make every string in words equal using any number of operations, and + * false otherwise. + */ + +/** + * @param {string[]} words + * @return {boolean} + */ +var makeEqual = function(words) { + const charCount = new Array(26).fill(0); + const wordCount = words.length; + + for (const word of words) { + for (const char of word) { + charCount[char.charCodeAt(0) - 97]++; + } + } + + for (const count of charCount) { + if (count % wordCount !== 0) return false; + } + + return true; +}; diff --git a/solutions/1898-maximum-number-of-removable-characters.js b/solutions/1898-maximum-number-of-removable-characters.js new file mode 100644 index 00000000..1a4c15fa --- /dev/null +++ b/solutions/1898-maximum-number-of-removable-characters.js @@ -0,0 +1,51 @@ +/** + * 1898. Maximum Number of Removable Characters + * https://leetcode.com/problems/maximum-number-of-removable-characters/ + * Difficulty: Medium + * + * You are given two strings s and p where p is a subsequence of s. You are also given a distinct + * 0-indexed integer array removable containing a subset of indices of s (s is also 0-indexed). + * + * You want to choose an integer k (0 <= k <= removable.length) such that, after removing k + * characters from s using the first k indices in removable, p is still a subsequence of s. + * More formally, you will mark the character at s[removable[i]] for each 0 <= i < k, then + * remove all marked characters and check if p is still a subsequence. + * + * Return the maximum k you can choose such that p is still a subsequence of s after the removals. + * + * A subsequence of a string is a new string generated from the original string with some + * characters (can be none) deleted without changing the relative order of the remaining characters. + */ + +/** + * @param {string} s + * @param {string} p + * @param {number[]} removable + * @return {number} + */ +var maximumRemovals = function(s, p, removable) { + let left = 0; + let right = removable.length; + + while (left <= right) { + const mid = (left + right) >> 1; + const removed = new Set(removable.slice(0, mid)); + let i = 0; + let j = 0; + + while (i < s.length && j < p.length) { + if (!removed.has(i) && s[i] === p[j]) { + j++; + } + i++; + } + + if (j === p.length) { + left = mid + 1; + } else { + right = mid - 1; + } + } + + return right; +}; diff --git a/solutions/1899-merge-triplets-to-form-target-triplet.js b/solutions/1899-merge-triplets-to-form-target-triplet.js new file mode 100644 index 00000000..606dacf4 --- /dev/null +++ b/solutions/1899-merge-triplets-to-form-target-triplet.js @@ -0,0 +1,40 @@ +/** + * 1899. Merge Triplets to Form Target Triplet + * https://leetcode.com/problems/merge-triplets-to-form-target-triplet/ + * Difficulty: Medium + * + * A triplet is an array of three integers. You are given a 2D integer array triplets, where + * triplets[i] = [ai, bi, ci] describes the ith triplet. You are also given an integer array + * target = [x, y, z] that describes the triplet you want to obtain. + * + * To obtain target, you may apply the following operation on triplets any number of times + * (possibly zero): + * - Choose two indices (0-indexed) i and j (i != j) and update triplets[j] to become + * [max(ai, aj), max(bi, bj), max(ci, cj)]. + * - For example, if triplets[i] = [2, 5, 3] and triplets[j] = [1, 7, 5], triplets[j] will + * be updated to [max(2, 1), max(5, 7), max(3, 5)] = [2, 7, 5]. + * + * Return true if it is possible to obtain the target triplet [x, y, z] as an element of triplets, + * or false otherwise. + */ + +/** + * @param {number[][]} triplets + * @param {number[]} target + * @return {boolean} + */ +var mergeTriplets = function(triplets, target) { + let canFormX = false; + let canFormY = false; + let canFormZ = false; + + for (const [a, b, c] of triplets) { + if (a <= target[0] && b <= target[1] && c <= target[2]) { + if (a === target[0]) canFormX = true; + if (b === target[1]) canFormY = true; + if (c === target[2]) canFormZ = true; + } + } + + return canFormX && canFormY && canFormZ; +}; diff --git a/solutions/1900-the-earliest-and-latest-rounds-where-players-compete.js b/solutions/1900-the-earliest-and-latest-rounds-where-players-compete.js new file mode 100644 index 00000000..47d9293b --- /dev/null +++ b/solutions/1900-the-earliest-and-latest-rounds-where-players-compete.js @@ -0,0 +1,86 @@ +/** + * 1900. The Earliest and Latest Rounds Where Players Compete + * https://leetcode.com/problems/the-earliest-and-latest-rounds-where-players-compete/ + * Difficulty: Hard + * + * There is a tournament where n players are participating. The players are standing in a single row + * and are numbered from 1 to n based on their initial standing position (player 1 is the first + * player in the row, player 2 is the second player in the row, etc.). + * + * The tournament consists of multiple rounds (starting from round number 1). In each round, the ith + * player from the front of the row competes against the ith player from the end of the row, and the + * winner advances to the next round. When the number of players is odd for the current round, the + * player in the middle automatically advances to the next round. + * - For example, if the row consists of players 1, 2, 4, 6, 7 + * - Player 1 competes against player 7. + * - Player 2 competes against player 6. + * - Player 4 automatically advances to the next round. + * + * After each round is over, the winners are lined back up in the row based on the original ordering + * assigned to them initially (ascending order). + * + * The players numbered firstPlayer and secondPlayer are the best in the tournament. They can win + * against any other player before they compete against each other. If any two other players compete + * against each other, either of them might win, and thus you may choose the outcome of this round. + * + * Given the integers n, firstPlayer, and secondPlayer, return an integer array containing two + * values, the earliest possible round number and the latest possible round number in which these + * two players will compete against each other, respectively. + */ + +/** + * @param {number} n + * @param {number} firstPlayer + * @param {number} secondPlayer + * @return {number[]} + */ +var earliestAndLatest = function(numPlayers, firstPlayer, secondPlayer) { + let minRounds = Infinity; + let maxRounds = 0; + + dfs(0, 1); + + return [minRounds, maxRounds]; + + function dfs(playersEliminated, numRounds) { + let roundResults = [playersEliminated]; + let i = 1; + let j = numPlayers; + + while (true) { + while (playersEliminated & (1 << i)) i++; + while (playersEliminated & (1 << j)) j--; + + if (i >= j) break; + + if (i === firstPlayer && j === secondPlayer) { + minRounds = Math.min(minRounds, numRounds); + maxRounds = Math.max(maxRounds, numRounds); + return; + } + + const newRoundResults = []; + + if (j !== firstPlayer && j !== secondPlayer) { + for (const roundResult of roundResults) { + newRoundResults.push(roundResult | (1 << j)); + } + } + + if (i !== firstPlayer && i !== secondPlayer) { + for (const roundResult of roundResults) { + newRoundResults.push(roundResult | (1 << i)); + } + } + + i++; + j--; + roundResults = newRoundResults; + } + + if (!roundResults.length) return; + + numRounds++; + roundResults.forEach(roundResult => dfs(roundResult, numRounds)); + } +}; diff --git a/solutions/1901-find-a-peak-element-ii.js b/solutions/1901-find-a-peak-element-ii.js new file mode 100644 index 00000000..fc0a48ca --- /dev/null +++ b/solutions/1901-find-a-peak-element-ii.js @@ -0,0 +1,61 @@ +/** + * 1901. Find a Peak Element II + * https://leetcode.com/problems/find-a-peak-element-ii/ + * Difficulty: Medium + * + * A peak element in a 2D grid is an element that is strictly greater than all of its adjacent + * neighbors to the left, right, top, and bottom. + * + * Given a 0-indexed m x n matrix mat where no two adjacent cells are equal, find any peak element + * mat[i][j] and return the length 2 array [i,j]. + * + * You may assume that the entire matrix is surrounded by an outer perimeter with the value -1 in + * each cell. + * + * You must write an algorithm that runs in O(m log(n)) or O(n log(m)) time. + */ + +/** + * @param {number[][]} mat + * @return {number[]} + */ +var findPeakGrid = function(mat) { + const rows = mat.length; + const cols = mat[0].length; + + return binarySearch(0, rows - 1); + + function getMaxIndexInRow(row, left, right) { + let maxIndex = left; + for (let i = left; i <= right; i++) { + if (mat[row][i] > mat[row][maxIndex]) { + maxIndex = i; + } + } + return maxIndex; + } + + function binarySearch(startRow, endRow) { + if (startRow > endRow) return null; + + const midRow = Math.floor((startRow + endRow) / 2); + const maxCol = getMaxIndexInRow(midRow, 0, cols - 1); + const maxValue = mat[midRow][maxCol]; + + const topValue = midRow > 0 ? mat[midRow - 1][maxCol] : -1; + const bottomValue = midRow < rows - 1 ? mat[midRow + 1][maxCol] : -1; + const leftValue = maxCol > 0 ? mat[midRow][maxCol - 1] : -1; + const rightValue = maxCol < cols - 1 ? mat[midRow][maxCol + 1] : -1; + + if (maxValue > topValue && maxValue > bottomValue + && maxValue > leftValue && maxValue > rightValue) { + return [midRow, maxCol]; + } + + if (midRow > 0 && topValue > maxValue) { + return binarySearch(startRow, midRow - 1); + } + + return binarySearch(midRow + 1, endRow); + } +}; diff --git a/solutions/1903-largest-odd-number-in-string.js b/solutions/1903-largest-odd-number-in-string.js new file mode 100644 index 00000000..9914883e --- /dev/null +++ b/solutions/1903-largest-odd-number-in-string.js @@ -0,0 +1,24 @@ +/** + * 1903. Largest Odd Number in String + * https://leetcode.com/problems/largest-odd-number-in-string/ + * Difficulty: Easy + * + * You are given a string num, representing a large integer. Return the largest-valued odd + * integer (as a string) that is a non-empty substring of num, or an empty string "" if no + * odd integer exists. + * + * A substring is a contiguous sequence of characters within a string. + */ + +/** + * @param {string} num + * @return {string} + */ +var largestOddNumber = function(num) { + for (let i = num.length - 1; i >= 0; i--) { + if (parseInt(num[i]) % 2 === 1) { + return num.slice(0, i + 1); + } + } + return ''; +}; diff --git a/solutions/1904-the-number-of-full-rounds-you-have-played.js b/solutions/1904-the-number-of-full-rounds-you-have-played.js new file mode 100644 index 00000000..4c7ad2d6 --- /dev/null +++ b/solutions/1904-the-number-of-full-rounds-you-have-played.js @@ -0,0 +1,47 @@ +/** + * 1904. The Number of Full Rounds You Have Played + * https://leetcode.com/problems/the-number-of-full-rounds-you-have-played/ + * Difficulty: Medium + * + * You are participating in an online chess tournament. There is a chess round that starts + * every 15 minutes. The first round of the day starts at 00:00, and after every 15 minutes, + * a new round starts. + * - For example, the second round starts at 00:15, the fourth round starts at 00:45, and the + * seventh round starts at 01:30. + * + * You are given two strings loginTime and logoutTime where: + * - loginTime is the time you will login to the game, and + * - logoutTime is the time you will logout from the game. + * + * If logoutTime is earlier than loginTime, this means you have played from loginTime to midnight + * and from midnight to logoutTime. + * + * Return the number of full chess rounds you have played in the tournament. + * + * Note: All the given times follow the 24-hour clock. That means the first round of the day starts + * at 00:00 and the last round of the day starts at 23:45. + */ + +/** + * @param {string} loginTime + * @param {string} logoutTime + * @return {number} + */ +var numberOfRounds = function(loginTime, logoutTime) { + let start = toMinutes(loginTime); + let end = toMinutes(logoutTime); + + if (end < start) { + end += 24 * 60; + } + + start = Math.ceil(start / 15); + end = Math.floor(end / 15); + + return Math.max(0, end - start); + + function toMinutes(time) { + const [hours, minutes] = time.split(':').map(Number); + return hours * 60 + minutes; + } +}; diff --git a/solutions/1905-count-sub-islands.js b/solutions/1905-count-sub-islands.js new file mode 100644 index 00000000..d6cf98c8 --- /dev/null +++ b/solutions/1905-count-sub-islands.js @@ -0,0 +1,51 @@ +/** + * 1905. Count Sub Islands + * https://leetcode.com/problems/count-sub-islands/ + * Difficulty: Medium + * + * You are given two m x n binary matrices grid1 and grid2 containing only 0's (representing water) + * and 1's (representing land). An island is a group of 1's connected 4-directionally (horizontal + * or vertical). Any cells outside of the grid are considered water cells. + * + * An island in grid2 is considered a sub-island if there is an island in grid1 that contains all + * the cells that make up this island in grid2. + * + * Return the number of islands in grid2 that are considered sub-islands. + */ + +/** + * @param {number[][]} grid1 + * @param {number[][]} grid2 + * @return {number} + */ +var countSubIslands = function(grid1, grid2) { + const rows = grid1.length; + const cols = grid1[0].length; + let result = 0; + + for (let i = 0; i < rows; i++) { + for (let j = 0; j < cols; j++) { + if (grid2[i][j] === 1 && isValidSubIsland(i, j)) { + result++; + } + } + } + + return result; + + function isValidSubIsland(row, col) { + if (row < 0 || row >= rows || col < 0 || col >= cols || grid2[row][col] === 0) { + return true; + } + + grid2[row][col] = 0; + let isSubIsland = grid1[row][col] === 1; + + isSubIsland &= isValidSubIsland(row - 1, col); + isSubIsland &= isValidSubIsland(row + 1, col); + isSubIsland &= isValidSubIsland(row, col - 1); + isSubIsland &= isValidSubIsland(row, col + 1); + + return isSubIsland; + } +}; diff --git a/solutions/1906-minimum-absolute-difference-queries.js b/solutions/1906-minimum-absolute-difference-queries.js new file mode 100644 index 00000000..62cfc15f --- /dev/null +++ b/solutions/1906-minimum-absolute-difference-queries.js @@ -0,0 +1,57 @@ +/** + * 1906. Minimum Absolute Difference Queries + * https://leetcode.com/problems/minimum-absolute-difference-queries/ + * Difficulty: Medium + * + * The minimum absolute difference of an array a is defined as the minimum value of |a[i] - a[j]|, + * where 0 <= i < j < a.length and a[i] != a[j]. If all elements of a are the same, the minimum + * absolute difference is -1. + * - For example, the minimum absolute difference of the array [5,2,3,7,2] is |2 - 3| = 1. Note + * that it is not 0 because a[i] and a[j] must be different. + * + * You are given an integer array nums and the array queries where queries[i] = [li, ri]. For each + * query i, compute the minimum absolute difference of the subarray nums[li...ri] containing the + * elements of nums between the 0-based indices li and ri (inclusive). + * + * Return an array ans where ans[i] is the answer to the ith query. + * + * A subarray is a contiguous sequence of elements in an array. + * + * The value of |x| is defined as: + * - x if x >= 0. + * - -x if x < 0. + */ + +/** + * @param {number[]} nums + * @param {number[][]} queries + * @return {number[]} + */ +var minDifference = function(nums, queries) { + const maxValue = 100; + const prefixCounts = new Array(nums.length + 1).fill().map(() => new Array(maxValue + 1).fill(0)); + + for (let i = 0; i < nums.length; i++) { + for (let j = 1; j <= maxValue; j++) { + prefixCounts[i + 1][j] = prefixCounts[i][j] + (nums[i] === j ? 1 : 0); + } + } + + return queries.map(([start, end]) => getMinDiff(start, end)); + + function getMinDiff(start, end) { + let minDiff = Infinity; + let prevValue = -1; + + for (let j = 1; j <= maxValue; j++) { + if (prefixCounts[end + 1][j] - prefixCounts[start][j] > 0) { + if (prevValue !== -1) { + minDiff = Math.min(minDiff, j - prevValue); + } + prevValue = j; + } + } + + return minDiff === Infinity ? -1 : minDiff; + } +}; diff --git a/solutions/1909-remove-one-element-to-make-the-array-strictly-increasing.js b/solutions/1909-remove-one-element-to-make-the-array-strictly-increasing.js new file mode 100644 index 00000000..3e47a059 --- /dev/null +++ b/solutions/1909-remove-one-element-to-make-the-array-strictly-increasing.js @@ -0,0 +1,33 @@ +/** + * 1909. Remove One Element to Make the Array Strictly Increasing + * https://leetcode.com/problems/remove-one-element-to-make-the-array-strictly-increasing/ + * Difficulty: Easy + * + * Given a 0-indexed integer array nums, return true if it can be made strictly increasing after + * removing exactly one element, or false otherwise. If the array is already strictly increasing, + * return true. + * + * The array nums is strictly increasing if nums[i - 1] < nums[i] for each index + * (1 <= i < nums.length). + */ + +/** + * @param {number[]} nums + * @return {boolean} + */ +var canBeIncreasing = function(nums) { + for (let i = 0; i < nums.length; i++) { + if (isStrictlyIncreasing(nums, i)) return true; + } + + return false; + + function isStrictlyIncreasing(arr, skipIndex) { + for (let i = 1; i < arr.length; i++) { + if (i === skipIndex) continue; + const prev = i - 1 === skipIndex ? i - 2 : i - 1; + if (prev >= 0 && arr[i] <= arr[prev]) return false; + } + return true; + } +}; diff --git a/solutions/1911-maximum-alternating-subsequence-sum.js b/solutions/1911-maximum-alternating-subsequence-sum.js new file mode 100644 index 00000000..cd33635e --- /dev/null +++ b/solutions/1911-maximum-alternating-subsequence-sum.js @@ -0,0 +1,34 @@ +/** + * 1911. Maximum Alternating Subsequence Sum + * https://leetcode.com/problems/maximum-alternating-subsequence-sum/ + * Difficulty: Medium + * + * The alternating sum of a 0-indexed array is defined as the sum of the elements at even + * indices minus the sum of the elements at odd indices. + * - For example, the alternating sum of [4,2,5,3] is (4 + 5) - (2 + 3) = 4. + * + * Given an array nums, return the maximum alternating sum of any subsequence of nums (after + * reindexing the elements of the subsequence). + * + * A subsequence of an array is a new array generated from the original array by deleting some + * elements (possibly none) without changing the remaining elements' relative order. For + * example, [2,7,4] is a subsequence of [4,2,3,7,2,1,4] (the underlined elements), + * while [2,4,2] is not. + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var maxAlternatingSum = function(nums) { + let result = 0; + let oddSum = 0; + + for (const num of nums) { + const prevEven = result; + result = Math.max(result, oddSum + num); + oddSum = Math.max(oddSum, prevEven - num); + } + + return result; +}; diff --git a/solutions/1912-design-movie-rental-system.js b/solutions/1912-design-movie-rental-system.js new file mode 100644 index 00000000..8f07b991 --- /dev/null +++ b/solutions/1912-design-movie-rental-system.js @@ -0,0 +1,147 @@ +/** + * 1912. Design Movie Rental System + * https://leetcode.com/problems/design-movie-rental-system/ + * Difficulty: Hard + * + * You have a movie renting company consisting of n shops. You want to implement a renting system + * that supports searching for, booking, and returning movies. The system should also support + * generating a report of the currently rented movies. + * + * Each movie is given as a 2D integer array entries where entries[i] = [shopi, moviei, pricei] + * indicates that there is a copy of movie moviei at shop shopi with a rental price of pricei. + * Each shop carries at most one copy of a movie moviei. + * + * The system should support the following functions: + * - Search: Finds the cheapest 5 shops that have an unrented copy of a given movie. The shops + * should be sorted by price in ascending order, and in case of a tie, the one with the smaller + * shopi should appear first. If there are less than 5 matching shops, then all of them should be + * returned. If no shop has an unrented copy, then an empty list should be returned. + * - Rent: Rents an unrented copy of a given movie from a given shop. + * - Drop: Drops off a previously rented copy of a given movie at a given shop. + * - Report: Returns the cheapest 5 rented movies (possibly of the same movie ID) as a 2D list res + * where res[j] = [shopj, moviej] describes that the jth cheapest rented movie moviej was rented + * from the shop shopj. The movies in res should be sorted by price in ascending order, and in + * case of a tie, the one with the smaller shopj should appear first, and if there is still tie, + * the one with the smaller moviej should appear first. If there are fewer than 5 rented movies, + * then all of them should be returned. If no movies are currently being rented, then an empty + * list should be returned. + * + * Implement the MovieRentingSystem class: + * - MovieRentingSystem(int n, int[][] entries) Initializes the MovieRentingSystem object with n + * shops and the movies in entries. + * - List search(int movie) Returns a list of shops that have an unrented copy of the + * given movie as described above. + * - void rent(int shop, int movie) Rents the given movie from the given shop. + * - void drop(int shop, int movie) Drops off a previously rented movie at the given shop. + * - List> report() Returns a list of cheapest rented movies as described above. + * + * Note: The test cases will be generated such that rent will only be called if the shop has an + * unrented copy of the movie, and drop will only be called if the shop had previously rented out + * the movie. + */ + +/** + * @param {number} n + * @param {number[][]} entries + */ +var MovieRentingSystem = function(n, entries) { + this.shopMovies = new Map(); + this.movieShops = new Map(); + this.rented = new PriorityQueue((a, b) => { + if (a[2] !== b[2]) return a[2] - b[2]; + if (a[0] !== b[0]) return a[0] - b[0]; + return a[1] - b[1]; + }); + this.rentedLookup = new Map(); + + for (const [shop, movie, price] of entries) { + if (!this.shopMovies.has(shop)) { + this.shopMovies.set(shop, new Map()); + } + this.shopMovies.get(shop).set(movie, price); + + if (!this.movieShops.has(movie)) { + this.movieShops.set(movie, new PriorityQueue((a, b) => { + if (a[1] !== b[1]) return a[1] - b[1]; + return a[0] - b[0]; + })); + } + this.movieShops.get(movie).enqueue([shop, price]); + } +}; + +/** + * @param {number} movie + * @return {number[]} + */ +MovieRentingSystem.prototype.search = function(movie) { + if (!this.movieShops.has(movie)) return []; + + const queue = this.movieShops.get(movie); + const result = []; + const seen = new Set(); + + while (!queue.isEmpty() && result.length < 5) { + const [shop, price] = queue.dequeue(); + if (this.shopMovies.get(shop)?.has(movie) && !seen.has(shop)) { + result.push(shop); + seen.add(shop); + } + } + + for (const shop of result) { + queue.enqueue([shop, this.shopMovies.get(shop).get(movie)]); + } + + return result; +}; + +/** + * @param {number} shop + * @param {number} movie + * @return {void} + */ +MovieRentingSystem.prototype.rent = function(shop, movie) { + const price = this.shopMovies.get(shop).get(movie); + this.shopMovies.get(shop).delete(movie); + this.rented.enqueue([shop, movie, price]); + this.rentedLookup.set(`${shop}:${movie}`, price); +}; + +/** + * @param {number} shop + * @param {number} movie + * @return {void} + */ +MovieRentingSystem.prototype.drop = function(shop, movie) { + const price = this.rentedLookup.get(`${shop}:${movie}`); + this.rentedLookup.delete(`${shop}:${movie}`); + if (!this.shopMovies.get(shop).has(movie)) { + this.shopMovies.get(shop).set(movie, price); + this.movieShops.get(movie).enqueue([shop, price]); + } +}; + +/** + * @return {number[][]} + */ +MovieRentingSystem.prototype.report = function() { + const result = []; + const seen = new Set(); + + while (!this.rented.isEmpty() && result.length < 5) { + const [shop, movie, price] = this.rented.dequeue(); + const key = `${shop}:${movie}`; + if (this.rentedLookup.has(key) && !seen.has(key)) { + result.push([shop, movie]); + seen.add(key); + } + } + + for (const [shop, movie] of result) { + const price = this.rentedLookup.get(`${shop}:${movie}`); + this.rented.enqueue([shop, movie, price]); + } + + return result; +}; diff --git a/solutions/1913-maximum-product-difference-between-two-pairs.js b/solutions/1913-maximum-product-difference-between-two-pairs.js new file mode 100644 index 00000000..91e73220 --- /dev/null +++ b/solutions/1913-maximum-product-difference-between-two-pairs.js @@ -0,0 +1,42 @@ +/** + * 1913. Maximum Product Difference Between Two Pairs + * https://leetcode.com/problems/maximum-product-difference-between-two-pairs/ + * Difficulty: Easy + * + * The product difference between two pairs (a, b) and (c, d) is defined as (a * b) - (c * d). + * - For example, the product difference between (5, 6) and (2, 7) is (5 * 6) - (2 * 7) = 16. + * + * Given an integer array nums, choose four distinct indices w, x, y, and z such that the product + * difference between pairs (nums[w], nums[x]) and (nums[y], nums[z]) is maximized. + * + * Return the maximum such product difference. + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var maxProductDifference = function(nums) { + let max1 = 0; + let max2 = 0; + let min1 = Infinity; + let min2 = Infinity; + + for (const num of nums) { + if (num > max1) { + max2 = max1; + max1 = num; + } else if (num > max2) { + max2 = num; + } + + if (num < min1) { + min2 = min1; + min1 = num; + } else if (num < min2) { + min2 = num; + } + } + + return max1 * max2 - min1 * min2; +}; diff --git a/solutions/1914-cyclically-rotating-a-grid.js b/solutions/1914-cyclically-rotating-a-grid.js new file mode 100644 index 00000000..84724945 --- /dev/null +++ b/solutions/1914-cyclically-rotating-a-grid.js @@ -0,0 +1,66 @@ +/** + * 1914. Cyclically Rotating a Grid + * https://leetcode.com/problems/cyclically-rotating-a-grid/ + * Difficulty: Medium + * + * You are given an m x n integer matrix grid, where m and n are both even integers, and + * an integer k. + * + * The matrix is composed of several layers, which is shown in the below image, where each + * color is its own layer. + * + * A cyclic rotation of the matrix is done by cyclically rotating each layer in the matrix. + * To cyclically rotate a layer once, each element in the layer will take the place of the + * adjacent element in the counter-clockwise direction. An example rotation is shown below. + */ + +/** + * @param {number[][]} grid + * @param {number} k + * @return {number[][]} + */ +var rotateGrid = function(grid, k) { + const rows = grid.length; + const cols = grid[0].length; + const result = grid.map(row => [...row]); + + for (let layer = 0; layer < Math.min(rows, cols) / 2; layer++) { + rotateLayer(layer, layer, rows - 1 - layer, cols - 1 - layer, k); + } + + return result; + + function rotateLayer(top, left, bottom, right, rotations) { + if (top >= bottom || left >= right) return; + + const perimeter = 2 * (bottom - top + right - left); + const effectiveRotations = rotations % perimeter; + if (effectiveRotations === 0) return; + + const elements = []; + for (let i = top; i <= bottom; i++) elements.push(grid[i][left]); + for (let j = left + 1; j <= right; j++) elements.push(grid[bottom][j]); + for (let i = bottom - 1; i >= top; i--) elements.push(grid[i][right]); + for (let j = right - 1; j > left; j--) elements.push(grid[top][j]); + + const offset = (perimeter - effectiveRotations) % perimeter; + let index = offset; + + for (let i = top; i <= bottom; i++) { + result[i][left] = elements[index % perimeter]; + index++; + } + for (let j = left + 1; j <= right; j++) { + result[bottom][j] = elements[index % perimeter]; + index++; + } + for (let i = bottom - 1; i >= top; i--) { + result[i][right] = elements[index % perimeter]; + index++; + } + for (let j = right - 1; j > left; j--) { + result[top][j] = elements[index % perimeter]; + index++; + } + } +}; diff --git a/solutions/1915-number-of-wonderful-substrings.js b/solutions/1915-number-of-wonderful-substrings.js new file mode 100644 index 00000000..b9aaf680 --- /dev/null +++ b/solutions/1915-number-of-wonderful-substrings.js @@ -0,0 +1,39 @@ +/** + * 1915. Number of Wonderful Substrings + * https://leetcode.com/problems/number-of-wonderful-substrings/ + * Difficulty: Medium + * + * A wonderful string is a string where at most one letter appears an odd number of times. + * - For example, "ccjjc" and "abab" are wonderful, but "ab" is not. + * + * Given a string word that consists of the first ten lowercase English letters ('a' through + * 'j'), return the number of wonderful non-empty substrings in word. If the same substring + * appears multiple times in word, then count each occurrence separately. + * + * A substring is a contiguous sequence of characters in a string. + */ + +/** + * @param {string} word + * @return {number} + */ +var wonderfulSubstrings = function(word) { + let count = 0; + const freq = new Map([[0, 1]]); + let state = 0; + + for (const char of word) { + const bit = 1 << (char.charCodeAt(0) - 97); + state ^= bit; + + count += freq.get(state) || 0; + freq.set(state, (freq.get(state) || 0) + 1); + + for (let i = 0; i < 10; i++) { + const oddBit = state ^ (1 << i); + count += freq.get(oddBit) || 0; + } + } + + return count; +}; diff --git a/solutions/1916-count-ways-to-build-rooms-in-an-ant-colony.js b/solutions/1916-count-ways-to-build-rooms-in-an-ant-colony.js new file mode 100644 index 00000000..93f715af --- /dev/null +++ b/solutions/1916-count-ways-to-build-rooms-in-an-ant-colony.js @@ -0,0 +1,71 @@ +/** + * 1916. Count Ways to Build Rooms in an Ant Colony + * https://leetcode.com/problems/count-ways-to-build-rooms-in-an-ant-colony/ + * Difficulty: Hard + * + * You are an ant tasked with adding n new rooms numbered 0 to n-1 to your colony. You are given + * the expansion plan as a 0-indexed integer array of length n, prevRoom, where prevRoom[i] + * indicates that you must build room prevRoom[i] before building room i, and these two rooms + * must be connected directly. Room 0 is already built, so prevRoom[0] = -1. The expansion plan + * is given such that once all the rooms are built, every room will be reachable from room 0. + * + * You can only build one room at a time, and you can travel freely between rooms you have + * already built only if they are connected. You can choose to build any room as long as its + * previous room is already built. + * + * Return the number of different orders you can build all the rooms in. Since the answer may + * be large, return it modulo 109 + 7. + */ + +/** + * @param {number[]} prevRoom + * @return {number} + */ +var waysToBuildRooms = function(prevRoom) { + const n = prevRoom.length; + const mod = 1e9 + 7; + const graph = Array(n).fill().map(() => []); + const factorial = Array(n + 1).fill(1n); + const invFactorial = Array(n + 1).fill(1n); + + for (let i = 1; i <= n; i++) { + factorial[i] = (factorial[i - 1] * BigInt(i)) % BigInt(mod); + } + + for (let i = 1; i <= n; i++) { + invFactorial[i] = modInverse(factorial[i], BigInt(mod)); + } + + for (let i = 1; i < n; i++) { + graph[prevRoom[i]].push(i); + } + + return Number(countSubtreeSizes(0)[1]); + + function countSubtreeSizes(node) { + let size = 1; + let result = 1n; + + for (const child of graph[node]) { + const [childSize, childResult] = countSubtreeSizes(child); + size += childSize; + result = (result * childResult * invFactorial[childSize]) % BigInt(mod); + } + + return [size, (result * factorial[size - 1]) % BigInt(mod)]; + } + + function modInverse(a, m) { + const m0 = m; + let q; + let x0 = 0n; + let x1 = 1n; + + while (a > 1n) { + q = a / m; + [a, m] = [m, a % m]; + [x0, x1] = [x1 - q * x0, x0]; + } + return x1 < 0n ? x1 + m0 : x1; + } +}; diff --git a/solutions/1921-eliminate-maximum-number-of-monsters.js b/solutions/1921-eliminate-maximum-number-of-monsters.js new file mode 100644 index 00000000..e9f43cd1 --- /dev/null +++ b/solutions/1921-eliminate-maximum-number-of-monsters.js @@ -0,0 +1,47 @@ +/** + * 1921. Eliminate Maximum Number of Monsters + * https://leetcode.com/problems/eliminate-maximum-number-of-monsters/ + * Difficulty: Medium + * + * You are playing a video game where you are defending your city from a group of n monsters. You + * are given a 0-indexed integer array dist of size n, where dist[i] is the initial distance in + * kilometers of the ith monster from the city. + * + * The monsters walk toward the city at a constant speed. The speed of each monster is given to + * you in an integer array speed of size n, where speed[i] is the speed of the ith monster in + * kilometers per minute. + * + * You have a weapon that, once fully charged, can eliminate a single monster. However, the weapon + * takes one minute to charge. The weapon is fully charged at the very start. + * + * You lose when any monster reaches your city. If a monster reaches the city at the exact moment + * the weapon is fully charged, it counts as a loss, and the game ends before you can use your + * weapon. + * + * Return the maximum number of monsters that you can eliminate before you lose, or n if you can + * eliminate all the monsters before they reach the city. + */ + +/** + * @param {number[]} dist + * @param {number[]} speed + * @return {number} + */ +var eliminateMaximum = function(dist, speed) { + const n = dist.length; + const arrivalTimes = new Array(n); + + for (let i = 0; i < n; i++) { + arrivalTimes[i] = dist[i] / speed[i]; + } + + arrivalTimes.sort((a, b) => a - b); + + for (let i = 0; i < n; i++) { + if (arrivalTimes[i] <= i) { + return i; + } + } + + return n; +}; diff --git a/solutions/1923-longest-common-subpath.js b/solutions/1923-longest-common-subpath.js new file mode 100644 index 00000000..1c2e1b0d --- /dev/null +++ b/solutions/1923-longest-common-subpath.js @@ -0,0 +1,148 @@ +/** + * 1923. Longest Common Subpath + * https://leetcode.com/problems/longest-common-subpath/ + * Difficulty: Hard + * + * There is a country of n cities numbered from 0 to n - 1. In this country, there is a road + * connecting every pair of cities. + * + * There are m friends numbered from 0 to m - 1 who are traveling through the country. Each one + * of them will take a path consisting of some cities. Each path is represented by an integer + * array that contains the visited cities in order. The path may contain a city more than once, + * but the same city will not be listed consecutively. + * + * Given an integer n and a 2D integer array paths where paths[i] is an integer array representing + * the path of the ith friend, return the length of the longest common subpath that is shared + * by every friend's path, or 0 if there is no common subpath at all. + * + * A subpath of a path is a contiguous sequence of cities within that path. + */ + +/** + * @param {number} n + * @param {number[][]} paths + * @return {number} + */ +var longestCommonSubpath = function(n, paths) { + if (paths.length === 0) return 0; + + paths.sort((a, b) => a.length - b.length); + + let left = 0; + let right = paths[0].length; + + while (left <= right) { + const mid = Math.floor((left + right) / 2); + + if (checkCommonSubpathExists(paths, mid)) { + left = mid + 1; + } else { + right = mid - 1; + } + } + + return right; +}; + +function checkCommonSubpathExists(paths, length) { + if (length === 0) return true; + + const firstPath = paths[0]; + + if (firstPath.length < length) return false; + + const prime = 1000000007; + const base = 100003; + + let highestPower = 1; + for (let i = 0; i < length - 1; i++) { + highestPower = (highestPower * base) % prime; + } + + let hashToPositions = new Map(); + + let hash = 0; + for (let i = 0; i < length; i++) { + hash = (hash * base + firstPath[i]) % prime; + } + + if (!hashToPositions.has(hash)) { + hashToPositions.set(hash, []); + } + hashToPositions.get(hash).push(0); + + for (let i = 1; i <= firstPath.length - length; i++) { + hash = ((hash - firstPath[i - 1] * highestPower % prime + prime) + % prime * base + firstPath[i + length - 1]) % prime; + + if (!hashToPositions.has(hash)) { + hashToPositions.set(hash, []); + } + hashToPositions.get(hash).push(i); + } + + for (let pathIdx = 1; pathIdx < paths.length; pathIdx++) { + const path = paths[pathIdx]; + + if (path.length < length) return false; + + const newHashToPositions = new Map(); + hash = 0; + for (let i = 0; i < length; i++) { + hash = (hash * base + path[i]) % prime; + } + + if (hashToPositions.has(hash)) { + const positions = hashToPositions.get(hash); + for (const pos of positions) { + let isMatch = true; + for (let j = 0; j < length; j++) { + if (firstPath[pos + j] !== path[j]) { + isMatch = false; + break; + } + } + + if (isMatch) { + if (!newHashToPositions.has(hash)) { + newHashToPositions.set(hash, []); + } + newHashToPositions.get(hash).push(pos); + break; + } + } + } + + for (let i = 1; i <= path.length - length; i++) { + hash = ((hash - path[i - 1] * highestPower % prime + prime) + % prime * base + path[i + length - 1]) % prime; + + if (hashToPositions.has(hash)) { + const positions = hashToPositions.get(hash); + for (const pos of positions) { + let isMatch = true; + for (let j = 0; j < length; j++) { + if (firstPath[pos + j] !== path[i + j]) { + isMatch = false; + break; + } + } + + if (isMatch) { + if (!newHashToPositions.has(hash)) { + newHashToPositions.set(hash, []); + } + newHashToPositions.get(hash).push(pos); + break; + } + } + } + } + + if (newHashToPositions.size === 0) return false; + + hashToPositions = newHashToPositions; + } + + return hashToPositions.size > 0; +} diff --git a/solutions/1925-count-square-sum-triples.js b/solutions/1925-count-square-sum-triples.js new file mode 100644 index 00000000..b917c4e1 --- /dev/null +++ b/solutions/1925-count-square-sum-triples.js @@ -0,0 +1,29 @@ +/** + * 1925. Count Square Sum Triples + * https://leetcode.com/problems/count-square-sum-triples/ + * Difficulty: Easy + * + * A square triple (a,b,c) is a triple where a, b, and c are integers and a2 + b2 = c2. + * + * Given an integer n, return the number of square triples such that 1 <= a, b, c <= n. + */ + +/** + * @param {number} n + * @return {number} + */ +var countTriples = function(n) { + let result = 0; + + for (let a = 1; a <= n; a++) { + for (let b = 1; b <= n; b++) { + const sum = a * a + b * b; + const c = Math.sqrt(sum); + if (c <= n && Number.isInteger(c)) { + result++; + } + } + } + + return result; +}; diff --git a/solutions/1927-sum-game.js b/solutions/1927-sum-game.js new file mode 100644 index 00000000..178435f2 --- /dev/null +++ b/solutions/1927-sum-game.js @@ -0,0 +1,56 @@ +/** + * 1927. Sum Game + * https://leetcode.com/problems/sum-game/ + * Difficulty: Medium + * + * Alice and Bob take turns playing a game, with Alice starting first. + * + * You are given a string num of even length consisting of digits and '?' characters. On each + * turn, a player will do the following if there is still at least one '?' in num: + * 1. Choose an index i where num[i] == '?'. + * 2. Replace num[i] with any digit between '0' and '9'. + * + * The game ends when there are no more '?' characters in num. + * + * For Bob to win, the sum of the digits in the first half of num must be equal to the sum of + * the digits in the second half. For Alice to win, the sums must not be equal. + * - For example, if the game ended with num = "243801", then Bob wins because 2+4+3 = 8+0+1. + * If the game ended with num = "243803", then Alice wins because 2+4+3 != 8+0+3. + * + * Assuming Alice and Bob play optimally, return true if Alice will win and false if Bob will win. + */ + +/** + * @param {string} num + * @return {boolean} + */ +var sumGame = function(num) { + const n = num.length; + const half = n / 2; + + let leftSum = 0; + let rightSum = 0; + let leftQuestionMarks = 0; + let rightQuestionMarks = 0; + + for (let i = 0; i < n; i++) { + if (i < half) { + if (num[i] === '?') { + leftQuestionMarks++; + } else { + leftSum += parseInt(num[i]); + } + } else { + if (num[i] === '?') { + rightQuestionMarks++; + } else { + rightSum += parseInt(num[i]); + } + } + } + + const sumDiff = leftSum - rightSum; + const diff = leftQuestionMarks - rightQuestionMarks; + + return (diff % 2 !== 0) || (sumDiff + diff * 4.5 !== 0); +}; diff --git a/solutions/1928-minimum-cost-to-reach-destination-in-time.js b/solutions/1928-minimum-cost-to-reach-destination-in-time.js new file mode 100644 index 00000000..a601d545 --- /dev/null +++ b/solutions/1928-minimum-cost-to-reach-destination-in-time.js @@ -0,0 +1,66 @@ +/** + * 1928. Minimum Cost to Reach Destination in Time + * https://leetcode.com/problems/minimum-cost-to-reach-destination-in-time/ + * Difficulty: Hard + * + * There is a country of n cities numbered from 0 to n - 1 where all the cities are connected by + * bi-directional roads. The roads are represented as a 2D integer array edges where + * edges[i] = [xi, yi, timei] denotes a road between cities xi and yi that takes timei minutes + * to travel. There may be multiple roads of differing travel times connecting the same two + * cities, but no road connects a city to itself. + * + * Each time you pass through a city, you must pay a passing fee. This is represented as a + * 0-indexed integer array passingFees of length n where passingFees[j] is the amount of dollars + * you must pay when you pass through city j. + * + * In the beginning, you are at city 0 and want to reach city n - 1 in maxTime minutes or less. + * The cost of your journey is the summation of passing fees for each city that you passed + * through at some moment of your journey (including the source and destination cities). + * + * Given maxTime, edges, and passingFees, return the minimum cost to complete your journey, + * or -1 if you cannot complete it within maxTime minutes. + */ + +/** + * @param {number} maxTime + * @param {number[][]} edges + * @param {number[]} passingFees + * @return {number} + */ +var minCost = function(maxTime, edges, passingFees) { + const n = passingFees.length; + const dp = new Array(n).fill().map(() => new Array(maxTime + 1).fill(Infinity)); + dp[0][0] = passingFees[0]; + + const graph = new Array(n).fill().map(() => []); + for (const [u, v, time] of edges) { + graph[u].push([v, time]); + graph[v].push([u, time]); + } + + const pq = new PriorityQueue((a, b) => a.cost - b.cost); + pq.enqueue({ cost: passingFees[0], city: 0, time: 0 }); + + while (!pq.isEmpty()) { + const { cost, city, time } = pq.dequeue(); + if (cost > dp[city][time]) continue; + + for (const [nextCity, travelTime] of graph[city]) { + const newTime = time + travelTime; + if (newTime > maxTime) continue; + + const newCost = cost + passingFees[nextCity]; + if (newCost < dp[nextCity][newTime]) { + dp[nextCity][newTime] = newCost; + pq.enqueue({ cost: newCost, city: nextCity, time: newTime }); + } + } + } + + let minCost = Infinity; + for (let t = 0; t <= maxTime; t++) { + minCost = Math.min(minCost, dp[n - 1][t]); + } + + return minCost === Infinity ? -1 : minCost; +}; diff --git a/solutions/1931-painting-a-grid-with-three-different-colors.js b/solutions/1931-painting-a-grid-with-three-different-colors.js new file mode 100644 index 00000000..ef8bf15b --- /dev/null +++ b/solutions/1931-painting-a-grid-with-three-different-colors.js @@ -0,0 +1,72 @@ +/** + * 1931. Painting a Grid With Three Different Colors + * https://leetcode.com/problems/painting-a-grid-with-three-different-colors/ + * Difficulty: Hard + * + * You are given two integers m and n. Consider an m x n grid where each cell is initially white. + * You can paint each cell red, green, or blue. All cells must be painted. + * + * Return the number of ways to color the grid with no two adjacent cells having the same color. + * Since the answer can be very large, return it modulo 109 + 7. + */ + +/** + * @param {number} m + * @param {number} n + * @return {number} + */ +var colorTheGrid = function(m, n) { + const MOD = 1e9 + 7; + const colors = 3; + const validStates = generateValidStates(m, colors); + const stateCount = validStates.length; + let dp = new Array(stateCount).fill(1); + + for (let col = 1; col < n; col++) { + const nextDp = new Array(stateCount).fill(0); + for (let i = 0; i < stateCount; i++) { + for (let j = 0; j < stateCount; j++) { + if (isCompatible(validStates[i], validStates[j])) { + nextDp[j] = (nextDp[j] + dp[i]) % MOD; + } + } + } + dp = nextDp; + } + + let totalWays = 0; + for (const count of dp) { + totalWays = (totalWays + count) % MOD; + } + + return totalWays; + + function generateValidStates(rows, colors) { + const states = []; + generateStates([], rows, colors, states); + return states; + } + + function generateStates(current, rows, colors, states) { + if (current.length === rows) { + states.push([...current]); + return; + } + for (let c = 0; c < colors; c++) { + if (current.length === 0 || current[current.length - 1] !== c) { + current.push(c); + generateStates(current, rows, colors, states); + current.pop(); + } + } + } + + function isCompatible(prevState, currState) { + for (let i = 0; i < prevState.length; i++) { + if (prevState[i] === currState[i]) { + return false; + } + } + return true; + } +}; diff --git a/solutions/1932-merge-bsts-to-create-single-bst.js b/solutions/1932-merge-bsts-to-create-single-bst.js new file mode 100644 index 00000000..a118a41a --- /dev/null +++ b/solutions/1932-merge-bsts-to-create-single-bst.js @@ -0,0 +1,86 @@ +/** + * 1932. Merge BSTs to Create Single BST + * https://leetcode.com/problems/merge-bsts-to-create-single-bst/ + * Difficulty: Hard + * + * You are given n BST (binary search tree) root nodes for n separate BSTs stored in an array + * trees (0-indexed). Each BST in trees has at most 3 nodes, and no two roots have the same + * value. In one operation, you can: + * - Select two distinct indices i and j such that the value stored at one of the leaves of + * trees[i] is equal to the root value of trees[j]. + * - Replace the leaf node in trees[i] with trees[j]. + * - Remove trees[j] from trees. + * + * Return the root of the resulting BST if it is possible to form a valid BST after + * performing n - 1 operations, or null if it is impossible to create a valid BST. + * + * A BST (binary search tree) is a binary tree where each node satisfies the following property: + * - Every node in the node's left subtree has a value strictly less than the node's value. + * - Every node in the node's right subtree has a value strictly greater than the node's value. + * + * A leaf is a node that has no children. + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {TreeNode[]} trees + * @return {TreeNode} + */ +var canMerge = function(trees) { + const valueToTree = new Map(); + const leafValues = new Set(); + const inDegree = new Map(); + + for (const tree of trees) { + valueToTree.set(tree.val, tree); + if (tree.left) leafValues.add(tree.left.val); + if (tree.right) leafValues.add(tree.right.val); + } + + let root = null; + for (const tree of trees) { + if (!leafValues.has(tree.val)) { + if (root) return null; + root = tree; + } + if (tree.left) inDegree.set(tree.left.val, (inDegree.get(tree.left.val) || 0) + 1); + if (tree.right) inDegree.set(tree.right.val, (inDegree.get(tree.right.val) || 0) + 1); + } + + if (!root) return null; + + const merged = mergeTrees(root, valueToTree, inDegree); + if (!merged || valueToTree.size > 1 || !isValidBST(merged, -Infinity, Infinity)) { + return null; + } + + return merged; + + function mergeTrees(node, valueToTree, inDegree) { + if (!node) return node; + + if (!node.left && !node.right && valueToTree.has(node.val) && inDegree.get(node.val) === 1) { + const tree = valueToTree.get(node.val); + if (tree === node) return node; + valueToTree.delete(node.val); + return mergeTrees(tree, valueToTree, inDegree); + } + + node.left = mergeTrees(node.left, valueToTree, inDegree); + node.right = mergeTrees(node.right, valueToTree, inDegree); + return node; + } + + function isValidBST(node, min, max) { + if (!node) return true; + if (node.val <= min || node.val >= max) return false; + return isValidBST(node.left, min, node.val) && isValidBST(node.right, node.val, max); + } +}; diff --git a/solutions/1936-add-minimum-number-of-rungs.js b/solutions/1936-add-minimum-number-of-rungs.js new file mode 100644 index 00000000..2dba6511 --- /dev/null +++ b/solutions/1936-add-minimum-number-of-rungs.js @@ -0,0 +1,36 @@ +/** + * 1936. Add Minimum Number of Rungs + * https://leetcode.com/problems/add-minimum-number-of-rungs/ + * Difficulty: Medium + * + * You are given a strictly increasing integer array rungs that represents the height of rungs + * on a ladder. You are currently on the floor at height 0, and you want to reach the last rung. + * + * You are also given an integer dist. You can only climb to the next highest rung if the + * distance between where you are currently at (the floor or on a rung) and the next rung is + * at most dist. You are able to insert rungs at any positive integer height if a rung is not + * already there. + * + * Return the minimum number of rungs that must be added to the ladder in order for you to climb + * to the last rung. + */ + +/** + * @param {number[]} rungs + * @param {number} dist + * @return {number} + */ +var addRungs = function(rungs, dist) { + let currentHeight = 0; + let result = 0; + + for (const rung of rungs) { + const gap = rung - currentHeight; + if (gap > dist) { + result += Math.ceil(gap / dist) - 1; + } + currentHeight = rung; + } + + return result; +}; diff --git a/solutions/1937-maximum-number-of-points-with-cost.js b/solutions/1937-maximum-number-of-points-with-cost.js new file mode 100644 index 00000000..288c1888 --- /dev/null +++ b/solutions/1937-maximum-number-of-points-with-cost.js @@ -0,0 +1,55 @@ +/** + * 1937. Maximum Number of Points with Cost + * https://leetcode.com/problems/maximum-number-of-points-with-cost/ + * Difficulty: Medium + * + * You are given an m x n integer matrix points (0-indexed). Starting with 0 points, you want + * to maximize the number of points you can get from the matrix. + * + * To gain points, you must pick one cell in each row. Picking the cell at coordinates (r, c) + * will add points[r][c] to your score. + * + * However, you will lose points if you pick a cell too far from the cell that you picked in + * the previous row. For every two adjacent rows r and r + 1 (where 0 <= r < m - 1), picking + * cells at coordinates (r, c1) and (r + 1, c2) will subtract abs(c1 - c2) from your score. + * + * Return the maximum number of points you can achieve. + * + * abs(x) is defined as: + * - x for x >= 0. + * - -x for x < 0. + */ + +/** + * @param {number[][]} points + * @return {number} + */ +var maxPoints = function(points) { + const rows = points.length; + const cols = points[0].length; + let prevRow = points[0].slice(); + + for (let r = 1; r < rows; r++) { + const currRow = new Array(cols).fill(0); + const leftMax = new Array(cols).fill(0); + const rightMax = new Array(cols).fill(0); + + leftMax[0] = prevRow[0]; + for (let c = 1; c < cols; c++) { + leftMax[c] = Math.max(leftMax[c - 1] - 1, prevRow[c]); + } + + rightMax[cols - 1] = prevRow[cols - 1]; + for (let c = cols - 2; c >= 0; c--) { + rightMax[c] = Math.max(rightMax[c + 1] - 1, prevRow[c]); + } + + for (let c = 0; c < cols; c++) { + currRow[c] = points[r][c] + Math.max(leftMax[c], rightMax[c]); + } + + prevRow = currRow; + } + + return Math.max(...prevRow); +}; diff --git a/solutions/1938-maximum-genetic-difference-query.js b/solutions/1938-maximum-genetic-difference-query.js new file mode 100644 index 00000000..e7b88f18 --- /dev/null +++ b/solutions/1938-maximum-genetic-difference-query.js @@ -0,0 +1,97 @@ +/** + * 1938. Maximum Genetic Difference Query + * https://leetcode.com/problems/maximum-genetic-difference-query/ + * Difficulty: Hard + * + * There is a rooted tree consisting of n nodes numbered 0 to n - 1. Each node's number denotes + * its unique genetic value (i.e. the genetic value of node x is x). The genetic difference + * between two genetic values is defined as the bitwise-XOR of their values. You are given + * the integer array parents, where parents[i] is the parent for node i. If node x is the root + * of the tree, then parents[x] == -1. + * + * You are also given the array queries where queries[i] = [nodei, vali]. For each query i, + * find the maximum genetic difference between vali and pi, where pi is the genetic value of + * any node that is on the path between nodei and the root (including nodei and the root). + * More formally, you want to maximize vali XOR pi. + * + * Return an array ans where ans[i] is the answer to the ith query. + */ + +/** + * @param {number[]} parents + * @param {number[][]} queries + * @return {number[]} + */ +var maxGeneticDifference = function(parents, queries) { + const n = parents.length; + const graph = Array(n).fill().map(() => []); + let root = -1; + + for (let i = 0; i < n; i++) { + if (parents[i] === -1) { + root = i; + } else { + graph[parents[i]].push(i); + } + } + + const trie = { count: 0, children: {} }; + const queryMap = Array(n).fill().map(() => []); + const result = new Array(queries.length).fill(0); + + for (let i = 0; i < queries.length; i++) { + queryMap[queries[i][0]].push([queries[i][1], i]); + } + + dfs(root); + return result; + + function insertTrie(val) { + let node = trie; + for (let bit = 17; bit >= 0; bit--) { + const b = (val >> bit) & 1; + if (!node.children[b]) { + node.children[b] = { count: 0, children: {} }; + } + node = node.children[b]; + node.count++; + } + } + + function removeTrie(val) { + let node = trie; + for (let bit = 17; bit >= 0; bit--) { + const b = (val >> bit) & 1; + node = node.children[b]; + node.count--; + } + } + + function queryTrie(val) { + let node = trie; + let maxXor = 0; + for (let bit = 17; bit >= 0; bit--) { + const b = (val >> bit) & 1; + if (node.children[1 - b]?.count > 0) { + maxXor |= (1 << bit); + node = node.children[1 - b]; + } else if (node.children[b]?.count > 0) { + node = node.children[b]; + } else { + return maxXor; + } + } + return maxXor; + } + + function dfs(node) { + insertTrie(node); + for (const [val, idx] of queryMap[node]) { + result[idx] = queryTrie(val); + } + for (const child of graph[node]) { + dfs(child); + } + removeTrie(node); + } +}; diff --git a/solutions/1941-check-if-all-characters-have-equal-number-of-occurrences.js b/solutions/1941-check-if-all-characters-have-equal-number-of-occurrences.js new file mode 100644 index 00000000..aa742eb2 --- /dev/null +++ b/solutions/1941-check-if-all-characters-have-equal-number-of-occurrences.js @@ -0,0 +1,24 @@ +/** + * 1941. Check if All Characters Have Equal Number of Occurrences + * https://leetcode.com/problems/check-if-all-characters-have-equal-number-of-occurrences/ + * Difficulty: Easy + * + * Given a string s, return true if s is a good string, or false otherwise. + * + * A string s is good if all the characters that appear in s have the same number of occurrences + * (i.e., the same frequency). + */ + +/** + * @param {string} s + * @return {boolean} + */ +var areOccurrencesEqual = function(s) { + const map = new Map(); + for (const char of s) { + map.set(char, (map.get(char) || 0) + 1); + } + + const frequencies = new Set(map.values()); + return frequencies.size === 1; +}; diff --git a/solutions/1943-describe-the-painting.js b/solutions/1943-describe-the-painting.js new file mode 100644 index 00000000..3e5c287a --- /dev/null +++ b/solutions/1943-describe-the-painting.js @@ -0,0 +1,60 @@ +/** + * 1943. Describe the Painting + * https://leetcode.com/problems/describe-the-painting/ + * Difficulty: Medium + * + * There is a long and thin painting that can be represented by a number line. The painting was + * painted with multiple overlapping segments where each segment was painted with a unique color. + * You are given a 2D integer array segments, where segments[i] = [starti, endi, colori] + * represents the half-closed segment [starti, endi) with colori as the color. + * + * The colors in the overlapping segments of the painting were mixed when it was painted. When + * two or more colors mix, they form a new color that can be represented as a set of mixed colors. + * - For example, if colors 2, 4, and 6 are mixed, then the resulting mixed color is {2,4,6}. + * + * For the sake of simplicity, you should only output the sum of the elements in the set rather + * than the full set. + * + * You want to describe the painting with the minimum number of non-overlapping half-closed + * segments of these mixed colors. These segments can be represented by the 2D array painting + * where painting[j] = [leftj, rightj, mixj] describes a half-closed segment [leftj, rightj) + * with the mixed color sum of mixj. + * - For example, the painting created with segments = [[1,4,5],[1,7,7]] can be described by + * painting = [[1,4,12],[4,7,7]] because: + * - [1,4) is colored {5,7} (with a sum of 12) from both the first and second segments. + * - [4,7) is colored {7} from only the second segment. + * + * Return the 2D array painting describing the finished painting (excluding any parts that are + * not painted). You may return the segments in any order. + * + * A half-closed segment [a, b) is the section of the number line between points a and b including + * point a and not including point b. + */ + +/** + * @param {number[][]} segments + * @return {number[][]} + */ +var splitPainting = function(segments) { + const events = []; + for (const [start, end, color] of segments) { + events.push([start, color]); + events.push([end, -color]); + } + + events.sort((a, b) => a[0] - b[0] || a[1] - b[1]); + + const result = []; + let currentSum = 0; + let prevPoint = events[0][0]; + + for (const [point, color] of events) { + if (currentSum > 0 && point > prevPoint) { + result.push([prevPoint, point, currentSum]); + } + currentSum += color; + prevPoint = point; + } + + return result; +}; diff --git a/solutions/1944-number-of-visible-people-in-a-queue.js b/solutions/1944-number-of-visible-people-in-a-queue.js new file mode 100644 index 00000000..8297710b --- /dev/null +++ b/solutions/1944-number-of-visible-people-in-a-queue.js @@ -0,0 +1,39 @@ +/** + * 1944. Number of Visible People in a Queue + * https://leetcode.com/problems/number-of-visible-people-in-a-queue/ + * Difficulty: Hard + * + * There are n people standing in a queue, and they numbered from 0 to n - 1 in left to right + * order. You are given an array heights of distinct integers where heights[i] represents the + * height of the ith person. + * + * A person can see another person to their right in the queue if everybody in between is + * shorter than both of them. More formally, the ith person can see the jth person + * if i < j and min(heights[i], heights[j]) > max(heights[i+1], heights[i+2], ..., heights[j-1]). + * + * Return an array answer of length n where answer[i] is the number of people the ith person + * can see to their right in the queue. + */ + +/** + * @param {number[]} heights + * @return {number[]} + */ +var canSeePersonsCount = function(heights) { + const n = heights.length; + const result = new Array(n).fill(0); + const stack = []; + + for (let i = n - 1; i >= 0; i--) { + while (stack.length && heights[i] > stack[stack.length - 1]) { + stack.pop(); + result[i]++; + } + if (stack.length) { + result[i]++; + } + stack.push(heights[i]); + } + + return result; +}; diff --git a/solutions/1945-sum-of-digits-of-string-after-convert.js b/solutions/1945-sum-of-digits-of-string-after-convert.js new file mode 100644 index 00000000..7e6e47d1 --- /dev/null +++ b/solutions/1945-sum-of-digits-of-string-after-convert.js @@ -0,0 +1,44 @@ +/** + * 1945. Sum of Digits of String After Convert + * https://leetcode.com/problems/sum-of-digits-of-string-after-convert/ + * Difficulty: Easy + * + * You are given a string s consisting of lowercase English letters, and an integer k. Your task + * is to convert the string into an integer by a special process, and then transform it by + * summing its digits repeatedly k times. More specifically, perform the following steps: + * 1. Convert s into an integer by replacing each letter with its position in the alphabet (i.e. + * replace 'a' with 1, 'b' with 2, ..., 'z' with 26). + * 2. Transform the integer by replacing it with the sum of its digits. + * 3. Repeat the transform operation (step 2) k times in total. + * + * For example, if s = "zbax" and k = 2, then the resulting integer would be 8 by the following + * operations: + * 1. Convert: "zbax" ➝ "(26)(2)(1)(24)" ➝ "262124" ➝ 262124 + * 2. Transform #1: 262124 ➝ 2 + 6 + 2 + 1 + 2 + 4 ➝ 17 + * 3. Transform #2: 17 ➝ 1 + 7 ➝ 8 + * + * Return the resulting integer after performing the operations described above. + */ + +/** + * @param {string} s + * @param {number} k + * @return {number} + */ +var getLucky = function(s, k) { + let number = ''; + for (const char of s) { + number += (char.charCodeAt(0) - 96).toString(); + } + + let result = 0; + for (let i = 0; i < k; i++) { + result = 0; + for (const digit of number) { + result += parseInt(digit); + } + number = result.toString(); + } + + return result; +}; diff --git a/solutions/1946-largest-number-after-mutating-substring.js b/solutions/1946-largest-number-after-mutating-substring.js new file mode 100644 index 00000000..f64e4db0 --- /dev/null +++ b/solutions/1946-largest-number-after-mutating-substring.js @@ -0,0 +1,41 @@ +/** + * 1946. Largest Number After Mutating Substring + * https://leetcode.com/problems/largest-number-after-mutating-substring/ + * Difficulty: Medium + * + * You are given a string num, which represents a large integer. You are also given a 0-indexed + * integer array change of length 10 that maps each digit 0-9 to another digit. More formally, + * digit d maps to digit change[d]. + * + * You may choose to mutate a single substring of num. To mutate a substring, replace each digit + * num[i] with the digit it maps to in change (i.e. replace num[i] with change[num[i]]). + * + * Return a string representing the largest possible integer after mutating (or choosing not to) + * a single substring of num. + * + * A substring is a contiguous sequence of characters within the string. + */ + +/** + * @param {string} num + * @param {number[]} change + * @return {string} + */ +var maximumNumber = function(num, change) { + const digits = num.split(''); + let mutated = false; + + for (let i = 0; i < digits.length; i++) { + const currentDigit = parseInt(digits[i]); + const mappedDigit = change[currentDigit]; + + if (mappedDigit > currentDigit) { + digits[i] = mappedDigit.toString(); + mutated = true; + } else if (mappedDigit < currentDigit && mutated) { + break; + } + } + + return digits.join(''); +}; diff --git a/solutions/1947-maximum-compatibility-score-sum.js b/solutions/1947-maximum-compatibility-score-sum.js new file mode 100644 index 00000000..985d1deb --- /dev/null +++ b/solutions/1947-maximum-compatibility-score-sum.js @@ -0,0 +1,63 @@ +/** + * 1947. Maximum Compatibility Score Sum + * https://leetcode.com/problems/maximum-compatibility-score-sum/ + * Difficulty: Medium + * + * There is a survey that consists of n questions where each question's answer is either 0 + * (no) or 1 (yes). + * + * The survey was given to m students numbered from 0 to m - 1 and m mentors numbered from + * 0 to m - 1. The answers of the students are represented by a 2D integer array students + * where students[i] is an integer array that contains the answers of the ith student + * (0-indexed). The answers of the mentors are represented by a 2D integer array mentors + * where mentors[j] is an integer array that contains the answers of the jth mentor (0-indexed). + * + * Each student will be assigned to one mentor, and each mentor will have one student assigned + * to them. The compatibility score of a student-mentor pair is the number of answers that + * are the same for both the student and the mentor. + * - For example, if the student's answers were [1, 0, 1] and the mentor's answers were + * [0, 0, 1], then their compatibility score is 2 because only the second and the third + * answers are the same. + * + * You are tasked with finding the optimal student-mentor pairings to maximize the sum of the + * compatibility scores. + * + * Given students and mentors, return the maximum compatibility score sum that can be achieved. + */ + +/** + * @param {number[][]} students + * @param {number[][]} mentors + * @return {number} + */ +var maxCompatibilitySum = function(students, mentors) { + const m = students.length; + let maxScore = 0; + + backtrack(0, new Array(m).fill(false), 0); + return maxScore; + + function calculateScore(student, mentor) { + let score = 0; + for (let i = 0; i < student.length; i++) { + if (student[i] === mentor[i]) score++; + } + return score; + } + + function backtrack(studentIndex, usedMentors, currentScore) { + if (studentIndex === m) { + maxScore = Math.max(maxScore, currentScore); + return; + } + + for (let mentorIndex = 0; mentorIndex < m; mentorIndex++) { + if (!usedMentors[mentorIndex]) { + usedMentors[mentorIndex] = true; + backtrack(studentIndex + 1, usedMentors, + currentScore + calculateScore(students[studentIndex], mentors[mentorIndex])); + usedMentors[mentorIndex] = false; + } + } + } +}; diff --git a/solutions/1948-delete-duplicate-folders-in-system.js b/solutions/1948-delete-duplicate-folders-in-system.js new file mode 100644 index 00000000..085f6d72 --- /dev/null +++ b/solutions/1948-delete-duplicate-folders-in-system.js @@ -0,0 +1,115 @@ +/** + * 1948. Delete Duplicate Folders in System + * https://leetcode.com/problems/delete-duplicate-folders-in-system/ + * Difficulty: Hard + * + * Due to a bug, there are many duplicate folders in a file system. You are given a 2D array + * paths, where paths[i] is an array representing an absolute path to the ith folder in the + * file system. + * - For example, ["one", "two", "three"] represents the path "/one/two/three". + * + * Two folders (not necessarily on the same level) are identical if they contain the same + * non-empty set of identical subfolders and underlying subfolder structure. The folders do + * not need to be at the root level to be identical. If two or more folders are identical, + * then mark the folders as well as all their subfolders. + * - For example, folders "/a" and "/b" in the file structure below are identical. They (as + * well as their subfolders) should all be marked: + * - /a + * - /a/x + * - /a/x/y + * - /a/z + * - /b + * - /b/x + * - /b/x/y + * - /b/z + * - However, if the file structure also included the path "/b/w", then the folders "/a" and "/b" + * would not be identical. Note that "/a/x" and "/b/x" would still be considered identical + * even with the added folder. + * + * Once all the identical folders and their subfolders have been marked, the file system will delete + * all of them. The file system only runs the deletion once, so any folders that become identical + * after the initial deletion are not deleted. + * + * Return the 2D array ans containing the paths of the remaining folders after deleting all the + * marked folders. The paths may be returned in any order. + */ + +/** + * @param {string[][]} paths + * @return {string[][]} + */ +var deleteDuplicateFolder = function(paths) { + const root = {}; + + for (const path of paths) { + let node = root; + for (const folder of path) { + if (!node[folder]) node[folder] = {}; + node = node[folder]; + } + } + + const structures = new Map(); + + const serialize = (node, path) => { + if (Object.keys(node).length === 0) return ''; + + const folders = []; + const keys = Object.keys(node); + for (const folder of keys) { + const serialized = serialize(node[folder], [...path, folder]); + if (serialized !== null) { + folders.push(`${folder}(${serialized})`); + } else { + delete node[folder]; + } + } + + folders.sort(); + const key = folders.join(''); + + if (key.length > 0) { + if (!structures.has(key)) { + structures.set(key, []); + } + structures.get(key).push(path); + } + + return key; + }; + + serialize(root, []); + + const toDelete = new Set(); + + for (const [structure, paths] of structures.entries()) { + if (paths.length > 1) { + for (const path of paths) { + toDelete.add(path.join('/')); + } + } + } + + const result = []; + + const collectPaths = (node, path) => { + const currentPath = path.join('/'); + if (toDelete.has(currentPath)) return; + + if (path.length > 0) { + result.push([...path]); + } + + const keys = Object.keys(node); + for (const folder of keys) { + collectPaths(node[folder], [...path, folder]); + } + }; + + const rootFolders = Object.keys(root); + for (const folder of rootFolders) { + collectPaths(root[folder], [folder]); + } + + return result; +}; diff --git a/solutions/1952-three-divisors.js b/solutions/1952-three-divisors.js new file mode 100644 index 00000000..c09cf96e --- /dev/null +++ b/solutions/1952-three-divisors.js @@ -0,0 +1,27 @@ +/** + * 1952. Three Divisors + * https://leetcode.com/problems/three-divisors/ + * Difficulty: Easy + * + * Given an integer n, return true if n has exactly three positive divisors. Otherwise, + * return false. + * + * An integer m is a divisor of n if there exists an integer k such that n = k * m. + */ + +/** + * @param {number} n + * @return {boolean} + */ +var isThree = function(n) { + let divisorCount = 0; + + for (let i = 1; i <= n; i++) { + if (n % i === 0) { + divisorCount++; + if (divisorCount > 3) return false; + } + } + + return divisorCount === 3; +}; diff --git a/solutions/1953-maximum-number-of-weeks-for-which-you-can-work.js b/solutions/1953-maximum-number-of-weeks-for-which-you-can-work.js new file mode 100644 index 00000000..730198a0 --- /dev/null +++ b/solutions/1953-maximum-number-of-weeks-for-which-you-can-work.js @@ -0,0 +1,34 @@ +/** + * 1953. Maximum Number of Weeks for Which You Can Work + * https://leetcode.com/problems/maximum-number-of-weeks-for-which-you-can-work/ + * Difficulty: Medium + * + * There are n projects numbered from 0 to n - 1. You are given an integer array milestones where + * each milestones[i] denotes the number of milestones the ith project has. + * + * You can work on the projects following these two rules: + * - Every week, you will finish exactly one milestone of one project. You must work every week. + * - You cannot work on two milestones from the same project for two consecutive weeks. + * - Once all the milestones of all the projects are finished, or if the only milestones that you + * can work on will cause you to violate the above rules, you will stop working. Note that you + * may not be able to finish every project's milestones due to these constraints. + * + * Return the maximum number of weeks you would be able to work on the projects without violating + * the rules mentioned above. + */ + +/** + * @param {number[]} milestones + * @return {number} + */ +var numberOfWeeks = function(milestones) { + let total = 0; + let maxMilestones = 0; + + for (const count of milestones) { + total += count; + maxMilestones = Math.max(maxMilestones, count); + } + + return Math.min(total, 2 * (total - maxMilestones) + 1); +}; diff --git a/solutions/1954-minimum-garden-perimeter-to-collect-enough-apples.js b/solutions/1954-minimum-garden-perimeter-to-collect-enough-apples.js new file mode 100644 index 00000000..e064083c --- /dev/null +++ b/solutions/1954-minimum-garden-perimeter-to-collect-enough-apples.js @@ -0,0 +1,34 @@ +/** + * 1954. Minimum Garden Perimeter to Collect Enough Apples + * https://leetcode.com/problems/minimum-garden-perimeter-to-collect-enough-apples/ + * Difficulty: Medium + * + * In a garden represented as an infinite 2D grid, there is an apple tree planted at every + * integer coordinate. The apple tree planted at an integer coordinate (i, j) has |i| + |j| + * apples growing on it. + * + * You will buy an axis-aligned square plot of land that is centered at (0, 0). + * + * Given an integer neededApples, return the minimum perimeter of a plot such that at least + * neededApples apples are inside or on the perimeter of that plot. + * + * The value of |x| is defined as: + * - x if x >= 0 + * - -x if x < 0 + */ + +/** + * @param {number} neededApples + * @return {number} + */ +var minimumPerimeter = function(neededApples) { + let n = 0; + let totalApples = 0; + + while (totalApples < neededApples) { + n++; + totalApples = 2 * n * (n + 1) * (2 * n + 1); + } + + return 8 * n; +}; diff --git a/solutions/1955-count-number-of-special-subsequences.js b/solutions/1955-count-number-of-special-subsequences.js new file mode 100644 index 00000000..5daa07ec --- /dev/null +++ b/solutions/1955-count-number-of-special-subsequences.js @@ -0,0 +1,32 @@ +/** + * 1955. Count Number of Special Subsequences + * https://leetcode.com/problems/count-number-of-special-subsequences/ + * Difficulty: Hard + * + * A sequence is special if it consists of a positive number of 0s, followed by a positive number + * of 1s, then a positive number of 2s. + * - For example, [0,1,2] and [0,0,1,1,1,2] are special. + * - In contrast, [2,1,0], [1], and [0,1,2,0] are not special. + * + * Given an array nums (consisting of only integers 0, 1, and 2), return the number of different + * subsequences that are special. Since the answer may be very large, return it modulo 109 + 7. + * + * A subsequence of an array is a sequence that can be derived from the array by deleting some + * or no elements without changing the order of the remaining elements. Two subsequences are + * different if the set of indices chosen are different. + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var countSpecialSubsequences = function(nums) { + const MOD = 1e9 + 7; + const dp = [1, 0, 0, 0]; + + for (const num of nums) { + dp[num + 1] = (dp[num + 1] * 2 % MOD + dp[num]) % MOD; + } + + return dp[3]; +}; diff --git a/solutions/1957-delete-characters-to-make-fancy-string.js b/solutions/1957-delete-characters-to-make-fancy-string.js new file mode 100644 index 00000000..39c92ece --- /dev/null +++ b/solutions/1957-delete-characters-to-make-fancy-string.js @@ -0,0 +1,36 @@ +/** + * 1957. Delete Characters to Make Fancy String + * https://leetcode.com/problems/delete-characters-to-make-fancy-string/ + * Difficulty: Easy + * + * A fancy string is a string where no three consecutive characters are equal. + * + * Given a string s, delete the minimum possible number of characters from s to make + * it fancy. + * + * Return the final string after the deletion. It can be shown that the answer will + * always be unique. + */ + +/** + * @param {string} s + * @return {string} + */ +var makeFancyString = function(s) { + let result = s[0]; + let count = 1; + + for (let i = 1; i < s.length; i++) { + if (s[i] === s[i - 1]) { + if (count < 2) { + result += s[i]; + count++; + } + } else { + result += s[i]; + count = 1; + } + } + + return result; +}; diff --git a/solutions/1958-check-if-move-is-legal.js b/solutions/1958-check-if-move-is-legal.js new file mode 100644 index 00000000..7fef6e2a --- /dev/null +++ b/solutions/1958-check-if-move-is-legal.js @@ -0,0 +1,54 @@ +/** + * 1958. Check if Move is Legal + * https://leetcode.com/problems/check-if-move-is-legal/ + * Difficulty: Medium + * + * You are given a 0-indexed 8 x 8 grid board, where board[r][c] represents the cell (r, c) on a + * game board. On the board, free cells are represented by '.', white cells are represented by + * 'W', and black cells are represented by 'B'. + * + * Each move in this game consists of choosing a free cell and changing it to the color you are + * playing as (either white or black). However, a move is only legal if, after changing it, the + * cell becomes the endpoint of a good line (horizontal, vertical, or diagonal). + * + * A good line is a line of three or more cells (including the endpoints) where the endpoints of + * the line are one color, and the remaining cells in the middle are the opposite color (no cells + * in the line are free). You can find examples for good lines in the figure below. + * + * Given two integers rMove and cMove and a character color representing the color you are playing + * as (white or black), return true if changing cell (rMove, cMove) to color color is a legal move, + * or false if it is not legal. + */ + +/** + * @param {character[][]} board + * @param {number} rMove + * @param {number} cMove + * @param {character} color + * @return {boolean} + */ +var checkMove = function(board, rMove, cMove, color) { + const opposite = color === 'B' ? 'W' : 'B'; + const directions = [ + [0, 1], [0, -1], [1, 0], [-1, 0], + [1, 1], [1, -1], [-1, 1], [-1, -1] + ]; + + for (const [dr, dc] of directions) { + let row = rMove + dr; + let col = cMove + dc; + let count = 1; + + while (row >= 0 && row < 8 && col >= 0 && col < 8 && board[row][col] === opposite) { + row += dr; + col += dc; + count++; + } + + if (count >= 2 && row >= 0 && row < 8 && col >= 0 && col < 8 && board[row][col] === color) { + return true; + } + } + + return false; +}; diff --git a/solutions/1959-minimum-total-space-wasted-with-k-resizing-operations.js b/solutions/1959-minimum-total-space-wasted-with-k-resizing-operations.js new file mode 100644 index 00000000..9576849d --- /dev/null +++ b/solutions/1959-minimum-total-space-wasted-with-k-resizing-operations.js @@ -0,0 +1,54 @@ +/** + * 1959. Minimum Total Space Wasted With K Resizing Operations + * https://leetcode.com/problems/minimum-total-space-wasted-with-k-resizing-operations/ + * Difficulty: Medium + * + * You are currently designing a dynamic array. You are given a 0-indexed integer array nums, + * where nums[i] is the number of elements that will be in the array at time i. In addition, + * you are given an integer k, the maximum number of times you can resize the array (to any size). + * + * The size of the array at time t, sizet, must be at least nums[t] because there needs to be + * enough space in the array to hold all the elements. The space wasted at time t is defined + * as sizet - nums[t], and the total space wasted is the sum of the space wasted across every + * time t where 0 <= t < nums.length. + * + * Return the minimum total space wasted if you can resize the array at most k times. + * + * Note: The array can have any size at the start and does not count towards the number of + * resizing operations. + */ + +/** + * @param {number[]} nums + * @param {number} k + * @return {number} + */ +var minSpaceWastedKResizing = function(nums, k) { + const n = nums.length; + const dp = new Array(n + 1).fill().map(() => new Array(k + 2).fill(Infinity)); + dp[0][0] = 0; + + for (let i = 1; i <= n; i++) { + let maxVal = 0; + let sum = 0; + + for (let j = i; j > 0; j--) { + maxVal = Math.max(maxVal, nums[j - 1]); + sum += nums[j - 1]; + const waste = maxVal * (i - j + 1) - sum; + + for (let resizes = 0; resizes <= k; resizes++) { + if (dp[j - 1][resizes] !== Infinity) { + dp[i][resizes + 1] = Math.min(dp[i][resizes + 1], dp[j - 1][resizes] + waste); + } + } + } + } + + let result = Infinity; + for (let resizes = 1; resizes <= k + 1; resizes++) { + result = Math.min(result, dp[n][resizes]); + } + + return result; +}; diff --git a/solutions/1960-maximum-product-of-the-length-of-two-palindromic-substrings.js b/solutions/1960-maximum-product-of-the-length-of-two-palindromic-substrings.js new file mode 100644 index 00000000..10d34b76 --- /dev/null +++ b/solutions/1960-maximum-product-of-the-length-of-two-palindromic-substrings.js @@ -0,0 +1,67 @@ +/** + * 1960. Maximum Product of the Length of Two Palindromic Substrings + * https://leetcode.com/problems/maximum-product-of-the-length-of-two-palindromic-substrings/ + * Difficulty: Hard + * + * You are given a 0-indexed string s and are tasked with finding two non-intersecting palindromic + * substrings of odd length such that the product of their lengths is maximized. + * + * More formally, you want to choose four integers i, j, k, l such that + * 0 <= i <= j < k <= l < s.length and both the substrings s[i...j] and s[k...l] are palindromes + * and have odd lengths. s[i...j] denotes a substring from index i to index j inclusive. + * + * Return the maximum possible product of the lengths of the two non-intersecting palindromic + * substrings. + * + * A palindrome is a string that is the same forward and backward. A substring is a contiguous + * sequence of characters in a string. + */ + +/** +* @param {string} s +* @return {number} +*/ +var maxProduct = function(s) { + const n = s.length; + const before = new Array(n).fill(0); + const after = new Array(n).fill(0); + + let center = -1; + let right = -1; + const dp = new Array(n).fill(0); + + for (let i = 0; i < n; i++) { + const radius = i <= right ? Math.min(dp[2 * center - i], right - i) : 0; + let left = i - radius; + let rt = i + radius; + + while (left >= 0 && rt < n && s[left] === s[rt]) { + before[rt] = Math.max(before[rt], rt - left + 1); + after[left] = Math.max(after[left], rt - left + 1); + left--; + rt++; + } + + dp[i] = rt - i - 1; + + if (rt - 1 > right) { + center = i; + right = rt - 1; + } + } + + for (let i = 1; i < n; i++) { + before[i] = Math.max(before[i - 1], before[i]); + } + + for (let i = n - 2; i >= 0; i--) { + after[i] = Math.max(after[i + 1], after[i]); + } + + let result = 0; + for (let i = 1; i < n; i++) { + result = Math.max(result, before[i - 1] * after[i]); + } + + return result; +}; diff --git a/solutions/1961-check-if-string-is-a-prefix-of-array.js b/solutions/1961-check-if-string-is-a-prefix-of-array.js new file mode 100644 index 00000000..68aaf4c0 --- /dev/null +++ b/solutions/1961-check-if-string-is-a-prefix-of-array.js @@ -0,0 +1,30 @@ +/** + * 1961. Check If String Is a Prefix of Array + * https://leetcode.com/problems/check-if-string-is-a-prefix-of-array/ + * Difficulty: Easy + * + * Given a string s and an array of strings words, determine whether s is a prefix string of words. + * + * A string s is a prefix string of words if s can be made by concatenating the first k strings in + * words for some positive k no larger than words.length. + * + * Return true if s is a prefix string of words, or false otherwise. + */ + +/** + * @param {string} s + * @param {string[]} words + * @return {boolean} + */ +var isPrefixString = function(s, words) { + let currentIndex = 0; + + for (const word of words) { + if (currentIndex + word.length > s.length) return false; + if (s.slice(currentIndex, currentIndex + word.length) !== word) return false; + currentIndex += word.length; + if (currentIndex === s.length) return true; + } + + return false; +}; diff --git a/solutions/1963-minimum-number-of-swaps-to-make-the-string-balanced.js b/solutions/1963-minimum-number-of-swaps-to-make-the-string-balanced.js new file mode 100644 index 00000000..2f687a52 --- /dev/null +++ b/solutions/1963-minimum-number-of-swaps-to-make-the-string-balanced.js @@ -0,0 +1,37 @@ +/** + * 1963. Minimum Number of Swaps to Make the String Balanced + * https://leetcode.com/problems/minimum-number-of-swaps-to-make-the-string-balanced/ + * Difficulty: Medium + * + * You are given a 0-indexed string s of even length n. The string consists of exactly n / 2 opening + * brackets '[' and n / 2 closing brackets ']'. + * + * A string is called balanced if and only if: + * - It is the empty string, or + * - It can be written as AB, where both A and B are balanced strings, or + * - It can be written as [C], where C is a balanced string. + * + * You may swap the brackets at any two indices any number of times. + * + * Return the minimum number of swaps to make s balanced. + */ + +/** + * @param {string} s + * @return {number} + */ +var minSwaps = function(s) { + let imbalance = 0; + let maxImbalance = 0; + + for (const bracket of s) { + if (bracket === '[') { + imbalance--; + } else { + imbalance++; + maxImbalance = Math.max(maxImbalance, imbalance); + } + } + + return Math.ceil(maxImbalance / 2); +}; diff --git a/solutions/1964-find-the-longest-valid-obstacle-course-at-each-position.js b/solutions/1964-find-the-longest-valid-obstacle-course-at-each-position.js new file mode 100644 index 00000000..cafb25a7 --- /dev/null +++ b/solutions/1964-find-the-longest-valid-obstacle-course-at-each-position.js @@ -0,0 +1,54 @@ +/** + * 1964. Find the Longest Valid Obstacle Course at Each Position + * https://leetcode.com/problems/find-the-longest-valid-obstacle-course-at-each-position/ + * Difficulty: Hard + * + * You want to build some obstacle courses. You are given a 0-indexed integer array obstacles of + * length n, where obstacles[i] describes the height of the ith obstacle. + * + * For every index i between 0 and n - 1 (inclusive), find the length of the longest obstacle + * course in obstacles such that: + * - You choose any number of obstacles between 0 and i inclusive. + * - You must include the ith obstacle in the course. + * - You must put the chosen obstacles in the same order as they appear in obstacles. + * - Every obstacle (except the first) is taller than or the same height as the obstacle immediately + * before it. + * + * Return an array ans of length n, where ans[i] is the length of the longest obstacle course for + * index i as described above. + */ + +/** + * @param {number[]} obstacles + * @return {number[]} + */ +var longestObstacleCourseAtEachPosition = function(obstacles) { + const n = obstacles.length; + const result = new Array(n).fill(1); + const stack = []; + + for (let i = 0; i < n; i++) { + const height = obstacles[i]; + let left = 0; + let right = stack.length; + + while (left < right) { + const mid = Math.floor((left + right) / 2); + if (stack[mid] <= height) { + left = mid + 1; + } else { + right = mid; + } + } + + if (left < stack.length) { + stack[left] = height; + } else { + stack.push(height); + } + + result[i] = left + 1; + } + + return result; +}; diff --git a/solutions/1967-number-of-strings-that-appear-as-substrings-in-word.js b/solutions/1967-number-of-strings-that-appear-as-substrings-in-word.js new file mode 100644 index 00000000..b0cb45d5 --- /dev/null +++ b/solutions/1967-number-of-strings-that-appear-as-substrings-in-word.js @@ -0,0 +1,19 @@ +/** + * 1967. Number of Strings That Appear as Substrings in Word + * https://leetcode.com/problems/number-of-strings-that-appear-as-substrings-in-word/ + * Difficulty: Easy + * + * Given an array of strings patterns and a string word, return the number of strings in patterns + * that exist as a substring in word. + * + * A substring is a contiguous sequence of characters within a string. + */ + +/** + * @param {string[]} patterns + * @param {string} word + * @return {number} + */ +var numOfStrings = function(patterns, word) { + return patterns.reduce((count, pattern) => word.includes(pattern) ? count + 1 : count, 0); +}; diff --git a/solutions/1968-array-with-elements-not-equal-to-average-of-neighbors.js b/solutions/1968-array-with-elements-not-equal-to-average-of-neighbors.js new file mode 100644 index 00000000..67994987 --- /dev/null +++ b/solutions/1968-array-with-elements-not-equal-to-average-of-neighbors.js @@ -0,0 +1,29 @@ +/** + * 1968. Array With Elements Not Equal to Average of Neighbors + * https://leetcode.com/problems/array-with-elements-not-equal-to-average-of-neighbors/ + * Difficulty: Medium + * + * You are given a 0-indexed array nums of distinct integers. You want to rearrange the elements + * in the array such that every element in the rearranged array is not equal to the average of + * its neighbors. + * + * More formally, the rearranged array should have the property such that for every i in the + * range 1 <= i < nums.length - 1, (nums[i-1] + nums[i+1]) / 2 is not equal to nums[i]. + * + * Return any rearrangement of nums that meets the requirements. + */ + +/** + * @param {number[]} nums + * @return {number[]} + */ +var rearrangeArray = function(nums) { + const result = new Array(nums.length); + nums.sort((a, b) => a - b); + + for (let i = 0, left = 0, right = nums.length - 1; i < nums.length; i++) { + result[i] = i % 2 === 0 ? nums[left++] : nums[right--]; + } + + return result; +}; diff --git a/solutions/1969-minimum-non-zero-product-of-the-array-elements.js b/solutions/1969-minimum-non-zero-product-of-the-array-elements.js new file mode 100644 index 00000000..9165df8e --- /dev/null +++ b/solutions/1969-minimum-non-zero-product-of-the-array-elements.js @@ -0,0 +1,44 @@ +/** + * 1969. Minimum Non-Zero Product of the Array Elements + * https://leetcode.com/problems/minimum-non-zero-product-of-the-array-elements/ + * Difficulty: Medium + * + * You are given a positive integer p. Consider an array nums (1-indexed) that consists of the + * integers in the inclusive range [1, 2p - 1] in their binary representations. You are allowed + * to do the following operation any number of times: + * - Choose two elements x and y from nums. + * - Choose a bit in x and swap it with its corresponding bit in y. Corresponding bit refers to + * the bit that is in the same position in the other integer. + * + * For example, if x = 1101 and y = 0011, after swapping the 2nd bit from the right, we have + * x = 1111 and y = 0001. + * + * Find the minimum non-zero product of nums after performing the above operation any number + * of times. Return this product modulo 109 + 7. + * + * Note: The answer should be the minimum product before the modulo operation is done. + */ + +/** + * @param {number} p + * @return {number} + */ +var minNonZeroProduct = function(p) { + const MOD = 1000000007n; + const maxVal = (1n << BigInt(p)) - 1n; + const halfCount = (maxVal - 1n) / 2n; + const base = maxVal - 1n; + + function pow(base, exp, mod) { + let result = 1n; + base = base % mod; + while (exp > 0n) { + if (exp & 1n) result = (result * base) % mod; + base = (base * base) % mod; + exp >>= 1n; + } + return result; + } + + return Number((maxVal * pow(base, halfCount, MOD)) % MOD); +}; diff --git a/solutions/1970-last-day-where-you-can-still-cross.js b/solutions/1970-last-day-where-you-can-still-cross.js new file mode 100644 index 00000000..7b36cd06 --- /dev/null +++ b/solutions/1970-last-day-where-you-can-still-cross.js @@ -0,0 +1,78 @@ +/** + * 1970. Last Day Where You Can Still Cross + * https://leetcode.com/problems/last-day-where-you-can-still-cross/ + * Difficulty: Hard + * + * There is a 1-based binary matrix where 0 represents land and 1 represents water. You are given + * integers row and col representing the number of rows and columns in the matrix, respectively. + * + * Initially on day 0, the entire matrix is land. However, each day a new cell becomes flooded + * with water. You are given a 1-based 2D array cells, where cells[i] = [ri, ci] represents that + * on the ith day, the cell on the rith row and cith column (1-based coordinates) will be covered + * with water (i.e., changed to 1). + * + * You want to find the last day that it is possible to walk from the top to the bottom by only + * walking on land cells. You can start from any cell in the top row and end at any cell in the + * bottom row. You can only travel in the four cardinal directions (left, right, up, and down). + * + * Return the last day where it is possible to walk from the top to the bottom by only walking + * on land cells. + */ + +/** + * @param {number} row + * @param {number} col + * @param {number[][]} cells + * @return {number} + */ +var latestDayToCross = function(row, col, cells) { + const directions = [[-1, 0], [1, 0], [0, -1], [0, 1]]; + let left = 1; + let right = cells.length; + let result = 0; + + while (left <= right) { + const mid = Math.floor((left + right) / 2); + if (canCross(mid)) { + result = mid; + left = mid + 1; + } else { + right = mid - 1; + } + } + + return result; + + function canCross(day) { + const grid = new Array(row).fill().map(() => new Array(col).fill(0)); + for (let i = 0; i < day; i++) { + const [r, c] = cells[i]; + grid[r - 1][c - 1] = 1; + } + + const queue = []; + const visited = new Array(row).fill().map(() => new Array(col).fill(false)); + + for (let c = 0; c < col; c++) { + if (grid[0][c] === 0) { + queue.push([0, c]); + visited[0][c] = true; + } + } + + while (queue.length) { + const [r, c] = queue.shift(); + if (r === row - 1) return true; + + for (const [dr, dc] of directions) { + const nr = r + dr; + const nc = c + dc; + if (nr >= 0 && nr < row && nc >= 0 && nc < col && !visited[nr][nc] && grid[nr][nc] === 0) { + queue.push([nr, nc]); + visited[nr][nc] = true; + } + } + } + return false; + } +}; diff --git a/solutions/1971-find-if-path-exists-in-graph.js b/solutions/1971-find-if-path-exists-in-graph.js new file mode 100644 index 00000000..4b032666 --- /dev/null +++ b/solutions/1971-find-if-path-exists-in-graph.js @@ -0,0 +1,50 @@ +/** + * 1971. Find if Path Exists in Graph + * https://leetcode.com/problems/find-if-path-exists-in-graph/ + * Difficulty: Easy + * + * There is a bi-directional graph with n vertices, where each vertex is labeled from 0 to + * n - 1 (inclusive). The edges in the graph are represented as a 2D integer array edges, + * where each edges[i] = [ui, vi] denotes a bi-directional edge between vertex ui and + * vertex vi. Every vertex pair is connected by at most one edge, and no vertex has an + * edge to itself. + * + * You want to determine if there is a valid path that exists from vertex source to vertex + * destination. + * + * Given edges and the integers n, source, and destination, return true if there is a valid + * path from source to destination, or false otherwise. + */ + +/** + * @param {number} n + * @param {number[][]} edges + * @param {number} source + * @param {number} destination + * @return {boolean} + */ +var validPath = function(n, edges, source, destination) { + const graph = Array.from({ length: n }, () => []); + for (const [u, v] of edges) { + graph[u].push(v); + graph[v].push(u); + } + + const visited = new Set(); + const queue = [source]; + + while (queue.length) { + const vertex = queue.shift(); + if (vertex === destination) return true; + if (visited.has(vertex)) continue; + visited.add(vertex); + + for (const neighbor of graph[vertex]) { + if (!visited.has(neighbor)) { + queue.push(neighbor); + } + } + } + + return false; +}; diff --git a/solutions/1974-minimum-time-to-type-word-using-special-typewriter.js b/solutions/1974-minimum-time-to-type-word-using-special-typewriter.js new file mode 100644 index 00000000..9c1641e7 --- /dev/null +++ b/solutions/1974-minimum-time-to-type-word-using-special-typewriter.js @@ -0,0 +1,34 @@ +/** + * 1974. Minimum Time to Type Word Using Special Typewriter + * https://leetcode.com/problems/minimum-time-to-type-word-using-special-typewriter/ + * Difficulty: Easy + * + * There is a special typewriter with lowercase English letters 'a' to 'z' arranged in a circle + * with a pointer. A character can only be typed if the pointer is pointing to that character. + * The pointer is initially pointing to the character 'a'. + * + * Each second, you may perform one of the following operations: + * - Move the pointer one character counterclockwise or clockwise. + * - Type the character the pointer is currently on. + * + * Given a string word, return the minimum number of seconds to type out the characters in word. + */ + +/** + * @param {string} word + * @return {number} + */ +var minTimeToType = function(word) { + let position = 'a'; + let result = 0; + + for (const char of word) { + const clockwise = Math.abs(char.charCodeAt(0) - position.charCodeAt(0)); + const counterclockwise = 26 - clockwise; + const moves = Math.min(clockwise, counterclockwise); + result += moves + 1; + position = char; + } + + return result; +}; diff --git a/solutions/1975-maximum-matrix-sum.js b/solutions/1975-maximum-matrix-sum.js new file mode 100644 index 00000000..92b65dd2 --- /dev/null +++ b/solutions/1975-maximum-matrix-sum.js @@ -0,0 +1,33 @@ +/** + * 1975. Maximum Matrix Sum + * https://leetcode.com/problems/maximum-matrix-sum/ + * Difficulty: Medium + * + * You are given an n x n integer matrix. You can do the following operation any number of times: + * - Choose any two adjacent elements of matrix and multiply each of them by -1. + * + * Two elements are considered adjacent if and only if they share a border. + * + * Your goal is to maximize the summation of the matrix's elements. Return the maximum sum of the + * matrix's elements using the operation mentioned above. + */ + +/** + * @param {number[][]} matrix + * @return {number} + */ +var maxMatrixSum = function(matrix) { + let totalSum = 0; + let negativeCount = 0; + let minAbs = Infinity; + + for (const row of matrix) { + for (const num of row) { + totalSum += Math.abs(num); + if (num < 0) negativeCount++; + minAbs = Math.min(minAbs, Math.abs(num)); + } + } + + return negativeCount % 2 === 0 ? totalSum : totalSum - 2 * minAbs; +}; diff --git a/solutions/1977-number-of-ways-to-separate-numbers.js b/solutions/1977-number-of-ways-to-separate-numbers.js new file mode 100644 index 00000000..6fad6b5d --- /dev/null +++ b/solutions/1977-number-of-ways-to-separate-numbers.js @@ -0,0 +1,77 @@ +/** + * 1977. Number of Ways to Separate Numbers + * https://leetcode.com/problems/number-of-ways-to-separate-numbers/ + * Difficulty: Hard + * + * You wrote down many positive integers in a string called num. However, you realized that you + * forgot to add commas to seperate the different numbers. You remember that the list of integers + * was non-decreasing and that no integer had leading zeros. + * + * Return the number of possible lists of integers that you could have written down to get the + * string num. Since the answer may be large, return it modulo 109 + 7. + */ + +/** + * @param {string} num + * @return {number} + */ +var numberOfCombinations = function(num) { + const n = num.length; + if (num[0] === '0') return 0; + + const MOD = 1e9 + 7; + const lcp = new Array(n + 1).fill().map(() => new Array(n + 1).fill(0)); + + for (let i = n - 1; i >= 0; i--) { + for (let j = n - 1; j >= 0; j--) { + if (num[i] === num[j]) { + lcp[i][j] = lcp[i + 1][j + 1] + 1; + } + } + } + + const dp = new Array(n).fill().map(() => new Array(n + 1).fill(0)); + const prefixSum = new Array(n).fill().map(() => new Array(n + 1).fill(0)); + + dp[0][1] = 1; + prefixSum[0][1] = 1; + + for (let i = 1; i < n; i++) { + for (let j = 1; j <= i; j++) { + prefixSum[i - 1][j] = (prefixSum[i - 1][j - 1] + dp[i - 1][j]) % MOD; + } + + for (let len = 1; len <= i + 1; len++) { + if (num[i - len + 1] === '0') continue; + + if (i - len < 0) { + dp[i][len] = 1; + continue; + } + + dp[i][len] = prefixSum[i - len][Math.min(i - len + 1, len)]; + + if (len <= i - len + 1) { + const start1 = i - 2 * len + 1; + const start2 = i - len + 1; + + if (!compare(start1, start2, len)) { + dp[i][len] = (dp[i][len] - dp[i - len][len] + MOD) % MOD; + } + } + } + + prefixSum[i][0] = 0; + for (let j = 1; j <= i + 1; j++) { + prefixSum[i][j] = (prefixSum[i][j - 1] + dp[i][j]) % MOD; + } + } + + return prefixSum[n - 1][n]; + + function compare(i1, i2, len) { + const commonLen = lcp[i1][i2]; + if (commonLen >= len) return true; + return i1 + commonLen < n && i2 + commonLen < n && num[i1 + commonLen] <= num[i2 + commonLen]; + } +}; diff --git a/solutions/1979-find-greatest-common-divisor-of-array.js b/solutions/1979-find-greatest-common-divisor-of-array.js new file mode 100644 index 00000000..acf2c5df --- /dev/null +++ b/solutions/1979-find-greatest-common-divisor-of-array.js @@ -0,0 +1,23 @@ +/** + * 1979. Find Greatest Common Divisor of Array + * https://leetcode.com/problems/find-greatest-common-divisor-of-array/ + * Difficulty: Easy + * + * Given an integer array nums, return the greatest common divisor of the smallest number and + * largest number in nums. + * + * The greatest common divisor of two numbers is the largest positive integer that evenly + * divides both numbers. + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var findGCD = function(nums) { + return gcd(Math.min(...nums), Math.max(...nums)); + + function gcd(a, b) { + return b === 0 ? a : gcd(b, a % b); + } +}; diff --git a/solutions/1981-minimize-the-difference-between-target-and-chosen-elements.js b/solutions/1981-minimize-the-difference-between-target-and-chosen-elements.js new file mode 100644 index 00000000..6e66a493 --- /dev/null +++ b/solutions/1981-minimize-the-difference-between-target-and-chosen-elements.js @@ -0,0 +1,45 @@ +/** + * 1981. Minimize the Difference Between Target and Chosen Elements + * https://leetcode.com/problems/minimize-the-difference-between-target-and-chosen-elements/ + * Difficulty: Medium + * + * You are given an m x n integer matrix mat and an integer target. + * + * Choose one integer from each row in the matrix such that the absolute difference between + * target and the sum of the chosen elements is minimized. + * + * Return the minimum absolute difference. + * + * The absolute difference between two numbers a and b is the absolute value of a - b. + */ + +/** + * @param {number[][]} mat + * @param {number} target + * @return {number} + */ +var minimizeTheDifference = function(mat, target) { + const m = mat.length; + const maxSum = 70 * m; + let possibleSums = new Set([0]); + + for (const row of mat) { + const nextSums = new Set(); + for (const num of row) { + for (const sum of possibleSums) { + const newSum = sum + num; + if (newSum <= target + maxSum) { + nextSums.add(newSum); + } + } + } + possibleSums = nextSums; + } + + let result = Infinity; + for (const sum of possibleSums) { + result = Math.min(result, Math.abs(sum - target)); + } + + return result; +}; diff --git a/solutions/1982-find-array-given-subset-sums.js b/solutions/1982-find-array-given-subset-sums.js new file mode 100644 index 00000000..da9ab09f --- /dev/null +++ b/solutions/1982-find-array-given-subset-sums.js @@ -0,0 +1,63 @@ +/** + * 1982. Find Array Given Subset Sums + * https://leetcode.com/problems/find-array-given-subset-sums/ + * Difficulty: Hard + * + * You are given an integer n representing the length of an unknown array that you are trying + * to recover. You are also given an array sums containing the values of all 2n subset sums of + * the unknown array (in no particular order). + * + * Return the array ans of length n representing the unknown array. If multiple answers exist, + * return any of them. + * + * An array sub is a subset of an array arr if sub can be obtained from arr by deleting some + * (possibly zero or all) elements of arr. The sum of the elements in sub is one possible + * subset sum of arr. The sum of an empty array is considered to be 0. + * + * Note: Test cases are generated such that there will always be at least one correct answer. + */ + +/** +* @param {number} n +* @param {number[]} sums +* @return {number[]} +*/ +var recoverArray = function(n, sums) { + sums.sort((a, b) => a - b); + + const result = []; + while (result.length < n) { + const diff = sums[1] - sums[0]; + + const withNum = []; + const withoutNum = []; + const freq = new Map(); + for (const sum of sums) { + freq.set(sum, (freq.get(sum) || 0) + 1); + } + + for (const sum of sums) { + if (freq.get(sum) > 0) { + freq.set(sum, freq.get(sum) - 1); + + if (freq.get(sum + diff) > 0) { + freq.set(sum + diff, freq.get(sum + diff) - 1); + withoutNum.push(sum); + withNum.push(sum + diff); + } else { + return []; + } + } + } + + if (withoutNum.includes(0)) { + result.push(diff); + sums = withoutNum; + } else { + result.push(-diff); + sums = withNum; + } + } + + return result; +}; diff --git a/solutions/1984-minimum-difference-between-highest-and-lowest-of-k-scores.js b/solutions/1984-minimum-difference-between-highest-and-lowest-of-k-scores.js new file mode 100644 index 00000000..889aae95 --- /dev/null +++ b/solutions/1984-minimum-difference-between-highest-and-lowest-of-k-scores.js @@ -0,0 +1,29 @@ +/** + * 1984. Minimum Difference Between Highest and Lowest of K Scores + * https://leetcode.com/problems/minimum-difference-between-highest-and-lowest-of-k-scores/ + * Difficulty: Easy + * + * You are given a 0-indexed integer array nums, where nums[i] represents the score of the + * ith student. You are also given an integer k. + * + * Pick the scores of any k students from the array so that the difference between the highest + * and the lowest of the k scores is minimized. + * + * Return the minimum possible difference. + */ + +/** + * @param {number[]} nums + * @param {number} k + * @return {number} + */ +var minimumDifference = function(nums, k) { + nums.sort((a, b) => a - b); + let result = Infinity; + + for (let i = 0; i <= nums.length - k; i++) { + result = Math.min(result, nums[i + k - 1] - nums[i]); + } + + return result; +}; diff --git a/solutions/1986-minimum-number-of-work-sessions-to-finish-the-tasks.js b/solutions/1986-minimum-number-of-work-sessions-to-finish-the-tasks.js new file mode 100644 index 00000000..f6174274 --- /dev/null +++ b/solutions/1986-minimum-number-of-work-sessions-to-finish-the-tasks.js @@ -0,0 +1,59 @@ +/** + * 1986. Minimum Number of Work Sessions to Finish the Tasks + * https://leetcode.com/problems/minimum-number-of-work-sessions-to-finish-the-tasks/ + * Difficulty: Medium + * + * There are n tasks assigned to you. The task times are represented as an integer array tasks of + * length n, where the ith task takes tasks[i] hours to finish. A work session is when you work + * for at most sessionTime consecutive hours and then take a break. + * + * You should finish the given tasks in a way that satisfies the following conditions: + * - If you start a task in a work session, you must complete it in the same work session. + * - You can start a new task immediately after finishing the previous one. + * - You may complete the tasks in any order. + * + * Given tasks and sessionTime, return the minimum number of work sessions needed to finish all the + * tasks following the conditions above. + * + * The tests are generated such that sessionTime is greater than or equal to the maximum element + * in tasks[i]. + */ + +/** + * @param {number[]} tasks + * @param {number} sessionTime + * @return {number} + */ +var minSessions = function(tasks, sessionTime) { + const n = tasks.length; + const dp = new Array(1 << n).fill(n + 1); + dp[0] = 0; + + for (let mask = 1; mask < 1 << n; mask++) { + let time = 0; + for (let i = 0; i < n; i++) { + if (mask & (1 << i)) { + time += tasks[i]; + } + } + + for (let subset = mask; subset; subset = (subset - 1) & mask) { + if (subset === mask) continue; + let subsetTime = 0; + for (let i = 0; i < n; i++) { + if (subset & (1 << i)) { + subsetTime += tasks[i]; + } + } + if (subsetTime <= sessionTime) { + dp[mask] = Math.min(dp[mask], dp[mask ^ subset] + 1); + } + } + + if (time <= sessionTime) { + dp[mask] = 1; + } + } + + return dp[(1 << n) - 1]; +}; diff --git a/solutions/1987-number-of-unique-good-subsequences.js b/solutions/1987-number-of-unique-good-subsequences.js new file mode 100644 index 00000000..e0d6651c --- /dev/null +++ b/solutions/1987-number-of-unique-good-subsequences.js @@ -0,0 +1,41 @@ +/** + * 1987. Number of Unique Good Subsequences + * https://leetcode.com/problems/number-of-unique-good-subsequences/ + * Difficulty: Hard + * + * You are given a binary string binary. A subsequence of binary is considered good if it is not + * empty and has no leading zeros (with the exception of "0"). + * + * Find the number of unique good subsequences of binary. + * - For example, if binary = "001", then all the good subsequences are ["0", "0", "1"], so the + * unique good subsequences are "0" and "1". Note that subsequences "00", "01", and "001" are + * not good because they have leading zeros. + * + * Return the number of unique good subsequences of binary. Since the answer may be very large, + * return it modulo 109 + 7. + * + * A subsequence is a sequence that can be derived from another sequence by deleting some or no + * elements without changing the order of the remaining elements. + */ + +/** + * @param {string} binary + * @return {number} + */ +var numberOfUniqueGoodSubsequences = function(binary) { + const MOD = 1e9 + 7; + let endsWithZero = 0; + let endsWithOne = 0; + let hasZero = false; + + for (const digit of binary) { + if (digit === '0') { + hasZero = true; + endsWithZero = (endsWithZero + endsWithOne) % MOD; + } else { + endsWithOne = (endsWithOne + endsWithZero + 1) % MOD; + } + } + + return (endsWithZero + endsWithOne + (hasZero ? 1 : 0)) % MOD; +}; diff --git a/solutions/1991-find-the-middle-index-in-array.js b/solutions/1991-find-the-middle-index-in-array.js new file mode 100644 index 00000000..fa993684 --- /dev/null +++ b/solutions/1991-find-the-middle-index-in-array.js @@ -0,0 +1,35 @@ +/** + * 1991. Find the Middle Index in Array + * https://leetcode.com/problems/find-the-middle-index-in-array/ + * Difficulty: Easy + * + * Given a 0-indexed integer array nums, find the leftmost middleIndex (i.e., the smallest amongst + * all the possible ones). + * + * A middleIndex is an index where nums[0] + nums[1] + ... + + * nums[middleIndex-1] == nums[middleIndex+1] + nums[middleIndex+2] + ... + nums[nums.length-1]. + * + * If middleIndex == 0, the left side sum is considered to be 0. Similarly, if + * middleIndex == nums.length - 1, the right side sum is considered to be 0. + * + * Return the leftmost middleIndex that satisfies the condition, or -1 if there is no such index. + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var findMiddleIndex = function(nums) { + let left = 0; + let right = nums.reduce((sum, n) => sum + n, 0); + + for (let i = 0; i < nums.length; i++) { + left += nums[i]; + right -= nums[i]; + if (left - nums[i] === right) { + return i; + } + } + + return -1; +}; diff --git a/solutions/1992-find-all-groups-of-farmland.js b/solutions/1992-find-all-groups-of-farmland.js new file mode 100644 index 00000000..0e39fd7f --- /dev/null +++ b/solutions/1992-find-all-groups-of-farmland.js @@ -0,0 +1,55 @@ +/** + * 1992. Find All Groups of Farmland + * https://leetcode.com/problems/find-all-groups-of-farmland/ + * Difficulty: Medium + * + * You are given a 0-indexed m x n binary matrix land where a 0 represents a hectare of forested + * land and a 1 represents a hectare of farmland. + * + * To keep the land organized, there are designated rectangular areas of hectares that consist + * entirely of farmland. These rectangular areas are called groups. No two groups are adjacent, + * meaning farmland in one group is not four-directionally adjacent to another farmland in a + * different group. + * + * land can be represented by a coordinate system where the top left corner of land is (0, 0) + * and the bottom right corner of land is (m-1, n-1). Find the coordinates of the top left and + * bottom right corner of each group of farmland. A group of farmland with a top left corner + * at (r1, c1) and a bottom right corner at (r2, c2) is represented by the 4-length + * array [r1, c1, r2, c2]. + * + * Return a 2D array containing the 4-length arrays described above for each group of farmland + * in land. If there are no groups of farmland, return an empty array. You may return the answer + * in any order. + */ + +/** + * @param {number[][]} land + * @return {number[][]} + */ +var findFarmland = function(land) { + const m = land.length; + const n = land[0].length; + const result = []; + + for (let r = 0; r < m; r++) { + for (let c = 0; c < n; c++) { + if (land[r][c] === 1) { + let r2 = r; + let c2 = c; + + while (r2 + 1 < m && land[r2 + 1][c] === 1) r2++; + while (c2 + 1 < n && land[r][c2 + 1] === 1) c2++; + + result.push([r, c, r2, c2]); + + for (let i = r; i <= r2; i++) { + for (let j = c; j <= c2; j++) { + land[i][j] = 0; + } + } + } + } + } + + return result; +}; diff --git a/solutions/1993-operations-on-tree.js b/solutions/1993-operations-on-tree.js new file mode 100644 index 00000000..e1f5952c --- /dev/null +++ b/solutions/1993-operations-on-tree.js @@ -0,0 +1,101 @@ +/** + * 1993. Operations on Tree + * https://leetcode.com/problems/operations-on-tree/ + * Difficulty: Medium + * + * You are given a tree with n nodes numbered from 0 to n - 1 in the form of a parent array + * parent where parent[i] is the parent of the ith node. The root of the tree is node 0, + * so parent[0] = -1 since it has no parent. You want to design a data structure that + * allows users to lock, unlock, and upgrade nodes in the tree. + * + * The data structure should support the following functions: + * - Lock: Locks the given node for the given user and prevents other users from locking + * the same node. You may only lock a node using this function if the node is unlocked. + * - Unlock: Unlocks the given node for the given user. You may only unlock a node using + * this function if it is currently locked by the same user. + * - Upgrade: Locks the given node for the given user and unlocks all of its descendants + * regardless of who locked it. You may only upgrade a node if all 3 conditions are true: + * - The node is unlocked, + * - It has at least one locked descendant (by any user), and + * - It does not have any locked ancestors. + * + * Implement the LockingTree class: + * - LockingTree(int[] parent) initializes the data structure with the parent array. + * - lock(int num, int user) returns true if it is possible for the user with id user to lock + * the node num, or false otherwise. If it is possible, the node num will become locked by + * the user with id user. + * - unlock(int num, int user) returns true if it is possible for the user with id user to + * unlock the node num, or false otherwise. If it is possible, the node num will become unlocked. + * - upgrade(int num, int user) returns true if it is possible for the user with id user to + * upgrade the node num, or false otherwise. If it is possible, the node num will be upgraded. + */ + +/** + * @param {number[]} parent + */ +var LockingTree = function(parent) { + this.parent = parent; + this.locked = new Map(); + this.children = new Array(parent.length).fill().map(() => []); + for (let i = 1; i < parent.length; i++) { + this.children[parent[i]].push(i); + } +}; + +/** + * @param {number} num + * @param {number} user + * @return {boolean} + */ +LockingTree.prototype.lock = function(num, user) { + if (this.locked.has(num)) return false; + this.locked.set(num, user); + return true; +}; + +/** + * @param {number} num + * @param {number} user + * @return {boolean} + */ +LockingTree.prototype.unlock = function(num, user) { + if (!this.locked.has(num) || this.locked.get(num) !== user) return false; + this.locked.delete(num); + return true; +}; + +/** + * @param {number} num + * @param {number} user + * @return {boolean} + */ +LockingTree.prototype.upgrade = function(num, user) { + if (this.locked.has(num)) return false; + + let node = num; + while (node !== -1) { + if (this.locked.has(node)) return false; + node = this.parent[node]; + } + + const descendants = []; + const queue = [num]; + let hasLockedDescendant = false; + + while (queue.length) { + const curr = queue.shift(); + if (this.locked.has(curr)) { + hasLockedDescendant = true; + descendants.push(curr); + } + queue.push(...this.children[curr]); + } + + if (!hasLockedDescendant) return false; + + for (const descendant of descendants) { + this.locked.delete(descendant); + } + this.locked.set(num, user); + return true; +}; diff --git a/solutions/1994-the-number-of-good-subsets.js b/solutions/1994-the-number-of-good-subsets.js new file mode 100644 index 00000000..7fb63535 --- /dev/null +++ b/solutions/1994-the-number-of-good-subsets.js @@ -0,0 +1,75 @@ +/** + * 1994. The Number of Good Subsets + * https://leetcode.com/problems/the-number-of-good-subsets/ + * Difficulty: Hard + * + * You are given an integer array nums. We call a subset of nums good if its product can be + * represented as a product of one or more distinct prime numbers. + * + * - For example, if nums = [1, 2, 3, 4]: + * - [2, 3], [1, 2, 3], and [1, 3] are good subsets with products 6 = 2*3, 6 = 2*3, and 3 = 3 + * respectively. + * - [1, 4] and [4] are not good subsets with products 4 = 2*2 and 4 = 2*2 respectively. + * + * Return the number of different good subsets in nums modulo 109 + 7. + * + * A subset of nums is any array that can be obtained by deleting some (possibly none or all) + * elements from nums. Two subsets are different if and only if the chosen indices to delete + * are different. + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var numberOfGoodSubsets = function(nums) { + const MOD = 1e9 + 7; + const primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]; + const freq = new Array(31).fill(0); + for (const num of nums) { + freq[num]++; + } + + const dp = new Array(1 << primes.length).fill(0); + dp[0] = 1; + for (let i = 0; i < freq[1]; i++) { + dp[0] = (dp[0] * 2) % MOD; + } + + for (let num = 2; num <= 30; num++) { + if (freq[num] === 0) continue; + let mask = 0; + let valid = true; + for (let i = 0; i < primes.length; i++) { + let count = 0; + let temp = num; + while (temp % primes[i] === 0) { + count++; + temp /= primes[i]; + } + if (count > 1) { + valid = false; + break; + } + if (count === 1) { + mask |= 1 << i; + } + } + + if (!valid) continue; + + const prev = dp.slice(); + for (let j = 0; j < 1 << primes.length; j++) { + if ((j & mask) === 0) { + dp[j | mask] = (dp[j | mask] + prev[j] * freq[num]) % MOD; + } + } + } + + let result = 0; + for (let i = 1; i < 1 << primes.length; i++) { + result = (result + dp[i]) % MOD; + } + + return result; +}; diff --git a/solutions/1995-count-special-quadruplets.js b/solutions/1995-count-special-quadruplets.js new file mode 100644 index 00000000..e37902ac --- /dev/null +++ b/solutions/1995-count-special-quadruplets.js @@ -0,0 +1,31 @@ +/** + * 1995. Count Special Quadruplets + * https://leetcode.com/problems/count-special-quadruplets/ + * Difficulty: Easy + * + * Given a 0-indexed integer array nums, return the number of distinct quadruplets + * (a, b, c, d) such that: + * - nums[a] + nums[b] + nums[c] == nums[d], and + * - a < b < c < d + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var countQuadruplets = function(nums) { + const map = new Map(); + let result = 0; + + for (let c = nums.length - 2; c >= 2; c--) { + map.set(nums[c + 1], (map.get(nums[c + 1]) || 0) + 1); + for (let a = 0; a < c - 1; a++) { + for (let b = a + 1; b < c; b++) { + const sum = nums[a] + nums[b] + nums[c]; + result += map.get(sum) || 0; + } + } + } + + return result; +}; diff --git a/solutions/1997-first-day-where-you-have-been-in-all-the-rooms.js b/solutions/1997-first-day-where-you-have-been-in-all-the-rooms.js new file mode 100644 index 00000000..6dde2362 --- /dev/null +++ b/solutions/1997-first-day-where-you-have-been-in-all-the-rooms.js @@ -0,0 +1,36 @@ +/** + * 1997. First Day Where You Have Been in All the Rooms + * https://leetcode.com/problems/first-day-where-you-have-been-in-all-the-rooms/ + * Difficulty: Medium + * + * There are n rooms you need to visit, labeled from 0 to n - 1. Each day is labeled, starting + * from 0. You will go in and visit one room a day. + * + * Initially on day 0, you visit room 0. The order you visit the rooms for the coming days is + * determined by the following rules and a given 0-indexed array nextVisit of length n: + * - Assuming that on a day, you visit room i, + * - if you have been in room i an odd number of times (including the current visit), on the next + * day you will visit a room with a lower or equal room number specified by nextVisit[i] + * where 0 <= nextVisit[i] <= i; + * - if you have been in room i an even number of times (including the current visit), on the + * next day you will visit room (i + 1) mod n. + * + * Return the label of the first day where you have been in all the rooms. It can be shown + * that such a day exists. Since the answer may be very large, return it modulo 109 + 7. + */ + +/** + * @param {number[]} nextVisit + * @return {number} + */ +var firstDayBeenInAllRooms = function(nextVisit) { + const MOD = 1e9 + 7; + const n = nextVisit.length; + const dp = new Array(n).fill(0); + + for (let i = 1; i < n; i++) { + dp[i] = (2 * dp[i - 1] + 2 - dp[nextVisit[i - 1]] + MOD) % MOD; + } + + return dp[n - 1]; +}; diff --git a/solutions/1998-gcd-sort-of-an-array.js b/solutions/1998-gcd-sort-of-an-array.js new file mode 100644 index 00000000..97bb5a39 --- /dev/null +++ b/solutions/1998-gcd-sort-of-an-array.js @@ -0,0 +1,69 @@ +/** + * 1998. GCD Sort of an Array + * https://leetcode.com/problems/gcd-sort-of-an-array/ + * Difficulty: Hard + * + * You are given an integer array nums, and you can perform the following operation any + * number of times on nums: + * - Swap the positions of two elements nums[i] and nums[j] if gcd(nums[i], nums[j]) > 1 + * where gcd(nums[i], nums[j]) is the greatest common divisor of nums[i] and nums[j]. + * + * Return true if it is possible to sort nums in non-decreasing order using the above swap + * method, or false otherwise. + */ + +/** + * @param {number[]} nums + * @return {boolean} + */ +var gcdSort = function(nums) { + const maxNum = Math.max(...nums); + const parent = new Array(maxNum + 1).fill().map((_, i) => i); + const minPrime = new Array(maxNum + 1).fill(0); + for (let i = 2; i <= maxNum; i++) { + if (minPrime[i] === 0) { + for (let j = i; j <= maxNum; j += i) { + minPrime[j] = i; + } + } + } + + const groups = new Map(); + for (const num of nums) { + let curr = num; + const primes = new Set(); + while (curr > 1) { + const prime = minPrime[curr]; + primes.add(prime); + curr /= prime; + } + for (const prime of primes) { + if (!groups.has(prime)) groups.set(prime, []); + groups.get(prime).push(num); + } + } + + for (const numbers of groups.values()) { + for (let i = 1; i < numbers.length; i++) { + union(numbers[i - 1], numbers[i], parent); + } + } + + const sorted = [...nums].sort((a, b) => a - b); + for (let i = 0; i < nums.length; i++) { + if (find(nums[i], parent) !== find(sorted[i], parent)) { + return false; + } + } + + return true; + + function find(x, parent) { + if (parent[x] !== x) parent[x] = find(parent[x], parent); + return parent[x]; + } + + function union(x, y, parent) { + parent[find(x, parent)] = find(y, parent); + } +}; diff --git a/solutions/2001-number-of-pairs-of-interchangeable-rectangles.js b/solutions/2001-number-of-pairs-of-interchangeable-rectangles.js new file mode 100644 index 00000000..89f2611e --- /dev/null +++ b/solutions/2001-number-of-pairs-of-interchangeable-rectangles.js @@ -0,0 +1,38 @@ +/** + * 2001. Number of Pairs of Interchangeable Rectangles + * https://leetcode.com/problems/number-of-pairs-of-interchangeable-rectangles/ + * Difficulty: Medium + * + * You are given n rectangles represented by a 0-indexed 2D integer array rectangles, + * where rectangles[i] = [widthi, heighti] denotes the width and height of the ith rectangle. + * + * Two rectangles i and j (i < j) are considered interchangeable if they have the same + * width-to-height ratio. More formally, two rectangles are interchangeable if + * widthi/heighti == widthj/heightj (using decimal division, not integer division). + * + * Return the number of pairs of interchangeable rectangles in rectangles. + */ + +/** + * @param {number[][]} rectangles + * @return {number} + */ +var interchangeableRectangles = function(rectangles) { + const map = new Map(); + let result = 0; + + for (const [width, height] of rectangles) { + const gcd = (a, b) => b === 0 ? a : gcd(b, a % b); + const divisor = gcd(width, height); + const ratio = `${width / divisor}/${height / divisor}`; + + if (map.has(ratio)) { + result += map.get(ratio); + map.set(ratio, map.get(ratio) + 1); + } else { + map.set(ratio, 1); + } + } + + return result; +}; diff --git a/solutions/2002-maximum-product-of-the-length-of-two-palindromic-subsequences.js b/solutions/2002-maximum-product-of-the-length-of-two-palindromic-subsequences.js new file mode 100644 index 00000000..ae489e83 --- /dev/null +++ b/solutions/2002-maximum-product-of-the-length-of-two-palindromic-subsequences.js @@ -0,0 +1,50 @@ +/** + * 2002. Maximum Product of the Length of Two Palindromic Subsequences + * https://leetcode.com/problems/maximum-product-of-the-length-of-two-palindromic-subsequences/ + * Difficulty: Medium + * + * Given a string s, find two disjoint palindromic subsequences of s such that the product of their + * lengths is maximized. The two subsequences are disjoint if they do not both pick a character at + * the same index. + * + * Return the maximum possible product of the lengths of the two palindromic subsequences. + * + * A subsequence is a string that can be derived from another string by deleting some or no + * characters without changing the order of the remaining characters. A string is palindromic + * if it reads the same forward and backward. + */ + +/** + * @param {string} s + * @return {number} + */ +var maxProduct = function(s) { + const n = s.length; + let result = 0; + + for (let mask1 = 1; mask1 < (1 << n); mask1++) { + for (let mask2 = 1; mask2 < (1 << n); mask2++) { + if (mask1 & mask2) continue; + const len1 = isPalindrome(s, mask1); + if (len1 === 0) continue; + const len2 = isPalindrome(s, mask2); + if (len2 === 0) continue; + result = Math.max(result, len1 * len2); + } + } + + return result; + + function isPalindrome(str, mask) { + const chars = []; + for (let i = 0; i < n; i++) { + if (mask & (1 << i)) chars.push(str[i]); + } + let left = 0; + let right = chars.length - 1; + while (left < right) { + if (chars[left++] !== chars[right--]) return 0; + } + return chars.length; + } +}; diff --git a/solutions/2003-smallest-missing-genetic-value-in-each-subtree.js b/solutions/2003-smallest-missing-genetic-value-in-each-subtree.js new file mode 100644 index 00000000..f57b89d8 --- /dev/null +++ b/solutions/2003-smallest-missing-genetic-value-in-each-subtree.js @@ -0,0 +1,55 @@ +/** + * 2003. Smallest Missing Genetic Value in Each Subtree + * https://leetcode.com/problems/smallest-missing-genetic-value-in-each-subtree/ + * Difficulty: Hard + * + * There is a family tree rooted at 0 consisting of n nodes numbered 0 to n - 1. You are given a + * 0-indexed integer array parents, where parents[i] is the parent for node i. Since node 0 is + * the root, parents[0] == -1. + * + * There are 105 genetic values, each represented by an integer in the inclusive range [1, 105]. + * You are given a 0-indexed integer array nums, where nums[i] is a distinct genetic value for + * node i. + * + * Return an array ans of length n where ans[i] is the smallest genetic value that is missing + * from the subtree rooted at node i. + * + * The subtree rooted at a node x contains node x and all of its descendant nodes. + */ + +/** + * @param {number[]} parents + * @param {number[]} nums + * @return {number[]} + */ +var smallestMissingValueSubtree = function(parents, nums) { + const n = parents.length; + const result = new Array(n).fill(1); + const children = Array.from({ length: n }, () => []); + const seen = new Set(); + let maxMissing = 1; + + for (let i = 1; i < n; i++) { + children[parents[i]].push(i); + } + + const nodeWithOne = nums.indexOf(1); + if (nodeWithOne === -1) return result; + + let current = nodeWithOne; + while (current !== -1) { + const stack = [current]; + while (stack.length) { + const node = stack.pop(); + seen.add(nums[node]); + for (const child of children[node]) { + if (!seen.has(nums[child])) stack.push(child); + } + } + while (seen.has(maxMissing)) maxMissing++; + result[current] = maxMissing; + current = parents[current]; + } + + return result; +}; diff --git a/solutions/2006-count-number-of-pairs-with-absolute-difference-k.js b/solutions/2006-count-number-of-pairs-with-absolute-difference-k.js new file mode 100644 index 00000000..022c9b4d --- /dev/null +++ b/solutions/2006-count-number-of-pairs-with-absolute-difference-k.js @@ -0,0 +1,29 @@ +/** + * 2006. Count Number of Pairs With Absolute Difference K + * https://leetcode.com/problems/count-number-of-pairs-with-absolute-difference-k/ + * Difficulty: Easy + * + * Given an integer array nums and an integer k, return the number of pairs (i, j) where + * i < j such that |nums[i] - nums[j]| == k. + * + * The value of |x| is defined as: + * - x if x >= 0. + * - -x if x < 0. + */ + +/** + * @param {number[]} nums + * @param {number} k + * @return {number} + */ +var countKDifference = function(nums, k) { + const map = new Map(); + let result = 0; + + for (const num of nums) { + result += (map.get(num - k) || 0) + (map.get(num + k) || 0); + map.set(num, (map.get(num) || 0) + 1); + } + + return result; +}; diff --git a/solutions/2007-find-original-array-from-doubled-array.js b/solutions/2007-find-original-array-from-doubled-array.js new file mode 100644 index 00000000..ca1d1357 --- /dev/null +++ b/solutions/2007-find-original-array-from-doubled-array.js @@ -0,0 +1,42 @@ +/** + * 2007. Find Original Array From Doubled Array + * https://leetcode.com/problems/find-original-array-from-doubled-array/ + * Difficulty: Medium + * + * An integer array original is transformed into a doubled array changed by appending twice the + * value of every element in original, and then randomly shuffling the resulting array. + * + * Given an array changed, return original if changed is a doubled array. If changed is not a + * doubled array, return an empty array. The elements in original may be returned in any order. + */ + +/** + * @param {number[]} changed + * @return {number[]} + */ +var findOriginalArray = function(changed) { + if (changed.length % 2 !== 0) return []; + + const frequency = new Map(); + const result = []; + + changed.sort((a, b) => a - b); + + for (const num of changed) { + frequency.set(num, (frequency.get(num) || 0) + 1); + } + + for (const num of changed) { + if (frequency.get(num) === 0) continue; + + frequency.set(num, frequency.get(num) - 1); + + const doubled = num * 2; + if (!frequency.has(doubled) || frequency.get(doubled) === 0) return []; + + frequency.set(doubled, frequency.get(doubled) - 1); + result.push(num); + } + + return result; +}; diff --git a/solutions/2008-maximum-earnings-from-taxi.js b/solutions/2008-maximum-earnings-from-taxi.js new file mode 100644 index 00000000..fd7cbaac --- /dev/null +++ b/solutions/2008-maximum-earnings-from-taxi.js @@ -0,0 +1,43 @@ +/** + * 2008. Maximum Earnings From Taxi + * https://leetcode.com/problems/maximum-earnings-from-taxi/ + * Difficulty: Medium + * + * There are n points on a road you are driving your taxi on. The n points on the road are + * labeled from 1 to n in the direction you are going, and you want to drive from point 1 + * to point n to make money by picking up passengers. You cannot change the direction of the taxi. + * + * The passengers are represented by a 0-indexed 2D integer array rides, where + * rides[i] = [starti, endi, tipi] denotes the ith passenger requesting a ride from point + * starti to point endi who is willing to give a tipi dollar tip. + * + * For each passenger i you pick up, you earn endi - starti + tipi dollars. You may only drive + * at most one passenger at a time. + * + * Given n and rides, return the maximum number of dollars you can earn by picking up the + * passengers optimally. + * + * Note: You may drop off a passenger and pick up a different passenger at the same point. + */ + +/** + * @param {number} n + * @param {number[][]} rides + * @return {number} + */ +var maxTaxiEarnings = function(n, rides) { + rides.sort((a, b) => a[1] - b[1]); + const dp = new Array(n + 1).fill(0); + let rideIndex = 0; + + for (let point = 1; point <= n; point++) { + dp[point] = dp[point - 1]; + while (rideIndex < rides.length && rides[rideIndex][1] === point) { + const [start, end, tip] = rides[rideIndex]; + dp[point] = Math.max(dp[point], dp[start] + (end - start + tip)); + rideIndex++; + } + } + + return dp[n]; +}; diff --git a/solutions/2009-minimum-number-of-operations-to-make-array-continuous.js b/solutions/2009-minimum-number-of-operations-to-make-array-continuous.js new file mode 100644 index 00000000..d4cd063e --- /dev/null +++ b/solutions/2009-minimum-number-of-operations-to-make-array-continuous.js @@ -0,0 +1,36 @@ +/** + * 2009. Minimum Number of Operations to Make Array Continuous + * https://leetcode.com/problems/minimum-number-of-operations-to-make-array-continuous/ + * Difficulty: Hard + * + * You are given an integer array nums. In one operation, you can replace any element in nums + * with any integer. + * + * nums is considered continuous if both of the following conditions are fulfilled: + * - All elements in nums are unique. + * - The difference between the maximum element and the minimum element in nums equals + * nums.length - 1. + * + * For example, nums = [4, 2, 5, 3] is continuous, but nums = [1, 2, 3, 5, 6] is not continuous. + * + * Return the minimum number of operations to make nums continuous. + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var minOperations = function(nums) { + const n = nums.length; + const uniqueNums = [...new Set(nums)].sort((a, b) => a - b); + let result = n; + + for (let i = 0, j = 0; i < uniqueNums.length; i++) { + while (j < uniqueNums.length && uniqueNums[j] - uniqueNums[i] <= n - 1) { + j++; + } + result = Math.min(result, n - (j - i)); + } + + return result; +}; diff --git a/solutions/2012-sum-of-beauty-in-the-array.js b/solutions/2012-sum-of-beauty-in-the-array.js new file mode 100644 index 00000000..957da790 --- /dev/null +++ b/solutions/2012-sum-of-beauty-in-the-array.js @@ -0,0 +1,42 @@ +/** + * 2012. Sum of Beauty in the Array + * https://leetcode.com/problems/sum-of-beauty-in-the-array/ + * Difficulty: Medium + * + * You are given a 0-indexed integer array nums. For each index i (1 <= i <= nums.length - 2) + * the beauty of nums[i] equals: + * - 2, if nums[j] < nums[i] < nums[k], for all 0 <= j < i and for all i < k <= nums.length - 1. + * - 1, if nums[i - 1] < nums[i] < nums[i + 1], and the previous condition is not satisfied. + * - 0, if none of the previous conditions holds. + * + * Return the sum of beauty of all nums[i] where 1 <= i <= nums.length - 2. + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var sumOfBeauties = function(nums) { + const n = nums.length; + let result = 0; + const leftMax = new Array(n).fill(nums[0]); + const rightMin = new Array(n).fill(nums[n - 1]); + + for (let i = 1; i < n; i++) { + leftMax[i] = Math.max(leftMax[i - 1], nums[i - 1]); + } + + for (let i = n - 2; i >= 0; i--) { + rightMin[i] = Math.min(rightMin[i + 1], nums[i + 1]); + } + + for (let i = 1; i < n - 1; i++) { + if (leftMax[i] < nums[i] && nums[i] < rightMin[i]) { + result += 2; + } else if (nums[i - 1] < nums[i] && nums[i] < nums[i + 1]) { + result += 1; + } + } + + return result; +}; diff --git a/solutions/2013-detect-squares.js b/solutions/2013-detect-squares.js new file mode 100644 index 00000000..606076c3 --- /dev/null +++ b/solutions/2013-detect-squares.js @@ -0,0 +1,54 @@ +/** + * 2013. Detect Squares + * https://leetcode.com/problems/detect-squares/ + * Difficulty: Medium + * + * You are given a stream of points on the X-Y plane. Design an algorithm that: + * - Adds new points from the stream into a data structure. Duplicate points are allowed and should + * be treated as different points. + * - Given a query point, counts the number of ways to choose three points from the data structure + * such that the three points and the query point form an axis-aligned square with positive area. + * + * An axis-aligned square is a square whose edges are all the same length and are either parallel + * or perpendicular to the x-axis and y-axis. + * + * Implement the DetectSquares class: + * - DetectSquares() Initializes the object with an empty data structure. + * - void add(int[] point) Adds a new point point = [x, y] to the data structure. + * - int count(int[] point) Counts the number of ways to form axis-aligned squares with point + * point = [x, y] as described above. + */ + +var DetectSquares = function() { + this.points = new Map(); +}; + +/** + * @param {number[]} point + * @return {void} + */ +DetectSquares.prototype.add = function(point) { + const [x, y] = point; + const key = `${x},${y}`; + this.points.set(key, (this.points.get(key) || 0) + 1); +}; + +/** + * @param {number[]} point + * @return {number} + */ +DetectSquares.prototype.count = function(point) { + const [x, y] = point; + let result = 0; + + for (const [key, count] of this.points) { + const [px, py] = key.split(',').map(Number); + if (px === x || py === y || Math.abs(px - x) !== Math.abs(py - y)) continue; + + const point1 = `${x},${py}`; + const point2 = `${px},${y}`; + result += count * (this.points.get(point1) || 0) * (this.points.get(point2) || 0); + } + + return result; +}; diff --git a/solutions/2014-longest-subsequence-repeated-k-times.js b/solutions/2014-longest-subsequence-repeated-k-times.js new file mode 100644 index 00000000..ec575695 --- /dev/null +++ b/solutions/2014-longest-subsequence-repeated-k-times.js @@ -0,0 +1,64 @@ +/** + * 2014. Longest Subsequence Repeated k Times + * https://leetcode.com/problems/longest-subsequence-repeated-k-times/ + * Difficulty: Hard + * + * You are given a string s of length n, and an integer k. You are tasked to find the longest + * subsequence repeated k times in string s. + * + * A subsequence is a string that can be derived from another string by deleting some or no + * characters without changing the order of the remaining characters. + * + * A subsequence seq is repeated k times in the string s if seq * k is a subsequence of s, + * where seq * k represents a string constructed by concatenating seq k times. + * - For example, "bba" is repeated 2 times in the string "bababcba", because the string + * "bbabba", constructed by concatenating "bba" 2 times, is a subsequence of the + * string "bababcba". + * + * Return the longest subsequence repeated k times in string s. If multiple such subsequences + * are found, return the lexicographically largest one. If there is no such subsequence, + * return an empty string. + */ + +/** + * @param {string} s + * @param {number} k + * @return {string} + */ +var longestSubsequenceRepeatedK = function(s, k) { + const n = s.length; + const freq = new Array(26).fill(0); + for (const char of s) { + freq[char.charCodeAt(0) - 97]++; + } + + let candidates = ''; + for (let i = 0; i < 26; i++) { + const count = Math.floor(freq[i] / k); + candidates += String.fromCharCode(97 + i).repeat(count); + } + + function canFormSubsequence(seq) { + let j = 0; + for (let i = 0; i < n && j < seq.length * k; i++) { + if (s[i] === seq[j % seq.length]) j++; + } + return j >= seq.length * k; + } + + let result = ''; + backtrack('', candidates); + return result; + + function backtrack(curr, remaining) { + if (curr.length > result.length || (curr.length === result.length && curr > result)) { + if (canFormSubsequence(curr)) result = curr; + } + if (!remaining) return; + + for (let i = remaining.length - 1; i >= 0; i--) { + const nextChar = remaining[i]; + backtrack(curr + nextChar, remaining.slice(0, i) + remaining.slice(i + 1)); + } + } +}; diff --git a/solutions/2018-check-if-word-can-be-placed-in-crossword.js b/solutions/2018-check-if-word-can-be-placed-in-crossword.js new file mode 100644 index 00000000..0a22bd5c --- /dev/null +++ b/solutions/2018-check-if-word-can-be-placed-in-crossword.js @@ -0,0 +1,66 @@ +/** + * 2018. Check if Word Can Be Placed In Crossword + * https://leetcode.com/problems/check-if-word-can-be-placed-in-crossword/ + * Difficulty: Medium + * + * You are given an m x n matrix board, representing the current state of a crossword puzzle. + * The crossword contains lowercase English letters (from solved words), ' ' to represent any + * empty cells, and '#' to represent any blocked cells. + * + * A word can be placed horizontally (left to right or right to left) or vertically (top to + * bottom or bottom to top) in the board if: + * - It does not occupy a cell containing the character '#'. + * - The cell each letter is placed in must either be ' ' (empty) or match the letter already + * on the board. + * - There must not be any empty cells ' ' or other lowercase letters directly left or right + * of the word if the word was placed horizontally. + * - There must not be any empty cells ' ' or other lowercase letters directly above or below + * the word if the word was placed vertically. + * + * Given a string word, return true if word can be placed in board, or false otherwise. + */ + +/** + * @param {character[][]} board + * @param {string} word + * @return {boolean} + */ +var placeWordInCrossword = function(board, word) { + const rows = board.length; + const cols = board[0].length; + const wordLen = word.length; + + function canPlace(row, col, dr, dc) { + for (let i = 0; i < wordLen; i++) { + const r = row + i * dr; + const c = col + i * dc; + if (r < 0 || r >= rows || c < 0 || c >= cols || board[r][c] === '#') return false; + if (board[r][c] !== ' ' && board[r][c] !== word[i]) return false; + } + + const beforeR = row - dr; + const beforeC = col - dc; + const afterR = row + wordLen * dr; + const afterC = col + wordLen * dc; + + if ((beforeR >= 0 && beforeR < rows && beforeC >= 0 + && beforeC < cols && board[beforeR][beforeC] !== '#') + || (afterR >= 0 && afterR < rows && afterC >= 0 + && afterC < cols && board[afterR][afterC] !== '#')) { + return false; + } + + return true; + } + + for (let r = 0; r < rows; r++) { + for (let c = 0; c < cols; c++) { + if (canPlace(r, c, 0, 1) || canPlace(r, c, 0, -1) + || canPlace(r, c, 1, 0) || canPlace(r, c, -1, 0)) { + return true; + } + } + } + + return false; +}; diff --git a/solutions/2019-the-score-of-students-solving-math-expression.js b/solutions/2019-the-score-of-students-solving-math-expression.js new file mode 100644 index 00000000..b4391da2 --- /dev/null +++ b/solutions/2019-the-score-of-students-solving-math-expression.js @@ -0,0 +1,72 @@ +/** + * 2019. The Score of Students Solving Math Expression + * https://leetcode.com/problems/the-score-of-students-solving-math-expression/ + * Difficulty: Hard + * + * You are given a string s that contains digits 0-9, addition symbols '+', and multiplication + * symbols '*' only, representing a valid math expression of single digit numbers (e.g., 3+5*2). + * This expression was given to n elementary school students. The students were instructed to + * get the answer of the expression by following this order of operations: + * 1. Compute multiplication, reading from left to right; Then, + * 2. Compute addition, reading from left to right. + * + * You are given an integer array answers of length n, which are the submitted answers of the + * students in no particular order. You are asked to grade the answers, by following these rules: + * - If an answer equals the correct answer of the expression, this student will be rewarded + * 5 points; + * - Otherwise, if the answer could be interpreted as if the student applied the operators in + * the wrong order but had correct arithmetic, this student will be rewarded 2 points; + * - Otherwise, this student will be rewarded 0 points. + * + * Return the sum of the points of the students. + */ + +/** + * @param {string} s + * @param {number[]} answers + * @return {number} + */ +var scoreOfStudents = function(s, answers) { + const correct = eval(s.replace(/(\d)([*+])/g, '$1 $2 ')); + + const n = s.length; + const dp = new Map(); + + function compute(start, end) { + const key = `${start},${end}`; + if (dp.has(key)) return dp.get(key); + + const results = new Set(); + if (start === end) { + results.add(Number(s[start])); + dp.set(key, results); + return results; + } + + for (let i = start + 1; i < end; i += 2) { + const leftResults = compute(start, i - 1); + const rightResults = compute(i + 1, end); + const op = s[i]; + + for (const left of leftResults) { + for (const right of rightResults) { + const val = op === '+' ? left + right : left * right; + if (val <= 1000) results.add(val); + } + } + } + + dp.set(key, results); + return results; + } + + const wrongAnswers = compute(0, n - 1); + let result = 0; + + for (const answer of answers) { + if (answer === correct) result += 5; + else if (wrongAnswers.has(answer)) result += 2; + } + + return result; +}; diff --git a/solutions/2022-convert-1d-array-into-2d-array.js b/solutions/2022-convert-1d-array-into-2d-array.js new file mode 100644 index 00000000..a550b710 --- /dev/null +++ b/solutions/2022-convert-1d-array-into-2d-array.js @@ -0,0 +1,33 @@ +/** + * 2022. Convert 1D Array Into 2D Array + * https://leetcode.com/problems/convert-1d-array-into-2d-array/ + * Difficulty: Easy + * + * You are given a 0-indexed 1-dimensional (1D) integer array original, and two integers, + * m and n. You are tasked with creating a 2-dimensional (2D) array with m rows and n + * columns using all the elements from original. + * + * The elements from indices 0 to n - 1 (inclusive) of original should form the first row + * of the constructed 2D array, the elements from indices n to 2 * n - 1 (inclusive) should + * form the second row of the constructed 2D array, and so on. + * + * Return an m x n 2D array constructed according to the above procedure, or an empty 2D array + * if it is impossible. + */ + +/** + * @param {number[]} original + * @param {number} m + * @param {number} n + * @return {number[][]} + */ +var construct2DArray = function(original, m, n) { + if (original.length !== m * n) return []; + + const result = []; + for (let i = 0; i < m; i++) { + result.push(original.slice(i * n, (i + 1) * n)); + } + + return result; +}; diff --git a/solutions/2023-number-of-pairs-of-strings-with-concatenation-equal-to-target.js b/solutions/2023-number-of-pairs-of-strings-with-concatenation-equal-to-target.js new file mode 100644 index 00000000..f2e98de0 --- /dev/null +++ b/solutions/2023-number-of-pairs-of-strings-with-concatenation-equal-to-target.js @@ -0,0 +1,32 @@ +/** + * 2023. Number of Pairs of Strings With Concatenation Equal to Target + * https://leetcode.com/problems/number-of-pairs-of-strings-with-concatenation-equal-to-target/ + * Difficulty: Medium + * + * Given an array of digit strings nums and a digit string target, return the number of pairs of + * indices (i, j) (where i != j) such that the concatenation of nums[i] + nums[j] equals target. + */ + +/** + * @param {string[]} nums + * @param {string} target + * @return {number} + */ +var numOfPairs = function(nums, target) { + const map = new Map(); + let result = 0; + + for (const num of nums) { + if (target.startsWith(num)) { + const suffix = target.slice(num.length); + result += map.get(suffix) || 0; + } + if (target.endsWith(num)) { + const prefix = target.slice(0, target.length - num.length); + result += map.get(prefix) || 0; + } + map.set(num, (map.get(num) || 0) + 1); + } + + return result; +}; diff --git a/solutions/2024-maximize-the-confusion-of-an-exam.js b/solutions/2024-maximize-the-confusion-of-an-exam.js new file mode 100644 index 00000000..f79d25b1 --- /dev/null +++ b/solutions/2024-maximize-the-confusion-of-an-exam.js @@ -0,0 +1,43 @@ +/** + * 2024. Maximize the Confusion of an Exam + * https://leetcode.com/problems/maximize-the-confusion-of-an-exam/ + * Difficulty: Medium + * + * A teacher is writing a test with n true/false questions, with 'T' denoting true and 'F' denoting + * false. He wants to confuse the students by maximizing the number of consecutive questions with + * the same answer (multiple trues or multiple falses in a row). + * + * You are given a string answerKey, where answerKey[i] is the original answer to the ith question. + * In addition, you are given an integer k, the maximum number of times you may perform the + * following operation: + * - Change the answer key for any question to 'T' or 'F' (i.e., set answerKey[i] to 'T' or 'F'). + * + * Return the maximum number of consecutive 'T's or 'F's in the answer key after performing the + * operation at most k times. + */ + +/** + * @param {string} answerKey + * @param {number} k + * @return {number} + */ +var maxConsecutiveAnswers = function(answerKey, k) { + const flipsLeft = k; + const count = { T: 0, F: 0 }; + let result = 0; + let left = 0; + + for (let right = 0; right < answerKey.length; right++) { + count[answerKey[right]]++; + const maxCount = Math.max(count.T, count.F); + + while (right - left + 1 - maxCount > flipsLeft) { + count[answerKey[left]]--; + left++; + } + + result = Math.max(result, right - left + 1); + } + + return result; +}; diff --git a/solutions/2025-maximum-number-of-ways-to-partition-an-array.js b/solutions/2025-maximum-number-of-ways-to-partition-an-array.js new file mode 100644 index 00000000..2e28cd39 --- /dev/null +++ b/solutions/2025-maximum-number-of-ways-to-partition-an-array.js @@ -0,0 +1,57 @@ +/** + * 2025. Maximum Number of Ways to Partition an Array + * https://leetcode.com/problems/maximum-number-of-ways-to-partition-an-array/ + * Difficulty: Hard + * + * You are given a 0-indexed integer array nums of length n. The number of ways to partition + * nums is the number of pivot indices that satisfy both conditions: + * - 1 <= pivot < n + * - nums[0] + nums[1] + ... + nums[pivot - 1] == nums[pivot] + nums[pivot + 1] + ... + nums[n - 1] + * + * You are also given an integer k. You can choose to change the value of one element of nums to + * k, or to leave the array unchanged. + * + * Return the maximum possible number of ways to partition nums to satisfy both conditions after + * changing at most one element. + */ + +/** + * @param {number[]} nums + * @param {number} k + * @return {number} + */ +var waysToPartition = function(nums, k) { + const n = nums.length; + const prefixSums = [nums[0]]; + const leftDiffs = new Map(); + const rightDiffs = new Map(); + + for (let i = 1; i < n; i++) { + prefixSums[i] = prefixSums[i - 1] + nums[i]; + const diff = prefixSums[i - 1]; + rightDiffs.set(diff, (rightDiffs.get(diff) || 0) + 1); + } + + const totalSum = prefixSums[n - 1]; + let result = totalSum % 2 === 0 ? (rightDiffs.get(totalSum / 2) || 0) : 0; + + for (let i = 0; i < n; i++) { + const delta = k - nums[i]; + const newTotalSum = totalSum + delta; + + if (newTotalSum % 2 === 0) { + const targetSum = newTotalSum / 2; + const waysFromLeft = leftDiffs.get(targetSum) || 0; + const waysFromRight = rightDiffs.get(targetSum - delta) || 0; + result = Math.max(result, waysFromLeft + waysFromRight); + } + + if (i < n - 1) { + const currentDiff = prefixSums[i]; + leftDiffs.set(currentDiff, (leftDiffs.get(currentDiff) || 0) + 1); + rightDiffs.set(currentDiff, rightDiffs.get(currentDiff) - 1); + } + } + + return result; +}; diff --git a/solutions/2028-find-missing-observations.js b/solutions/2028-find-missing-observations.js new file mode 100644 index 00000000..29296fbc --- /dev/null +++ b/solutions/2028-find-missing-observations.js @@ -0,0 +1,49 @@ +/** + * 2028. Find Missing Observations + * https://leetcode.com/problems/find-missing-observations/ + * Difficulty: Medium + * + * You have observations of n + m 6-sided dice rolls with each face numbered from 1 to 6. n + * of the observations went missing, and you only have the observations of m rolls. + * Fortunately, you have also calculated the average value of the n + m rolls. + * + * You are given an integer array rolls of length m where rolls[i] is the value of the ith + * observation. You are also given the two integers mean and n. + * + * Return an array of length n containing the missing observations such that the average + * value of the n + m rolls is exactly mean. If there are multiple valid answers, return + * any of them. If no such array exists, return an empty array. + * + * The average value of a set of k numbers is the sum of the numbers divided by k. + * + * Note that mean is an integer, so the sum of the n + m rolls should be divisible by n + m. + */ + +/** + * @param {number[]} rolls + * @param {number} mean + * @param {number} n + * @return {number[]} + */ +var missingRolls = function(rolls, mean, n) { + const totalRolls = rolls.length + n; + const targetSum = mean * totalRolls; + const currentSum = rolls.reduce((sum, roll) => sum + roll, 0); + const missingSum = targetSum - currentSum; + + if (missingSum < n || missingSum > 6 * n) return []; + + const baseValue = Math.floor(missingSum / n); + const remainder = missingSum % n; + const result = []; + + for (let i = 0; i < n; i++) { + if (i < remainder) { + result.push(baseValue + 1); + } else { + result.push(baseValue); + } + } + + return result; +}; diff --git a/solutions/2029-stone-game-ix.js b/solutions/2029-stone-game-ix.js new file mode 100644 index 00000000..31ea3bb8 --- /dev/null +++ b/solutions/2029-stone-game-ix.js @@ -0,0 +1,33 @@ +/** + * 2029. Stone Game IX + * https://leetcode.com/problems/stone-game-ix/ + * Difficulty: Medium + * + * Alice and Bob continue their games with stones. There is a row of n stones, and each stone has + * an associated value. You are given an integer array stones, where stones[i] is the value of the + * ith stone. + * + * Alice and Bob take turns, with Alice starting first. On each turn, the player may remove any + * stone from stones. The player who removes a stone loses if the sum of the values of all + * removed stones is divisible by 3. Bob will win automatically if there are no remaining stones + * (even if it is Alice's turn). + * + * Assuming both players play optimally, return true if Alice wins and false if Bob wins. + */ + +/** + * @param {number[]} stones + * @return {boolean} + */ +var stoneGameIX = function(stones) { + const remainderCount = [0, 0, 0]; + for (const stone of stones) { + remainderCount[stone % 3]++; + } + + if (remainderCount[0] % 2 === 0) { + return remainderCount[1] >= 1 && remainderCount[2] >= 1; + } + + return Math.abs(remainderCount[1] - remainderCount[2]) > 2; +}; diff --git a/solutions/2030-smallest-k-length-subsequence-with-occurrences-of-a-letter.js b/solutions/2030-smallest-k-length-subsequence-with-occurrences-of-a-letter.js new file mode 100644 index 00000000..9e3f916b --- /dev/null +++ b/solutions/2030-smallest-k-length-subsequence-with-occurrences-of-a-letter.js @@ -0,0 +1,83 @@ +/** + * 2030. Smallest K-Length Subsequence With Occurrences of a Letter + * https://leetcode.com/problems/smallest-k-length-subsequence-with-occurrences-of-a-letter/ + * Difficulty: Hard + * + * You are given a string s, an integer k, a letter letter, and an integer repetition. + * + * Return the lexicographically smallest subsequence of s of length k that has the letter + * letter appear at least repetition times. The test cases are generated so that the letter + * appears in s at least repetition times. + * + * A subsequence is a string that can be derived from another string by deleting some or no + * characters without changing the order of the remaining characters. + * + * A string a is lexicographically smaller than a string b if in the first position where a + * and b differ, string a has a letter that appears earlier in the alphabet than the + * corresponding letter in b. + */ + +/** + * @param {string} s + * @param {number} k + * @param {character} letter + * @param {number} repetition + * @return {string} + */ +var smallestSubsequence = function(s, k, letter, repetition) { + const n = s.length; + let letterTotal = 0; + for (let i = 0; i < n; i++) { + if (s[i] === letter) letterTotal++; + } + + const stack = []; + let stackLetterCount = 0; + let remainingCount = letterTotal; + + for (let i = 0; i < n; i++) { + const char = s[i]; + + if (char === letter) { + remainingCount--; + } + + while ( + stack.length > 0 && stack[stack.length - 1] > char && stack.length - 1 + (n - i) >= k + && (stack[stack.length - 1] !== letter || stackLetterCount + remainingCount > repetition) + ) { + if (stack[stack.length - 1] === letter) { + stackLetterCount--; + } + stack.pop(); + } + + if (stack.length < k) { + if (char === letter) { + stackLetterCount++; + } + + const neededLetters = repetition - stackLetterCount; + const remainingPositions = k - stack.length - 1; + if (char === letter || remainingPositions >= neededLetters) { + stack.push(char); + } + } + } + + if (stackLetterCount < repetition) { + let missingLetters = repetition - stackLetterCount; + const result = [...stack]; + + for (let i = k - 1; i >= 0 && missingLetters > 0; i--) { + if (result[i] !== letter) { + result[i] = letter; + missingLetters--; + } + } + + return result.join(''); + } + + return stack.join(''); +}; diff --git a/solutions/2032-two-out-of-three.js b/solutions/2032-two-out-of-three.js new file mode 100644 index 00000000..566e6033 --- /dev/null +++ b/solutions/2032-two-out-of-three.js @@ -0,0 +1,41 @@ +/** + * 2032. Two Out of Three + * https://leetcode.com/problems/two-out-of-three/ + * Difficulty: Easy + * + * Given three integer arrays nums1, nums2, and nums3, return a distinct array containing all + * the values that are present in at least two out of the three arrays. You may return the + * values in any order. + */ + +/** + * @param {number[]} nums1 + * @param {number[]} nums2 + * @param {number[]} nums3 + * @return {number[]} + */ +var twoOutOfThree = function(nums1, nums2, nums3) { + const set1 = new Set(nums1); + const set2 = new Set(nums2); + const set3 = new Set(nums3); + const count = new Map(); + + for (const num of set1) { + count.set(num, (count.get(num) || 0) + 1); + } + + for (const num of set2) { + count.set(num, (count.get(num) || 0) + 1); + } + + for (const num of set3) { + count.set(num, (count.get(num) || 0) + 1); + } + + const result = []; + for (const [num, freq] of count) { + if (freq >= 2) result.push(num); + } + + return result; +}; diff --git a/solutions/2035-partition-array-into-two-arrays-to-minimize-sum-difference.js b/solutions/2035-partition-array-into-two-arrays-to-minimize-sum-difference.js new file mode 100644 index 00000000..1f3266b1 --- /dev/null +++ b/solutions/2035-partition-array-into-two-arrays-to-minimize-sum-difference.js @@ -0,0 +1,93 @@ +/** + * 2035. Partition Array Into Two Arrays to Minimize Sum Difference + * https://leetcode.com/problems/partition-array-into-two-arrays-to-minimize-sum-difference/ + * Difficulty: Hard + * + * You are given an integer array nums of 2 * n integers. You need to partition nums into two arrays + * of length n to minimize the absolute difference of the sums of the arrays. To partition nums, + * put each element of nums into one of the two arrays. + * + * Return the minimum possible absolute difference. + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var minimumDifference = function(nums) { + const n = nums.length / 2; + let result = Infinity; + const totalSum = nums.reduce((sum, num) => sum + num, 0); + const firstHalfSubsets = new Map(); + + for (let mask = 0; mask < (1 << n); mask++) { + let size = 0; + let subsetSum = 0; + + for (let i = 0; i < n; i++) { + if ((mask & (1 << i)) !== 0) { + size++; + subsetSum += nums[i]; + } + } + + if (!firstHalfSubsets.has(size)) { + firstHalfSubsets.set(size, []); + } + firstHalfSubsets.get(size).push(subsetSum); + } + + for (const [size, sums] of firstHalfSubsets) { + sums.sort((a, b) => a - b); + } + + for (let mask = 0; mask < (1 << n); mask++) { + let size = 0; + let secondHalfSum = 0; + + for (let i = 0; i < n; i++) { + if ((mask & (1 << i)) !== 0) { + size++; + secondHalfSum += nums[n + i]; + } + } + + const complementSize = n - size; + const firstHalfSums = firstHalfSubsets.get(complementSize); + const target = (totalSum - 2 * secondHalfSum) / 2; + const closestIndex = binarySearch(firstHalfSums, target); + + if (closestIndex < firstHalfSums.length) { + result = Math.min( + result, Math.abs(totalSum - 2 * (secondHalfSum + firstHalfSums[closestIndex])) + ); + } + + if (closestIndex > 0) { + result = Math.min( + result, Math.abs(totalSum - 2 * (secondHalfSum + firstHalfSums[closestIndex - 1])) + ); + } + } + + return result; +}; + +function binarySearch(arr, target) { + let left = 0; + let right = arr.length - 1; + + if (right < 0) return 0; + + while (left < right) { + const mid = Math.floor((left + right) / 2); + + if (arr[mid] < target) { + left = mid + 1; + } else { + right = mid; + } + } + + return left; +} diff --git a/solutions/2038-remove-colored-pieces-if-both-neighbors-are-the-same-color.js b/solutions/2038-remove-colored-pieces-if-both-neighbors-are-the-same-color.js new file mode 100644 index 00000000..7a42cfcb --- /dev/null +++ b/solutions/2038-remove-colored-pieces-if-both-neighbors-are-the-same-color.js @@ -0,0 +1,38 @@ +/** + * 2038. Remove Colored Pieces if Both Neighbors are the Same Color + * https://leetcode.com/problems/remove-colored-pieces-if-both-neighbors-are-the-same-color/ + * Difficulty: Medium + * + * There are n pieces arranged in a line, and each piece is colored either by 'A' or by 'B'. + * You are given a string colors of length n where colors[i] is the color of the ith piece. + * + * Alice and Bob are playing a game where they take alternating turns removing pieces from the + * line. In this game, Alice moves first. + * - Alice is only allowed to remove a piece colored 'A' if both its neighbors are also colored + * 'A'. She is not allowed to remove pieces that are colored 'B'. + * - Bob is only allowed to remove a piece colored 'B' if both its neighbors are also colored + * 'B'. He is not allowed to remove pieces that are colored 'A'. + * - Alice and Bob cannot remove pieces from the edge of the line. + * - If a player cannot make a move on their turn, that player loses and the other player wins. + * + * Assuming Alice and Bob play optimally, return true if Alice wins, or return false if Bob wins. + */ + +/** + * @param {string} colors + * @return {boolean} + */ +var winnerOfGame = function(colors) { + let aliceMoves = 0; + let bobMoves = 0; + + for (let i = 1; i < colors.length - 1; i++) { + if (colors[i] === 'A' && colors[i - 1] === 'A' && colors[i + 1] === 'A') { + aliceMoves++; + } else if (colors[i] === 'B' && colors[i - 1] === 'B' && colors[i + 1] === 'B') { + bobMoves++; + } + } + + return aliceMoves > bobMoves; +}; diff --git a/solutions/2039-the-time-when-the-network-becomes-idle.js b/solutions/2039-the-time-when-the-network-becomes-idle.js new file mode 100644 index 00000000..38287340 --- /dev/null +++ b/solutions/2039-the-time-when-the-network-becomes-idle.js @@ -0,0 +1,71 @@ +/** + * 2039. The Time When the Network Becomes Idle + * https://leetcode.com/problems/the-time-when-the-network-becomes-idle/ + * Difficulty: Medium + * + * There is a network of n servers, labeled from 0 to n - 1. You are given a 2D integer array + * edges, where edges[i] = [ui, vi] indicates there is a message channel between servers ui + * and vi, and they can pass any number of messages to each other directly in one second. + * You are also given a 0-indexed integer array patience of length n. + * + * All servers are connected, i.e., a message can be passed from one server to any other + * server(s) directly or indirectly through the message channels. + * + * The server labeled 0 is the master server. The rest are data servers. Each data server + * needs to send its message to the master server for processing and wait for a reply. + * Messages move between servers optimally, so every message takes the least amount of + * time to arrive at the master server. The master server will process all newly arrived + * messages instantly and send a reply to the originating server via the reversed path + * the message had gone through. + * + * At the beginning of second 0, each data server sends its message to be processed. Starting + * from second 1, at the beginning of every second, each data server will check if it has + * received a reply to the message it sent (including any newly arrived replies) from the + * master server: + * - If it has not, it will resend the message periodically. The data server i will resend + * the message every patience[i] second(s), i.e., the data server i will resend the message + * if patience[i] second(s) have elapsed since the last time the message was sent from this + * server. + * - Otherwise, no more resending will occur from this server. + * + * The network becomes idle when there are no messages passing between servers or arriving + * at servers. + * + * Return the earliest second starting from which the network becomes idle. + */ + +/** + * @param {number[][]} edges + * @param {number[]} patience + * @return {number} + */ +var networkBecomesIdle = function(edges, patience) { + const n = patience.length; + const adjList = Array.from({ length: n }, () => []); + for (const [u, v] of edges) { + adjList[u].push(v); + adjList[v].push(u); + } + + const distances = new Array(n).fill(Infinity); + distances[0] = 0; + const queue = [0]; + let maxTime = 0; + + while (queue.length) { + const curr = queue.shift(); + for (const next of adjList[curr]) { + if (distances[next] === Infinity) { + distances[next] = distances[curr] + 1; + queue.push(next); + if (next !== 0) { + const roundTrip = 2 * distances[next]; + const lastSent = Math.floor((roundTrip - 1) / patience[next]) * patience[next]; + maxTime = Math.max(maxTime, lastSent + roundTrip); + } + } + } + } + + return maxTime + 1; +}; diff --git a/solutions/2040-kth-smallest-product-of-two-sorted-arrays.js b/solutions/2040-kth-smallest-product-of-two-sorted-arrays.js new file mode 100644 index 00000000..80a4da8c --- /dev/null +++ b/solutions/2040-kth-smallest-product-of-two-sorted-arrays.js @@ -0,0 +1,53 @@ +/** + * 2040. Kth Smallest Product of Two Sorted Arrays + * https://leetcode.com/problems/kth-smallest-product-of-two-sorted-arrays/ + * Difficulty: Hard + * + * Given two sorted 0-indexed integer arrays nums1 and nums2 as well as an integer k, return + * the kth (1-based) smallest product of nums1[i] * nums2[j] where 0 <= i < nums1.length + * and 0 <= j < nums2.length. + */ + +/** + * @param {number[]} nums1 + * @param {number[]} nums2 + * @param {number} k + * @return {number} + */ +var kthSmallestProduct = function(nums1, nums2, k) { + function countProducts(maxProduct) { + let count = 0; + for (const num1 of nums1) { + let left = 0; + let right = nums2.length; + + if (num1 >= 0) { + while (left < right) { + const mid = Math.floor((left + right) / 2); + if (num1 * nums2[mid] <= maxProduct) left = mid + 1; + else right = mid; + } + count += left; + } else { + while (left < right) { + const mid = Math.floor((left + right) / 2); + if (num1 * nums2[mid] <= maxProduct) right = mid; + else left = mid + 1; + } + count += nums2.length - left; + } + } + return count; + } + + let low = -(10 ** 10); + let high = 10 ** 10; + + while (low < high) { + const mid = Math.floor((low + high) / 2); + if (countProducts(mid) >= k) high = mid; + else low = mid + 1; + } + + return low; +}; diff --git a/solutions/2042-check-if-numbers-are-ascending-in-a-sentence.js b/solutions/2042-check-if-numbers-are-ascending-in-a-sentence.js new file mode 100644 index 00000000..5b91979b --- /dev/null +++ b/solutions/2042-check-if-numbers-are-ascending-in-a-sentence.js @@ -0,0 +1,29 @@ +/** + * 2042. Check if Numbers Are Ascending in a Sentence + * https://leetcode.com/problems/check-if-numbers-are-ascending-in-a-sentence/ + * Difficulty: Easy + * + * A sentence is a list of tokens separated by a single space with no leading or trailing spaces. + * Every token is either a positive number consisting of digits 0-9 with no leading zeros, or a + * word consisting of lowercase English letters. + * - For example, "a puppy has 2 eyes 4 legs" is a sentence with seven tokens: "2" and "4" are + * numbers and the other tokens such as "puppy" are words. + * + * Given a string s representing a sentence, you need to check if all the numbers in s are strictly + * increasing from left to right (i.e., other than the last number, each number is strictly smaller + * than the number on its right in s). + * + * Return true if so, or false otherwise. + */ + +/** + * @param {string} s + * @return {boolean} + */ +var areNumbersAscending = function(s) { + const numbers = s.split(' ').filter(token => !isNaN(token)).map(Number); + for (let i = 1; i < numbers.length; i++) { + if (numbers[i] <= numbers[i - 1]) return false; + } + return true; +}; diff --git a/solutions/2043-simple-bank-system.js b/solutions/2043-simple-bank-system.js new file mode 100644 index 00000000..3cb80cb1 --- /dev/null +++ b/solutions/2043-simple-bank-system.js @@ -0,0 +1,71 @@ +/** + * 2043. Simple Bank System + * https://leetcode.com/problems/simple-bank-system/ + * Difficulty: Medium + * + * You have been tasked with writing a program for a popular bank that will automate all its + * incoming transactions (transfer, deposit, and withdraw). The bank has n accounts numbered + * from 1 to n. The initial balance of each account is stored in a 0-indexed integer array + * balance, with the (i + 1)th account having an initial balance of balance[i]. + * + * Execute all the valid transactions. A transaction is valid if: + * - The given account number(s) are between 1 and n, and + * - The amount of money withdrawn or transferred from is less than or equal to the balance + * of the account. + * + * Implement the Bank class: + * - Bank(long[] balance) Initializes the object with the 0-indexed integer array balance. + * - boolean transfer(int account1, int account2, long money) Transfers money dollars from the + * account numbered account1 to the account numbered account2. Return true if the transaction + * was successful, false otherwise. + * - boolean deposit(int account, long money) Deposit money dollars into the account numbered + * account. Return true if the transaction was successful, false otherwise. + * - boolean withdraw(int account, long money) Withdraw money dollars from the account numbered + * account. Return true if the transaction was successful, false otherwise. + */ + +/** + * @param {number[]} balance + */ +var Bank = function(balance) { + this.accounts = balance; +}; + +/** + * @param {number} account1 + * @param {number} account2 + * @param {number} money + * @return {boolean} + */ +Bank.prototype.transfer = function(account1, account2, money) { + if (account1 > this.accounts.length || account2 > this.accounts.length) return false; + if (this.accounts[account1 - 1] < money) return false; + + this.accounts[account1 - 1] -= money; + this.accounts[account2 - 1] += money; + return true; +}; + +/** + * @param {number} account + * @param {number} money + * @return {boolean} + */ +Bank.prototype.deposit = function(account, money) { + if (account > this.accounts.length) return false; + + this.accounts[account - 1] += money; + return true; +}; + +/** + * @param {number} account + * @param {number} money + * @return {boolean} + */ +Bank.prototype.withdraw = function(account, money) { + if (account > this.accounts.length || this.accounts[account - 1] < money) return false; + + this.accounts[account - 1] -= money; + return true; +}; diff --git a/solutions/2044-count-number-of-maximum-bitwise-or-subsets.js b/solutions/2044-count-number-of-maximum-bitwise-or-subsets.js new file mode 100644 index 00000000..c318115a --- /dev/null +++ b/solutions/2044-count-number-of-maximum-bitwise-or-subsets.js @@ -0,0 +1,34 @@ +/** + * 2044. Count Number of Maximum Bitwise-OR Subsets + * https://leetcode.com/problems/count-number-of-maximum-bitwise-or-subsets/ + * Difficulty: Medium + * + * Given an integer array nums, find the maximum possible bitwise OR of a subset of nums and return + * the number of different non-empty subsets with the maximum bitwise OR. + * + * An array a is a subset of an array b if a can be obtained from b by deleting some (possibly zero) + * elements of b. Two subsets are considered different if the indices of the elements chosen are + * different. + * + * The bitwise OR of an array a is equal to a[0] OR a[1] OR ... OR a[a.length - 1] (0-indexed). + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var countMaxOrSubsets = function(nums) { + const maxOr = nums.reduce((or, num) => or | num, 0); + let count = 0; + + backtrack(0, 0); + + return count; + + function backtrack(index, currentOr) { + if (currentOr === maxOr) count++; + for (let i = index; i < nums.length; i++) { + backtrack(i + 1, currentOr | nums[i]); + } + } +}; diff --git a/solutions/2045-second-minimum-time-to-reach-destination.js b/solutions/2045-second-minimum-time-to-reach-destination.js new file mode 100644 index 00000000..522eabab --- /dev/null +++ b/solutions/2045-second-minimum-time-to-reach-destination.js @@ -0,0 +1,67 @@ +/** + * 2045. Second Minimum Time to Reach Destination + * https://leetcode.com/problems/second-minimum-time-to-reach-destination/ + * Difficulty: Hard + * + * A city is represented as a bi-directional connected graph with n vertices where each vertex + * is labeled from 1 to n (inclusive). The edges in the graph are represented as a 2D integer + * array edges, where each edges[i] = [ui, vi] denotes a bi-directional edge between vertex + * ui and vertex vi. Every vertex pair is connected by at most one edge, and no vertex has + * an edge to itself. The time taken to traverse any edge is time minutes. + * + * Each vertex has a traffic signal which changes its color from green to red and vice versa + * every change minutes. All signals change at the same time. You can enter a vertex at any + * time, but can leave a vertex only when the signal is green. You cannot wait at a vertex + * if the signal is green. + * + * The second minimum value is defined as the smallest value strictly larger than the minimum value. + * - For example the second minimum value of [2, 3, 4] is 3, and the second minimum value of + * [2, 2, 4] is 4. + * + * Given n, edges, time, and change, return the second minimum time it will take to go from + * vertex 1 to vertex n. + */ + +/** + * @param {number} n + * @param {number[][]} edges + * @param {number} time + * @param {number} change + * @return {number} + */ +var secondMinimum = function(n, edges, time, change) { + const adjList = Array.from({ length: n + 1 }, () => []); + for (const [u, v] of edges) { + adjList[u].push(v); + adjList[v].push(u); + } + + const distances = Array.from({ length: n + 1 }, () => [Infinity, Infinity]); + const queue = [[1, 0]]; + distances[1][0] = 0; + + while (queue.length) { + const [node, currTime] = queue.shift(); + + for (const next of adjList[node]) { + const signalCycle = Math.floor(currTime / change); + const isGreen = signalCycle % 2 === 0; + let nextTime = currTime + time; + + if (!isGreen) { + nextTime = (signalCycle + 1) * change + time; + } + + if (nextTime < distances[next][0]) { + distances[next][1] = distances[next][0]; + distances[next][0] = nextTime; + queue.push([next, nextTime]); + } else if (nextTime > distances[next][0] && nextTime < distances[next][1]) { + distances[next][1] = nextTime; + queue.push([next, nextTime]); + } + } + } + + return distances[n][1]; +}; diff --git a/solutions/2048-next-greater-numerically-balanced-number.js b/solutions/2048-next-greater-numerically-balanced-number.js new file mode 100644 index 00000000..523a302a --- /dev/null +++ b/solutions/2048-next-greater-numerically-balanced-number.js @@ -0,0 +1,39 @@ +/** + * 2048. Next Greater Numerically Balanced Number + * https://leetcode.com/problems/next-greater-numerically-balanced-number/ + * Difficulty: Medium + * + * An integer x is numerically balanced if for every digit d in the number x, there are exactly + * d occurrences of that digit in x. + * + * Given an integer n, return the smallest numerically balanced number strictly greater than n. + */ + +/** + * @param {number} n + * @return {number} + */ +var nextBeautifulNumber = function(n) { + let candidate = n + 1; + while (candidate <= 10000000) { + if (isBalanced(candidate)) return candidate; + candidate++; + } + + return -1; + + function isBalanced(num) { + const freq = new Array(10).fill(0); + const str = num.toString(); + + for (const digit of str) { + freq[digit]++; + } + + for (const digit of str) { + if (freq[digit] !== parseInt(digit)) return false; + } + + return true; + } +}; diff --git a/solutions/2049-count-nodes-with-the-highest-score.js b/solutions/2049-count-nodes-with-the-highest-score.js new file mode 100644 index 00000000..1f13961e --- /dev/null +++ b/solutions/2049-count-nodes-with-the-highest-score.js @@ -0,0 +1,61 @@ +/** + * 2049. Count Nodes With the Highest Score + * https://leetcode.com/problems/count-nodes-with-the-highest-score/ + * Difficulty: Medium + * + * There is a binary tree rooted at 0 consisting of n nodes. The nodes are labeled from 0 to n - 1. + * You are given a 0-indexed integer array parents representing the tree, where parents[i] is the + * parent of node i. Since node 0 is the root, parents[0] == -1. + * + * Each node has a score. To find the score of a node, consider if the node and the edges connected + * to it were removed. The tree would become one or more non-empty subtrees. The size of a subtree + * is the number of the nodes in it. The score of the node is the product of the sizes of all + * those subtrees. + * + * Return the number of nodes that have the highest score. + */ + +/** + * @param {number[]} parents + * @return {number} + */ +var countHighestScoreNodes = function(parents) { + const n = parents.length; + const children = Array.from({ length: n }, () => []); + for (let i = 1; i < n; i++) { + children[parents[i]].push(i); + } + + const sizes = new Array(n).fill(0); + let maxScore = 0n; + let maxScoreCount = 0; + + calculateSize(0); + + return maxScoreCount; + + function calculateSize(node) { + let leftSize = 0; + let rightSize = 0; + + if (children[node].length > 0) leftSize = calculateSize(children[node][0]); + if (children[node].length > 1) rightSize = calculateSize(children[node][1]); + + sizes[node] = leftSize + rightSize + 1; + + let score = 1n; + if (leftSize > 0) score *= BigInt(leftSize); + if (rightSize > 0) score *= BigInt(rightSize); + const parentSize = n - sizes[node]; + if (parentSize > 0) score *= BigInt(parentSize); + + if (score > maxScore) { + maxScore = score; + maxScoreCount = 1; + } else if (score === maxScore) { + maxScoreCount++; + } + + return sizes[node]; + } +}; diff --git a/solutions/2050-parallel-courses-iii.js b/solutions/2050-parallel-courses-iii.js new file mode 100644 index 00000000..62cdec65 --- /dev/null +++ b/solutions/2050-parallel-courses-iii.js @@ -0,0 +1,61 @@ +/** + * 2050. Parallel Courses III + * https://leetcode.com/problems/parallel-courses-iii/ + * Difficulty: Hard + * + * You are given an integer n, which indicates that there are n courses labeled from 1 to n. + * You are also given a 2D integer array relations where relations[j] = [prevCoursej, nextCoursej] + * denotes that course prevCoursej has to be completed before course nextCoursej (prerequisite + * relationship). Furthermore, you are given a 0-indexed integer array time where time[i] denotes + * how many months it takes to complete the (i+1)th course. + * + * You must find the minimum number of months needed to complete all the courses following these + * rules: + * - You may start taking a course at any time if the prerequisites are met. + * - Any number of courses can be taken at the same time. + * + * Return the minimum number of months needed to complete all the courses. + * + * Note: The test cases are generated such that it is possible to complete every course (i.e., the + * graph is a directed acyclic graph). + */ + +/** + * @param {number} n + * @param {number[][]} relations + * @param {number[]} time + * @return {number} + */ +var minimumTime = function(n, relations, time) { + const adjacencyList = Array.from({ length: n + 1 }, () => []); + const inDegree = new Array(n + 1).fill(0); + const completionTime = new Array(n + 1).fill(0); + + for (const [prev, next] of relations) { + adjacencyList[prev].push(next); + inDegree[next]++; + } + + const queue = []; + for (let i = 1; i <= n; i++) { + if (inDegree[i] === 0) { + queue.push(i); + completionTime[i] = time[i - 1]; + } + } + + while (queue.length) { + const current = queue.shift(); + for (const next of adjacencyList[current]) { + completionTime[next] = Math.max( + completionTime[next], + completionTime[current] + time[next - 1] + ); + if (--inDegree[next] === 0) { + queue.push(next); + } + } + } + + return Math.max(...completionTime); +}; diff --git a/solutions/2055-plates-between-candles.js b/solutions/2055-plates-between-candles.js new file mode 100644 index 00000000..347ed4ae --- /dev/null +++ b/solutions/2055-plates-between-candles.js @@ -0,0 +1,55 @@ +/** + * 2055. Plates Between Candles + * https://leetcode.com/problems/plates-between-candles/ + * Difficulty: Medium + * + * There is a long table with a line of plates and candles arranged on top of it. You are given + * a 0-indexed string s consisting of characters '*' and '|' only, where a '*' represents a plate + * and a '|' represents a candle. + * + * You are also given a 0-indexed 2D integer array queries where queries[i] = [lefti, righti] + * denotes the substring s[lefti...righti] (inclusive). For each query, you need to find the + * number of plates between candles that are in the substring. A plate is considered between + * candles if there is at least one candle to its left and at least one candle to its right + * in the substring. + * - For example, s = "||**||**|*", and a query [3, 8] denotes the substring "*||**|". The number + * of plates between candles in this substring is 2, as each of the two plates has at least one + * candle in the substring to its left and right. + * + * Return an integer array answer where answer[i] is the answer to the ith query. + */ + +/** + * @param {string} s + * @param {number[][]} queries + * @return {number[]} + */ +var platesBetweenCandles = function(s, queries) { + const n = s.length; + const prefixPlates = new Array(n + 1).fill(0); + const leftCandle = new Array(n).fill(-1); + const rightCandle = new Array(n).fill(-1); + + for (let i = 0, candle = -1; i < n; i++) { + prefixPlates[i + 1] = prefixPlates[i] + (s[i] === '*' ? 1 : 0); + if (s[i] === '|') candle = i; + leftCandle[i] = candle; + } + + for (let i = n - 1, candle = -1; i >= 0; i--) { + if (s[i] === '|') candle = i; + rightCandle[i] = candle; + } + + const result = new Array(queries.length).fill(0); + for (let i = 0; i < queries.length; i++) { + const [start, end] = queries[i]; + const left = rightCandle[start]; + const right = leftCandle[end]; + if (left !== -1 && right !== -1 && left < right) { + result[i] = prefixPlates[right] - prefixPlates[left]; + } + } + + return result; +}; diff --git a/solutions/2056-number-of-valid-move-combinations-on-chessboard.js b/solutions/2056-number-of-valid-move-combinations-on-chessboard.js new file mode 100644 index 00000000..94716f2b --- /dev/null +++ b/solutions/2056-number-of-valid-move-combinations-on-chessboard.js @@ -0,0 +1,108 @@ +/** + * 2056. Number of Valid Move Combinations On Chessboard + * https://leetcode.com/problems/number-of-valid-move-combinations-on-chessboard/ + * Difficulty: Hard + * + * There is an 8 x 8 chessboard containing n pieces (rooks, queens, or bishops). You are given a + * string array pieces of length n, where pieces[i] describes the type (rook, queen, or bishop) + * of the ith piece. In addition, you are given a 2D integer array positions also of length n, + * where positions[i] = [ri, ci] indicates that the ith piece is currently at the 1-based + * coordinate (ri, ci) on the chessboard. + * + * When making a move for a piece, you choose a destination square that the piece will travel + * toward and stop on. + * - A rook can only travel horizontally or vertically from (r, c) to the direction of (r+1, c), + * (r-1, c), (r, c+1), or (r, c-1). + * - A queen can only travel horizontally, vertically, or diagonally from (r, c) to the direction + * of (r+1, c), (r-1, c), (r, c+1), (r, c-1), (r+1, c+1), (r+1, c-1), (r-1, c+1), (r-1, c-1). + * - A bishop can only travel diagonally from (r, c) to the direction of (r+1, c+1), (r+1, c-1), + * (r-1, c+1), (r-1, c-1). + * + * You must make a move for every piece on the board simultaneously. A move combination consists of + * all the moves performed on all the given pieces. Every second, each piece will instantaneously + * travel one square towards their destination if they are not already at it. All pieces start + * traveling at the 0th second. A move combination is invalid if, at a given time, two or more + * pieces occupy the same square. + * + * Return the number of valid move combinations. + * + * Notes: + * - No two pieces will start in the same square. + * - You may choose the square a piece is already on as its destination. + * - If two pieces are directly adjacent to each other, it is valid for them to move past each other + * and swap positions in one second. + */ + +/** + * @param {string[]} pieces + * @param {number[][]} positions + * @return {number} + */ +var countCombinations = function(pieces, positions) { + const n = pieces.length; + const directions = { + rook: [[0, 1], [0, -1], [1, 0], [-1, 0]], + bishop: [[1, 1], [1, -1], [-1, 1], [-1, -1]], + queen: [[0, 1], [0, -1], [1, 0], [-1, 0], [1, 1], [1, -1], [-1, 1], [-1, -1]] + }; + + return generateCombinations(0, [], []); + + function isValidPosition(row, col) { + return row >= 1 && row <= 8 && col >= 1 && col <= 8; + } + + function simulateMoves(moves, steps) { + const current = positions.map(([r, c]) => [r, c]); + const maxSteps = Math.max(...steps); + + for (let t = 0; t <= maxSteps; t++) { + const positionsAtTime = new Set(); + for (let i = 0; i < n; i++) { + const [dr, dc] = moves[i]; + const step = Math.min(t, steps[i]); + const newRow = current[i][0] + dr * step; + const newCol = current[i][1] + dc * step; + + if (t > steps[i] && steps[i] > 0 && !isValidPosition(newRow, newCol)) continue; + + const posKey = `${newRow},${newCol}`; + if (positionsAtTime.has(posKey)) return false; + positionsAtTime.add(posKey); + } + } + + return true; + } + + function generateCombinations(index, selectedMoves, selectedSteps) { + if (index === n) { + return simulateMoves(selectedMoves, selectedSteps) ? 1 : 0; + } + + let total = 0; + const [startRow, startCol] = positions[index]; + const pieceDirections = directions[pieces[index]]; + + total += generateCombinations(index + 1, [...selectedMoves, [0, 0]], [...selectedSteps, 0]); + + for (const [dr, dc] of pieceDirections) { + let row = startRow; + let col = startCol; + let step = 0; + + while (isValidPosition(row + dr, col + dc)) { + row += dr; + col += dc; + step++; + total += generateCombinations( + index + 1, + [...selectedMoves, [dr, dc]], + [...selectedSteps, step] + ); + } + } + + return total; + } +}; diff --git a/solutions/2057-smallest-index-with-equal-value.js b/solutions/2057-smallest-index-with-equal-value.js new file mode 100644 index 00000000..3fe1c453 --- /dev/null +++ b/solutions/2057-smallest-index-with-equal-value.js @@ -0,0 +1,23 @@ +/** + * 2057. Smallest Index With Equal Value + * https://leetcode.com/problems/smallest-index-with-equal-value/ + * Difficulty: Easy + * + * Given a 0-indexed integer array nums, return the smallest index i of nums such that i mod + * 10 == nums[i], or -1 if such index does not exist. + * + * x mod y denotes the remainder when x is divided by y. + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var smallestEqual = function(nums) { + for (let i = 0; i < nums.length; i++) { + if (i % 10 === nums[i]) { + return i; + } + } + return -1; +}; diff --git a/solutions/2058-find-the-minimum-and-maximum-number-of-nodes-between-critical-points.js b/solutions/2058-find-the-minimum-and-maximum-number-of-nodes-between-critical-points.js new file mode 100644 index 00000000..da92ff90 --- /dev/null +++ b/solutions/2058-find-the-minimum-and-maximum-number-of-nodes-between-critical-points.js @@ -0,0 +1,63 @@ +/** + * 2058. Find the Minimum and Maximum Number of Nodes Between Critical Points + * https://leetcode.com/problems/find-the-minimum-and-maximum-number-of-nodes-between-critical-points/ + * Difficulty: Medium + * + * A critical point in a linked list is defined as either a local maxima or a local minima. + * + * A node is a local maxima if the current node has a value strictly greater than the previous node + * and the next node. + * + * A node is a local minima if the current node has a value strictly smaller than the previous node + * and the next node. + * + * Note that a node can only be a local maxima/minima if there exists both a previous node and a + * next node. + * + * Given a linked list head, return an array of length 2 containing [minDistance, maxDistance] + * where minDistance is the minimum distance between any two distinct critical points and + * maxDistance is the maximum distance between any two distinct critical points. If there are + * fewer than two critical points, return [-1, -1]. + */ + +/** + * Definition for singly-linked list. + * function ListNode(val, next) { + * this.val = (val===undefined ? 0 : val) + * this.next = (next===undefined ? null : next) + * } + */ +/** + * @param {ListNode} head + * @return {number[]} + */ +var nodesBetweenCriticalPoints = function(head) { + const criticalPositions = []; + let position = 1; + let prev = head; + let current = head.next; + + while (current.next) { + const next = current.next; + if ((current.val > prev.val && current.val > next.val) || + (current.val < prev.val && current.val < next.val)) { + criticalPositions.push(position); + } + prev = current; + current = next; + position++; + } + + if (criticalPositions.length < 2) { + return [-1, -1]; + } + + let minDistance = Infinity; + for (let i = 1; i < criticalPositions.length; i++) { + minDistance = Math.min(minDistance, criticalPositions[i] - criticalPositions[i - 1]); + } + + const maxDistance = criticalPositions[criticalPositions.length - 1] - criticalPositions[0]; + + return [minDistance, maxDistance]; +}; diff --git a/solutions/2059-minimum-operations-to-convert-number.js b/solutions/2059-minimum-operations-to-convert-number.js new file mode 100644 index 00000000..677e5de9 --- /dev/null +++ b/solutions/2059-minimum-operations-to-convert-number.js @@ -0,0 +1,57 @@ +/** + * 2059. Minimum Operations to Convert Number + * https://leetcode.com/problems/minimum-operations-to-convert-number/ + * Difficulty: Medium + * + * You are given a 0-indexed integer array nums containing distinct numbers, an integer start, + * and an integer goal. There is an integer x that is initially set to start, and you want to + * perform operations on x such that it is converted to goal. You can perform the following + * operation repeatedly on the number x: + * + * If 0 <= x <= 1000, then for any index i in the array (0 <= i < nums.length), you can set x + * to any of the following: + * - x + nums[i] + * - x - nums[i] + * - x ^ nums[i] (bitwise-XOR) + * + * Note that you can use each nums[i] any number of times in any order. Operations that set x + * to be out of the range 0 <= x <= 1000 are valid, but no more operations can be done afterward. + * + * Return the minimum number of operations needed to convert x = start into goal, and -1 if it + * is not possible. + */ + +/** + * @param {number[]} nums + * @param {number} start + * @param {number} goal + * @return {number} + */ +var minimumOperations = function(nums, start, goal) { + const queue = [[start, 0]]; + const visited = new Set([start]); + + while (queue.length) { + const [current, steps] = queue.shift(); + + for (const num of nums) { + const candidates = [ + current + num, + current - num, + current ^ num + ]; + + for (const next of candidates) { + if (next === goal) { + return steps + 1; + } + if (next >= 0 && next <= 1000 && !visited.has(next)) { + visited.add(next); + queue.push([next, steps + 1]); + } + } + } + } + + return -1; +}; diff --git a/solutions/2060-check-if-an-original-string-exists-given-two-encoded-strings.js b/solutions/2060-check-if-an-original-string-exists-given-two-encoded-strings.js new file mode 100644 index 00000000..520e531e --- /dev/null +++ b/solutions/2060-check-if-an-original-string-exists-given-two-encoded-strings.js @@ -0,0 +1,73 @@ +/** + * 2060. Check if an Original String Exists Given Two Encoded Strings + * https://leetcode.com/problems/check-if-an-original-string-exists-given-two-encoded-strings/ + * Difficulty: Hard + * + * An original string, consisting of lowercase English letters, can be encoded by the following + * steps: + * - Arbitrarily split it into a sequence of some number of non-empty substrings. + * - Arbitrarily choose some elements (possibly none) of the sequence, and replace each with its + * length (as a numeric string). + * - Concatenate the sequence as the encoded string. + * + * For example, one way to encode an original string "abcdefghijklmnop" might be: + * - Split it as a sequence: ["ab", "cdefghijklmn", "o", "p"]. + * - Choose the second and third elements to be replaced by their lengths, respectively. The + * sequence becomes ["ab", "12", "1", "p"]. + * - Concatenate the elements of the sequence to get the encoded string: "ab121p". + * + * Given two encoded strings s1 and s2, consisting of lowercase English letters and digits 1-9 + * (inclusive), return true if there exists an original string that could be encoded as both s1 + * and s2. Otherwise, return false. + * + * Note: The test cases are generated such that the number of consecutive digits in s1 and s2 + * does not exceed 3. + */ + +/** + * @param {string} s1 + * @param {string} s2 + * @return {boolean} + */ +var possiblyEquals = function(s1, s2) { + const memo = new Array(s1.length + 1).fill().map(() => new Array(s2.length + 1).fill() + .map(() => ({}))); + + function match(pos1, pos2, diff) { + if (pos1 === s1.length && pos2 === s2.length) return diff === 0; + if (memo[pos1][pos2][diff] !== undefined) return memo[pos1][pos2][diff]; + + const char1 = s1[pos1]; + const char2 = s2[pos2]; + + if (pos1 < s1.length && pos2 < s2.length && char1 === char2 && diff === 0) { + if (match(pos1 + 1, pos2 + 1, 0)) return true; + } + + if (pos1 < s1.length && isNaN(char1) && diff < 0) { + if (match(pos1 + 1, pos2, diff + 1)) return true; + } + + if (pos2 < s2.length && isNaN(char2) && diff > 0) { + if (match(pos1, pos2 + 1, diff - 1)) return true; + } + + let num = 0; + for (let i = 0; i < 3 && pos1 + i < s1.length; i++) { + if (isNaN(s1[pos1 + i])) break; + num = num * 10 + parseInt(s1[pos1 + i]); + if (match(pos1 + i + 1, pos2, diff + num)) return true; + } + + num = 0; + for (let i = 0; i < 3 && pos2 + i < s2.length; i++) { + if (isNaN(s2[pos2 + i])) break; + num = num * 10 + parseInt(s2[pos2 + i]); + if (match(pos1, pos2 + i + 1, diff - num)) return true; + } + + return memo[pos1][pos2][diff] = false; + } + + return match(0, 0, 0); +}; diff --git a/solutions/2062-count-vowel-substrings-of-a-string.js b/solutions/2062-count-vowel-substrings-of-a-string.js new file mode 100644 index 00000000..8d427ac8 --- /dev/null +++ b/solutions/2062-count-vowel-substrings-of-a-string.js @@ -0,0 +1,33 @@ +/** + * 2062. Count Vowel Substrings of a String + * https://leetcode.com/problems/count-vowel-substrings-of-a-string/ + * Difficulty: Easy + * + * A substring is a contiguous (non-empty) sequence of characters within a string. + * + * A vowel substring is a substring that only consists of vowels ('a', 'e', 'i', 'o', and 'u') + * and has all five vowels present in it. + * + * Given a string word, return the number of vowel substrings in word. + */ + +/** + * @param {string} word + * @return {number} + */ +var countVowelSubstrings = function(word) { + const vowels = new Set(['a', 'e', 'i', 'o', 'u']); + let total = 0; + + for (let start = 0; start < word.length; start++) { + const vowelCount = new Map(); + for (let end = start; end < word.length && vowels.has(word[end]); end++) { + vowelCount.set(word[end], (vowelCount.get(word[end]) || 0) + 1); + if (vowelCount.size === 5) { + total++; + } + } + } + + return total; +}; diff --git a/solutions/2063-vowels-of-all-substrings.js b/solutions/2063-vowels-of-all-substrings.js new file mode 100644 index 00000000..bde705e8 --- /dev/null +++ b/solutions/2063-vowels-of-all-substrings.js @@ -0,0 +1,30 @@ +/** + * 2063. Vowels of All Substrings + * https://leetcode.com/problems/vowels-of-all-substrings/ + * Difficulty: Medium + * + * Given a string word, return the sum of the number of vowels ('a', 'e', 'i', 'o', and 'u') in + * every substring of word. + * + * A substring is a contiguous (non-empty) sequence of characters within a string. + * + * Note: Due to the large constraints, the answer may not fit in a signed 32-bit integer. Please + * be careful during the calculations. + */ + +/** + * @param {string} word + * @return {number} + */ +var countVowels = function(word) { + const vowels = new Set(['a', 'e', 'i', 'o', 'u']); + let total = 0; + + for (let i = 0; i < word.length; i++) { + if (vowels.has(word[i])) { + total += (i + 1) * (word.length - i); + } + } + + return total; +}; diff --git a/solutions/2064-minimized-maximum-of-products-distributed-to-any-store.js b/solutions/2064-minimized-maximum-of-products-distributed-to-any-store.js new file mode 100644 index 00000000..b1781081 --- /dev/null +++ b/solutions/2064-minimized-maximum-of-products-distributed-to-any-store.js @@ -0,0 +1,45 @@ +/** + * 2064. Minimized Maximum of Products Distributed to Any Store + * https://leetcode.com/problems/minimized-maximum-of-products-distributed-to-any-store/ + * Difficulty: Medium + * + * You are given an integer n indicating there are n specialty retail stores. There are m product + * types of varying amounts, which are given as a 0-indexed integer array quantities, where + * quantities[i] represents the number of products of the ith product type. + * + * You need to distribute all products to the retail stores following these rules: + * - A store can only be given at most one product type but can be given any amount of it. + * - After distribution, each store will have been given some number of products (possibly 0). + * Let x represent the maximum number of products given to any store. You want x to be as small + * as possible, i.e., you want to minimize the maximum number of products that are given to any + * store. + * + * Return the minimum possible x. + */ + +/** + * @param {number} n + * @param {number[]} quantities + * @return {number} + */ +var minimizedMaximum = function(n, quantities) { + let left = 1; + let right = Math.max(...quantities); + + while (left < right) { + const mid = Math.floor((left + right) / 2); + let storesNeeded = 0; + + for (const quantity of quantities) { + storesNeeded += Math.ceil(quantity / mid); + } + + if (storesNeeded <= n) { + right = mid; + } else { + left = mid + 1; + } + } + + return left; +}; diff --git a/solutions/2065-maximum-path-quality-of-a-graph.js b/solutions/2065-maximum-path-quality-of-a-graph.js new file mode 100644 index 00000000..9d07048c --- /dev/null +++ b/solutions/2065-maximum-path-quality-of-a-graph.js @@ -0,0 +1,59 @@ +/** + * 2065. Maximum Path Quality of a Graph + * https://leetcode.com/problems/maximum-path-quality-of-a-graph/ + * Difficulty: Hard + * + * There is an undirected graph with n nodes numbered from 0 to n - 1 (inclusive). You are given a + * 0-indexed integer array values where values[i] is the value of the ith node. You are also given + * a 0-indexed 2D integer array edges, where each edges[j] = [uj, vj, timej] indicates that there + * is an undirected edge between the nodes uj and vj, and it takes timej seconds to travel between + * the two nodes. Finally, you are given an integer maxTime. + * + * A valid path in the graph is any path that starts at node 0, ends at node 0, and takes at most + * maxTime seconds to complete. You may visit the same node multiple times. The quality of a valid + * path is the sum of the values of the unique nodes visited in the path (each node's value is + * added at most once to the sum). + * + * Return the maximum quality of a valid path. + * + * Note: There are at most four edges connected to each node. + */ + +/** + * @param {number[]} values + * @param {number[][]} edges + * @param {number} maxTime + * @return {number} + */ +var maximalPathQuality = function(values, edges, maxTime) { + const n = values.length; + const adjList = Array.from({ length: n }, () => []); + + for (const [u, v, time] of edges) { + adjList[u].push([v, time]); + adjList[v].push([u, time]); + } + + let result = 0; + const initialVisited = new Set([0]); + + dfs(0, maxTime, values[0], initialVisited); + + return result; + + function dfs(node, timeLeft, quality, visited) { + if (timeLeft < 0) return 0; + if (node === 0) { + result = Math.max(result, quality); + } + + for (const [nextNode, travelTime] of adjList[node]) { + const newVisited = new Set(visited); + const newQuality = newVisited.has(nextNode) ? quality : quality + values[nextNode]; + newVisited.add(nextNode); + dfs(nextNode, timeLeft - travelTime, newQuality, newVisited); + } + + return result; + } +}; diff --git a/solutions/2068-check-whether-two-strings-are-almost-equivalent.js b/solutions/2068-check-whether-two-strings-are-almost-equivalent.js new file mode 100644 index 00000000..210aeb88 --- /dev/null +++ b/solutions/2068-check-whether-two-strings-are-almost-equivalent.js @@ -0,0 +1,29 @@ +/** + * 2068. Check Whether Two Strings are Almost Equivalent + * https://leetcode.com/problems/check-whether-two-strings-are-almost-equivalent/ + * Difficulty: Easy + * + * Two strings word1 and word2 are considered almost equivalent if the differences between the + * frequencies of each letter from 'a' to 'z' between word1 and word2 is at most 3. + * + * Given two strings word1 and word2, each of length n, return true if word1 and word2 are almost + * equivalent, or false otherwise. + * + * The frequency of a letter x is the number of times it occurs in the string. + */ + +/** + * @param {string} word1 + * @param {string} word2 + * @return {boolean} + */ +var checkAlmostEquivalent = function(word1, word2) { + const map = new Array(26).fill(0); + + for (let i = 0; i < word1.length; i++) { + map[word1.charCodeAt(i) - 97]++; + map[word2.charCodeAt(i) - 97]--; + } + + return map.every(diff => Math.abs(diff) <= 3); +}; diff --git a/solutions/2069-walking-robot-simulation-ii.js b/solutions/2069-walking-robot-simulation-ii.js new file mode 100644 index 00000000..e4896040 --- /dev/null +++ b/solutions/2069-walking-robot-simulation-ii.js @@ -0,0 +1,84 @@ +/** + * 2069. Walking Robot Simulation II + * https://leetcode.com/problems/walking-robot-simulation-ii/ + * Difficulty: Medium + * + * A width x height grid is on an XY-plane with the bottom-left cell at (0, 0) and the + * top-right cell at (width - 1, height - 1). The grid is aligned with the four cardinal + * directions ("North", "East", "South", and "West"). A robot is initially at cell (0, 0) + * facing direction "East". + * + * The robot can be instructed to move for a specific number of steps. For each step, it does + * the following. + * 1. Attempts to move forward one cell in the direction it is facing. + * 2. If the cell the robot is moving to is out of bounds, the robot instead turns 90 degrees + * counterclockwise and retries the step. + * + * After the robot finishes moving the number of steps required, it stops and awaits the next + * instruction. + * + * Implement the Robot class: + * - Robot(int width, int height) Initializes the width x height grid with the robot at (0, 0) + * facing "East". + * - void step(int num) Instructs the robot to move forward num steps. + * - int[] getPos() Returns the current cell the robot is at, as an array of length 2, [x, y]. + * - String getDir() Returns the current direction of the robot, "North", "East", "South", or + * "West". + */ + +/** + * @param {number} width + * @param {number} height + */ +var Robot = function(width, height) { + this.width = width; + this.height = height; + this.position = [0, 0]; + this.directionIndex = 0; + this.directions = ['East', 'North', 'West', 'South']; + this.moves = [[1, 0], [0, 1], [-1, 0], [0, -1]]; + this.perimeter = 2 * (width + height - 2); +}; + +/** + * @param {number} num + * @return {void} + */ +Robot.prototype.step = function(num) { + num %= this.perimeter; + if (num === 0) num = this.perimeter; + + while (num > 0) { + const [dx, dy] = this.moves[this.directionIndex]; + const [x, y] = this.position; + let steps; + + if (this.directionIndex === 0) steps = this.width - 1 - x; + else if (this.directionIndex === 1) steps = this.height - 1 - y; + else if (this.directionIndex === 2) steps = x; + else steps = y; + + if (steps >= num) { + this.position = [x + dx * num, y + dy * num]; + num = 0; + } else { + this.position = [x + dx * steps, y + dy * steps]; + this.directionIndex = (this.directionIndex + 1) % 4; + num -= steps; + } + } +}; + +/** + * @return {number[]} + */ +Robot.prototype.getPos = function() { + return this.position; +}; + +/** + * @return {string} + */ +Robot.prototype.getDir = function() { + return this.directions[this.directionIndex]; +}; diff --git a/solutions/2070-most-beautiful-item-for-each-query.js b/solutions/2070-most-beautiful-item-for-each-query.js new file mode 100644 index 00000000..1931e875 --- /dev/null +++ b/solutions/2070-most-beautiful-item-for-each-query.js @@ -0,0 +1,54 @@ +/** + * 2070. Most Beautiful Item for Each Query + * https://leetcode.com/problems/most-beautiful-item-for-each-query/ + * Difficulty: Medium + * + * You are given a 2D integer array items where items[i] = [pricei, beautyi] denotes the price and + * beauty of an item respectively. + * + * You are also given a 0-indexed integer array queries. For each queries[j], you want to determine + * the maximum beauty of an item whose price is less than or equal to queries[j]. If no such item + * exists, then the answer to this query is 0. + * + * Return an array answer of the same length as queries where answer[j] is the answer to the jth + * query. + */ + +/** + * @param {number[][]} items + * @param {number[]} queries + * @return {number[]} + */ +var maximumBeauty = function(items, queries) { + items.sort((a, b) => a[0] - b[0]); + const maxBeauty = []; + let currentMax = 0; + + for (const [, beauty] of items) { + currentMax = Math.max(currentMax, beauty); + maxBeauty.push(currentMax); + } + + const result = new Array(queries.length).fill(0); + + for (let i = 0; i < queries.length; i++) { + const price = queries[i]; + let left = 0; + let right = items.length - 1; + + while (left <= right) { + const mid = Math.floor((left + right) / 2); + if (items[mid][0] <= price) { + left = mid + 1; + } else { + right = mid - 1; + } + } + + if (right >= 0) { + result[i] = maxBeauty[right]; + } + } + + return result; +}; diff --git a/solutions/2071-maximum-number-of-tasks-you-can-assign.js b/solutions/2071-maximum-number-of-tasks-you-can-assign.js new file mode 100644 index 00000000..5382d5d5 --- /dev/null +++ b/solutions/2071-maximum-number-of-tasks-you-can-assign.js @@ -0,0 +1,79 @@ +/** + * 2071. Maximum Number of Tasks You Can Assign + * https://leetcode.com/problems/maximum-number-of-tasks-you-can-assign/ + * Difficulty: Hard + * + * You have n tasks and m workers. Each task has a strength requirement stored in a 0-indexed + * integer array tasks, with the ith task requiring tasks[i] strength to complete. The strength + * of each worker is stored in a 0-indexed integer array workers, with the jth worker having + * workers[j] strength. Each worker can only be assigned to a single task and must have a + * strength greater than or equal to the task's strength requirement (i.e., workers[j] >= tasks[i]). + * + * Additionally, you have pills magical pills that will increase a worker's strength by strength. + * You can decide which workers receive the magical pills, however, you may only give each worker + * at most one magical pill. + * + * Given the 0-indexed integer arrays tasks and workers and the integers pills and strength, + * return the maximum number of tasks that can be completed. + */ + +/** + * @param {number[]} tasks + * @param {number[]} workers + * @param {number} pills + * @param {number} strength + * @return {number} + */ +var maxTaskAssign = function(tasks, workers, pills, strength) { + tasks.sort((a, b) => a - b); + workers.sort((a, b) => a - b); + + const n = tasks.length; + const m = workers.length; + + let left = 0; + let right = Math.min(n, m); + + while (left < right) { + const mid = Math.floor((left + right + 1) / 2); + + if (canAssign(mid)) { + left = mid; + } else { + right = mid - 1; + } + } + + return left; + + function canAssign(k) { + const availableTasks = tasks.slice(0, k); + const availableWorkers = workers.slice(m - k); + let remainingPills = pills; + + for (let i = k - 1; i >= 0; i--) { + const task = availableTasks[i]; + + if (availableWorkers[availableWorkers.length - 1] >= task) { + availableWorkers.pop(); + continue; + } + + if (remainingPills === 0) return false; + + let found = false; + for (let j = 0; j < availableWorkers.length; j++) { + if (availableWorkers[j] + strength >= task) { + availableWorkers.splice(j, 1); + remainingPills--; + found = true; + break; + } + } + + if (!found) return false; + } + + return true; + } +}; diff --git a/solutions/2074-reverse-nodes-in-even-length-groups.js b/solutions/2074-reverse-nodes-in-even-length-groups.js new file mode 100644 index 00000000..2608277e --- /dev/null +++ b/solutions/2074-reverse-nodes-in-even-length-groups.js @@ -0,0 +1,72 @@ +/** + * 2074. Reverse Nodes in Even Length Groups + * https://leetcode.com/problems/reverse-nodes-in-even-length-groups/ + * Difficulty: Medium + * + * You are given the head of a linked list. + * + * The nodes in the linked list are sequentially assigned to non-empty groups whose lengths form + * the sequence of the natural numbers (1, 2, 3, 4, ...). The length of a group is the number + * of nodes assigned to it. In other words: + * - The 1st node is assigned to the first group. + * - The 2nd and the 3rd nodes are assigned to the second group. + * - The 4th, 5th, and 6th nodes are assigned to the third group, and so on. + * + * Note that the length of the last group may be less than or equal to 1 + the length of the second + * to last group. + * + * Reverse the nodes in each group with an even length, and return the head of the modified linked + * list. + */ + +/** + * Definition for singly-linked list. + * function ListNode(val, next) { + * this.val = (val===undefined ? 0 : val) + * this.next = (next===undefined ? null : next) + * } + */ +/** + * @param {ListNode} head + * @return {ListNode} + */ +var reverseEvenLengthGroups = function(head) { + let prevGroup = head; + let groupLength = 2; + + while (prevGroup.next) { + let count = 0; + let current = prevGroup.next; + const groupStart = current; + + while (current && count < groupLength) { + current = current.next; + count++; + } + + if (count % 2 === 0) { + prevGroup.next = reverseGroup(groupStart, count); + } + + for (let i = 0; i < count; i++) { + prevGroup = prevGroup.next; + } + + groupLength++; + } + + return head; + + function reverseGroup(start, length) { + let prev = null; + let current = start; + for (let i = 0; i < length; i++) { + const next = current.next; + current.next = prev; + prev = current; + current = next; + } + start.next = current; + return prev; + } +}; diff --git a/solutions/2075-decode-the-slanted-ciphertext.js b/solutions/2075-decode-the-slanted-ciphertext.js new file mode 100644 index 00000000..63f5a41d --- /dev/null +++ b/solutions/2075-decode-the-slanted-ciphertext.js @@ -0,0 +1,51 @@ +/** + * 2075. Decode the Slanted Ciphertext + * https://leetcode.com/problems/decode-the-slanted-ciphertext/ + * Difficulty: Medium + * + * A string originalText is encoded using a slanted transposition cipher to a string encodedText + * with the help of a matrix having a fixed number of rows rows. + * + * originalText is placed first in a top-left to bottom-right manner. + * + * The blue cells are filled first, followed by the red cells, then the yellow cells, and so on, + * until we reach the end of originalText. The arrow indicates the order in which the cells are + * filled. All empty cells are filled with ' '. The number of columns is chosen such that the + * rightmost column will not be empty after filling in originalText. + * + * encodedText is then formed by appending all characters of the matrix in a row-wise fashion. + * + * The characters in the blue cells are appended first to encodedText, then the red cells, and so + * on, and finally the yellow cells. The arrow indicates the order in which the cells are accessed. + * + * For example, if originalText = "cipher" and rows = 3, then we encode it in the following manner. + * + * The blue arrows depict how originalText is placed in the matrix, and the red arrows denote the + * order in which encodedText is formed. In the above example, encodedText = "ch ie pr". + * + * Given the encoded string encodedText and number of rows rows, return the original string + * originalText. + * + * Note: originalText does not have any trailing spaces ' '. The test cases are generated such that + * there is only one possible originalText. + */ + +/** + * @param {string} encodedText + * @param {number} rows + * @return {string} + */ +var decodeCiphertext = function(encodedText, rows) { + if (rows === 1) return encodedText; + + const count = encodedText.length / rows; + let result = ''; + + for (let i = 0; i < count; i++) { + for (let row = 0; row < rows && row + i < count; row++) { + result += encodedText[row * count + i + row]; + } + } + + return result.trimEnd(); +}; diff --git a/solutions/2076-process-restricted-friend-requests.js b/solutions/2076-process-restricted-friend-requests.js new file mode 100644 index 00000000..dff94d09 --- /dev/null +++ b/solutions/2076-process-restricted-friend-requests.js @@ -0,0 +1,70 @@ +/** + * 2076. Process Restricted Friend Requests + * https://leetcode.com/problems/process-restricted-friend-requests/ + * Difficulty: Hard + * + * You are given an integer n indicating the number of people in a network. Each person is + * labeled from 0 to n - 1. + * + * You are also given a 0-indexed 2D integer array restrictions, where restrictions[i] = [xi, yi] + * means that person xi and person yi cannot become friends, either directly or indirectly through + * other people. + * + * Initially, no one is friends with each other. You are given a list of friend requests as a + * 0-indexed 2D integer array requests, where requests[j] = [uj, vj] is a friend request between + * person uj and person vj. + * + * A friend request is successful if uj and vj can be friends. Each friend request is processed + * in the given order (i.e., requests[j] occurs before requests[j + 1]), and upon a successful + * request, uj and vj become direct friends for all future friend requests. + * + * Return a boolean array result, where each result[j] is true if the jth friend request is + * successful or false if it is not. + * + * Note: If uj and vj are already direct friends, the request is still successful. + */ + +/** + * @param {number} n + * @param {number[][]} restrictions + * @param {number[][]} requests + * @return {boolean[]} + */ +var friendRequests = function(n, restrictions, requests) { + const parent = Array.from({ length: n }, (_, i) => i); + const result = new Array(requests.length).fill(true); + + for (let j = 0; j < requests.length; j++) { + const [u, v] = requests[j]; + const pu = find(u); + const pv = find(v); + + let canBeFriends = true; + for (const [x, y] of restrictions) { + const px = find(x); + const py = find(y); + if ((pu === px && pv === py) || (pu === py && pv === px)) { + canBeFriends = false; + break; + } + } + + result[j] = canBeFriends; + if (canBeFriends) { + union(u, v); + } + } + + return result; + + function find(x) { + if (parent[x] !== x) { + parent[x] = find(parent[x]); + } + return parent[x]; + } + + function union(x, y) { + parent[find(x)] = find(y); + } +}; diff --git a/solutions/2078-two-furthest-houses-with-different-colors.js b/solutions/2078-two-furthest-houses-with-different-colors.js new file mode 100644 index 00000000..9a42b696 --- /dev/null +++ b/solutions/2078-two-furthest-houses-with-different-colors.js @@ -0,0 +1,32 @@ +/** + * 2078. Two Furthest Houses With Different Colors + * https://leetcode.com/problems/two-furthest-houses-with-different-colors/ + * Difficulty: Easy + * + * There are n houses evenly lined up on the street, and each house is beautifully painted. + * You are given a 0-indexed integer array colors of length n, where colors[i] represents + * the color of the ith house. + * + * Return the maximum distance between two houses with different colors. + * + * The distance between the ith and jth houses is abs(i - j), where abs(x) is the absolute + * value of x. + */ + +/** + * @param {number[]} colors + * @return {number} + */ +var maxDistance = function(colors) { + let result = 0; + + for (let i = 0; i < colors.length; i++) { + for (let j = i + 1; j < colors.length; j++) { + if (colors[i] !== colors[j]) { + result = Math.max(result, j - i); + } + } + } + + return result; +}; diff --git a/solutions/2079-watering-plants.js b/solutions/2079-watering-plants.js new file mode 100644 index 00000000..ba77b302 --- /dev/null +++ b/solutions/2079-watering-plants.js @@ -0,0 +1,42 @@ +/** + * 2079. Watering Plants + * https://leetcode.com/problems/watering-plants/ + * Difficulty: Medium + * + * You want to water n plants in your garden with a watering can. The plants are arranged in + * a row and are labeled from 0 to n - 1 from left to right where the ith plant is located at + * x = i. There is a river at x = -1 that you can refill your watering can at. + * + * Each plant needs a specific amount of water. You will water the plants in the following way: + * - Water the plants in order from left to right. + * - After watering the current plant, if you do not have enough water to completely water the + * next plant, return to the river to fully refill the watering can. + * - You cannot refill the watering can early. + * + * You are initially at the river (i.e., x = -1). It takes one step to move one unit on the x-axis. + * + * Given a 0-indexed integer array plants of n integers, where plants[i] is the amount of water + * the ith plant needs, and an integer capacity representing the watering can capacity, return + * the number of steps needed to water all the plants. + */ + +/** + * @param {number[]} plants + * @param {number} capacity + * @return {number} + */ +var wateringPlants = function(plants, capacity) { + let water = capacity; + let result = 0; + + for (let i = 0; i < plants.length; i++) { + if (water < plants[i]) { + result += 2 * i; + water = capacity; + } + water -= plants[i]; + result++; + } + + return result; +}; diff --git a/solutions/2080-range-frequency-queries.js b/solutions/2080-range-frequency-queries.js new file mode 100644 index 00000000..32b1bb27 --- /dev/null +++ b/solutions/2080-range-frequency-queries.js @@ -0,0 +1,72 @@ +/** + * 2080. Range Frequency Queries + * https://leetcode.com/problems/range-frequency-queries/ + * Difficulty: Medium + * + * Design a data structure to find the frequency of a given value in a given subarray. + * + * The frequency of a value in a subarray is the number of occurrences of that value in + * the subarray. + * + * Implement the RangeFreqQuery class: + * - RangeFreqQuery(int[] arr) Constructs an instance of the class with the given 0-indexed + * integer array arr. + * - int query(int left, int right, int value) Returns the frequency of value in the subarray + * arr[left...right]. + * - A subarray is a contiguous sequence of elements within an array. arr[left...right] denotes + * the subarray that contains the elements of nums between indices left and right (inclusive). + */ + +/** + * @param {number[]} arr + */ +var RangeFreqQuery = function(arr) { + this.frequencyMap = new Map(); + + for (let i = 0; i < arr.length; i++) { + if (!this.frequencyMap.has(arr[i])) { + this.frequencyMap.set(arr[i], []); + } + this.frequencyMap.get(arr[i]).push(i); + } +}; + +/** + * @param {number} left + * @param {number} right + * @param {number} value + * @return {number} + */ +RangeFreqQuery.prototype.query = function(left, right, value) { + if (!this.frequencyMap.has(value)) return 0; + + const indices = this.frequencyMap.get(value); + let start = 0; + let end = indices.length - 1; + let leftBound = -1; + let rightBound = -1; + + while (start <= end) { + const mid = Math.floor((start + end) / 2); + if (indices[mid] >= left) { + leftBound = mid; + end = mid - 1; + } else { + start = mid + 1; + } + } + + start = 0; + end = indices.length - 1; + while (start <= end) { + const mid = Math.floor((start + end) / 2); + if (indices[mid] <= right) { + rightBound = mid; + start = mid + 1; + } else { + end = mid - 1; + } + } + + return leftBound === -1 || rightBound === -1 ? 0 : rightBound - leftBound + 1; +}; diff --git a/solutions/2081-sum-of-k-mirror-numbers.js b/solutions/2081-sum-of-k-mirror-numbers.js new file mode 100644 index 00000000..600d62d8 --- /dev/null +++ b/solutions/2081-sum-of-k-mirror-numbers.js @@ -0,0 +1,105 @@ +/** + * 2081. Sum of k-Mirror Numbers + * https://leetcode.com/problems/sum-of-k-mirror-numbers/ + * Difficulty: Hard + * + * A k-mirror number is a positive integer without leading zeros that reads the same both forward + * and backward in base-10 as well as in base-k. + * - For example, 9 is a 2-mirror number. The representation of 9 in base-10 and base-2 are 9 and + * 1001 respectively, which read the same both forward and backward. + * - On the contrary, 4 is not a 2-mirror number. The representation of 4 in base-2 is 100, which + * does not read the same both forward and backward. + * + * Given the base k and the number n, return the sum of the n smallest k-mirror numbers. + */ + +/** + * @param {number} k + * @param {number} n + * @return {number} + */ +var kMirror = function(k, n) { + const kMirrorNumbers = []; + let sum = 0; + let length = 1; + + while (kMirrorNumbers.length < n) { + generatePalindromes(length).forEach(num => { + if (kMirrorNumbers.length < n && isKMirror(num, k)) { + kMirrorNumbers.push(num); + sum += num; + } + }); + length++; + } + + return sum; +}; + +function toBaseK(num, k) { + if (num === 0) return '0'; + + let result = ''; + while (num > 0) { + result = (num % k) + result; + num = Math.floor(num / k); + } + + return result; +} + +function isKMirror(num, k) { + const baseKRepresentation = toBaseK(num, k); + return isPalindrome(baseKRepresentation); +} + +function isPalindrome(str) { + let left = 0; + let right = str.length - 1; + + while (left < right) { + if (str[left] !== str[right]) return false; + left++; + right--; + } + + return true; +} + +function generatePalindromes(length) { + const palindromes = []; + + if (length === 1) { + for (let i = 1; i <= 9; i++) { + palindromes.push(i); + } + return palindromes; + } + + if (length % 2 === 0) { + const half = length / 2; + const start = Math.pow(10, half - 1); + const end = Math.pow(10, half) - 1; + + for (let i = start; i <= end; i++) { + const firstHalf = i.toString(); + const secondHalf = firstHalf.split('').reverse().join(''); + palindromes.push(parseInt(firstHalf + secondHalf)); + } + } else { + const half = Math.floor(length / 2); + const start = Math.pow(10, half); + const end = Math.pow(10, half + 1) - 1; + + for (let i = start; i <= end; i++) { + const withoutMiddle = Math.floor(i / 10); + const middle = i % 10; + const firstHalf = withoutMiddle.toString(); + const secondHalf = firstHalf.split('').reverse().join(''); + palindromes.push(parseInt(firstHalf + middle + secondHalf)); + } + } + + return palindromes; +} + diff --git a/solutions/2086-minimum-number-of-food-buckets-to-feed-the-hamsters.js b/solutions/2086-minimum-number-of-food-buckets-to-feed-the-hamsters.js new file mode 100644 index 00000000..5cda9132 --- /dev/null +++ b/solutions/2086-minimum-number-of-food-buckets-to-feed-the-hamsters.js @@ -0,0 +1,43 @@ +/** + * 2086. Minimum Number of Food Buckets to Feed the Hamsters + * https://leetcode.com/problems/minimum-number-of-food-buckets-to-feed-the-hamsters/ + * Difficulty: Medium + * + * You are given a 0-indexed string hamsters where hamsters[i] is either: + * - 'H' indicating that there is a hamster at index i, or + * - '.' indicating that index i is empty. + * + * You will add some number of food buckets at the empty indices in order to feed the hamsters. + * A hamster can be fed if there is at least one food bucket to its left or to its right. More + * formally, a hamster at index i can be fed if you place a food bucket at index i - 1 and/or + * at index i + 1. + * + * Return the minimum number of food buckets you should place at empty indices to feed all the + * hamsters or -1 if it is impossible to feed all of them. + */ + +/** + * @param {string} hamsters + * @return {number} + */ +var minimumBuckets = function(hamsters) { + const n = hamsters.length; + let result = 0; + + for (let i = 0; i < n; i++) { + if (hamsters[i] === 'H') { + if (i > 0 && hamsters[i - 1] === 'B') continue; + if (i < n - 1 && hamsters[i + 1] === '.') { + result++; + hamsters = hamsters.slice(0, i + 1) + 'B' + hamsters.slice(i + 2); + } else if (i > 0 && hamsters[i - 1] === '.') { + result++; + hamsters = hamsters.slice(0, i - 1) + 'B' + hamsters.slice(i); + } else { + return -1; + } + } + } + + return result; +}; diff --git a/solutions/2087-minimum-cost-homecoming-of-a-robot-in-a-grid.js b/solutions/2087-minimum-cost-homecoming-of-a-robot-in-a-grid.js new file mode 100644 index 00000000..8fde0697 --- /dev/null +++ b/solutions/2087-minimum-cost-homecoming-of-a-robot-in-a-grid.js @@ -0,0 +1,45 @@ +/** + * 2087. Minimum Cost Homecoming of a Robot in a Grid + * https://leetcode.com/problems/minimum-cost-homecoming-of-a-robot-in-a-grid/ + * Difficulty: Medium + * + * There is an m x n grid, where (0, 0) is the top-left cell and (m - 1, n - 1) is the bottom-right + * cell. You are given an integer array startPos where startPos = [startrow, startcol] indicates + * that initially, a robot is at the cell (startrow, startcol). You are also given an integer array + * homePos where homePos = [homerow, homecol] indicates that its home is at the cell (homerow, + * homecol). + * + * The robot needs to go to its home. It can move one cell in four directions: left, right, up, + * or down, and it can not move outside the boundary. Every move incurs some cost. You are further + * given two 0-indexed integer arrays: rowCosts of length m and colCosts of length n. + * - If the robot moves up or down into a cell whose row is r, then this move costs rowCosts[r]. + * - If the robot moves left or right into a cell whose column is c, then this move costs + * colCosts[c]. + * + * Return the minimum total cost for this robot to return home. + */ + +/** + * @param {number[]} startPos + * @param {number[]} homePos + * @param {number[]} rowCosts + * @param {number[]} colCosts + * @return {number} + */ +var minCost = function(startPos, homePos, rowCosts, colCosts) { + let result = 0; + const [startRow, startCol] = startPos; + const [homeRow, homeCol] = homePos; + + const rowStep = startRow < homeRow ? 1 : -1; + for (let row = startRow + rowStep; row !== homeRow + rowStep; row += rowStep) { + result += rowCosts[row]; + } + + const colStep = startCol < homeCol ? 1 : -1; + for (let col = startCol + colStep; col !== homeCol + colStep; col += colStep) { + result += colCosts[col]; + } + + return result; +}; diff --git a/solutions/2088-count-fertile-pyramids-in-a-land.js b/solutions/2088-count-fertile-pyramids-in-a-land.js new file mode 100644 index 00000000..0780710b --- /dev/null +++ b/solutions/2088-count-fertile-pyramids-in-a-land.js @@ -0,0 +1,71 @@ +/** + * 2088. Count Fertile Pyramids in a Land + * https://leetcode.com/problems/count-fertile-pyramids-in-a-land/ + * Difficulty: Hard + * + * A farmer has a rectangular grid of land with m rows and n columns that can be divided into + * unit cells. Each cell is either fertile (represented by a 1) or barren (represented by a 0). + * All cells outside the grid are considered barren. + * + * A pyramidal plot of land can be defined as a set of cells with the following criteria: + * 1. The number of cells in the set has to be greater than 1 and all cells must be fertile. + * 2. The apex of a pyramid is the topmost cell of the pyramid. The height of a pyramid is the + * number of rows it covers. Let (r, c) be the apex of the pyramid, and its height be h. + * Then, the plot comprises of cells (i, j) where r <= i <= r + h - 1 and + * c - (i - r) <= j <= c + (i - r). + * + * An inverse pyramidal plot of land can be defined as a set of cells with similar criteria: + * 1. The number of cells in the set has to be greater than 1 and all cells must be fertile. + * 2. The apex of an inverse pyramid is the bottommost cell of the inverse pyramid. The height + * of an inverse pyramid is the number of rows it covers. Let (r, c) be the apex of the + * pyramid, and its height be h. Then, the plot comprises of cells (i, j) where + * r - h + 1 <= i <= r and c - (r - i) <= j <= c + (r - i). + * + * Some examples of valid and invalid pyramidal (and inverse pyramidal) plots are shown below. + * Black cells indicate fertile cells. + * + * Given a 0-indexed m x n binary matrix grid representing the farmland, return the total number + * of pyramidal and inverse pyramidal plots that can be found in grid. + */ + +/** + * @param {number[][]} grid + * @return {number} + */ +var countPyramids = function(grid) { + const rows = grid.length; + const cols = grid[0].length; + let result = 0; + + for (let i = 0; i < rows; i++) { + for (let j = 0; j < cols; j++) { + if (grid[i][j] === 1) { + result += countPyramidAt(i, j, false); + result += countPyramidAt(i, j, true); + } + } + } + + return result; + + function countPyramidAt(row, col, isInverse) { + let height = 0; + for (let h = 1; ; h++) { + const r = isInverse ? row - h : row + h; + if (r < 0 || r >= rows) break; + const left = col - h; + const right = col + h; + if (left < 0 || right >= cols) break; + let valid = true; + for (let j = left; j <= right; j++) { + if (grid[r][j] === 0) { + valid = false; + break; + } + } + if (!valid) break; + height++; + } + return height; + } +}; diff --git a/solutions/2089-find-target-indices-after-sorting-array.js b/solutions/2089-find-target-indices-after-sorting-array.js new file mode 100644 index 00000000..c7235faa --- /dev/null +++ b/solutions/2089-find-target-indices-after-sorting-array.js @@ -0,0 +1,32 @@ +/** + * 2089. Find Target Indices After Sorting Array + * https://leetcode.com/problems/find-target-indices-after-sorting-array/ + * Difficulty: Easy + * + * You are given a 0-indexed integer array nums and a target element target. + * + * A target index is an index i such that nums[i] == target. + * + * Return a list of the target indices of nums after sorting nums in non-decreasing order. + * If there are no target indices, return an empty list. The returned list must be sorted + * in increasing order. + */ + +/** + * @param {number[]} nums + * @param {number} target + * @return {number[]} + */ +var targetIndices = function(nums, target) { + const result = []; + + nums.sort((a, b) => a - b); + + for (let i = 0; i < nums.length; i++) { + if (nums[i] === target) { + result.push(i); + } + } + + return result; +}; diff --git a/solutions/2090-k-radius-subarray-averages.js b/solutions/2090-k-radius-subarray-averages.js new file mode 100644 index 00000000..3808077d --- /dev/null +++ b/solutions/2090-k-radius-subarray-averages.js @@ -0,0 +1,46 @@ +/** + * 2090. K Radius Subarray Averages + * https://leetcode.com/problems/k-radius-subarray-averages/ + * Difficulty: Medium + * + * You are given a 0-indexed array nums of n integers, and an integer k. + * + * The k-radius average for a subarray of nums centered at some index i with the radius k is + * the average of all elements in nums between the indices i - k and i + k (inclusive). If + * there are less than k elements before or after the index i, then the k-radius average is -1. + * + * Build and return an array avgs of length n where avgs[i] is the k-radius average for the + * subarray centered at index i. + * + * The average of x elements is the sum of the x elements divided by x, using integer division. + * The integer division truncates toward zero, which means losing its fractional part. + * - For example, the average of four elements 2, 3, 1, and + * 5 is (2 + 3 + 1 + 5) / 4 = 11 / 4 = 2.75, which truncates to 2. + */ + +/** + * @param {number[]} nums + * @param {number} k + * @return {number[]} + */ +var getAverages = function(nums, k) { + const n = nums.length; + const windowSize = 2 * k + 1; + const result = new Array(n).fill(-1); + + if (windowSize > n) return result; + + let sum = 0; + for (let i = 0; i < windowSize; i++) { + sum += nums[i]; + } + + result[k] = Math.floor(sum / windowSize); + + for (let i = k + 1; i < n - k; i++) { + sum = sum - nums[i - k - 1] + nums[i + k]; + result[i] = Math.floor(sum / windowSize); + } + + return result; +}; diff --git a/solutions/2091-removing-minimum-and-maximum-from-array.js b/solutions/2091-removing-minimum-and-maximum-from-array.js new file mode 100644 index 00000000..b62e781e --- /dev/null +++ b/solutions/2091-removing-minimum-and-maximum-from-array.js @@ -0,0 +1,41 @@ +/** + * 2091. Removing Minimum and Maximum From Array + * https://leetcode.com/problems/removing-minimum-and-maximum-from-array/ + * Difficulty: Medium + * + * You are given a 0-indexed array of distinct integers nums. + * + * There is an element in nums that has the lowest value and an element that has the highest + * value. We call them the minimum and maximum respectively. Your goal is to remove both these + * elements from the array. + * + * A deletion is defined as either removing an element from the front of the array or removing + * an element from the back of the array. + * + * Return the minimum number of deletions it would take to remove both the minimum and maximum + * element from the array. + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var minimumDeletions = function(nums) { + const n = nums.length; + let minIndex = 0; + let maxIndex = 0; + + for (let i = 1; i < n; i++) { + if (nums[i] < nums[minIndex]) minIndex = i; + if (nums[i] > nums[maxIndex]) maxIndex = i; + } + + const left = Math.min(minIndex, maxIndex); + const right = Math.max(minIndex, maxIndex); + + return Math.min( + right + 1, + n - left, + left + 1 + n - right + ); +}; diff --git a/solutions/2092-find-all-people-with-secret.js b/solutions/2092-find-all-people-with-secret.js new file mode 100644 index 00000000..f5fecbdc --- /dev/null +++ b/solutions/2092-find-all-people-with-secret.js @@ -0,0 +1,73 @@ +/** + * 2092. Find All People With Secret + * https://leetcode.com/problems/find-all-people-with-secret/ + * Difficulty: Hard + * + * You are given an integer n indicating there are n people numbered from 0 to n - 1. You are also + * given a 0-indexed 2D integer array meetings where meetings[i] = [xi, yi, timei] indicates that + * person xi and person yi have a meeting at timei. A person may attend multiple meetings at the + * same time. Finally, you are given an integer firstPerson. + * + * Person 0 has a secret and initially shares the secret with a person firstPerson at time 0. This + * secret is then shared every time a meeting takes place with a person that has the secret. More + * formally, for every meeting, if a person xi has the secret at timei, then they will share the + * secret with person yi, and vice versa. + * + * The secrets are shared instantaneously. That is, a person may receive the secret and share it + * with people in other meetings within the same time frame. + * + * Return a list of all the people that have the secret after all the meetings have taken place. + * You may return the answer in any order. + */ + +/** + * @param {number} n + * @param {number[][]} meetings + * @param {number} firstPerson + * @return {number[]} + */ +var findAllPeople = function(n, meetings, firstPerson) { + const parent = Array.from({ length: n }, (_, i) => i); + + union(0, firstPerson); + meetings.sort((a, b) => a[2] - b[2]); + + let i = 0; + while (i < meetings.length) { + const currentTime = meetings[i][2]; + const group = []; + + while (i < meetings.length && meetings[i][2] === currentTime) { + const [x, y] = meetings[i]; + group.push(x, y); + union(x, y); + i++; + } + + for (const person of group) { + if (find(person) !== find(0)) { + parent[person] = person; + } + } + } + + const result = []; + for (let j = 0; j < n; j++) { + if (find(j) === find(0)) { + result.push(j); + } + } + + return result; + + function find(x) { + if (parent[x] !== x) { + parent[x] = find(parent[x]); + } + return parent[x]; + } + + function union(x, y) { + parent[find(x)] = find(y); + } +}; diff --git a/solutions/2094-finding-3-digit-even-numbers.js b/solutions/2094-finding-3-digit-even-numbers.js new file mode 100644 index 00000000..f021bdff --- /dev/null +++ b/solutions/2094-finding-3-digit-even-numbers.js @@ -0,0 +1,51 @@ +/** + * 2094. Finding 3-Digit Even Numbers + * https://leetcode.com/problems/finding-3-digit-even-numbers/ + * Difficulty: Easy + * + * You are given an integer array digits, where each element is a digit. The array may contain + * duplicates. + * + * You need to find all the unique integers that follow the given requirements: + * - The integer consists of the concatenation of three elements from digits in any arbitrary order. + * - The integer does not have leading zeros. + * - The integer is even. + * + * For example, if the given digits were [1, 2, 3], integers 132 and 312 follow the requirements. + * + * Return a sorted array of the unique integers. + */ + +/** + * @param {number[]} digits + * @return {number[]} + */ +var findEvenNumbers = function(digits) { + const frequency = new Array(10).fill(0); + const uniqueNumbers = new Set(); + + for (const digit of digits) { + frequency[digit]++; + } + + for (let hundreds = 1; hundreds <= 9; hundreds++) { + if (frequency[hundreds] === 0) continue; + frequency[hundreds]--; + + for (let tens = 0; tens <= 9; tens++) { + if (frequency[tens] === 0) continue; + frequency[tens]--; + + for (let ones = 0; ones <= 8; ones += 2) { + if (frequency[ones] === 0) continue; + uniqueNumbers.add(hundreds * 100 + tens * 10 + ones); + } + + frequency[tens]++; + } + + frequency[hundreds]++; + } + + return Array.from(uniqueNumbers).sort((a, b) => a - b); +}; diff --git a/solutions/2096-step-by-step-directions-from-a-binary-tree-node-to-another.js b/solutions/2096-step-by-step-directions-from-a-binary-tree-node-to-another.js new file mode 100644 index 00000000..4eb7d4e9 --- /dev/null +++ b/solutions/2096-step-by-step-directions-from-a-binary-tree-node-to-another.js @@ -0,0 +1,65 @@ +/** + * 2096. Step-By-Step Directions From a Binary Tree Node to Another + * https://leetcode.com/problems/step-by-step-directions-from-a-binary-tree-node-to-another/ + * Difficulty: Medium + * + * You are given the root of a binary tree with n nodes. Each node is uniquely assigned a value + * from 1 to n. You are also given an integer startValue representing the value of the start node + * s, and a different integer destValue representing the value of the destination node t. + * + * Find the shortest path starting from node s and ending at node t. Generate step-by-step + * directions of such path as a string consisting of only the uppercase letters 'L', 'R', and + * 'U'. Each letter indicates a specific direction: + * - 'L' means to go from a node to its left child node. + * - 'R' means to go from a node to its right child node. + * - 'U' means to go from a node to its parent node. + * + * Return the step-by-step directions of the shortest path from node s to node t. + */ + +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {TreeNode} root + * @param {number} startValue + * @param {number} destValue + * @return {string} + */ +var getDirections = function(root, startValue, destValue) { + const startPath = []; + const destPath = []; + + findPath(root, startValue, startPath); + findPath(root, destValue, destPath); + + let i = 0; + while (i < startPath.length && i < destPath.length && startPath[i] === destPath[i]) { + i++; + } + + const upMoves = 'U'.repeat(startPath.length - i); + const downMoves = destPath.slice(i).join(''); + + return upMoves + downMoves; + + function findPath(node, value, path) { + if (!node) return false; + if (node.val === value) return true; + + path.push('L'); + if (findPath(node.left, value, path)) return true; + path.pop(); + + path.push('R'); + if (findPath(node.right, value, path)) return true; + path.pop(); + + return false; + } +}; diff --git a/solutions/2097-valid-arrangement-of-pairs.js b/solutions/2097-valid-arrangement-of-pairs.js new file mode 100644 index 00000000..d3c5ee1c --- /dev/null +++ b/solutions/2097-valid-arrangement-of-pairs.js @@ -0,0 +1,50 @@ +/** + * 2097. Valid Arrangement of Pairs + * https://leetcode.com/problems/valid-arrangement-of-pairs/ + * Difficulty: Hard + * + * You are given a 0-indexed 2D integer array pairs where pairs[i] = [starti, endi]. An arrangement + * of pairs is valid if for every index i where 1 <= i < pairs.length, we have endi-1 == starti. + * + * Return any valid arrangement of pairs. + * + * Note: The inputs will be generated such that there exists a valid arrangement of pairs. + */ + +/** + * @param {number[][]} pairs + * @return {number[][]} + */ +var validArrangement = function(pairs) { + const graph = new Map(); + const degree = new Map(); + + for (const [start, end] of pairs) { + if (!graph.has(start)) graph.set(start, []); + graph.get(start).push(end); + + degree.set(start, (degree.get(start) || 0) + 1); + degree.set(end, (degree.get(end) || 0) - 1); + } + + let startNode = pairs[0][0]; + for (const [node, deg] of degree) { + if (deg > 0) { + startNode = node; + break; + } + } + + const result = []; + helper(startNode); + + return result.reverse(); + + function helper(node) { + while (graph.get(node)?.length) { + const next = graph.get(node).pop(); + helper(next); + result.push([node, next]); + } + } +}; diff --git a/solutions/2100-find-good-days-to-rob-the-bank.js b/solutions/2100-find-good-days-to-rob-the-bank.js new file mode 100644 index 00000000..1dc59611 --- /dev/null +++ b/solutions/2100-find-good-days-to-rob-the-bank.js @@ -0,0 +1,50 @@ +/** + * 2100. Find Good Days to Rob the Bank + * https://leetcode.com/problems/find-good-days-to-rob-the-bank/ + * Difficulty: Medium + * + * You and a gang of thieves are planning on robbing a bank. You are given a 0-indexed integer + * array security, where security[i] is the number of guards on duty on the ith day. The days + * are numbered starting from 0. You are also given an integer time. + * + * The ith day is a good day to rob the bank if: + * - There are at least time days before and after the ith day, + * - The number of guards at the bank for the time days before i are non-increasing, and + * - The number of guards at the bank for the time days after i are non-decreasing. + * + * More formally, this means day i is a good day to rob the bank if and only if + * security[i - time] >= security[i - time + 1] >= ... >= security[i] + * <= ... <= security[i + time - 1] <= security[i + time]. + * + * Return a list of all days (0-indexed) that are good days to rob the bank. The order that the + * days are returned in does not matter. + */ + +/** + * @param {number[]} security + * @param {number} time + * @return {number[]} + */ +var goodDaysToRobBank = function(security, time) { + const n = security.length; + const nonIncreasing = new Array(n).fill(0); + const nonDecreasing = new Array(n).fill(0); + const result = []; + + for (let i = 1; i < n; i++) { + if (security[i] <= security[i - 1]) { + nonIncreasing[i] = nonIncreasing[i - 1] + 1; + } + if (security[n - i - 1] <= security[n - i]) { + nonDecreasing[n - i - 1] = nonDecreasing[n - i] + 1; + } + } + + for (let i = time; i < n - time; i++) { + if (nonIncreasing[i] >= time && nonDecreasing[i] >= time) { + result.push(i); + } + } + + return result; +}; diff --git a/solutions/2101-detonate-the-maximum-bombs.js b/solutions/2101-detonate-the-maximum-bombs.js new file mode 100644 index 00000000..11069857 --- /dev/null +++ b/solutions/2101-detonate-the-maximum-bombs.js @@ -0,0 +1,57 @@ +/** + * 2101. Detonate the Maximum Bombs + * https://leetcode.com/problems/detonate-the-maximum-bombs/ + * Difficulty: Medium + * + * You are given a list of bombs. The range of a bomb is defined as the area where its effect + * can be felt. This area is in the shape of a circle with the center as the location of the bomb. + * + * The bombs are represented by a 0-indexed 2D integer array bombs where bombs[i] = [xi, yi, ri]. + * xi and yi denote the X-coordinate and Y-coordinate of the location of the ith bomb, whereas ri + * denotes the radius of its range. + * + * You may choose to detonate a single bomb. When a bomb is detonated, it will detonate all bombs + * that lie in its range. These bombs will further detonate the bombs that lie in their ranges. + * + * Given the list of bombs, return the maximum number of bombs that can be detonated if you are + * allowed to detonate only one bomb. + */ + +/** + * @param {number[][]} bombs + * @return {number} + */ +var maximumDetonation = function(bombs) { + const n = bombs.length; + const graph = Array.from({ length: n }, () => []); + + for (let i = 0; i < n; i++) { + const [x1, y1, r1] = bombs[i]; + for (let j = 0; j < n; j++) { + if (i === j) continue; + const [x2, y2] = bombs[j]; + const distance = Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2); + if (distance <= r1) { + graph[i].push(j); + } + } + } + + let result = 0; + for (let i = 0; i < n; i++) { + result = Math.max(result, dfs(i, new Set())); + } + + return result; + + function dfs(node, visited) { + visited.add(node); + let count = 1; + for (const neighbor of graph[node]) { + if (!visited.has(neighbor)) { + count += dfs(neighbor, visited); + } + } + return count; + } +}; diff --git a/solutions/2103-rings-and-rods.js b/solutions/2103-rings-and-rods.js new file mode 100644 index 00000000..b7cc219e --- /dev/null +++ b/solutions/2103-rings-and-rods.js @@ -0,0 +1,42 @@ +/** + * 2103. Rings and Rods + * https://leetcode.com/problems/rings-and-rods/ + * Difficulty: Easy + * + * There are n rings and each ring is either red, green, or blue. The rings are distributed across + * ten rods labeled from 0 to 9. + * + * You are given a string rings of length 2n that describes the n rings that are placed onto the + * rods. Every two characters in rings forms a color-position pair that is used to describe each + * ring where: + * - The first character of the ith pair denotes the ith ring's color ('R', 'G', 'B'). + * - The second character of the ith pair denotes the rod that the ith ring is placed on + * ('0' to '9'). + * + * For example, "R3G2B1" describes n == 3 rings: a red ring placed onto the rod labeled 3, a green + * ring placed onto the rod labeled 2, and a blue ring placed onto the rod labeled 1. + * + * Return the number of rods that have all three colors of rings on them. + */ + +/** + * @param {string} rings + * @return {number} + */ +var countPoints = function(rings) { + const map = new Map(); + + for (let i = 0; i < rings.length; i += 2) { + const color = rings[i]; + const rod = rings[i + 1]; + if (!map.has(rod)) map.set(rod, new Set()); + map.get(rod).add(color); + } + + let result = 0; + for (const colors of map.values()) { + if (colors.size === 3) result++; + } + + return result; +}; diff --git a/solutions/2104-sum-of-subarray-ranges.js b/solutions/2104-sum-of-subarray-ranges.js new file mode 100644 index 00000000..0efaf1d7 --- /dev/null +++ b/solutions/2104-sum-of-subarray-ranges.js @@ -0,0 +1,33 @@ +/** + * 2104. Sum of Subarray Ranges + * https://leetcode.com/problems/sum-of-subarray-ranges/ + * Difficulty: Medium + * + * You are given an integer array nums. The range of a subarray of nums is the difference between + * the largest and smallest element in the subarray. + * + * Return the sum of all subarray ranges of nums. + * + * A subarray is a contiguous non-empty sequence of elements within an array. + */ + +/** + * @param {number[]} nums + * @return {number} + */ +var subArrayRanges = function(nums) { + let result = 0; + + for (let i = 0; i < nums.length; i++) { + let min = nums[i]; + let max = nums[i]; + + for (let j = i; j < nums.length; j++) { + min = Math.min(min, nums[j]); + max = Math.max(max, nums[j]); + result += max - min; + } + } + + return result; +}; diff --git a/solutions/2105-watering-plants-ii.js b/solutions/2105-watering-plants-ii.js new file mode 100644 index 00000000..dcdaf994 --- /dev/null +++ b/solutions/2105-watering-plants-ii.js @@ -0,0 +1,61 @@ +/** + * 2105. Watering Plants II + * https://leetcode.com/problems/watering-plants-ii/ + * Difficulty: Medium + * + * Alice and Bob want to water n plants in their garden. The plants are arranged in a row and are + * labeled from 0 to n - 1 from left to right where the ith plant is located at x = i. + * + * Each plant needs a specific amount of water. Alice and Bob have a watering can each, initially + * full. They water the plants in the following way: + * - Alice waters the plants in order from left to right, starting from the 0th plant. Bob waters + * the plants in order from right to left, starting from the (n - 1)th plant. They begin watering + * the plants simultaneously. + * - It takes the same amount of time to water each plant regardless of how much water it needs. + * - Alice/Bob must water the plant if they have enough in their can to fully water it. Otherwise, + * they first refill their can (instantaneously) then water the plant. + * - In case both Alice and Bob reach the same plant, the one with more water currently in his/her + * watering can should water this plant. If they have the same amount of water, then Alice should + * water this plant. + * + * Given a 0-indexed integer array plants of n integers, where plants[i] is the amount of water the + * ith plant needs, and two integers capacityA and capacityB representing the capacities of Alice's + * and Bob's watering cans respectively, return the number of times they have to refill to water all + * the plants. + */ + +/** + * @param {number[]} plants + * @param {number} capacityA + * @param {number} capacityB + * @return {number} + */ +var minimumRefill = function(plants, capacityA, capacityB) { + let result = 0; + let left = 0; + let right = plants.length - 1; + let waterA = capacityA; + let waterB = capacityB; + + while (left <= right) { + if (left === right) { + if (waterA >= waterB && waterA < plants[left]) result++; + if (waterB > waterA && waterB < plants[right]) result++; + break; + } + + if (waterA < plants[left]) { + waterA = capacityA; + result++; + } + waterA -= plants[left++]; + + if (waterB < plants[right]) { + waterB = capacityB; + result++; + } + waterB -= plants[right--]; + } + + return result; +}; diff --git a/solutions/2106-maximum-fruits-harvested-after-at-most-k-steps.js b/solutions/2106-maximum-fruits-harvested-after-at-most-k-steps.js new file mode 100644 index 00000000..bd81e17e --- /dev/null +++ b/solutions/2106-maximum-fruits-harvested-after-at-most-k-steps.js @@ -0,0 +1,52 @@ +/** + * 2106. Maximum Fruits Harvested After at Most K Steps + * https://leetcode.com/problems/maximum-fruits-harvested-after-at-most-k-steps/ + * Difficulty: Hard + * + * Fruits are available at some positions on an infinite x-axis. You are given a 2D integer array + * fruits where fruits[i] = [positioni, amounti] depicts amounti fruits at the position positioni. + * fruits is already sorted by positioni in ascending order, and each positioni is unique. + * + * You are also given an integer startPos and an integer k. Initially, you are at the position + * startPos. From any position, you can either walk to the left or right. It takes one step to + * move one unit on the x-axis, and you can walk at most k steps in total. For every position + * you reach, you harvest all the fruits at that position, and the fruits will disappear from + * that position. + * + * Return the maximum total number of fruits you can harvest. + */ + +/** + * @param {number[][]} fruits + * @param {number} startPos + * @param {number} k + * @return {number} + */ +var maxTotalFruits = function(fruits, startPos, k) { + let result = 0; + let left = 0; + let currentSum = 0; + + for (let right = 0; right < fruits.length; right++) { + currentSum += fruits[right][1]; + + while (left <= right) { + const minPos = fruits[left][0]; + const maxPos = fruits[right][0]; + const steps = Math.min( + Math.abs(startPos - minPos) + (maxPos - minPos), + Math.abs(startPos - maxPos) + (maxPos - minPos) + ); + + if (steps <= k) break; + currentSum -= fruits[left][1]; + left++; + } + + if (left <= right) { + result = Math.max(result, currentSum); + } + } + + return result; +}; diff --git a/solutions/2108-find-first-palindromic-string-in-the-array.js b/solutions/2108-find-first-palindromic-string-in-the-array.js new file mode 100644 index 00000000..a72a02b0 --- /dev/null +++ b/solutions/2108-find-first-palindromic-string-in-the-array.js @@ -0,0 +1,23 @@ +/** + * 2108. Find First Palindromic String in the Array + * https://leetcode.com/problems/find-first-palindromic-string-in-the-array/ + * Difficulty: Easy + * + * Given an array of strings words, return the first palindromic string in the array. If there is + * no such string, return an empty string "". + * + * A string is palindromic if it reads the same forward and backward. + */ + +/** + * @param {string[]} words + * @return {string} + */ +var firstPalindrome = function(words) { + for (const word of words) { + if (word === word.split('').reverse().join('')) { + return word; + } + } + return ''; +}; diff --git a/solutions/2109-adding-spaces-to-a-string.js b/solutions/2109-adding-spaces-to-a-string.js new file mode 100644 index 00000000..7f4a85ba --- /dev/null +++ b/solutions/2109-adding-spaces-to-a-string.js @@ -0,0 +1,33 @@ +/** + * 2109. Adding Spaces to a String + * https://leetcode.com/problems/adding-spaces-to-a-string/ + * Difficulty: Medium + * + * You are given a 0-indexed string s and a 0-indexed integer array spaces that describes the + * indices in the original string where spaces will be added. Each space should be inserted + * before the character at the given index. + * - For example, given s = "EnjoyYourCoffee" and spaces = [5, 9], we place spaces before 'Y' + * and 'C', which are at indices 5 and 9 respectively. Thus, we obtain "Enjoy Your Coffee". + * + * Return the modified string after the spaces have been added. + */ + +/** + * @param {string} s + * @param {number[]} spaces + * @return {string} + */ +var addSpaces = function(s, spaces) { + let result = ''; + let spaceIndex = 0; + + for (let i = 0; i < s.length; i++) { + if (spaceIndex < spaces.length && i === spaces[spaceIndex]) { + result += ' '; + spaceIndex++; + } + result += s[i]; + } + + return result; +}; diff --git a/solutions/2110-number-of-smooth-descent-periods-of-a-stock.js b/solutions/2110-number-of-smooth-descent-periods-of-a-stock.js new file mode 100644 index 00000000..09a08e95 --- /dev/null +++ b/solutions/2110-number-of-smooth-descent-periods-of-a-stock.js @@ -0,0 +1,34 @@ +/** + * 2110. Number of Smooth Descent Periods of a Stock + * https://leetcode.com/problems/number-of-smooth-descent-periods-of-a-stock/ + * Difficulty: Medium + * + * You are given an integer array prices representing the daily price history of a stock, + * where prices[i] is the stock price on the ith day. + * + * A smooth descent period of a stock consists of one or more contiguous days such that the + * price on each day is lower than the price on the preceding day by exactly 1. The first + * day of the period is exempted from this rule. + * + * Return the number of smooth descent periods. + */ + +/** + * @param {number[]} prices + * @return {number} + */ +var getDescentPeriods = function(prices) { + let result = 1; + let currentLength = 1; + + for (let i = 1; i < prices.length; i++) { + if (prices[i] === prices[i - 1] - 1) { + currentLength++; + } else { + currentLength = 1; + } + result += currentLength; + } + + return result; +}; diff --git a/solutions/2111-minimum-operations-to-make-the-array-k-increasing.js b/solutions/2111-minimum-operations-to-make-the-array-k-increasing.js new file mode 100644 index 00000000..8f861b84 --- /dev/null +++ b/solutions/2111-minimum-operations-to-make-the-array-k-increasing.js @@ -0,0 +1,58 @@ +/** + * 2111. Minimum Operations to Make the Array K-Increasing + * https://leetcode.com/problems/minimum-operations-to-make-the-array-k-increasing/ + * Difficulty: Hard + * + * You are given a 0-indexed array arr consisting of n positive integers, and a positive integer k. + * + * The array arr is called K-increasing if arr[i-k] <= arr[i] holds for every index i, where + * k <= i <= n-1. + * + * - For example, arr = [4, 1, 5, 2, 6, 2] is K-increasing for k = 2 because: + * - arr[0] <= arr[2] (4 <= 5) + * - arr[1] <= arr[3] (1 <= 2) + * - arr[2] <= arr[4] (5 <= 6) + * - arr[3] <= arr[5] (2 <= 2) + * - However, the same arr is not K-increasing for k = 1 (because arr[0] > arr[1]) or k = 3 (because + * arr[0] > arr[3]). + * + * In one operation, you can choose an index i and change arr[i] into any positive integer. + * + * Return the minimum number of operations required to make the array K-increasing for the given k. + */ + +/** + * @param {number[]} arr + * @param {number} k + * @return {number} + */ +var kIncreasing = function(arr, k) { + let result = 0; + for (let i = 0; i < k; i++) { + const subsequence = []; + for (let j = i; j < arr.length; j += k) { + subsequence.push(arr[j]); + } + result += longestNonDecreasingSubsequence(subsequence); + } + + return result; + + function longestNonDecreasingSubsequence(nums) { + const tails = []; + for (const num of nums) { + let left = 0; + let right = tails.length; + while (left < right) { + const mid = Math.floor((left + right) / 2); + if (tails[mid] <= num) { + left = mid + 1; + } else { + right = mid; + } + } + tails[left] = num; + } + return nums.length - tails.length; + } +}; diff --git a/solutions/2117-abbreviating-the-product-of-a-range.js b/solutions/2117-abbreviating-the-product-of-a-range.js new file mode 100644 index 00000000..4334b25b --- /dev/null +++ b/solutions/2117-abbreviating-the-product-of-a-range.js @@ -0,0 +1,91 @@ +/** + * 2117. Abbreviating the Product of a Range + * https://leetcode.com/problems/abbreviating-the-product-of-a-range/ + * Difficulty: Hard + * + * You are given two positive integers left and right with left <= right. Calculate the product of + * all integers in the inclusive range [left, right]. + * + * Since the product may be very large, you will abbreviate it following these steps: + * 1. Count all trailing zeros in the product and remove them. Let us denote this count as C. + * - For example, there are 3 trailing zeros in 1000, and there are 0 trailing zeros in 546. + * 2. Denote the remaining number of digits in the product as d. If d > 10, then express the product + * as
... where 
 denotes the first 5 digits of the product, and  denotes the
+ *    last 5 digits of the product after removing all trailing zeros. If d <= 10, we keep it
+ *    unchanged.
+ *    - For example, we express 1234567654321 as 12345...54321, but 1234567 is represented as
+ *      1234567.
+ * 3. Finally, represent the product as a string "
...eC".
+ *    - For example, 12345678987600000 will be represented as "12345...89876e5".
+ *
+ * Return a string denoting the abbreviated product of all integers in the inclusive range [left,
+ * right].
+ */
+
+/**
+ * @param {number} left
+ * @param {number} right
+ * @return {string}
+ */
+var abbreviateProduct = function(left, right) {
+  let zeros = 0;
+  let count2 = 0;
+  let count5 = 0;
+
+  for (let i = left; i <= right; i++) {
+    let n = i;
+    while (n % 2 === 0) {
+      count2++;
+      n = Math.floor(n / 2);
+    }
+    n = i;
+    while (n % 5 === 0) {
+      count5++;
+      n = Math.floor(n / 5);
+    }
+  }
+  zeros = Math.min(count2, count5);
+
+  let digits = 0;
+  for (let i = left; i <= right; i++) {
+    digits += Math.log10(i);
+  }
+  digits = Math.floor(digits) + 1;
+
+  if (digits - zeros <= 10) {
+    let product = 1n;
+    for (let i = left; i <= right; i++) {
+      product *= BigInt(i);
+    }
+    for (let i = 0; i < zeros; i++) {
+      product /= 10n;
+    }
+    return product.toString() + 'e' + zeros;
+  }
+
+  let prefix = 1;
+  for (let i = left; i <= right; i++) {
+    prefix *= i;
+    while (prefix >= 1e10) {
+      prefix /= 10;
+    }
+  }
+  prefix = prefix.toString().slice(0, 5);
+
+  let suffix = 1n;
+  for (let i = right; i >= left; i--) {
+    suffix = (suffix * BigInt(i));
+    while (suffix % 10n === 0n) {
+      suffix /= 10n;
+    }
+    suffix = suffix % (10n ** 15n);
+  }
+
+  suffix = suffix.toString();
+  while (suffix.length < 5) {
+    suffix = '0' + suffix;
+  }
+  suffix = suffix.slice(-5);
+
+  return prefix + '...' + suffix + 'e' + zeros;
+};
diff --git a/solutions/2119-a-number-after-a-double-reversal.js b/solutions/2119-a-number-after-a-double-reversal.js
new file mode 100644
index 00000000..efc1d321
--- /dev/null
+++ b/solutions/2119-a-number-after-a-double-reversal.js
@@ -0,0 +1,20 @@
+/**
+ * 2119. A Number After a Double Reversal
+ * https://leetcode.com/problems/a-number-after-a-double-reversal/
+ * Difficulty: Easy
+ *
+ * Reversing an integer means to reverse all its digits.
+ * - For example, reversing 2021 gives 1202. Reversing 12300 gives 321 as the leading zeros
+ *   are not retained.
+ *
+ * Given an integer num, reverse num to get reversed1, then reverse reversed1 to get reversed2.
+ * Return true if reversed2 equals num. Otherwise return false.
+ */
+
+/**
+ * @param {number} num
+ * @return {boolean}
+ */
+var isSameAfterReversals = function(num) {
+  return num === 0 || num % 10 !== 0;
+};
diff --git a/solutions/2120-execution-of-all-suffix-instructions-staying-in-a-grid.js b/solutions/2120-execution-of-all-suffix-instructions-staying-in-a-grid.js
new file mode 100644
index 00000000..940ddc72
--- /dev/null
+++ b/solutions/2120-execution-of-all-suffix-instructions-staying-in-a-grid.js
@@ -0,0 +1,51 @@
+/**
+ * 2120. Execution of All Suffix Instructions Staying in a Grid
+ * https://leetcode.com/problems/execution-of-all-suffix-instructions-staying-in-a-grid/
+ * Difficulty: Medium
+ *
+ * There is an n x n grid, with the top-left cell at (0, 0) and the bottom-right cell at
+ * (n - 1, n - 1). You are given the integer n and an integer array startPos where
+ * startPos = [startrow, startcol] indicates that a robot is initially at cell (startrow, startcol).
+ *
+ * You are also given a 0-indexed string s of length m where s[i] is the ith instruction for the
+ * robot: 'L' (move left), 'R' (move right), 'U' (move up), and 'D' (move down).
+ *
+ * The robot can begin executing from any ith instruction in s. It executes the instructions one
+ * by one towards the end of s but it stops if either of these conditions is met:
+ * - The next instruction will move the robot off the grid.
+ * - There are no more instructions left to execute.
+ *
+ * Return an array answer of length m where answer[i] is the number of instructions the robot can
+ * execute if the robot begins executing from the ith instruction in s.
+ */
+
+/**
+ * @param {number} n
+ * @param {number[]} startPos
+ * @param {string} s
+ * @return {number[]}
+ */
+var executeInstructions = function(n, startPos, s) {
+  const m = s.length;
+  const result = new Array(m).fill(0);
+
+  for (let i = 0; i < m; i++) {
+    let row = startPos[0];
+    let col = startPos[1];
+    let steps = 0;
+
+    for (let j = i; j < m; j++) {
+      if (s[j] === 'L') col--;
+      else if (s[j] === 'R') col++;
+      else if (s[j] === 'U') row--;
+      else row++;
+
+      if (row < 0 || row >= n || col < 0 || col >= n) break;
+      steps++;
+    }
+
+    result[i] = steps;
+  }
+
+  return result;
+};
diff --git a/solutions/2121-intervals-between-identical-elements.js b/solutions/2121-intervals-between-identical-elements.js
new file mode 100644
index 00000000..3686726b
--- /dev/null
+++ b/solutions/2121-intervals-between-identical-elements.js
@@ -0,0 +1,48 @@
+/**
+ * 2121. Intervals Between Identical Elements
+ * https://leetcode.com/problems/intervals-between-identical-elements/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed array of n integers arr.
+ *
+ * The interval between two elements in arr is defined as the absolute difference between their
+ * indices. More formally, the interval between arr[i] and arr[j] is |i - j|.
+ *
+ * Return an array intervals of length n where intervals[i] is the sum of intervals between arr[i]
+ * and each element in arr with the same value as arr[i].
+ *
+ * Note: |x| is the absolute value of x.
+ */
+
+/**
+ * @param {number[]} arr
+ * @return {number[]}
+ */
+var getDistances = function(arr) {
+  const valueIndices = new Map();
+  const result = new Array(arr.length).fill(0);
+
+  for (let i = 0; i < arr.length; i++) {
+    if (!valueIndices.has(arr[i])) {
+      valueIndices.set(arr[i], []);
+    }
+    valueIndices.get(arr[i]).push(i);
+  }
+
+  for (const indices of valueIndices.values()) {
+    let prefixSum = 0;
+    for (let i = 1; i < indices.length; i++) {
+      prefixSum += indices[i] - indices[0];
+    }
+
+    result[indices[0]] = prefixSum;
+
+    for (let i = 1; i < indices.length; i++) {
+      const diff = indices[i] - indices[i - 1];
+      prefixSum += diff * (i - (indices.length - i));
+      result[indices[i]] = prefixSum;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2122-recover-the-original-array.js b/solutions/2122-recover-the-original-array.js
new file mode 100644
index 00000000..7b6030fb
--- /dev/null
+++ b/solutions/2122-recover-the-original-array.js
@@ -0,0 +1,55 @@
+/**
+ * 2122. Recover the Original Array
+ * https://leetcode.com/problems/recover-the-original-array/
+ * Difficulty: Hard
+ *
+ * Alice had a 0-indexed array arr consisting of n positive integers. She chose an arbitrary
+ * positive integer k and created two new 0-indexed integer arrays lower and higher in the
+ * following manner:
+ * 1. lower[i] = arr[i] - k, for every index i where 0 <= i < n
+ * 2. higher[i] = arr[i] + k, for every index i where 0 <= i < n
+ *
+ * Unfortunately, Alice lost all three arrays. However, she remembers the integers that were
+ * present in the arrays lower and higher, but not the array each integer belonged to. Help
+ * Alice and recover the original array.
+ *
+ * Given an array nums consisting of 2n integers, where exactly n of the integers were present
+ * in lower and the remaining in higher, return the original array arr. In case the answer is
+ * not unique, return any valid array.
+ *
+ * Note: The test cases are generated such that there exists at least one valid array arr.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number[]}
+ */
+var recoverArray = function(nums) {
+  const n = nums.length / 2;
+  nums.sort((a, b) => a - b);
+
+  for (let i = 1; i < 2 * n; i++) {
+    const k = nums[i] - nums[0];
+    if (k <= 0 || k % 2 !== 0) continue;
+
+    const original = [];
+    const used = new Array(2 * n).fill(false);
+    let count = 0;
+
+    for (let left = 0, right = i; right < 2 * n && count < n; right++) {
+      while (left < right && used[left]) left++;
+      if (left >= right) continue;
+
+      if (nums[right] - nums[left] === k) {
+        original.push(nums[left] + k / 2);
+        used[left] = used[right] = true;
+        count++;
+        left++;
+      }
+    }
+
+    if (count === n) return original;
+  }
+
+  return [];
+};
diff --git a/solutions/2124-check-if-all-as-appears-before-all-bs.js b/solutions/2124-check-if-all-as-appears-before-all-bs.js
new file mode 100644
index 00000000..57f06772
--- /dev/null
+++ b/solutions/2124-check-if-all-as-appears-before-all-bs.js
@@ -0,0 +1,23 @@
+/**
+ * 2124. Check if All A's Appears Before All B's
+ * https://leetcode.com/problems/check-if-all-as-appears-before-all-bs/
+ * Difficulty: Easy
+ *
+ * Given a string s consisting of only the characters 'a' and 'b', return true if every 'a' appears
+ * before every 'b' in the string. Otherwise, return false.
+ */
+
+/**
+ * @param {string} s
+ * @return {boolean}
+ */
+var checkString = function(s) {
+  let seen = false;
+
+  for (const char of s) {
+    if (char === 'b') seen = true;
+    else if (seen) return false;
+  }
+
+  return true;
+};
diff --git a/solutions/2125-number-of-laser-beams-in-a-bank.js b/solutions/2125-number-of-laser-beams-in-a-bank.js
new file mode 100644
index 00000000..58a8afb7
--- /dev/null
+++ b/solutions/2125-number-of-laser-beams-in-a-bank.js
@@ -0,0 +1,40 @@
+/**
+ * 2125. Number of Laser Beams in a Bank
+ * https://leetcode.com/problems/number-of-laser-beams-in-a-bank/
+ * Difficulty: Medium
+ *
+ * Anti-theft security devices are activated inside a bank. You are given a 0-indexed binary string
+ * array bank representing the floor plan of the bank, which is an m x n 2D matrix. bank[i]
+ * represents the ith row, consisting of '0's and '1's. '0' means the cell is empty, while'1'
+ * means the cell has a security device.
+ *
+ * There is one laser beam between any two security devices if both conditions are met:
+ * - The two devices are located on two different rows: r1 and r2, where r1 < r2.
+ * - For each row i where r1 < i < r2, there are no security devices in the ith row.
+ *
+ * Laser beams are independent, i.e., one beam does not interfere nor join with another.
+ *
+ * Return the total number of laser beams in the bank.
+ */
+
+/**
+ * @param {string[]} bank
+ * @return {number}
+ */
+var numberOfBeams = function(bank) {
+  let result = 0;
+  let prevDevices = 0;
+
+  for (const row of bank) {
+    let currentDevices = 0;
+    for (const cell of row) {
+      if (cell === '1') currentDevices++;
+    }
+    if (currentDevices > 0) {
+      result += prevDevices * currentDevices;
+      prevDevices = currentDevices;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2126-destroying-asteroids.js b/solutions/2126-destroying-asteroids.js
new file mode 100644
index 00000000..8c0ff17e
--- /dev/null
+++ b/solutions/2126-destroying-asteroids.js
@@ -0,0 +1,31 @@
+/**
+ * 2126. Destroying Asteroids
+ * https://leetcode.com/problems/destroying-asteroids/
+ * Difficulty: Medium
+ *
+ * You are given an integer mass, which represents the original mass of a planet. You are further
+ * given an integer array asteroids, where asteroids[i] is the mass of the ith asteroid.
+ *
+ * You can arrange for the planet to collide with the asteroids in any arbitrary order. If the mass
+ * of the planet is greater than or equal to the mass of the asteroid, the asteroid is destroyed
+ * and the planet gains the mass of the asteroid. Otherwise, the planet is destroyed.
+ *
+ * Return true if all asteroids can be destroyed. Otherwise, return false.
+ */
+
+/**
+ * @param {number} mass
+ * @param {number[]} asteroids
+ * @return {boolean}
+ */
+var asteroidsDestroyed = function(mass, asteroids) {
+  asteroids.sort((a, b) => a - b);
+
+  let planetMass = BigInt(mass);
+  for (const asteroid of asteroids) {
+    if (planetMass < BigInt(asteroid)) return false;
+    planetMass += BigInt(asteroid);
+  }
+
+  return true;
+};
diff --git a/solutions/2131-longest-palindrome-by-concatenating-two-letter-words.js b/solutions/2131-longest-palindrome-by-concatenating-two-letter-words.js
new file mode 100644
index 00000000..296b3bd0
--- /dev/null
+++ b/solutions/2131-longest-palindrome-by-concatenating-two-letter-words.js
@@ -0,0 +1,47 @@
+/**
+ * 2131. Longest Palindrome by Concatenating Two Letter Words
+ * https://leetcode.com/problems/longest-palindrome-by-concatenating-two-letter-words/
+ * Difficulty: Medium
+ *
+ * You are given an array of strings words. Each element of words consists of two lowercase
+ * English letters.
+ *
+ * Create the longest possible palindrome by selecting some elements from words and concatenating
+ * them in any order. Each element can be selected at most once.
+ *
+ * Return the length of the longest palindrome that you can create. If it is impossible to create
+ * any palindrome, return 0.
+ *
+ * A palindrome is a string that reads the same forward and backward.
+ */
+
+/**
+ * @param {string[]} words
+ * @return {number}
+ */
+var longestPalindrome = function(words) {
+  const map = new Map();
+  let length = 0;
+  let hasCenter = false;
+
+  for (const word of words) {
+    map.set(word, (map.get(word) || 0) + 1);
+  }
+
+  for (const word of map.keys()) {
+    const reverse = word[1] + word[0];
+
+    if (word === reverse) {
+      const count = map.get(word);
+      length += Math.floor(count / 2) * 4;
+      if (count % 2 === 1) hasCenter = true;
+    } else if (map.has(reverse)) {
+      const pairs = Math.min(map.get(word), map.get(reverse));
+      length += pairs * 4;
+      map.set(word, 0);
+      map.set(reverse, 0);
+    }
+  }
+
+  return hasCenter ? length + 2 : length;
+};
diff --git a/solutions/2132-stamping-the-grid.js b/solutions/2132-stamping-the-grid.js
new file mode 100644
index 00000000..3143e1e3
--- /dev/null
+++ b/solutions/2132-stamping-the-grid.js
@@ -0,0 +1,64 @@
+/**
+ * 2132. Stamping the Grid
+ * https://leetcode.com/problems/stamping-the-grid/
+ * Difficulty: Hard
+ *
+ * You are given an m x n binary matrix grid where each cell is either 0 (empty) or 1 (occupied).
+ *
+ * You are then given stamps of size stampHeight x stampWidth. We want to fit the stamps such that
+ * they follow the given restrictions and requirements:
+ * 1. Cover all the empty cells.
+ * 2. Do not cover any of the occupied cells.
+ * 3. We can put as many stamps as we want.
+ * 4. Stamps can overlap with each other.
+ * 5. Stamps are not allowed to be rotated.
+ * 6. Stamps must stay completely inside the grid.
+ *
+ * Return true if it is possible to fit the stamps while following the given restrictions and
+ * requirements. Otherwise, return false.
+ */
+
+/**
+ * @param {number[][]} grid
+ * @param {number} stampHeight
+ * @param {number} stampWidth
+ * @return {boolean}
+ */
+var possibleToStamp = function(grid, stampHeight, stampWidth) {
+  const rows = grid.length;
+  const cols = grid[0].length;
+  const prefixSum = new Array(rows + 1).fill().map(() => new Array(cols + 1).fill(0));
+  const diff = new Array(rows + 1).fill().map(() => new Array(cols + 1).fill(0));
+
+  for (let i = 0; i < rows; i++) {
+    for (let j = 0; j < cols; j++) {
+      prefixSum[i + 1][j + 1] = prefixSum[i + 1][j] + prefixSum[i][j + 1]
+        - prefixSum[i][j] + grid[i][j];
+    }
+  }
+
+  for (let i = 0; i <= rows - stampHeight; i++) {
+    for (let j = 0; j <= cols - stampWidth; j++) {
+      const x = i + stampHeight;
+      const y = j + stampWidth;
+      if (prefixSum[x][y] - prefixSum[x][j] - prefixSum[i][y] + prefixSum[i][j] === 0) {
+        diff[i][j]++;
+        diff[i][y]--;
+        diff[x][j]--;
+        diff[x][y]++;
+      }
+    }
+  }
+
+  const covered = new Array(rows).fill().map(() => new Array(cols).fill(0));
+  for (let i = 0; i < rows; i++) {
+    for (let j = 0; j < cols; j++) {
+      covered[i][j] = (i > 0 ? covered[i - 1][j] : 0)
+        + (j > 0 ? covered[i][j - 1] : 0)
+        - (i > 0 && j > 0 ? covered[i - 1][j - 1] : 0) + diff[i][j];
+      if (grid[i][j] === 0 && covered[i][j] === 0) return false;
+    }
+  }
+
+  return true;
+};
diff --git a/solutions/2133-check-if-every-row-and-column-contains-all-numbers.js b/solutions/2133-check-if-every-row-and-column-contains-all-numbers.js
new file mode 100644
index 00000000..e8d6990a
--- /dev/null
+++ b/solutions/2133-check-if-every-row-and-column-contains-all-numbers.js
@@ -0,0 +1,33 @@
+/**
+ * 2133. Check if Every Row and Column Contains All Numbers
+ * https://leetcode.com/problems/check-if-every-row-and-column-contains-all-numbers/
+ * Difficulty: Easy
+ *
+ * An n x n matrix is valid if every row and every column contains all the integers from 1
+ * to n (inclusive).
+ *
+ * Given an n x n integer matrix matrix, return true if the matrix is valid. Otherwise,
+ * return false.
+ */
+
+/**
+ * @param {number[][]} matrix
+ * @return {boolean}
+ */
+var checkValid = function(matrix) {
+  const n = matrix.length;
+
+  for (let i = 0; i < n; i++) {
+    const rowSet = new Set();
+    const colSet = new Set();
+
+    for (let j = 0; j < n; j++) {
+      rowSet.add(matrix[i][j]);
+      colSet.add(matrix[j][i]);
+    }
+
+    if (rowSet.size !== n || colSet.size !== n) return false;
+  }
+
+  return true;
+};
diff --git a/solutions/2134-minimum-swaps-to-group-all-1s-together-ii.js b/solutions/2134-minimum-swaps-to-group-all-1s-together-ii.js
new file mode 100644
index 00000000..1105dced
--- /dev/null
+++ b/solutions/2134-minimum-swaps-to-group-all-1s-together-ii.js
@@ -0,0 +1,38 @@
+/**
+ * 2134. Minimum Swaps to Group All 1's Together II
+ * https://leetcode.com/problems/minimum-swaps-to-group-all-1s-together-ii/
+ * Difficulty: Medium
+ *
+ * A swap is defined as taking two distinct positions in an array and swapping the values in them.
+ *
+ * A circular array is defined as an array where we consider the first element and the last element
+ * to be adjacent.
+ *
+ * Given a binary circular array nums, return the minimum number of swaps required to group all
+ * 1's present in the array together at any location.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var minSwaps = function(nums) {
+  const onesCount = nums.reduce((sum, num) => sum + num, 0);
+  const n = nums.length;
+  let result = Infinity;
+  let currentZeros = 0;
+
+  for (let i = 0; i < onesCount; i++) {
+    if (nums[i] === 0) currentZeros++;
+  }
+
+  result = currentZeros;
+
+  for (let i = 1; i < n; i++) {
+    if (nums[(i - 1) % n] === 0) currentZeros--;
+    if (nums[(i + onesCount - 1) % n] === 0) currentZeros++;
+    result = Math.min(result, currentZeros);
+  }
+
+  return result;
+};
diff --git a/solutions/2135-count-words-obtained-after-adding-a-letter.js b/solutions/2135-count-words-obtained-after-adding-a-letter.js
new file mode 100644
index 00000000..c7b08943
--- /dev/null
+++ b/solutions/2135-count-words-obtained-after-adding-a-letter.js
@@ -0,0 +1,49 @@
+/**
+ * 2135. Count Words Obtained After Adding a Letter
+ * https://leetcode.com/problems/count-words-obtained-after-adding-a-letter/
+ * Difficulty: Medium
+ *
+ * You are given two 0-indexed arrays of strings startWords and targetWords. Each string consists
+ * of lowercase English letters only.
+ *
+ * For each string in targetWords, check if it is possible to choose a string from startWords and
+ * perform a conversion operation on it to be equal to that from targetWords.
+ *
+ * The conversion operation is described in the following two steps:
+ * 1. Append any lowercase letter that is not present in the string to its end.
+ *    - For example, if the string is "abc", the letters 'd', 'e', or 'y' can be added to it, but
+ *      not 'a'. If 'd' is added, the resulting string will be "abcd".
+ * 2. Rearrange the letters of the new string in any arbitrary order.
+ *    - For example, "abcd" can be rearranged to "acbd", "bacd", "cbda", and so on. Note that it
+ *      can also be rearranged to "abcd" itself.
+ *
+ * Return the number of strings in targetWords that can be obtained by performing the operations
+ * on any string of startWords.
+ *
+ * Note that you will only be verifying if the string in targetWords can be obtained from a string
+ * in startWords by performing the operations. The strings in startWords do not actually change
+ * during this process.
+ */
+
+/**
+ * @param {string[]} startWords
+ * @param {string[]} targetWords
+ * @return {number}
+ */
+var wordCount = function(startWords, targetWords) {
+  const sortedStartWords = new Set(startWords.map(word => [...word].sort().join('')));
+  let result = 0;
+
+  for (const target of targetWords) {
+    const sortedTarget = [...target].sort().join('');
+    for (let i = 0; i < target.length; i++) {
+      const candidate = sortedTarget.slice(0, i) + sortedTarget.slice(i + 1);
+      if (sortedStartWords.has(candidate)) {
+        result++;
+        break;
+      }
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2136-earliest-possible-day-of-full-bloom.js b/solutions/2136-earliest-possible-day-of-full-bloom.js
new file mode 100644
index 00000000..e4a07b6c
--- /dev/null
+++ b/solutions/2136-earliest-possible-day-of-full-bloom.js
@@ -0,0 +1,39 @@
+/**
+ * 2136. Earliest Possible Day of Full Bloom
+ * https://leetcode.com/problems/earliest-possible-day-of-full-bloom/
+ * Difficulty: Hard
+ *
+ * You have n flower seeds. Every seed must be planted first before it can begin to grow, then
+ * bloom. Planting a seed takes time and so does the growth of a seed. You are given two 0-indexed
+ * integer arrays plantTime and growTime, of length n each:
+ * - plantTime[i] is the number of full days it takes you to plant the ith seed. Every day, you can
+ *   work on planting exactly one seed. You do not have to work on planting the same seed on
+ *   consecutive days, but the planting of a seed is not complete until you have worked plantTime[i]
+ *   days on planting it in total.
+ * - growTime[i] is the number of full days it takes the ith seed to grow after being completely
+ *   planted. After the last day of its growth, the flower blooms and stays bloomed forever.
+ *
+ * From the beginning of day 0, you can plant the seeds in any order.
+ *
+ * Return the earliest possible day where all seeds are blooming.
+ */
+
+/**
+ * @param {number[]} plantTime
+ * @param {number[]} growTime
+ * @return {number}
+ */
+var earliestFullBloom = function(plantTime, growTime) {
+  const seeds = plantTime.map((plant, index) => ({ plant, grow: growTime[index] }));
+  seeds.sort((a, b) => b.grow - a.grow);
+
+  let plantingDays = 0;
+  let result = 0;
+
+  for (const { plant, grow } of seeds) {
+    plantingDays += plant;
+    result = Math.max(result, plantingDays + grow);
+  }
+
+  return result;
+};
diff --git a/solutions/2138-divide-a-string-into-groups-of-size-k.js b/solutions/2138-divide-a-string-into-groups-of-size-k.js
new file mode 100644
index 00000000..24d0197f
--- /dev/null
+++ b/solutions/2138-divide-a-string-into-groups-of-size-k.js
@@ -0,0 +1,35 @@
+/**
+ * 2138. Divide a String Into Groups of Size k
+ * https://leetcode.com/problems/divide-a-string-into-groups-of-size-k/
+ * Difficulty: Easy
+ *
+ * A string s can be partitioned into groups of size k using the following procedure:
+ * - The first group consists of the first k characters of the string, the second group consists
+ *   of the next k characters of the string, and so on. Each element can be a part of exactly one
+ *   group.
+ * - For the last group, if the string does not have k characters remaining, a character fill is
+ *   used to complete the group.
+ *
+ * Note that the partition is done so that after removing the fill character from the last group
+ * (if it exists) and concatenating all the groups in order, the resultant string should be s.
+ *
+ * Given the string s, the size of each group k and the character fill, return a string array
+ * denoting the composition of every group s has been divided into, using the above procedure.
+ */
+
+/**
+ * @param {string} s
+ * @param {number} k
+ * @param {character} fill
+ * @return {string[]}
+ */
+var divideString = function(s, k, fill) {
+  const paddedString = s + fill.repeat((k - s.length % k) % k);
+  const result = [];
+
+  for (let i = 0; i < paddedString.length; i += k) {
+    result.push(paddedString.slice(i, i + k));
+  }
+
+  return result;
+};
diff --git a/solutions/2139-minimum-moves-to-reach-target-score.js b/solutions/2139-minimum-moves-to-reach-target-score.js
new file mode 100644
index 00000000..a074595f
--- /dev/null
+++ b/solutions/2139-minimum-moves-to-reach-target-score.js
@@ -0,0 +1,40 @@
+/**
+ * 2139. Minimum Moves to Reach Target Score
+ * https://leetcode.com/problems/minimum-moves-to-reach-target-score/
+ * Difficulty: Medium
+ *
+ * You are playing a game with integers. You start with the integer 1 and you want to reach
+ * the integer target.
+ *
+ * In one move, you can either:
+ * - Increment the current integer by one (i.e., x = x + 1).
+ * - Double the current integer (i.e., x = 2 * x).
+ *
+ * You can use the increment operation any number of times, however, you can only use the double
+ * operation at most maxDoubles times.
+ *
+ * Given the two integers target and maxDoubles, return the minimum number of moves needed to
+ * reach target starting with 1.
+ */
+
+/**
+ * @param {number} target
+ * @param {number} maxDoubles
+ * @return {number}
+ */
+var minMoves = function(target, maxDoubles) {
+  let moves = 0;
+  let current = target;
+
+  while (current > 1 && maxDoubles > 0) {
+    if (current % 2 === 0) {
+      current /= 2;
+      maxDoubles--;
+    } else {
+      current--;
+    }
+    moves++;
+  }
+
+  return moves + (current - 1);
+};
diff --git a/solutions/2141-maximum-running-time-of-n-computers.js b/solutions/2141-maximum-running-time-of-n-computers.js
new file mode 100644
index 00000000..b5f7b090
--- /dev/null
+++ b/solutions/2141-maximum-running-time-of-n-computers.js
@@ -0,0 +1,41 @@
+/**
+ * 2141. Maximum Running Time of N Computers
+ * https://leetcode.com/problems/maximum-running-time-of-n-computers/
+ * Difficulty: Hard
+ *
+ * You have n computers. You are given the integer n and a 0-indexed integer array batteries
+ * where the ith battery can run a computer for batteries[i] minutes. You are interested in
+ * running all n computers simultaneously using the given batteries.
+ *
+ * Initially, you can insert at most one battery into each computer. After that and at any
+ * integer time moment, you can remove a battery from a computer and insert another battery
+ * any number of times. The inserted battery can be a totally new battery or a battery from
+ * another computer. You may assume that the removing and inserting processes take no time.
+ *
+ * Note that the batteries cannot be recharged.
+ *
+ * Return the maximum number of minutes you can run all the n computers simultaneously.
+ */
+
+/**
+ * @param {number} n
+ * @param {number[]} batteries
+ * @return {number}
+ */
+var maxRunTime = function(n, batteries) {
+  let left = 1;
+  let right = Math.floor(batteries.reduce((sum, battery) => sum + battery, 0) / n);
+
+  while (left < right) {
+    const mid = Math.floor((left + right + 1) / 2);
+    const total = batteries.reduce((sum, battery) => sum + Math.min(battery, mid), 0);
+
+    if (total >= n * mid) {
+      left = mid;
+    } else {
+      right = mid - 1;
+    }
+  }
+
+  return left;
+};
diff --git a/solutions/2144-minimum-cost-of-buying-candies-with-discount.js b/solutions/2144-minimum-cost-of-buying-candies-with-discount.js
new file mode 100644
index 00000000..86eca1e2
--- /dev/null
+++ b/solutions/2144-minimum-cost-of-buying-candies-with-discount.js
@@ -0,0 +1,33 @@
+/**
+ * 2144. Minimum Cost of Buying Candies With Discount
+ * https://leetcode.com/problems/minimum-cost-of-buying-candies-with-discount/
+ * Difficulty: Easy
+ *
+ * A shop is selling candies at a discount. For every two candies sold, the shop gives a
+ * third candy for free.
+ *
+ * The customer can choose any candy to take away for free as long as the cost of the
+ * chosen candy is less than or equal to the minimum cost of the two candies bought.
+ *
+ * - For example, if there are 4 candies with costs 1, 2, 3, and 4, and the customer buys
+ *   candies with costs 2 and 3, they can take the candy with cost 1 for free, but not the
+ *   candy with cost 4.
+ *
+ * Given a 0-indexed integer array cost, where cost[i] denotes the cost of the ith candy,
+ * return the minimum cost of buying all the candies.
+ */
+
+/**
+ * @param {number[]} cost
+ * @return {number}
+ */
+var minimumCost = function(cost) {
+  cost.sort((a, b) => b - a);
+  let result = 0;
+
+  for (let i = 0; i < cost.length; i += 3) {
+    result += cost[i] + (cost[i + 1] || 0);
+  }
+
+  return result;
+};
diff --git a/solutions/2147-number-of-ways-to-divide-a-long-corridor.js b/solutions/2147-number-of-ways-to-divide-a-long-corridor.js
new file mode 100644
index 00000000..e504b765
--- /dev/null
+++ b/solutions/2147-number-of-ways-to-divide-a-long-corridor.js
@@ -0,0 +1,58 @@
+/**
+ * 2147. Number of Ways to Divide a Long Corridor
+ * https://leetcode.com/problems/number-of-ways-to-divide-a-long-corridor/
+ * Difficulty: Hard
+ *
+ * Along a long library corridor, there is a line of seats and decorative plants. You are given
+ * a 0-indexed string corridor of length n consisting of letters 'S' and 'P' where each 'S'
+ * represents a seat and each 'P' represents a plant.
+ *
+ * One room divider has already been installed to the left of index 0, and another to the right
+ * of index n - 1. Additional room dividers can be installed. For each position between indices
+ * i - 1 and i (1 <= i <= n - 1), at most one divider can be installed.
+ *
+ * Divide the corridor into non-overlapping sections, where each section has exactly two seats
+ * with any number of plants. There may be multiple ways to perform the division. Two ways are
+ * different if there is a position with a room divider installed in the first way but not in
+ * the second way.
+ *
+ * Return the number of ways to divide the corridor. Since the answer may be very large, return
+ * it modulo 109 + 7. If there is no way, return 0.
+ */
+
+/**
+ * @param {string} corridor
+ * @return {number}
+ */
+var numberOfWays = function(corridor) {
+  const MOD = 1e9 + 7;
+  let seatCount = 0;
+  let result = 1;
+  let lastPairEnd = -1;
+
+  for (let i = 0; i < corridor.length; i++) {
+    if (corridor[i] === 'S') {
+      seatCount++;
+    }
+  }
+  if (seatCount === 0 || seatCount % 2 !== 0) {
+    return 0;
+  }
+
+  seatCount = 0;
+
+  for (let i = 0; i < corridor.length; i++) {
+    if (corridor[i] === 'S') {
+      seatCount++;
+
+      if (seatCount % 2 === 0) {
+        lastPairEnd = i;
+      } else if (seatCount > 1) {
+        const plantsCount = i - lastPairEnd - 1;
+        result = (result * (plantsCount + 1)) % MOD;
+      }
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2148-count-elements-with-strictly-smaller-and-greater-elements.js b/solutions/2148-count-elements-with-strictly-smaller-and-greater-elements.js
new file mode 100644
index 00000000..194880af
--- /dev/null
+++ b/solutions/2148-count-elements-with-strictly-smaller-and-greater-elements.js
@@ -0,0 +1,25 @@
+/**
+ * 2148. Count Elements With Strictly Smaller and Greater Elements
+ * https://leetcode.com/problems/count-elements-with-strictly-smaller-and-greater-elements/
+ * Difficulty: Easy
+ *
+ * Given an integer array nums, return the number of elements that have both a strictly
+ * smaller and a strictly greater element appear in nums.
+ */
+
+/**
+* @param {number[]} nums
+* @return {number}
+*/
+var countElements = function(nums) {
+  let result = 0;
+
+  if (nums.length <= 2) return 0;
+  for (const num of nums) {
+    if (num > Math.min(...nums) && num < Math.max(...nums)) {
+      result++;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2149-rearrange-array-elements-by-sign.js b/solutions/2149-rearrange-array-elements-by-sign.js
new file mode 100644
index 00000000..7979e5ef
--- /dev/null
+++ b/solutions/2149-rearrange-array-elements-by-sign.js
@@ -0,0 +1,33 @@
+/**
+ * 2149. Rearrange Array Elements by Sign
+ * https://leetcode.com/problems/rearrange-array-elements-by-sign/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed integer array nums of even length consisting of an equal number
+ * of positive and negative integers.
+ *
+ * You should return the array of nums such that the the array follows the given conditions:
+ * 1. Every consecutive pair of integers have opposite signs.
+ * 2. For all integers with the same sign, the order in which they were present in nums is
+ *    preserved.
+ * 3. The rearranged array begins with a positive integer.
+ *
+ * Return the modified array after rearranging the elements to satisfy the aforementioned
+ * conditions.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number[]}
+ */
+var rearrangeArray = function(nums) {
+  const positives = nums.filter(num => num > 0);
+  const negatives = nums.filter(num => num < 0);
+  const result = [];
+
+  for (let i = 0; i < positives.length; i++) {
+    result.push(positives[i], negatives[i]);
+  }
+
+  return result;
+};
diff --git a/solutions/2150-find-all-lonely-numbers-in-the-array.js b/solutions/2150-find-all-lonely-numbers-in-the-array.js
new file mode 100644
index 00000000..676badc6
--- /dev/null
+++ b/solutions/2150-find-all-lonely-numbers-in-the-array.js
@@ -0,0 +1,31 @@
+/**
+ * 2150. Find All Lonely Numbers in the Array
+ * https://leetcode.com/problems/find-all-lonely-numbers-in-the-array/
+ * Difficulty: Medium
+ *
+ * You are given an integer array nums. A number x is lonely when it appears only once, and
+ * no adjacent numbers (i.e. x + 1 and x - 1) appear in the array.
+ *
+ * Return all lonely numbers in nums. You may return the answer in any order.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number[]}
+ */
+var findLonely = function(nums) {
+  const map = new Map();
+
+  for (const num of nums) {
+    map.set(num, (map.get(num) || 0) + 1);
+  }
+
+  const result = [];
+  for (const [num, count] of map) {
+    if (count === 1 && !map.has(num - 1) && !map.has(num + 1)) {
+      result.push(num);
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2151-maximum-good-people-based-on-statements.js b/solutions/2151-maximum-good-people-based-on-statements.js
new file mode 100644
index 00000000..9a5d71cd
--- /dev/null
+++ b/solutions/2151-maximum-good-people-based-on-statements.js
@@ -0,0 +1,59 @@
+/**
+ * 2151. Maximum Good People Based on Statements
+ * https://leetcode.com/problems/maximum-good-people-based-on-statements/
+ * Difficulty: Hard
+ *
+ * There are two types of persons:
+ * - The good person: The person who always tells the truth.
+ * - The bad person: The person who might tell the truth and might lie.
+ *
+ * You are given a 0-indexed 2D integer array statements of size n x n that represents the
+ * statements made by n people about each other. More specifically, statements[i][j] could
+ * be one of the following:
+ * - 0 which represents a statement made by person i that person j is a bad person.
+ * - 1 which represents a statement made by person i that person j is a good person.
+ * - 2 represents that no statement is made by person i about person j.
+ *
+ * Additionally, no person ever makes a statement about themselves. Formally, we have that
+ * statements[i][i] = 2 for all 0 <= i < n.
+ *
+ * Return the maximum number of people who can be good based on the statements made by the
+ * n people.
+ */
+
+/**
+ * @param {number[][]} statements
+ * @return {number}
+ */
+var maximumGood = function(statements) {
+  const n = statements.length;
+  let result = 0;
+
+  backtrack(0, new Array(n).fill(false), 0);
+  return result;
+
+  function isValid(goodPeople) {
+    for (let i = 0; i < n; i++) {
+      if (!goodPeople[i]) continue;
+      for (let j = 0; j < n; j++) {
+        if (statements[i][j] === 0 && goodPeople[j]) return false;
+        if (statements[i][j] === 1 && !goodPeople[j]) return false;
+      }
+    }
+    return true;
+  }
+
+  function backtrack(index, goodPeople, goodCount) {
+    if (index === n) {
+      if (isValid(goodPeople)) {
+        result = Math.max(result, goodCount);
+      }
+      return;
+    }
+
+    goodPeople[index] = true;
+    backtrack(index + 1, goodPeople, goodCount + 1);
+    goodPeople[index] = false;
+    backtrack(index + 1, goodPeople, goodCount);
+  }
+};
diff --git a/solutions/2155-all-divisions-with-the-highest-score-of-a-binary-array.js b/solutions/2155-all-divisions-with-the-highest-score-of-a-binary-array.js
new file mode 100644
index 00000000..66db5b2f
--- /dev/null
+++ b/solutions/2155-all-divisions-with-the-highest-score-of-a-binary-array.js
@@ -0,0 +1,45 @@
+/**
+ * 2155. All Divisions With the Highest Score of a Binary Array
+ * https://leetcode.com/problems/all-divisions-with-the-highest-score-of-a-binary-array/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed binary array nums of length n. nums can be divided at index i
+ * (where 0 <= i <= n) into two arrays (possibly empty) numsleft and numsright:
+ * - numsleft has all the elements of nums between index 0 and i - 1 (inclusive), while numsright
+ *   has all the elements of nums between index i and n - 1 (inclusive).
+ * - If i == 0, numsleft is empty, while numsright has all the elements of nums.
+ * - If i == n, numsleft has all the elements of nums, while numsright is empty.
+ *
+ * The division score of an index i is the sum of the number of 0's in numsleft and the number
+ * of 1's in numsright.
+ *
+ * Return all distinct indices that have the highest possible division score. You may return
+ * the answer in any order.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number[]}
+ */
+var maxScoreIndices = function(nums) {
+  const result = [0];
+  let leftZeros = 0;
+  let rightOnes = nums.reduce((sum, num) => sum + num, 0);
+  let maxScore = rightOnes;
+
+  for (let i = 0; i < nums.length; i++) {
+    leftZeros += nums[i] === 0 ? 1 : 0;
+    rightOnes -= nums[i];
+    const score = leftZeros + rightOnes;
+
+    if (score > maxScore) {
+      maxScore = score;
+      result.length = 0;
+      result.push(i + 1);
+    } else if (score === maxScore) {
+      result.push(i + 1);
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2156-find-substring-with-given-hash-value.js b/solutions/2156-find-substring-with-given-hash-value.js
new file mode 100644
index 00000000..a43f4a10
--- /dev/null
+++ b/solutions/2156-find-substring-with-given-hash-value.js
@@ -0,0 +1,51 @@
+/**
+ * 2156. Find Substring With Given Hash Value
+ * https://leetcode.com/problems/find-substring-with-given-hash-value/
+ * Difficulty: Hard
+ *
+ * The hash of a 0-indexed string s of length k, given integers p and m, is computed using
+ * the following function:
+ * - hash(s, p, m) = (val(s[0]) * p0 + val(s[1]) * p1 + ... + val(s[k-1]) * pk-1) mod m.
+ *
+ * Where val(s[i]) represents the index of s[i] in the alphabet from val('a') = 1 to val('z') = 26.
+ *
+ * You are given a string s and the integers power, modulo, k, and hashValue. Return sub, the
+ * first substring of s of length k such that hash(sub, power, modulo) == hashValue.
+ *
+ * The test cases will be generated such that an answer always exists.
+ *
+ * A substring is a contiguous non-empty sequence of characters within a string.
+ */
+
+/**
+* @param {string} s
+* @param {number} power
+* @param {number} modulo
+* @param {number} k
+* @param {number} hashValue
+* @return {string}
+*/
+var subStrHash = function(s, power, modulo, k, hashValue) {
+  power = BigInt(power);
+  modulo = BigInt(modulo);
+  hashValue = BigInt(hashValue);
+
+  const powers = new Array(k);
+  powers[0] = 1n;
+  for (let i = 1; i < k; i++) {
+    powers[i] = (powers[i - 1] * power) % modulo;
+  }
+
+  for (let start = 0; start <= s.length - k; start++) {
+    let hash = 0n;
+    for (let i = 0; i < k; i++) {
+      const charVal = BigInt(s.charCodeAt(start + i) - 'a'.charCodeAt(0) + 1);
+      hash = (hash + charVal * powers[i]) % modulo;
+    }
+    if (hash === hashValue) {
+      return s.substring(start, start + k);
+    }
+  }
+
+  return '';
+};
diff --git a/solutions/2157-groups-of-strings.js b/solutions/2157-groups-of-strings.js
new file mode 100644
index 00000000..8af51c12
--- /dev/null
+++ b/solutions/2157-groups-of-strings.js
@@ -0,0 +1,140 @@
+/**
+ * 2157. Groups of Strings
+ * https://leetcode.com/problems/groups-of-strings/
+ * Difficulty: Hard
+ *
+ * You are given a 0-indexed array of strings words. Each string consists of lowercase English
+ * letters only. No letter occurs more than once in any string of words.
+ *
+ * Two strings s1 and s2 are said to be connected if the set of letters of s2 can be obtained
+ * from the set of letters of s1 by any one of the following operations:
+ * - Adding exactly one letter to the set of the letters of s1.
+ * - Deleting exactly one letter from the set of the letters of s1.
+ * - Replacing exactly one letter from the set of the letters of s1 with any letter, including
+ *   itself.
+ *
+ * The array words can be divided into one or more non-intersecting groups. A string belongs
+ * to a group if any one of the following is true:
+ * - It is connected to at least one other string of the group.
+ * - It is the only string present in the group.
+ *
+ * Note that the strings in words should be grouped in such a manner that a string belonging
+ * to a group cannot be connected to a string present in any other group. It can be proved
+ * that such an arrangement is always unique.
+ *
+ * Return an array ans of size 2 where:
+ * - ans[0] is the maximum number of groups words can be divided into, and
+ * - ans[1] is the size of the largest group.
+ */
+
+/**
+ * @param {string[]} words
+ * @return {number[]}
+ */
+var groupStrings = function(words) {
+  const n = words.length;
+  const masks = words.map(word => {
+    let mask = 0;
+    for (let i = 0; i < word.length; i++) {
+      mask |= (1 << (word.charCodeAt(i) - 'a'.charCodeAt(0)));
+    }
+    return mask;
+  });
+  const uf = new UnionFind(n);
+  const maskToIndex = new Map();
+  for (let i = 0; i < n; i++) {
+    if (maskToIndex.has(masks[i])) {
+      uf.union(maskToIndex.get(masks[i]), i);
+    } else {
+      maskToIndex.set(masks[i], i);
+    }
+  }
+  const processed = new Set();
+
+  for (let i = 0; i < n; i++) {
+    const mask = masks[i];
+    if (processed.has(mask)) continue;
+    processed.add(mask);
+
+    for (let bit = 0; bit < 26; bit++) {
+      if ((mask & (1 << bit)) === 0) {
+        const newMask = mask | (1 << bit);
+        if (maskToIndex.has(newMask)) {
+          uf.union(i, maskToIndex.get(newMask));
+        }
+      }
+    }
+
+    for (let bit = 0; bit < 26; bit++) {
+      if ((mask & (1 << bit)) !== 0) {
+        const newMask = mask & ~(1 << bit);
+        if (maskToIndex.has(newMask)) {
+          uf.union(i, maskToIndex.get(newMask));
+        }
+      }
+    }
+
+    for (let remove = 0; remove < 26; remove++) {
+      if ((mask & (1 << remove)) !== 0) {
+        for (let add = 0; add < 26; add++) {
+          if ((mask & (1 << add)) === 0) {
+            const newMask = (mask & ~(1 << remove)) | (1 << add);
+            if (maskToIndex.has(newMask)) {
+              uf.union(i, maskToIndex.get(newMask));
+            }
+          }
+        }
+      }
+    }
+  }
+
+  return [uf.count, uf.getMaxSize()];
+};
+
+class UnionFind {
+  constructor(n) {
+    this.parent = Array(n).fill().map((_, i) => i);
+    this.rank = Array(n).fill(0);
+    this.count = n;
+    this.sizes = Array(n).fill(1);
+  }
+
+  find(x) {
+    if (this.parent[x] !== x) {
+      this.parent[x] = this.find(this.parent[x]);
+    }
+    return this.parent[x];
+  }
+
+  union(x, y) {
+    const rootX = this.find(x);
+    const rootY = this.find(y);
+
+    if (rootX === rootY) return false;
+
+    if (this.rank[rootX] < this.rank[rootY]) {
+      this.parent[rootX] = rootY;
+      this.sizes[rootY] += this.sizes[rootX];
+    } else if (this.rank[rootX] > this.rank[rootY]) {
+      this.parent[rootY] = rootX;
+      this.sizes[rootX] += this.sizes[rootY];
+    } else {
+      this.parent[rootY] = rootX;
+      this.rank[rootX]++;
+      this.sizes[rootX] += this.sizes[rootY];
+    }
+
+    this.count--;
+    return true;
+  }
+
+  getMaxSize() {
+    let maxSize = 0;
+    for (let i = 0; i < this.parent.length; i++) {
+      if (this.parent[i] === i) {
+        maxSize = Math.max(maxSize, this.sizes[i]);
+      }
+    }
+    return maxSize;
+  }
+}
diff --git a/solutions/2160-minimum-sum-of-four-digit-number-after-splitting-digits.js b/solutions/2160-minimum-sum-of-four-digit-number-after-splitting-digits.js
new file mode 100644
index 00000000..fa3b9b86
--- /dev/null
+++ b/solutions/2160-minimum-sum-of-four-digit-number-after-splitting-digits.js
@@ -0,0 +1,22 @@
+/**
+ * 2160. Minimum Sum of Four Digit Number After Splitting Digits
+ * https://leetcode.com/problems/minimum-sum-of-four-digit-number-after-splitting-digits/
+ * Difficulty: Easy
+ *
+ * You are given a positive integer num consisting of exactly four digits. Split num into two
+ * new integers new1 and new2 by using the digits found in num. Leading zeros are allowed in
+ * new1 and new2, and all the digits found in num must be used.
+ * - For example, given num = 2932, you have the following digits: two 2's, one 9 and one 3.
+ *   Some of the possible pairs [new1, new2] are [22, 93], [23, 92], [223, 9] and [2, 329].
+ *
+ * Return the minimum possible sum of new1 and new2.
+ */
+
+/**
+ * @param {number} num
+ * @return {number}
+ */
+var minimumSum = function(num) {
+  const digits = String(num).split('').map(Number).sort((a, b) => a - b);
+  return (digits[0] * 10 + digits[2]) + (digits[1] * 10 + digits[3]);
+};
diff --git a/solutions/2162-minimum-cost-to-set-cooking-time.js b/solutions/2162-minimum-cost-to-set-cooking-time.js
new file mode 100644
index 00000000..e1c51c1b
--- /dev/null
+++ b/solutions/2162-minimum-cost-to-set-cooking-time.js
@@ -0,0 +1,90 @@
+/**
+ * 2162. Minimum Cost to Set Cooking Time
+ * https://leetcode.com/problems/minimum-cost-to-set-cooking-time/
+ * Difficulty: Medium
+ *
+ * A generic microwave supports cooking times for:
+ * - at least 1 second.
+ * - at most 99 minutes and 99 seconds.
+ *
+ * To set the cooking time, you push at most four digits. The microwave normalizes what you push
+ * as four digits by prepending zeroes. It interprets the first two digits as the minutes and
+ * the last two digits as the seconds. It then adds them up as the cooking time. For example,
+ * - You push 9 5 4 (three digits). It is normalized as 0954 and interpreted as 9 minutes and
+ *   54 seconds.
+ * - You push 0 0 0 8 (four digits). It is interpreted as 0 minutes and 8 seconds.
+ * - You push 8 0 9 0. It is interpreted as 80 minutes and 90 seconds.
+ * - You push 8 1 3 0. It is interpreted as 81 minutes and 30 seconds.
+ *
+ * You are given integers startAt, moveCost, pushCost, and targetSeconds. Initially, your finger
+ * is on the digit startAt. Moving the finger above any specific digit costs moveCost units of
+ * fatigue. Pushing the digit below the finger once costs pushCost units of fatigue.
+ *
+ * There can be multiple ways to set the microwave to cook for targetSeconds seconds but you are
+ * interested in the way with the minimum cost.
+ *
+ * Return the minimum cost to set targetSeconds seconds of cooking time.
+ *
+ * Remember that one minute consists of 60 seconds.
+ */
+
+/**
+ * @param {number} startAt
+ * @param {number} moveCost
+ * @param {number} pushCost
+ * @param {number} targetSeconds
+ * @return {number}
+ */
+var minCostSetTime = function(startAt, moveCost, pushCost, targetSeconds) {
+  const minutes1 = Math.floor(targetSeconds / 60);
+  const seconds1 = targetSeconds % 60;
+  let result = Infinity;
+
+  if (minutes1 <= 99) {
+    const digits1 = getDigits(minutes1, seconds1);
+    result = Math.min(result, calculateCost(digits1));
+  }
+
+  const minutes2 = Math.floor(targetSeconds / 60) - 1;
+  const seconds2 = targetSeconds % 60 + 60;
+  if (minutes2 >= 0 && minutes2 <= 99 && seconds2 <= 99) {
+    const digits2 = getDigits(minutes2, seconds2);
+    result = Math.min(result, calculateCost(digits2));
+  }
+
+  return result;
+
+  function calculateCost(digits) {
+    let totalCost = 0;
+    let currentDigit = startAt;
+
+    for (const digit of digits) {
+      if (digit !== currentDigit) {
+        totalCost += moveCost;
+        currentDigit = digit;
+      }
+      totalCost += pushCost;
+    }
+
+    return totalCost;
+  }
+
+  function getDigits(minutes, seconds) {
+    const result = [];
+
+    if (minutes > 0) {
+      if (minutes >= 10) {
+        result.push(Math.floor(minutes / 10));
+      }
+      result.push(minutes % 10);
+    }
+
+    if (minutes > 0 || seconds >= 10) {
+      result.push(Math.floor(seconds / 10));
+    }
+
+    result.push(seconds % 10);
+
+    return result;
+  }
+};
diff --git a/solutions/2164-sort-even-and-odd-indices-independently.js b/solutions/2164-sort-even-and-odd-indices-independently.js
new file mode 100644
index 00000000..ed9322c6
--- /dev/null
+++ b/solutions/2164-sort-even-and-odd-indices-independently.js
@@ -0,0 +1,50 @@
+/**
+ * 2164. Sort Even and Odd Indices Independently
+ * https://leetcode.com/problems/sort-even-and-odd-indices-independently/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed integer array nums. Rearrange the values of nums according to the
+ * following rules:
+ * 1. Sort the values at odd indices of nums in non-increasing order.
+ *    - For example, if nums = [4,1,2,3] before this step, it becomes [4,3,2,1] after. The values
+ *      at odd indices 1 and 3 are sorted in non-increasing order.
+ * 2. Sort the values at even indices of nums in non-decreasing order.
+ *    - For example, if nums = [4,1,2,3] before this step, it becomes [2,1,4,3] after. The values
+ *      at even indices 0 and 2 are sorted in non-decreasing order.
+ *
+ * Return the array formed after rearranging the values of nums.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number[]}
+ */
+var sortEvenOdd = function(nums) {
+  const evens = [];
+  const odds = [];
+
+  for (let i = 0; i < nums.length; i++) {
+    if (i % 2 === 0) {
+      evens.push(nums[i]);
+    } else {
+      odds.push(nums[i]);
+    }
+  }
+
+  evens.sort((a, b) => a - b);
+  odds.sort((a, b) => b - a);
+
+  const result = [];
+  let evenIndex = 0;
+  let oddIndex = 0;
+
+  for (let i = 0; i < nums.length; i++) {
+    if (i % 2 === 0) {
+      result.push(evens[evenIndex++]);
+    } else {
+      result.push(odds[oddIndex++]);
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2165-smallest-value-of-the-rearranged-number.js b/solutions/2165-smallest-value-of-the-rearranged-number.js
new file mode 100644
index 00000000..c3226062
--- /dev/null
+++ b/solutions/2165-smallest-value-of-the-rearranged-number.js
@@ -0,0 +1,34 @@
+/**
+ * 2165. Smallest Value of the Rearranged Number
+ * https://leetcode.com/problems/smallest-value-of-the-rearranged-number/
+ * Difficulty: Medium
+ *
+ * You are given an integer num. Rearrange the digits of num such that its value is minimized
+ * and it does not contain any leading zeros.
+ *
+ * Return the rearranged number with minimal value.
+ *
+ * Note that the sign of the number does not change after rearranging the digits.
+ */
+
+/**
+ * @param {number} num
+ * @return {number}
+ */
+var smallestNumber = function(num) {
+  const isNegative = num < 0;
+  const digits = Math.abs(num).toString().split('').map(Number);
+
+  if (isNegative) {
+    digits.sort((a, b) => b - a);
+    return -parseInt(digits.join(''), 10);
+  }
+
+  digits.sort((a, b) => a - b);
+  const firstNonZero = digits.findIndex(d => d !== 0);
+
+  if (firstNonZero === -1) return 0;
+
+  [digits[0], digits[firstNonZero]] = [digits[firstNonZero], digits[0]];
+  return parseInt(digits.join(''), 10);
+};
diff --git a/solutions/2166-design-bitset.js b/solutions/2166-design-bitset.js
new file mode 100644
index 00000000..155fe39b
--- /dev/null
+++ b/solutions/2166-design-bitset.js
@@ -0,0 +1,109 @@
+/**
+ * 2166. Design Bitset
+ * https://leetcode.com/problems/design-bitset/
+ * Difficulty: Medium
+ *
+ * A Bitset is a data structure that compactly stores bits.
+ *
+ * Implement the Bitset class:
+ * - Bitset(int size) Initializes the Bitset with size bits, all of which are 0.
+ * - void fix(int idx) Updates the value of the bit at the index idx to 1. If the value was
+ *   already 1, no change occurs.
+ * - void unfix(int idx) Updates the value of the bit at the index idx to 0. If the value
+ *   was already 0, no change occurs.
+ * - void flip() Flips the values of each bit in the Bitset. In other words, all bits with
+ *   value 0 will now have value 1 and vice versa.
+ * - boolean all() Checks if the value of each bit in the Bitset is 1. Returns true if it
+ *   satisfies the condition, false otherwise.
+ * - boolean one() Checks if there is at least one bit in the Bitset with value 1. Returns
+ *   true if it satisfies the condition, false otherwise.
+ * - int count() Returns the total number of bits in the Bitset which have value 1.
+ * - String toString() Returns the current composition of the Bitset. Note that in the
+ *   resultant string, the character at the ith index should coincide with the value at
+ *   the ith bit of the Bitset.
+ */
+
+/**
+ * @param {number} size
+ */
+var Bitset = function(size) {
+  this.bits = new Uint8Array(size);
+  this.ones = 0;
+  this.flipped = false;
+};
+
+/**
+ * @param {number} idx
+ * @return {void}
+ */
+Bitset.prototype.fix = function(idx) {
+  if (this.flipped) {
+    if (this.bits[idx] === 1) {
+      this.bits[idx] = 0;
+      this.ones++;
+    }
+  } else {
+    if (this.bits[idx] === 0) {
+      this.bits[idx] = 1;
+      this.ones++;
+    }
+  }
+};
+
+/**
+ * @param {number} idx
+ * @return {void}
+ */
+Bitset.prototype.unfix = function(idx) {
+  if (this.flipped) {
+    if (this.bits[idx] === 0) {
+      this.bits[idx] = 1;
+      this.ones--;
+    }
+  } else {
+    if (this.bits[idx] === 1) {
+      this.bits[idx] = 0;
+      this.ones--;
+    }
+  }
+};
+
+/**
+ * @return {void}
+ */
+Bitset.prototype.flip = function() {
+  this.flipped = !this.flipped;
+  this.ones = this.bits.length - this.ones;
+};
+
+/**
+ * @return {boolean}
+ */
+Bitset.prototype.all = function() {
+  return this.ones === this.bits.length;
+};
+
+/**
+ * @return {boolean}
+ */
+Bitset.prototype.one = function() {
+  return this.ones > 0;
+};
+
+/**
+ * @return {number}
+ */
+Bitset.prototype.count = function() {
+  return this.ones;
+};
+
+/**
+ * @return {string}
+ */
+Bitset.prototype.toString = function() {
+  let result = '';
+  for (let i = 0; i < this.bits.length; i++) {
+    result += this.flipped ? 1 - this.bits[i] : this.bits[i];
+  }
+  return result;
+};
diff --git a/solutions/2167-minimum-time-to-remove-all-cars-containing-illegal-goods.js b/solutions/2167-minimum-time-to-remove-all-cars-containing-illegal-goods.js
new file mode 100644
index 00000000..4877a0de
--- /dev/null
+++ b/solutions/2167-minimum-time-to-remove-all-cars-containing-illegal-goods.js
@@ -0,0 +1,37 @@
+/**
+ * 2167. Minimum Time to Remove All Cars Containing Illegal Goods
+ * https://leetcode.com/problems/minimum-time-to-remove-all-cars-containing-illegal-goods/
+ * Difficulty: Hard
+ *
+ * You are given a 0-indexed binary string s which represents a sequence of train cars. s[i] = '0'
+ * denotes that the ith car does not contain illegal goods and s[i] = '1' denotes that the ith car
+ * does contain illegal goods.
+ *
+ * As the train conductor, you would like to get rid of all the cars containing illegal goods.
+ * You can do any of the following three operations any number of times:
+ * 1. Remove a train car from the left end (i.e., remove s[0]) which takes 1 unit of time.
+ * 2. Remove a train car from the right end (i.e., remove s[s.length - 1]) which takes 1 unit
+ *    of time.
+ * 3. Remove a train car from anywhere in the sequence which takes 2 units of time.
+ *
+ * Return the minimum time to remove all the cars containing illegal goods.
+ *
+ * Note that an empty sequence of cars is considered to have no cars containing illegal goods.
+ */
+
+/**
+ * @param {string} s
+ * @return {number}
+ */
+var minimumTime = function(s) {
+  let leftCost = 0;
+  let result = s.length;
+
+  for (let i = 0; i < s.length; i++) {
+    leftCost = Math.min(leftCost + (s[i] === '1' ? 2 : 0), i + 1);
+    const rightCost = s.length - i - 1;
+    result = Math.min(result, leftCost + rightCost);
+  }
+
+  return result;
+};
diff --git a/solutions/2169-count-operations-to-obtain-zero.js b/solutions/2169-count-operations-to-obtain-zero.js
new file mode 100644
index 00000000..428bd42a
--- /dev/null
+++ b/solutions/2169-count-operations-to-obtain-zero.js
@@ -0,0 +1,34 @@
+/**
+ * 2169. Count Operations to Obtain Zero
+ * https://leetcode.com/problems/count-operations-to-obtain-zero/
+ * Difficulty: Easy
+ *
+ * You are given two non-negative integers num1 and num2.
+ *
+ * In one operation, if num1 >= num2, you must subtract num2 from num1, otherwise subtract num1
+ * from num2.
+ * - For example, if num1 = 5 and num2 = 4, subtract num2 from num1, thus obtaining num1 = 1 and
+ *   num2 = 4. However, if num1 = 4 and num2 = 5, after one operation, num1 = 4 and num2 = 1.
+ *
+ * Return the number of operations required to make either num1 = 0 or num2 = 0.
+ */
+
+/**
+ * @param {number} num1
+ * @param {number} num2
+ * @return {number}
+ */
+var countOperations = function(num1, num2) {
+  let operations = 0;
+
+  while (num1 !== 0 && num2 !== 0) {
+    if (num1 >= num2) {
+      num1 -= num2;
+    } else {
+      num2 -= num1;
+    }
+    operations++;
+  }
+
+  return operations;
+};
diff --git a/solutions/2170-minimum-operations-to-make-the-array-alternating.js b/solutions/2170-minimum-operations-to-make-the-array-alternating.js
new file mode 100644
index 00000000..770b6d62
--- /dev/null
+++ b/solutions/2170-minimum-operations-to-make-the-array-alternating.js
@@ -0,0 +1,49 @@
+/**
+ * 2170. Minimum Operations to Make the Array Alternating
+ * https://leetcode.com/problems/minimum-operations-to-make-the-array-alternating/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed array nums consisting of n positive integers.
+ *
+ * The array nums is called alternating if:
+ * - nums[i - 2] == nums[i], where 2 <= i <= n - 1.
+ * - nums[i - 1] != nums[i], where 1 <= i <= n - 1.
+ *
+ * In one operation, you can choose an index i and change nums[i] into any positive integer.
+ *
+ * Return the minimum number of operations required to make the array alternating.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var minimumOperations = function(nums) {
+  const evenFreq = new Map();
+  const oddFreq = new Map();
+
+  if (nums.length <= 1) return 0;
+  for (let i = 0; i < nums.length; i++) {
+    if (i % 2 === 0) {
+      evenFreq.set(nums[i], (evenFreq.get(nums[i]) || 0) + 1);
+    } else {
+      oddFreq.set(nums[i], (oddFreq.get(nums[i]) || 0) + 1);
+    }
+  }
+
+  const evenTop = [...evenFreq.entries()].sort((a, b) => b[1] - a[1]).slice(0, 2);
+  const oddTop = [...oddFreq.entries()].sort((a, b) => b[1] - a[1]).slice(0, 2);
+  const evenTotal = Math.ceil(nums.length / 2);
+  const oddTotal = Math.floor(nums.length / 2);
+  let minOps = nums.length;
+
+  for (const [evenNum, evenCount] of evenTop.length ? evenTop : [[0, 0]]) {
+    for (const [oddNum, oddCount] of oddTop.length ? oddTop : [[0, 0]]) {
+      if (evenNum !== oddNum || evenNum === 0) {
+        minOps = Math.min(minOps, (evenTotal - evenCount) + (oddTotal - oddCount));
+      }
+    }
+  }
+
+  return minOps === nums.length ? Math.min(evenTotal, oddTotal) : minOps;
+};
diff --git a/solutions/2171-removing-minimum-number-of-magic-beans.js b/solutions/2171-removing-minimum-number-of-magic-beans.js
new file mode 100644
index 00000000..23fd2236
--- /dev/null
+++ b/solutions/2171-removing-minimum-number-of-magic-beans.js
@@ -0,0 +1,33 @@
+/**
+ * 2171. Removing Minimum Number of Magic Beans
+ * https://leetcode.com/problems/removing-minimum-number-of-magic-beans/
+ * Difficulty: Medium
+ *
+ * You are given an array of positive integers beans, where each integer represents the number
+ * of magic beans found in a particular magic bag.
+ *
+ * Remove any number of beans (possibly none) from each bag such that the number of beans in
+ * each remaining non-empty bag (still containing at least one bean) is equal. Once a bean
+ * has been removed from a bag, you are not allowed to return it to any of the bags.
+ *
+ * Return the minimum number of magic beans that you have to remove.
+ */
+
+/**
+ * @param {number[]} beans
+ * @return {number}
+ */
+var minimumRemoval = function(beans) {
+  const sortedBeans = beans.sort((a, b) => a - b);
+  const totalBeans = sortedBeans.reduce((sum, bean) => sum + bean, 0);
+  let result = totalBeans;
+  let remaining = totalBeans;
+
+  for (let i = 0; i < sortedBeans.length; i++) {
+    remaining -= sortedBeans[i];
+    const equalBags = sortedBeans.length - i;
+    result = Math.min(result, totalBeans - sortedBeans[i] * equalBags);
+  }
+
+  return result;
+};
diff --git a/solutions/2172-maximum-and-sum-of-array.js b/solutions/2172-maximum-and-sum-of-array.js
new file mode 100644
index 00000000..6c9020d6
--- /dev/null
+++ b/solutions/2172-maximum-and-sum-of-array.js
@@ -0,0 +1,46 @@
+/**
+ * 2172. Maximum AND Sum of Array
+ * https://leetcode.com/problems/maximum-and-sum-of-array/
+ * Difficulty: Hard
+ *
+ * You are given an integer array nums of length n and an integer numSlots such that
+ * 2 * numSlots >= n. There are numSlots slots numbered from 1 to numSlots.
+ *
+ * You have to place all n integers into the slots such that each slot contains at most
+ * two numbers. The AND sum of a given placement is the sum of the bitwise AND of every
+ * number with its respective slot number.
+ * - For example, the AND sum of placing the numbers [1, 3] into slot 1 and [4, 6] into
+ *   slot 2 is equal to (1 AND 1) + (3 AND 1) + (4 AND 2) + (6 AND 2) = 1 + 1 + 0 + 2 = 4.
+ *
+ * Return the maximum possible AND sum of nums given numSlots slots.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} numSlots
+ * @return {number}
+ */
+var maximumANDSum = function(nums, numSlots) {
+  const map = new Map();
+
+  return dp(0, new Array(numSlots).fill(0));
+
+  function dp(index, slots) {
+    if (index >= nums.length) return 0;
+
+    const key = `${index},${slots.join(',')}`;
+    if (map.has(key)) return map.get(key);
+
+    let result = 0;
+    for (let i = 0; i < numSlots; i++) {
+      if (slots[i] < 2) {
+        slots[i]++;
+        result = Math.max(result, (nums[index] & (i + 1)) + dp(index + 1, slots));
+        slots[i]--;
+      }
+    }
+
+    map.set(key, result);
+    return result;
+  }
+};
diff --git a/solutions/2177-find-three-consecutive-integers-that-sum-to-a-given-number.js b/solutions/2177-find-three-consecutive-integers-that-sum-to-a-given-number.js
new file mode 100644
index 00000000..f77b1221
--- /dev/null
+++ b/solutions/2177-find-three-consecutive-integers-that-sum-to-a-given-number.js
@@ -0,0 +1,19 @@
+/**
+ * 2177. Find Three Consecutive Integers That Sum to a Given Number
+ * https://leetcode.com/problems/find-three-consecutive-integers-that-sum-to-a-given-number/
+ * Difficulty: Medium
+ *
+ * Given an integer num, return three consecutive integers (as a sorted array) that sum to num.
+ * If num cannot be expressed as the sum of three consecutive integers, return an empty array.
+ */
+
+/**
+ * @param {number} num
+ * @return {number[]}
+ */
+var sumOfThree = function(num) {
+  if (num % 3 !== 0) return [];
+
+  const middle = num / 3;
+  return [middle - 1, middle, middle + 1];
+};
diff --git a/solutions/2178-maximum-split-of-positive-even-integers.js b/solutions/2178-maximum-split-of-positive-even-integers.js
new file mode 100644
index 00000000..602b2ab7
--- /dev/null
+++ b/solutions/2178-maximum-split-of-positive-even-integers.js
@@ -0,0 +1,40 @@
+/**
+ * 2178. Maximum Split of Positive Even Integers
+ * https://leetcode.com/problems/maximum-split-of-positive-even-integers/
+ * Difficulty: Medium
+ *
+ * You are given an integer finalSum. Split it into a sum of a maximum number of unique
+ * positive even integers.
+ * - For example, given finalSum = 12, the following splits are valid (unique positive even
+ *   integers summing up to finalSum): (12), (2 + 10), (2 + 4 + 6), and (4 + 8). Among them,
+ *   (2 + 4 + 6) contains the maximum number of integers. Note that finalSum cannot be split
+ *   into (2 + 2 + 4 + 4) as all the numbers should be unique.
+ *
+ * Return a list of integers that represent a valid split containing a maximum number of
+ * integers. If no valid split exists for finalSum, return an empty list. You may return
+ * the integers in any order.
+ */
+
+/**
+ * @param {number} finalSum
+ * @return {number[]}
+ */
+var maximumEvenSplit = function(finalSum) {
+  if (finalSum % 2 !== 0) return [];
+
+  const result = [];
+  let current = 2;
+  let remaining = finalSum;
+
+  while (remaining >= current) {
+    if (remaining - current <= current) {
+      result.push(remaining);
+      return result;
+    }
+    result.push(current);
+    remaining -= current;
+    current += 2;
+  }
+
+  return result;
+};
diff --git a/solutions/2180-count-integers-with-even-digit-sum.js b/solutions/2180-count-integers-with-even-digit-sum.js
new file mode 100644
index 00000000..c1a077e6
--- /dev/null
+++ b/solutions/2180-count-integers-with-even-digit-sum.js
@@ -0,0 +1,32 @@
+/**
+ * 2180. Count Integers With Even Digit Sum
+ * https://leetcode.com/problems/count-integers-with-even-digit-sum/
+ * Difficulty: Easy
+ *
+ * Given a positive integer num, return the number of positive integers less than or equal to num
+ * whose digit sums are even.
+ *
+ * The digit sum of a positive integer is the sum of all its digits.
+ */
+
+/**
+ * @param {number} num
+ * @return {number}
+ */
+var countEven = function(num) {
+  let result = 0;
+
+  for (let i = 1; i <= num; i++) {
+    let sum = 0;
+    let current = i;
+    while (current > 0) {
+      sum += current % 10;
+      current = Math.floor(current / 10);
+    }
+    if (sum % 2 === 0) {
+      result++;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2181-merge-nodes-in-between-zeros.js b/solutions/2181-merge-nodes-in-between-zeros.js
new file mode 100644
index 00000000..f5993c27
--- /dev/null
+++ b/solutions/2181-merge-nodes-in-between-zeros.js
@@ -0,0 +1,46 @@
+/**
+ * 2181. Merge Nodes in Between Zeros
+ * https://leetcode.com/problems/merge-nodes-in-between-zeros/
+ * Difficulty: Medium
+ *
+ * You are given the head of a linked list, which contains a series of integers separated
+ * by 0's. The beginning and end of the linked list will have Node.val == 0.
+ *
+ * For every two consecutive 0's, merge all the nodes lying in between them into a single
+ * node whose value is the sum of all the merged nodes. The modified list should not contain
+ * any 0's.
+ *
+ * Return the head of the modified linked list.
+ */
+
+/**
+ * Definition for singly-linked list.
+ * function ListNode(val, next) {
+ *     this.val = (val===undefined ? 0 : val)
+ *     this.next = (next===undefined ? null : next)
+ * }
+ */
+/**
+ * @param {ListNode} head
+ * @return {ListNode}
+ */
+var mergeNodes = function(head) {
+  const result = new ListNode(0);
+  let current = result;
+  let sum = 0;
+
+  head = head.next;
+
+  while (head) {
+    if (head.val === 0) {
+      current.next = new ListNode(sum);
+      current = current.next;
+      sum = 0;
+    } else {
+      sum += head.val;
+    }
+    head = head.next;
+  }
+
+  return result.next;
+};
diff --git a/solutions/2183-count-array-pairs-divisible-by-k.js b/solutions/2183-count-array-pairs-divisible-by-k.js
new file mode 100644
index 00000000..96f923c4
--- /dev/null
+++ b/solutions/2183-count-array-pairs-divisible-by-k.js
@@ -0,0 +1,39 @@
+/**
+ * 2183. Count Array Pairs Divisible by K
+ * https://leetcode.com/problems/count-array-pairs-divisible-by-k/
+ * Difficulty: Hard
+ *
+ * Given a 0-indexed integer array nums of length n and an integer k, return the number
+ * of pairs (i, j) such that:
+ * - 0 <= i < j <= n - 1 and
+ * - nums[i] * nums[j] is divisible by k.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @return {number}
+ */
+var countPairs = function(nums, k) {
+  const map = new Map();
+  let pairs = 0;
+
+  for (const num of nums) {
+    const gcd1 = gcd(num, k);
+    for (const [gcd2, count] of map) {
+      if ((gcd1 * gcd2) % k === 0) {
+        pairs += count;
+      }
+    }
+    map.set(gcd1, (map.get(gcd1) || 0) + 1);
+  }
+
+  return pairs;
+};
+
+function gcd(a, b) {
+  while (b) {
+    [a, b] = [b, a % b];
+  }
+  return a;
+}
diff --git a/solutions/2186-minimum-number-of-steps-to-make-two-strings-anagram-ii.js b/solutions/2186-minimum-number-of-steps-to-make-two-strings-anagram-ii.js
new file mode 100644
index 00000000..2501cbd5
--- /dev/null
+++ b/solutions/2186-minimum-number-of-steps-to-make-two-strings-anagram-ii.js
@@ -0,0 +1,36 @@
+/**
+ * 2186. Minimum Number of Steps to Make Two Strings Anagram II
+ * https://leetcode.com/problems/minimum-number-of-steps-to-make-two-strings-anagram-ii/
+ * Difficulty: Medium
+ *
+ * You are given two strings s and t. In one step, you can append any character to either s or t.
+ *
+ * Return the minimum number of steps to make s and t anagrams of each other.
+ *
+ * An anagram of a string is a string that contains the same characters with a different (or the
+ * same) ordering.
+ */
+
+/**
+ * @param {string} s
+ * @param {string} t
+ * @return {number}
+ */
+var minSteps = function(s, t) {
+  const charCount = new Array(26).fill(0);
+
+  for (const char of s) {
+    charCount[char.charCodeAt(0) - 97]++;
+  }
+
+  for (const char of t) {
+    charCount[char.charCodeAt(0) - 97]--;
+  }
+
+  let result = 0;
+  for (const count of charCount) {
+    result += Math.abs(count);
+  }
+
+  return result;
+};
diff --git a/solutions/2187-minimum-time-to-complete-trips.js b/solutions/2187-minimum-time-to-complete-trips.js
new file mode 100644
index 00000000..305712f8
--- /dev/null
+++ b/solutions/2187-minimum-time-to-complete-trips.js
@@ -0,0 +1,39 @@
+/**
+ * 2187. Minimum Time to Complete Trips
+ * https://leetcode.com/problems/minimum-time-to-complete-trips/
+ * Difficulty: Medium
+ *
+ * You are given an array time where time[i] denotes the time taken by the ith bus to complete
+ * one trip.
+ *
+ * Each bus can make multiple trips successively; that is, the next trip can start immediately
+ * after completing the current trip. Also, each bus operates independently; that is, the trips
+ * of one bus do not influence the trips of any other bus.
+ *
+ * You are also given an integer totalTrips, which denotes the number of trips all buses should
+ * make in total. Return the minimum time required for all buses to complete at least totalTrips
+ * trips.
+ */
+
+/**
+ * @param {number[]} time
+ * @param {number} totalTrips
+ * @return {number}
+ */
+var minimumTime = function(time, totalTrips) {
+  let left = 1;
+  let right = Math.min(...time) * totalTrips;
+
+  while (left < right) {
+    const mid = Math.floor((left + right) / 2);
+    const trips = time.reduce((sum, t) => sum + Math.floor(mid / t), 0);
+
+    if (trips >= totalTrips) {
+      right = mid;
+    } else {
+      left = mid + 1;
+    }
+  }
+
+  return left;
+};
diff --git a/solutions/2188-minimum-time-to-finish-the-race.js b/solutions/2188-minimum-time-to-finish-the-race.js
new file mode 100644
index 00000000..fbce3d25
--- /dev/null
+++ b/solutions/2188-minimum-time-to-finish-the-race.js
@@ -0,0 +1,56 @@
+/**
+ * 2188. Minimum Time to Finish the Race
+ * https://leetcode.com/problems/minimum-time-to-finish-the-race/
+ * Difficulty: Hard
+ *
+ * You are given a 0-indexed 2D integer array tires where tires[i] = [fi, ri] indicates that
+ * the ith tire can finish its xth successive lap in fi * ri(x-1) seconds.
+ * - For example, if fi = 3 and ri = 2, then the tire would finish its 1st lap in 3 seconds,
+ *   its 2nd lap in 3 * 2 = 6 seconds, its 3rd lap in 3 * 22 = 12 seconds, etc.
+ *
+ * You are also given an integer changeTime and an integer numLaps.
+ *
+ * The race consists of numLaps laps and you may start the race with any tire. You have an
+ * unlimited supply of each tire and after every lap, you may change to any given tire (including
+ * the current tire type) if you wait changeTime seconds.
+ *
+ * Return the minimum time to finish the race.
+ */
+
+/**
+ * @param {number[][]} tires
+ * @param {number} changeTime
+ * @param {number} numLaps
+ * @return {number}
+ */
+var minimumFinishTime = function(tires, changeTime, numLaps) {
+  const minTimes = new Array(18).fill(Infinity);
+  const bestTime = new Array(numLaps + 1).fill(Infinity);
+
+  for (const [baseTime, multiplier] of tires) {
+    let currentTime = baseTime;
+    let totalTime = baseTime;
+
+    for (let lap = 1; lap <= Math.min(numLaps, 17); lap++) {
+      if (currentTime > changeTime + baseTime) break;
+      minTimes[lap] = Math.min(minTimes[lap], totalTime);
+      currentTime *= multiplier;
+      totalTime += currentTime;
+    }
+  }
+
+  bestTime[0] = 0;
+
+  for (let lap = 1; lap <= numLaps; lap++) {
+    for (let prev = 1; prev <= Math.min(lap, 17); prev++) {
+      if (minTimes[prev] !== Infinity) {
+        bestTime[lap] = Math.min(
+          bestTime[lap],
+          bestTime[lap - prev] + minTimes[prev] + (lap === prev ? 0 : changeTime)
+        );
+      }
+    }
+  }
+
+  return bestTime[numLaps];
+};
diff --git a/solutions/2190-most-frequent-number-following-key-in-an-array.js b/solutions/2190-most-frequent-number-following-key-in-an-array.js
new file mode 100644
index 00000000..b5485503
--- /dev/null
+++ b/solutions/2190-most-frequent-number-following-key-in-an-array.js
@@ -0,0 +1,43 @@
+/**
+ * 2190. Most Frequent Number Following Key In an Array
+ * https://leetcode.com/problems/most-frequent-number-following-key-in-an-array/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed integer array nums. You are also given an integer key, which is
+ * present in nums.
+ *
+ * For every unique integer target in nums, count the number of times target immediately follows
+ * an occurrence of key in nums. In other words, count the number of indices i such that:
+ * - 0 <= i <= nums.length - 2,
+ * - nums[i] == key and,
+ * - nums[i + 1] == target.
+ *
+ * Return the target with the maximum count. The test cases will be generated such that the target
+ * with maximum count is unique.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} key
+ * @return {number}
+ */
+var mostFrequent = function(nums, key) {
+  const frequency = new Map();
+  let maxCount = 0;
+  let result = 0;
+
+  for (let i = 0; i < nums.length - 1; i++) {
+    if (nums[i] === key) {
+      const target = nums[i + 1];
+      const count = (frequency.get(target) || 0) + 1;
+      frequency.set(target, count);
+
+      if (count > maxCount) {
+        maxCount = count;
+        result = target;
+      }
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2191-sort-the-jumbled-numbers.js b/solutions/2191-sort-the-jumbled-numbers.js
new file mode 100644
index 00000000..490e1d17
--- /dev/null
+++ b/solutions/2191-sort-the-jumbled-numbers.js
@@ -0,0 +1,53 @@
+/**
+ * 2191. Sort the Jumbled Numbers
+ * https://leetcode.com/problems/sort-the-jumbled-numbers/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed integer array mapping which represents the mapping rule of a shuffled
+ * decimal system. mapping[i] = j means digit i should be mapped to digit j in this system.
+ *
+ * The mapped value of an integer is the new integer obtained by replacing each occurrence of digit
+ * i in the integer with mapping[i] for all 0 <= i <= 9.
+ *
+ * You are also given another integer array nums. Return the array nums sorted in non-decreasing
+ * order based on the mapped values of its elements.
+ *
+ * Notes:
+ * - Elements with the same mapped values should appear in the same relative order as in the input.
+ * - The elements of nums should only be sorted based on their mapped values and not be replaced by
+ *   them.
+ */
+
+/**
+ * @param {number[]} mapping
+ * @param {number[]} nums
+ * @return {number[]}
+ */
+var sortJumbled = function(mapping, nums) {
+  const mapped = nums.map((num, index) => {
+    let mappedNum = 0;
+    let temp = num;
+
+    if (temp === 0) {
+      mappedNum = mapping[0];
+    } else {
+      const digits = [];
+      while (temp > 0) {
+        digits.push(mapping[temp % 10]);
+        temp = Math.floor(temp / 10);
+      }
+      while (digits.length > 0) {
+        mappedNum = mappedNum * 10 + digits.pop();
+      }
+    }
+
+    return { original: num, mapped: mappedNum, index };
+  });
+
+  mapped.sort((a, b) => {
+    if (a.mapped === b.mapped) return a.index - b.index;
+    return a.mapped - b.mapped;
+  });
+
+  return mapped.map(item => item.original);
+};
diff --git a/solutions/2192-all-ancestors-of-a-node-in-a-directed-acyclic-graph.js b/solutions/2192-all-ancestors-of-a-node-in-a-directed-acyclic-graph.js
new file mode 100644
index 00000000..9eeb8509
--- /dev/null
+++ b/solutions/2192-all-ancestors-of-a-node-in-a-directed-acyclic-graph.js
@@ -0,0 +1,48 @@
+/**
+ * 2192. All Ancestors of a Node in a Directed Acyclic Graph
+ * https://leetcode.com/problems/all-ancestors-of-a-node-in-a-directed-acyclic-graph/
+ * Difficulty: Medium
+ *
+ * You are given a positive integer n representing the number of nodes of a Directed Acyclic
+ * Graph (DAG). The nodes are numbered from 0 to n - 1 (inclusive).
+ *
+ * You are also given a 2D integer array edges, where edges[i] = [fromi, toi] denotes that there
+ * is a unidirectional edge from fromi to toi in the graph.
+ *
+ * Return a list answer, where answer[i] is the list of ancestors of the ith node, sorted in
+ * ascending order.
+ *
+ * A node u is an ancestor of another node v if u can reach v via a set of edges.
+ */
+
+/**
+ * @param {number} n
+ * @param {number[][]} edges
+ * @return {number[][]}
+ */
+var getAncestors = function(n, edges) {
+  const graph = Array.from({ length: n }, () => []);
+  const ancestors = Array.from({ length: n }, () => new Set());
+
+  for (const [from, to] of edges) {
+    graph[to].push(from);
+  }
+
+  for (let i = 0; i < n; i++) {
+    findAncestors(i);
+  }
+
+  return ancestors.map(set => [...set].sort((a, b) => a - b));
+
+  function findAncestors(node) {
+    if (ancestors[node].size > 0) return;
+
+    for (const parent of graph[node]) {
+      ancestors[node].add(parent);
+      findAncestors(parent);
+      for (const ancestor of ancestors[parent]) {
+        ancestors[node].add(ancestor);
+      }
+    }
+  }
+};
diff --git a/solutions/2193-minimum-number-of-moves-to-make-palindrome.js b/solutions/2193-minimum-number-of-moves-to-make-palindrome.js
new file mode 100644
index 00000000..c25800e2
--- /dev/null
+++ b/solutions/2193-minimum-number-of-moves-to-make-palindrome.js
@@ -0,0 +1,42 @@
+/**
+ * 2193. Minimum Number of Moves to Make Palindrome
+ * https://leetcode.com/problems/minimum-number-of-moves-to-make-palindrome/
+ * Difficulty: Hard
+ *
+ * You are given a string s consisting only of lowercase English letters.
+ *
+ * In one move, you can select any two adjacent characters of s and swap them.
+ *
+ * Return the minimum number of moves needed to make s a palindrome.
+ *
+ * Note that the input will be generated such that s can always be converted to a palindrome.
+ */
+
+/**
+* @param {string} s
+* @return {number}
+*/
+var minMovesToMakePalindrome = function(s) {
+  const chars = s.split('');
+  let moves = 0;
+
+  while (chars.length > 1) {
+    const matchIndex = chars.lastIndexOf(chars[0]);
+
+    if (matchIndex === 0) {
+      const middlePos = Math.floor(chars.length / 2);
+      moves += middlePos;
+      chars.splice(0, 1);
+    } else {
+      for (let i = matchIndex; i < chars.length - 1; i++) {
+        [chars[i], chars[i + 1]] = [chars[i + 1], chars[i]];
+        moves++;
+      }
+
+      chars.pop();
+      chars.shift();
+    }
+  }
+
+  return moves;
+};
diff --git a/solutions/2194-cells-in-a-range-on-an-excel-sheet.js b/solutions/2194-cells-in-a-range-on-an-excel-sheet.js
new file mode 100644
index 00000000..194c60cc
--- /dev/null
+++ b/solutions/2194-cells-in-a-range-on-an-excel-sheet.js
@@ -0,0 +1,37 @@
+/**
+ * 2194. Cells in a Range on an Excel Sheet
+ * https://leetcode.com/problems/cells-in-a-range-on-an-excel-sheet/
+ * Difficulty: Easy
+ *
+ * A cell (r, c) of an excel sheet is represented as a string "" where:
+ * -  denotes the column number c of the cell. It is represented by alphabetical letters.
+ *   - For example, the 1st column is denoted by 'A', the 2nd by 'B', the 3rd by 'C', and so on.
+ * -  is the row number r of the cell. The rth row is represented by the integer r.
+ *   - You are given a string s in the format ":", where  represents
+ *     the column c1,  represents the row r1,  represents the column c2, and 
+ *     represents the row r2, such that r1 <= r2 and c1 <= c2.
+ *
+ * Return the list of cells (x, y) such that r1 <= x <= r2 and c1 <= y <= c2. The cells should
+ * be represented as strings in the format mentioned above and be sorted in non-decreasing order
+ * first by columns and then by rows.
+ */
+
+/**
+ * @param {string} s
+ * @return {string[]}
+ */
+var cellsInRange = function(s) {
+  const result = [];
+  const startCol = s.charCodeAt(0);
+  const endCol = s.charCodeAt(3);
+  const startRow = parseInt(s[1], 10);
+  const endRow = parseInt(s[4], 10);
+
+  for (let col = startCol; col <= endCol; col++) {
+    for (let row = startRow; row <= endRow; row++) {
+      result.push(String.fromCharCode(col) + row);
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2195-append-k-integers-with-minimal-sum.js b/solutions/2195-append-k-integers-with-minimal-sum.js
new file mode 100644
index 00000000..bc873455
--- /dev/null
+++ b/solutions/2195-append-k-integers-with-minimal-sum.js
@@ -0,0 +1,40 @@
+/**
+ * 2195. Append K Integers With Minimal Sum
+ * https://leetcode.com/problems/append-k-integers-with-minimal-sum/
+ * Difficulty: Medium
+ *
+ * You are given an integer array nums and an integer k. Append k unique positive integers that do
+ * not appear in nums to nums such that the resulting total sum is minimum.
+ *
+ * Return the sum of the k integers appended to nums.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @return {number}
+ */
+var minimalKSum = function(nums, k) {
+  const sortedUnique = [...new Set(nums)].sort((a, b) => a - b);
+  let sum = BigInt(0);
+  let current = 1;
+  let i = 0;
+
+  while (k > 0 && i < sortedUnique.length) {
+    if (current < sortedUnique[i]) {
+      const count = Math.min(k, sortedUnique[i] - current);
+      sum += (BigInt(current) + BigInt(current + count - 1)) * BigInt(count) / BigInt(2);
+      k -= count;
+      current += count;
+    } else {
+      current = sortedUnique[i] + 1;
+      i++;
+    }
+  }
+
+  if (k > 0) {
+    sum += (BigInt(current) + BigInt(current + k - 1)) * BigInt(k) / BigInt(2);
+  }
+
+  return Number(sum);
+};
diff --git a/solutions/2196-create-binary-tree-from-descriptions.js b/solutions/2196-create-binary-tree-from-descriptions.js
new file mode 100644
index 00000000..67af6416
--- /dev/null
+++ b/solutions/2196-create-binary-tree-from-descriptions.js
@@ -0,0 +1,54 @@
+/**
+ * 2196. Create Binary Tree From Descriptions
+ * https://leetcode.com/problems/create-binary-tree-from-descriptions/
+ * Difficulty: Medium
+ *
+ * You are given a 2D integer array descriptions where descriptions[i] = [parenti, childi, isLefti]
+ * indicates that parenti is the parent of childi in a binary tree of unique values. Furthermore,
+ * - If isLefti == 1, then childi is the left child of parenti.
+ * - If isLefti == 0, then childi is the right child of parenti.
+ *
+ * Construct the binary tree described by descriptions and return its root.
+ *
+ * The test cases will be generated such that the binary tree is valid.
+ */
+
+/**
+ * Definition for a binary tree node.
+ * function TreeNode(val, left, right) {
+ *     this.val = (val===undefined ? 0 : val)
+ *     this.left = (left===undefined ? null : left)
+ *     this.right = (right===undefined ? null : right)
+ * }
+ */
+/**
+ * @param {number[][]} descriptions
+ * @return {TreeNode}
+ */
+var createBinaryTree = function(descriptions) {
+  const nodes = new Map();
+  const children = new Set();
+
+  for (const [parent, child, isLeft] of descriptions) {
+    if (!nodes.has(parent)) {
+      nodes.set(parent, new TreeNode(parent));
+    }
+    if (!nodes.has(child)) {
+      nodes.set(child, new TreeNode(child));
+    }
+    children.add(child);
+    if (isLeft) {
+      nodes.get(parent).left = nodes.get(child);
+    } else {
+      nodes.get(parent).right = nodes.get(child);
+    }
+  }
+
+  for (const [val, node] of nodes) {
+    if (!children.has(val)) {
+      return node;
+    }
+  }
+
+  return null;
+};
diff --git a/solutions/2197-replace-non-coprime-numbers-in-array.js b/solutions/2197-replace-non-coprime-numbers-in-array.js
new file mode 100644
index 00000000..2bc8e2d5
--- /dev/null
+++ b/solutions/2197-replace-non-coprime-numbers-in-array.js
@@ -0,0 +1,48 @@
+/**
+ * 2197. Replace Non-Coprime Numbers in Array
+ * https://leetcode.com/problems/replace-non-coprime-numbers-in-array/
+ * Difficulty: Hard
+ *
+ * You are given an array of integers nums. Perform the following steps:
+ * 1. Find any two adjacent numbers in nums that are non-coprime.
+ * 2. If no such numbers are found, stop the process.
+ * 3. Otherwise, delete the two numbers and replace them with their LCM (Least Common Multiple).
+ * 4. Repeat this process as long as you keep finding two adjacent non-coprime numbers.
+ *
+ * Return the final modified array. It can be shown that replacing adjacent non-coprime numbers in
+ * any arbitrary order will lead to the same result.
+ *
+ * The test cases are generated such that the values in the final array are less than or equal to
+ * 108.
+ *
+ * Two values x and y are non-coprime if GCD(x, y) > 1 where GCD(x, y) is the Greatest Common
+ * Divisor of x and y.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number[]}
+ */
+var replaceNonCoprimes = function(nums) {
+  const result = [];
+
+  for (let num of nums) {
+    while (result.length > 0) {
+      const last = result[result.length - 1];
+      const gcdValue = gcd(last, num);
+      if (gcdValue === 1) break;
+      result.pop();
+      num = (last / gcdValue) * num;
+    }
+    result.push(num);
+  }
+
+  return result;
+};
+
+function gcd(a, b) {
+  while (b) {
+    [a, b] = [b, a % b];
+  }
+  return a;
+}
diff --git a/solutions/2200-find-all-k-distant-indices-in-an-array.js b/solutions/2200-find-all-k-distant-indices-in-an-array.js
new file mode 100644
index 00000000..5a2cd1bd
--- /dev/null
+++ b/solutions/2200-find-all-k-distant-indices-in-an-array.js
@@ -0,0 +1,31 @@
+/**
+ * 2200. Find All K-Distant Indices in an Array
+ * https://leetcode.com/problems/find-all-k-distant-indices-in-an-array/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed integer array nums and two integers key and k. A k-distant index
+ * is an index i of nums for which there exists at least one index j such that |i - j| <= k
+ * and nums[j] == key.
+ *
+ * Return a list of all k-distant indices sorted in increasing order.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} key
+ * @param {number} k
+ * @return {number[]}
+ */
+var findKDistantIndices = function(nums, key, k) {
+  const result = new Set();
+
+  for (let j = 0; j < nums.length; j++) {
+    if (nums[j] === key) {
+      for (let i = Math.max(0, j - k); i <= Math.min(nums.length - 1, j + k); i++) {
+        result.add(i);
+      }
+    }
+  }
+
+  return [...result].sort((a, b) => a - b);
+};
diff --git a/solutions/2201-count-artifacts-that-can-be-extracted.js b/solutions/2201-count-artifacts-that-can-be-extracted.js
new file mode 100644
index 00000000..cd5f5627
--- /dev/null
+++ b/solutions/2201-count-artifacts-that-can-be-extracted.js
@@ -0,0 +1,57 @@
+/**
+ * 2201. Count Artifacts That Can Be Extracted
+ * https://leetcode.com/problems/count-artifacts-that-can-be-extracted/
+ * Difficulty: Medium
+ *
+ * There is an n x n 0-indexed grid with some artifacts buried in it. You are given the integer
+ * n and a 0-indexed 2D integer array artifacts describing the positions of the rectangular
+ * artifacts where artifacts[i] = [r1i, c1i, r2i, c2i] denotes that the ith artifact is buried
+ * in the subgrid where:
+ * - (r1i, c1i) is the coordinate of the top-left cell of the ith artifact and
+ * - (r2i, c2i) is the coordinate of the bottom-right cell of the ith artifact.
+ *
+ * You will excavate some cells of the grid and remove all the mud from them. If the cell has a
+ * part of an artifact buried underneath, it will be uncovered. If all the parts of an artifact
+ * are uncovered, you can extract it.
+ *
+ * Given a 0-indexed 2D integer array dig where dig[i] = [ri, ci] indicates that you will excavate
+ * the cell (ri, ci), return the number of artifacts that you can extract.
+ *
+ * The test cases are generated such that:
+ * - No two artifacts overlap.
+ * - Each artifact only covers at most 4 cells.
+ * - The entries of dig are unique.
+ */
+
+/**
+ * @param {number} n
+ * @param {number[][]} artifacts
+ * @param {number[][]} dig
+ * @return {number}
+ */
+var digArtifacts = function(n, artifacts, dig) {
+  const excavated = new Set();
+  let result = 0;
+
+  for (const [row, col] of dig) {
+    excavated.add(`${row},${col}`);
+  }
+
+  for (const [r1, c1, r2, c2] of artifacts) {
+    let allUncovered = true;
+
+    for (let r = r1; r <= r2; r++) {
+      for (let c = c1; c <= c2; c++) {
+        if (!excavated.has(`${r},${c}`)) {
+          allUncovered = false;
+          break;
+        }
+      }
+      if (!allUncovered) break;
+    }
+
+    if (allUncovered) result++;
+  }
+
+  return result;
+};
diff --git a/solutions/2202-maximize-the-topmost-element-after-k-moves.js b/solutions/2202-maximize-the-topmost-element-after-k-moves.js
new file mode 100644
index 00000000..8b1554b2
--- /dev/null
+++ b/solutions/2202-maximize-the-topmost-element-after-k-moves.js
@@ -0,0 +1,42 @@
+/**
+ * 2202. Maximize the Topmost Element After K Moves
+ * https://leetcode.com/problems/maximize-the-topmost-element-after-k-moves/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed integer array nums representing the contents of a pile, where nums[0]
+ * is the topmost element of the pile.
+ *
+ * In one move, you can perform either of the following:
+ * - If the pile is not empty, remove the topmost element of the pile.
+ * - If there are one or more removed elements, add any one of them back onto the pile. This element
+ *   becomes the new topmost element.
+ *
+ * You are also given an integer k, which denotes the total number of moves to be made.
+ *
+ * Return the maximum value of the topmost element of the pile possible after exactly k moves. In
+ * case it is not possible to obtain a non-empty pile after k moves, return -1.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @return {number}
+ */
+var maximumTop = function(nums, k) {
+  const n = nums.length;
+
+  if (n === 1 && k % 2 === 1) return -1;
+  if (k === 0) return nums[0];
+  if (k === 1) return n > 1 ? nums[1] : -1;
+
+  let result = 0;
+  for (let i = 0; i < Math.min(k - 1, n); i++) {
+    result = Math.max(result, nums[i]);
+  }
+
+  if (k < n) {
+    result = Math.max(result, nums[k]);
+  }
+
+  return result;
+};
diff --git a/solutions/2203-minimum-weighted-subgraph-with-the-required-paths.js b/solutions/2203-minimum-weighted-subgraph-with-the-required-paths.js
new file mode 100644
index 00000000..4ace48ff
--- /dev/null
+++ b/solutions/2203-minimum-weighted-subgraph-with-the-required-paths.js
@@ -0,0 +1,73 @@
+/**
+ * 2203. Minimum Weighted Subgraph With the Required Paths
+ * https://leetcode.com/problems/minimum-weighted-subgraph-with-the-required-paths/
+ * Difficulty: Hard
+ *
+ * You are given an integer n denoting the number of nodes of a weighted directed graph. The nodes
+ * are numbered from 0 to n - 1.
+ *
+ * You are also given a 2D integer array edges where edges[i] = [fromi, toi, weighti] denotes that
+ * there exists a directed edge from fromi to toi with weight weighti.
+ *
+ * Lastly, you are given three distinct integers src1, src2, and dest denoting three distinct nodes
+ * of the graph.
+ *
+ * Return the minimum weight of a subgraph of the graph such that it is possible to reach dest from
+ * both src1 and src2 via a set of edges of this subgraph. In case such a subgraph does not exist,
+ * return -1.
+ *
+ * A subgraph is a graph whose vertices and edges are subsets of the original graph. The weight of
+ * a subgraph is the sum of weights of its constituent edges.
+ */
+
+/**
+ * @param {number} n
+ * @param {number[][]} edges
+ * @param {number} src1
+ * @param {number} src2
+ * @param {number} dest
+ * @return {number}
+ */
+var minimumWeight = function(n, edges, src1, src2, dest) {
+  const forwardGraph = Array.from({ length: n }, () => []);
+  const reverseGraph = Array.from({ length: n }, () => []);
+
+  for (const [from, to, weight] of edges) {
+    forwardGraph[from].push([to, weight]);
+    reverseGraph[to].push([from, weight]);
+  }
+
+  const distFromSrc1 = dijkstra(forwardGraph, src1);
+  const distFromSrc2 = dijkstra(forwardGraph, src2);
+  const distToDest = dijkstra(reverseGraph, dest);
+  let minWeight = Infinity;
+  for (let i = 0; i < n; i++) {
+    if (distFromSrc1[i] !== Infinity && distFromSrc2[i] !== Infinity
+        && distToDest[i] !== Infinity) {
+      minWeight = Math.min(minWeight, distFromSrc1[i] + distFromSrc2[i] + distToDest[i]);
+    }
+  }
+
+  return minWeight === Infinity ? -1 : minWeight;
+
+  function dijkstra(graph, start) {
+    const distances = new Array(n).fill(Infinity);
+    distances[start] = 0;
+    const pq = new PriorityQueue((a, b) => a[0] - b[0]);
+    pq.enqueue([0, start]);
+
+    while (!pq.isEmpty()) {
+      const [dist, node] = pq.dequeue();
+      if (dist > distances[node]) continue;
+
+      for (const [next, weight] of graph[node]) {
+        if (distances[next] > dist + weight) {
+          distances[next] = dist + weight;
+          pq.enqueue([distances[next], next]);
+        }
+      }
+    }
+
+    return distances;
+  }
+};
diff --git a/solutions/2207-maximize-number-of-subsequences-in-a-string.js b/solutions/2207-maximize-number-of-subsequences-in-a-string.js
new file mode 100644
index 00000000..d7ad35a6
--- /dev/null
+++ b/solutions/2207-maximize-number-of-subsequences-in-a-string.js
@@ -0,0 +1,41 @@
+/**
+ * 2207. Maximize Number of Subsequences in a String
+ * https://leetcode.com/problems/maximize-number-of-subsequences-in-a-string/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed string text and another 0-indexed string pattern of length 2, both
+ * of which consist of only lowercase English letters.
+ *
+ * You can add either pattern[0] or pattern[1] anywhere in text exactly once. Note that the
+ * character can be added even at the beginning or at the end of text.
+ *
+ * Return the maximum number of times pattern can occur as a subsequence of the modified text.
+ *
+ * A subsequence is a string that can be derived from another string by deleting some or no
+ * characters without changing the order of the remaining characters.
+ */
+
+/**
+ * @param {string} text
+ * @param {string} pattern
+ * @return {number}
+ */
+var maximumSubsequenceCount = function(text, pattern) {
+  const firstChar = pattern[0];
+  const secondChar = pattern[1];
+  let firstCount = 0;
+  let secondCount = 0;
+  let subsequences = 0;
+
+  for (const char of text) {
+    if (char === secondChar) {
+      subsequences += firstCount;
+      secondCount++;
+    }
+    if (char === firstChar) {
+      firstCount++;
+    }
+  }
+
+  return subsequences + Math.max(firstCount, secondCount);
+};
diff --git a/solutions/2209-minimum-white-tiles-after-covering-with-carpets.js b/solutions/2209-minimum-white-tiles-after-covering-with-carpets.js
new file mode 100644
index 00000000..08fb5fd3
--- /dev/null
+++ b/solutions/2209-minimum-white-tiles-after-covering-with-carpets.js
@@ -0,0 +1,36 @@
+/**
+ * 2209. Minimum White Tiles After Covering With Carpets
+ * https://leetcode.com/problems/minimum-white-tiles-after-covering-with-carpets/
+ * Difficulty: Hard
+ *
+ * You are given a 0-indexed binary string floor, which represents the colors of tiles on a floor:
+ * - floor[i] = '0' denotes that the ith tile of the floor is colored black.
+ * - On the other hand, floor[i] = '1' denotes that the ith tile of the floor is colored white.
+ *
+ * You are also given numCarpets and carpetLen. You have numCarpets black carpets, each of length
+ * carpetLen tiles. Cover the tiles with the given carpets such that the number of white tiles
+ * still visible is minimum. Carpets may overlap one another.
+ *
+ * Return the minimum number of white tiles still visible.
+ */
+
+/**
+ * @param {string} floor
+ * @param {number} numCarpets
+ * @param {number} carpetLen
+ * @return {number}
+ */
+var minimumWhiteTiles = function(floor, numCarpets, carpetLen) {
+  const n = floor.length;
+  const dp = Array.from({ length: n + 1 }, () => Array(numCarpets + 1).fill(0));
+
+  for (let i = 1; i <= n; i++) {
+    for (let j = 0; j <= numCarpets; j++) {
+      const skip = dp[i - 1][j] + (floor[i - 1] === '1' ? 1 : 0);
+      const cover = j > 0 ? dp[Math.max(0, i - carpetLen)][j - 1] : Infinity;
+      dp[i][j] = Math.min(skip, cover);
+    }
+  }
+
+  return dp[n][numCarpets];
+};
diff --git a/solutions/2210-count-hills-and-valleys-in-an-array.js b/solutions/2210-count-hills-and-valleys-in-an-array.js
new file mode 100644
index 00000000..388d78f5
--- /dev/null
+++ b/solutions/2210-count-hills-and-valleys-in-an-array.js
@@ -0,0 +1,38 @@
+/**
+ * 2210. Count Hills and Valleys in an Array
+ * https://leetcode.com/problems/count-hills-and-valleys-in-an-array/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed integer array nums. An index i is part of a hill in nums if the
+ * closest non-equal neighbors of i are smaller than nums[i]. Similarly, an index i is part
+ * of a valley in nums if the closest non-equal neighbors of i are larger than nums[i].
+ * Adjacent indices i and j are part of the same hill or valley if nums[i] == nums[j].
+ *
+ * Note that for an index to be part of a hill or valley, it must have a non-equal neighbor
+ * on both the left and right of the index.
+ *
+ * Return the number of hills and valleys in nums.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var countHillValley = function(nums) {
+  let count = 0;
+  let prev = nums[0];
+
+  for (let i = 1; i < nums.length - 1; i++) {
+    if (nums[i] === nums[i + 1]) continue;
+    const left = prev;
+    const right = nums[i + 1];
+
+    if ((nums[i] > left && nums[i] > right) || (nums[i] < left && nums[i] < right)) {
+      count++;
+    }
+
+    prev = nums[i];
+  }
+
+  return count;
+};
diff --git a/solutions/2211-count-collisions-on-a-road.js b/solutions/2211-count-collisions-on-a-road.js
new file mode 100644
index 00000000..acbd8920
--- /dev/null
+++ b/solutions/2211-count-collisions-on-a-road.js
@@ -0,0 +1,41 @@
+/**
+ * 2211. Count Collisions on a Road
+ * https://leetcode.com/problems/count-collisions-on-a-road/
+ * Difficulty: Medium
+ *
+ * There are n cars on an infinitely long road. The cars are numbered from 0 to n - 1 from left
+ * to right and each car is present at a unique point.
+ *
+ * You are given a 0-indexed string directions of length n. directions[i] can be either 'L', 'R',
+ * or 'S' denoting whether the ith car is moving towards the left, towards the right, or staying
+ * at its current point respectively. Each moving car has the same speed.
+ *
+ * The number of collisions can be calculated as follows:
+ * - When two cars moving in opposite directions collide with each other, the number of collisions
+ *   increases by 2.
+ * - When a moving car collides with a stationary car, the number of collisions increases by 1.
+ *
+ * After a collision, the cars involved can no longer move and will stay at the point where they
+ * collided. Other than that, cars cannot change their state or direction of motion.
+ *
+ * Return the total number of collisions that will happen on the road.
+ */
+
+/**
+ * @param {string} directions
+ * @return {number}
+ */
+var countCollisions = function(directions) {
+  let result = 0;
+  let left = 0;
+  let right = directions.length - 1;
+
+  while (left < directions.length && directions[left] === 'L') left++;
+  while (right >= 0 && directions[right] === 'R') right--;
+
+  for (let i = left; i <= right; i++) {
+    if (directions[i] !== 'S') result++;
+  }
+
+  return result;
+};
diff --git a/solutions/2212-maximum-points-in-an-archery-competition.js b/solutions/2212-maximum-points-in-an-archery-competition.js
new file mode 100644
index 00000000..2c09fc29
--- /dev/null
+++ b/solutions/2212-maximum-points-in-an-archery-competition.js
@@ -0,0 +1,60 @@
+/**
+ * 2212. Maximum Points in an Archery Competition
+ * https://leetcode.com/problems/maximum-points-in-an-archery-competition/
+ * Difficulty: Medium
+ *
+ * Alice and Bob are opponents in an archery competition. The competition has set the
+ * following rules:
+ * 1. Alice first shoots numArrows arrows and then Bob shoots numArrows arrows.
+ * 2. The points are then calculated as follows:
+ *    1. The target has integer scoring sections ranging from 0 to 11 inclusive.
+ *    2. For each section of the target with score k (in between 0 to 11), say Alice and Bob have
+ *       shot ak and bk arrows on that section respectively. If ak >= bk, then Alice takes k points.
+ *       If ak < bk, then Bob takes k points.
+ *    3. However, if ak == bk == 0, then nobody takes k points.
+ * - For example, if Alice and Bob both shot 2 arrows on the section with score 11, then Alice takes
+ *   11 points. On the other hand, if Alice shot 0 arrows on the section with score 11 and Bob shot
+ *   2 arrows on that same section, then Bob takes 11 points.
+ *
+ * You are given the integer numArrows and an integer array aliceArrows of size 12, which represents
+ * the number of arrows Alice shot on each scoring section from 0 to 11. Now, Bob wants to maximize
+ * the total number of points he can obtain.
+ *
+ * Return the array bobArrows which represents the number of arrows Bob shot on each scoring section
+ * from 0 to 11. The sum of the values in bobArrows should equal numArrows.
+ *
+ * If there are multiple ways for Bob to earn the maximum total points, return any one of them.
+ */
+
+/**
+ * @param {number} numArrows
+ * @param {number[]} aliceArrows
+ * @return {number[]}
+ */
+var maximumBobPoints = function(numArrows, aliceArrows) {
+  let maxScore = 0;
+  let bestConfig = new Array(12).fill(0);
+
+  backtrack(1, numArrows, 0, new Array(12).fill(0));
+  return bestConfig;
+
+  function backtrack(index, arrowsLeft, score, config) {
+    if (index === 12 || arrowsLeft === 0) {
+      if (score > maxScore) {
+        maxScore = score;
+        bestConfig = [...config];
+        bestConfig[0] += arrowsLeft;
+      }
+      return;
+    }
+
+    const needed = aliceArrows[index] + 1;
+    if (arrowsLeft >= needed) {
+      config[index] = needed;
+      backtrack(index + 1, arrowsLeft - needed, score + index, config);
+      config[index] = 0;
+    }
+
+    backtrack(index + 1, arrowsLeft, score, config);
+  }
+};
diff --git a/solutions/2213-longest-substring-of-one-repeating-character.js b/solutions/2213-longest-substring-of-one-repeating-character.js
new file mode 100644
index 00000000..ca5e006d
--- /dev/null
+++ b/solutions/2213-longest-substring-of-one-repeating-character.js
@@ -0,0 +1,117 @@
+/**
+ * 2213. Longest Substring of One Repeating Character
+ * https://leetcode.com/problems/longest-substring-of-one-repeating-character/
+ * Difficulty: Hard
+ *
+ * You are given a 0-indexed string s. You are also given a 0-indexed string queryCharacters of
+ * length k and a 0-indexed array of integer indices queryIndices of length k, both of which are
+ * used to describe k queries.
+ *
+ * The ith query updates the character in s at index queryIndices[i] to the character
+ * queryCharacters[i].
+ *
+ * Return an array lengths of length k where lengths[i] is the length of the longest substring of
+ * s consisting of only one repeating character after the ith query is performed.
+ */
+
+/**
+* @param {string} s
+* @param {string} queryCharacters
+* @param {number[]} queryIndices
+* @return {number[]}
+*/
+var longestRepeating = function(s, queryCharacters, queryIndices) {
+  const chars = s.split('');
+  const n = chars.length;
+  const k = queryIndices.length;
+  const result = [];
+
+  class Node {
+    constructor() {
+      this.left = 0;
+      this.right = 0;
+      this.max = 0;
+      this.total = 0;
+    }
+  }
+
+  const tree = new Array(4 * n);
+  for (let i = 0; i < 4 * n; i++) {
+    tree[i] = new Node();
+  }
+
+  function buildTree(node, start, end) {
+    if (start === end) {
+      tree[node].left = 1;
+      tree[node].right = 1;
+      tree[node].max = 1;
+      tree[node].total = 1;
+      return;
+    }
+
+    const mid = Math.floor((start + end) / 2);
+    buildTree(2 * node, start, mid);
+    buildTree(2 * node + 1, mid + 1, end);
+
+    updateNode(node, start, end);
+  }
+
+  function updateNode(node, start, end) {
+    const leftChild = 2 * node;
+    const rightChild = 2 * node + 1;
+    const mid = Math.floor((start + end) / 2);
+
+    tree[node].total = tree[leftChild].total + tree[rightChild].total;
+
+    if (tree[leftChild].total === tree[leftChild].left
+        && mid + 1 <= end && chars[mid] === chars[mid + 1]) {
+      tree[node].left = tree[leftChild].total + tree[rightChild].left;
+    } else {
+      tree[node].left = tree[leftChild].left;
+    }
+
+    if (tree[rightChild].total === tree[rightChild].right
+        && mid >= start && chars[mid] === chars[mid + 1]) {
+      tree[node].right = tree[rightChild].total + tree[leftChild].right;
+    } else {
+      tree[node].right = tree[rightChild].right;
+    }
+
+    tree[node].max = Math.max(tree[leftChild].max, tree[rightChild].max);
+
+    if (mid >= start && mid + 1 <= end && chars[mid] === chars[mid + 1]) {
+      tree[node].max = Math.max(tree[node].max,
+        tree[leftChild].right + tree[rightChild].left);
+    }
+  }
+
+  function update(node, start, end, index) {
+    if (index < start || index > end) {
+      return;
+    }
+
+    if (start === end) {
+      return;
+    }
+
+    const mid = Math.floor((start + end) / 2);
+    update(2 * node, start, mid, index);
+    update(2 * node + 1, mid + 1, end, index);
+
+    updateNode(node, start, end);
+  }
+
+  buildTree(1, 0, n - 1);
+
+  for (let q = 0; q < k; q++) {
+    const index = queryIndices[q];
+    const newChar = queryCharacters[q];
+
+    chars[index] = newChar;
+    update(1, 0, n - 1, index);
+
+    result.push(tree[1].max);
+  }
+
+  return result;
+};
diff --git a/solutions/2216-minimum-deletions-to-make-array-beautiful.js b/solutions/2216-minimum-deletions-to-make-array-beautiful.js
new file mode 100644
index 00000000..7cb1012e
--- /dev/null
+++ b/solutions/2216-minimum-deletions-to-make-array-beautiful.js
@@ -0,0 +1,41 @@
+/**
+ * 2216. Minimum Deletions to Make Array Beautiful
+ * https://leetcode.com/problems/minimum-deletions-to-make-array-beautiful/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed integer array nums. The array nums is beautiful if:
+ * - nums.length is even.
+ * - nums[i] != nums[i + 1] for all i % 2 == 0.
+ *
+ * Note that an empty array is considered beautiful.
+ *
+ * You can delete any number of elements from nums. When you delete an element, all the elements
+ * to the right of the deleted element will be shifted one unit to the left to fill the gap
+ * created and all the elements to the left of the deleted element will remain unchanged.
+ *
+ * Return the minimum number of elements to delete from nums to make it beautiful.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var minDeletion = function(nums) {
+  let result = 0;
+  let i = 0;
+
+  while (i < nums.length - 1) {
+    if (nums[i] === nums[i + 1]) {
+      result++;
+      i++;
+    } else {
+      i += 2;
+    }
+  }
+
+  if ((nums.length - result) % 2 !== 0) {
+    result++;
+  }
+
+  return result;
+};
diff --git a/solutions/2217-find-palindrome-with-fixed-length.js b/solutions/2217-find-palindrome-with-fixed-length.js
new file mode 100644
index 00000000..4e6a83aa
--- /dev/null
+++ b/solutions/2217-find-palindrome-with-fixed-length.js
@@ -0,0 +1,40 @@
+/**
+ * 2217. Find Palindrome With Fixed Length
+ * https://leetcode.com/problems/find-palindrome-with-fixed-length/
+ * Difficulty: Medium
+ *
+ * Given an integer array queries and a positive integer intLength, return an array answer where
+ * answer[i] is either the queries[i]th smallest positive palindrome of length intLength or -1
+ * if no such palindrome exists.
+ *
+ * A palindrome is a number that reads the same backwards and forwards. Palindromes cannot have
+ * leading zeros.
+ */
+
+/**
+ * @param {number[]} queries
+ * @param {number} intLength
+ * @return {number[]}
+ */
+var kthPalindrome = function(queries, intLength) {
+  const halfLength = Math.ceil(intLength / 2);
+  const maxPalindromes = Math.pow(10, halfLength - 1) * 9;
+
+  return queries.map(generatePalindrome);
+
+  function generatePalindrome(query) {
+    if (query > maxPalindromes) return -1;
+
+    let firstHalf = Math.pow(10, halfLength - 1) + query - 1;
+    let result = firstHalf;
+
+    if (intLength % 2 === 1) firstHalf = Math.floor(firstHalf / 10);
+
+    while (firstHalf > 0) {
+      result = result * 10 + (firstHalf % 10);
+      firstHalf = Math.floor(firstHalf / 10);
+    }
+
+    return result;
+  }
+};
diff --git a/solutions/2218-maximum-value-of-k-coins-from-piles.js b/solutions/2218-maximum-value-of-k-coins-from-piles.js
new file mode 100644
index 00000000..743b4b17
--- /dev/null
+++ b/solutions/2218-maximum-value-of-k-coins-from-piles.js
@@ -0,0 +1,44 @@
+/**
+ * 2218. Maximum Value of K Coins From Piles
+ * https://leetcode.com/problems/maximum-value-of-k-coins-from-piles/
+ * Difficulty: Hard
+ *
+ * There are n piles of coins on a table. Each pile consists of a positive number of coins of
+ * assorted denominations.
+ *
+ * In one move, you can choose any coin on top of any pile, remove it, and add it to your wallet.
+ *
+ * Given a list piles, where piles[i] is a list of integers denoting the composition of the ith
+ * pile from top to bottom, and a positive integer k, return the maximum total value of coins
+ * you can have in your wallet if you choose exactly k coins optimally.
+ */
+
+/**
+ * @param {number[][]} piles
+ * @param {number} k
+ * @return {number}
+ */
+var maxValueOfCoins = function(piles, k) {
+  const n = piles.length;
+  const dp = Array.from({ length: n + 1 }, () => new Array(k + 1).fill(-1));
+
+  return maximize(0, k);
+
+  function maximize(pileIndex, remainingCoins) {
+    if (pileIndex === n || remainingCoins === 0) return 0;
+    if (dp[pileIndex][remainingCoins] !== -1) return dp[pileIndex][remainingCoins];
+
+    let maxValue = maximize(pileIndex + 1, remainingCoins);
+    let currentSum = 0;
+
+    for (let i = 0; i < Math.min(piles[pileIndex].length, remainingCoins); i++) {
+      currentSum += piles[pileIndex][i];
+      maxValue = Math.max(
+        maxValue,
+        currentSum + maximize(pileIndex + 1, remainingCoins - (i + 1))
+      );
+    }
+
+    return dp[pileIndex][remainingCoins] = maxValue;
+  }
+};
diff --git a/solutions/2220-minimum-bit-flips-to-convert-number.js b/solutions/2220-minimum-bit-flips-to-convert-number.js
new file mode 100644
index 00000000..28e0a9da
--- /dev/null
+++ b/solutions/2220-minimum-bit-flips-to-convert-number.js
@@ -0,0 +1,24 @@
+/**
+ * 2220. Minimum Bit Flips to Convert Number
+ * https://leetcode.com/problems/minimum-bit-flips-to-convert-number/
+ * Difficulty: Easy
+ *
+ * A bit flip of a number x is choosing a bit in the binary representation of x and flipping it
+ * from either 0 to 1 or 1 to 0.
+ * - For example, for x = 7, the binary representation is 111 and we may choose any bit (including
+ *   any leading zeros not shown) and flip it. We can flip the first bit from the right to get 110,
+ *   flip the second bit from the right to get 101, flip the fifth bit from the right (a leading
+ *   zero) to get 10111, etc.
+ *
+ * Given two integers start and goal, return the minimum number of bit flips to convert start to
+ * goal.
+ */
+
+/**
+ * @param {number} start
+ * @param {number} goal
+ * @return {number}
+ */
+var minBitFlips = function(start, goal) {
+  return (start ^ goal).toString(2).replace(/0+/g, '').length;
+};
diff --git a/solutions/2221-find-triangular-sum-of-an-array.js b/solutions/2221-find-triangular-sum-of-an-array.js
new file mode 100644
index 00000000..3ef02fcd
--- /dev/null
+++ b/solutions/2221-find-triangular-sum-of-an-array.js
@@ -0,0 +1,34 @@
+/**
+ * 2221. Find Triangular Sum of an Array
+ * https://leetcode.com/problems/find-triangular-sum-of-an-array/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed integer array nums, where nums[i] is a digit between 0 and
+ * 9 (inclusive).
+ *
+ * The triangular sum of nums is the value of the only element present in nums after the
+ * following process terminates:
+ * 1. Let nums comprise of n elements. If n == 1, end the process. Otherwise, create a new
+ *    0-indexed integer array newNums of length n - 1.
+ * 2. For each index i, where 0 <= i < n - 1, assign the value of newNums[i] as
+ *    (nums[i] + nums[i+1]) % 10, where % denotes modulo operator.
+ * 3. Replace the array nums with newNums.
+ * 4. Repeat the entire process starting from step 1.
+ *
+ * Return the triangular sum of nums.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var triangularSum = function(nums) {
+  while (nums.length > 1) {
+    const updated = [];
+    for (let i = 0; i < nums.length - 1; i++) {
+      updated.push((nums[i] + nums[i + 1]) % 10);
+    }
+    nums = updated;
+  }
+  return nums[0];
+};
diff --git a/solutions/2222-number-of-ways-to-select-buildings.js b/solutions/2222-number-of-ways-to-select-buildings.js
new file mode 100644
index 00000000..012573fc
--- /dev/null
+++ b/solutions/2222-number-of-ways-to-select-buildings.js
@@ -0,0 +1,49 @@
+/**
+ * 2222. Number of Ways to Select Buildings
+ * https://leetcode.com/problems/number-of-ways-to-select-buildings/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed binary string s which represents the types of buildings along
+ * a street where:
+ * - s[i] = '0' denotes that the ith building is an office and
+ * - s[i] = '1' denotes that the ith building is a restaurant.
+ *
+ * As a city official, you would like to select 3 buildings for random inspection. However, to
+ * ensure variety, no two consecutive buildings out of the selected buildings can be of the same
+ * type.
+ * - For example, given s = "001101", we cannot select the 1st, 3rd, and 5th buildings as that
+ *   would form "011" which is not allowed due to having two consecutive buildings of the same type.
+ *
+ * Return the number of valid ways to select 3 buildings.
+ */
+
+/**
+ * @param {string} s
+ * @return {number}
+ */
+var numberOfWays = function(s) {
+  const prefixCounts = [[0, 0]];
+  let zeros = 0;
+  let ones = 0;
+
+  for (const char of s) {
+    if (char === '0') zeros++;
+    else ones++;
+    prefixCounts.push([zeros, ones]);
+  }
+
+  let result = 0;
+  for (let i = 1; i < s.length - 1; i++) {
+    if (s[i] === '0') {
+      const leftOnes = prefixCounts[i][1];
+      const rightOnes = prefixCounts[s.length][1] - prefixCounts[i + 1][1];
+      result += leftOnes * rightOnes;
+    } else {
+      const leftZeros = prefixCounts[i][0];
+      const rightZeros = prefixCounts[s.length][0] - prefixCounts[i + 1][0];
+      result += leftZeros * rightZeros;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2223-sum-of-scores-of-built-strings.js b/solutions/2223-sum-of-scores-of-built-strings.js
new file mode 100644
index 00000000..4b5110cc
--- /dev/null
+++ b/solutions/2223-sum-of-scores-of-built-strings.js
@@ -0,0 +1,40 @@
+/**
+ * 2223. Sum of Scores of Built Strings
+ * https://leetcode.com/problems/sum-of-scores-of-built-strings/
+ * Difficulty: Hard
+ *
+ * You are building a string s of length n one character at a time, prepending each new character
+ * to the front of the string. The strings are labeled from 1 to n, where the string with length
+ * i is labeled si.
+ * - For example, for s = "abaca", s1 == "a", s2 == "ca", s3 == "aca", etc.
+ *
+ * The score of si is the length of the longest common prefix between si and sn (Note that s == sn).
+ *
+ * Given the final string s, return the sum of the score of every si.
+ */
+
+/**
+ * @param {string} s
+ * @return {number}
+ */
+var sumScores = function(s) {
+  const n = s.length;
+  const z = new Array(n).fill(0);
+  let left = 0;
+  let right = 0;
+
+  for (let i = 1; i < n; i++) {
+    if (i <= right) {
+      z[i] = Math.min(right - i + 1, z[i - left]);
+    }
+    while (i + z[i] < n && s[z[i]] === s[i + z[i]]) {
+      z[i]++;
+    }
+    if (i + z[i] - 1 > right) {
+      left = i;
+      right = i + z[i] - 1;
+    }
+  }
+
+  return z.reduce((sum, val) => sum + val, n);
+};
diff --git a/solutions/2224-minimum-number-of-operations-to-convert-time.js b/solutions/2224-minimum-number-of-operations-to-convert-time.js
new file mode 100644
index 00000000..95b7a154
--- /dev/null
+++ b/solutions/2224-minimum-number-of-operations-to-convert-time.js
@@ -0,0 +1,38 @@
+/**
+ * 2224. Minimum Number of Operations to Convert Time
+ * https://leetcode.com/problems/minimum-number-of-operations-to-convert-time/
+ * Difficulty: Easy
+ *
+ * You are given two strings current and correct representing two 24-hour times.
+ *
+ * 24-hour times are formatted as "HH:MM", where HH is between 00 and 23, and MM is between 00
+ * and 59. The earliest 24-hour time is 00:00, and the latest is 23:59.
+ *
+ * In one operation you can increase the time current by 1, 5, 15, or 60 minutes. You can perform
+ * this operation any number of times.
+ *
+ * Return the minimum number of operations needed to convert current to correct.
+ */
+
+/**
+ * @param {string} current
+ * @param {string} correct
+ * @return {number}
+ */
+var convertTime = function(current, correct) {
+  const toMinutes = time => {
+    const [hours, minutes] = time.split(':').map(Number);
+    return hours * 60 + minutes;
+  };
+
+  let diff = toMinutes(correct) - toMinutes(current);
+  const increments = [60, 15, 5, 1];
+  let result = 0;
+
+  for (const increment of increments) {
+    result += Math.floor(diff / increment);
+    diff %= increment;
+  }
+
+  return result;
+};
diff --git a/solutions/2225-find-players-with-zero-or-one-losses.js b/solutions/2225-find-players-with-zero-or-one-losses.js
new file mode 100644
index 00000000..3182523e
--- /dev/null
+++ b/solutions/2225-find-players-with-zero-or-one-losses.js
@@ -0,0 +1,44 @@
+/**
+ * 2225. Find Players With Zero or One Losses
+ * https://leetcode.com/problems/find-players-with-zero-or-one-losses/
+ * Difficulty: Medium
+ *
+ * You are given an integer array matches where matches[i] = [winneri, loseri] indicates that
+ * the player winneri defeated player loseri in a match.
+ *
+ * Return a list answer of size 2 where:
+ * - answer[0] is a list of all players that have not lost any matches.
+ * - answer[1] is a list of all players that have lost exactly one match.
+ *
+ * The values in the two lists should be returned in increasing order.
+ *
+ * Note:
+ * - You should only consider the players that have played at least one match.
+ * - The testcases will be generated such that no two matches will have the same outcome.
+ */
+
+/**
+ * @param {number[][]} matches
+ * @return {number[][]}
+ */
+var findWinners = function(matches) {
+  const lossCount = new Map();
+
+  for (const [winner, loser] of matches) {
+    lossCount.set(winner, lossCount.get(winner) || 0);
+    lossCount.set(loser, (lossCount.get(loser) || 0) + 1);
+  }
+
+  const noLosses = [];
+  const oneLoss = [];
+
+  for (const [player, losses] of lossCount) {
+    if (losses === 0) noLosses.push(player);
+    else if (losses === 1) oneLoss.push(player);
+  }
+
+  return [
+    noLosses.sort((a, b) => a - b),
+    oneLoss.sort((a, b) => a - b)
+  ];
+};
diff --git a/solutions/2227-encrypt-and-decrypt-strings.js b/solutions/2227-encrypt-and-decrypt-strings.js
new file mode 100644
index 00000000..fd773ffb
--- /dev/null
+++ b/solutions/2227-encrypt-and-decrypt-strings.js
@@ -0,0 +1,77 @@
+/**
+ * 2227. Encrypt and Decrypt Strings
+ * https://leetcode.com/problems/encrypt-and-decrypt-strings/
+ * Difficulty: Hard
+ *
+ * You are given a character array keys containing unique characters and a string array values
+ * containing strings of length 2. You are also given another string array dictionary that
+ * contains all permitted original strings after decryption. You should implement a data structure
+ * that can encrypt or decrypt a 0-indexed string.
+ *
+ * A string is encrypted with the following process:
+ * 1. For each character c in the string, we find the index i satisfying keys[i] == c in keys.
+ * 2. Replace c with values[i] in the string.
+ *
+ * Note that in case a character of the string is not present in keys, the encryption process cannot
+ * be carried out, and an empty string "" is returned.
+ *
+ * A string is decrypted with the following process:
+ * 1. For each substring s of length 2 occurring at an even index in the string, we find an i such
+ *    that values[i] == s. If there are multiple valid i, we choose any one of them. This means a
+ *    string could have multiple possible strings it can decrypt to.
+ * 2. Replace s with keys[i] in the string.
+ *
+ * Implement the Encrypter class:
+ * - Encrypter(char[] keys, String[] values, String[] dictionary) Initializes the Encrypter class
+ *   with keys, values, and dictionary.
+ * - String encrypt(String word1) Encrypts word1 with the encryption process described above and
+ *   returns the encrypted string.
+ * - int decrypt(String word2) Returns the number of possible strings word2 could decrypt to that
+ *   also appear in dictionary.
+ */
+
+/**
+ * @param {character[]} keys
+ * @param {string[]} values
+ * @param {string[]} dictionary
+ */
+var Encrypter = function(keys, values, dictionary) {
+  this.encryptMap = new Map();
+  this.validEncryptions = new Map();
+
+  for (let i = 0; i < keys.length; i++) {
+    this.encryptMap.set(keys[i], values[i]);
+  }
+
+  for (const word of dictionary) {
+    const encrypted = this.encrypt(word);
+    if (encrypted !== '') {
+      this.validEncryptions.set(encrypted, (this.validEncryptions.get(encrypted) || 0) + 1);
+    }
+  }
+};
+
+/**
+ * @param {string} word1
+ * @return {string}
+ */
+Encrypter.prototype.encrypt = function(word1) {
+  let result = '';
+
+  for (const char of word1) {
+    if (!this.encryptMap.has(char)) {
+      return '';
+    }
+    result += this.encryptMap.get(char);
+  }
+
+  return result;
+};
+
+/**
+ * @param {string} word2
+ * @return {number}
+ */
+Encrypter.prototype.decrypt = function(word2) {
+  return this.validEncryptions.get(word2) || 0;
+};
diff --git a/solutions/2232-minimize-result-by-adding-parentheses-to-expression.js b/solutions/2232-minimize-result-by-adding-parentheses-to-expression.js
new file mode 100644
index 00000000..f32f3fd9
--- /dev/null
+++ b/solutions/2232-minimize-result-by-adding-parentheses-to-expression.js
@@ -0,0 +1,50 @@
+/**
+ * 2232. Minimize Result by Adding Parentheses to Expression
+ * https://leetcode.com/problems/minimize-result-by-adding-parentheses-to-expression/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed string expression of the form "+" where 
+ * and  represent positive integers.
+ *
+ * Add a pair of parentheses to expression such that after the addition of parentheses,
+ * expression is a valid mathematical expression and evaluates to the smallest possible
+ * value. The left parenthesis must be added to the left of '+' and the right parenthesis
+ * must be added to the right of '+'.
+ *
+ * Return expression after adding a pair of parentheses such that expression evaluates to the
+ * smallest possible value. If there are multiple answers that yield the same result, return
+ * any of them.
+ *
+ * The input has been generated such that the original value of expression, and the value of
+ * expression after adding any pair of parentheses that meets the requirements fits within
+ * a signed 32-bit integer.
+ */
+
+/**
+ * @param {string} expression
+ * @return {string}
+ */
+var minimizeResult = function(expression) {
+  const plusIndex = expression.indexOf('+');
+  const left = expression.slice(0, plusIndex);
+  const right = expression.slice(plusIndex + 1);
+  let minValue = Infinity;
+  let result = '';
+
+  for (let i = 0; i < left.length; i++) {
+    for (let j = 1; j <= right.length; j++) {
+      const leftPrefix = i === 0 ? 1 : parseInt(left.slice(0, i));
+      const leftNum = parseInt(left.slice(i), 10);
+      const rightNum = parseInt(right.slice(0, j), 10);
+      const rightSuffix = j === right.length ? 1 : parseInt(right.slice(j), 10);
+      const value = leftPrefix * (leftNum + rightNum) * rightSuffix;
+
+      if (value < minValue) {
+        minValue = value;
+        result = `${left.slice(0, i)}(${left.slice(i)}+${right.slice(0, j)})${right.slice(j)}`;
+      }
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2234-maximum-total-beauty-of-the-gardens.js b/solutions/2234-maximum-total-beauty-of-the-gardens.js
new file mode 100644
index 00000000..54985527
--- /dev/null
+++ b/solutions/2234-maximum-total-beauty-of-the-gardens.js
@@ -0,0 +1,99 @@
+/**
+ * 2234. Maximum Total Beauty of the Gardens
+ * https://leetcode.com/problems/maximum-total-beauty-of-the-gardens/
+ * Difficulty: Hard
+ *
+ * Alice is a caretaker of n gardens and she wants to plant flowers to maximize the total
+ * beauty of all her gardens.
+ *
+ * You are given a 0-indexed integer array flowers of size n, where flowers[i] is the number
+ * of flowers already planted in the ith garden. Flowers that are already planted cannot be
+ * removed. You are then given another integer newFlowers, which is the maximum number of
+ * flowers that Alice can additionally plant. You are also given the integers target, full,
+ * and partial.
+ *
+ * A garden is considered complete if it has at least target flowers. The total beauty of the
+ * gardens is then determined as the sum of the following:
+ * - The number of complete gardens multiplied by full.
+ * - The minimum number of flowers in any of the incomplete gardens multiplied by partial.
+ *   If there are no incomplete gardens, then this value will be 0.
+ *
+ * Return the maximum total beauty that Alice can obtain after planting at most newFlowers flowers.
+ */
+
+/**
+ * @param {number[]} flowers
+ * @param {number} newFlowers
+ * @param {number} target
+ * @param {number} full
+ * @param {number} partial
+ * @return {number}
+ */
+var maximumBeauty = function(flowers, newFlowers, target, full, partial) {
+  const n = flowers.length;
+  flowers.sort((a, b) => b - a);
+
+  const suffixCost = Array(n + 1).fill(0);
+  let lastUniqueIndex = n - 1;
+  let minIndex = n - 2;
+
+  for (; minIndex >= 0; --minIndex) {
+    if (flowers[minIndex] >= target) break;
+
+    const flowerDiff = flowers[minIndex] - flowers[minIndex + 1];
+    const gardenCount = n - lastUniqueIndex;
+    suffixCost[minIndex] = suffixCost[minIndex + 1] + flowerDiff * gardenCount;
+
+    if (suffixCost[minIndex] > newFlowers) break;
+
+    if (flowers[minIndex] !== flowers[minIndex - 1]) {
+      lastUniqueIndex = minIndex;
+    }
+  }
+
+  ++minIndex;
+
+  const remainingFlowersForMin = newFlowers - suffixCost[minIndex];
+  const gardenCountForMin = n - minIndex;
+  let minFlowerValue = Math.min(
+    target - 1,
+    flowers[minIndex] + Math.floor(remainingFlowersForMin / gardenCountForMin)
+  );
+
+  let result = 0;
+
+  for (let i = 0; i < n; ++i) {
+    if (flowers[i] >= target) {
+      continue;
+    }
+
+    const currentBeauty = i * full + minFlowerValue * partial;
+    result = Math.max(result, currentBeauty);
+
+    const flowersNeeded = target - flowers[i];
+    if (flowersNeeded > newFlowers) break;
+
+    newFlowers -= flowersNeeded;
+    flowers[i] = target;
+
+    while (
+      minIndex <= i || newFlowers < suffixCost[minIndex]
+      || (minIndex > 0 && flowers[minIndex] === flowers[minIndex - 1])
+    ) {
+      ++minIndex;
+    }
+
+    const updatedRemaining = newFlowers - suffixCost[minIndex];
+    const updatedGardenCount = n - minIndex;
+    minFlowerValue = Math.min(
+      target - 1,
+      flowers[minIndex] + Math.floor(updatedRemaining / updatedGardenCount)
+    );
+  }
+
+  if (flowers[n - 1] >= target) {
+    result = Math.max(result, n * full);
+  }
+
+  return result;
+};
diff --git a/solutions/2236-root-equals-sum-of-children.js b/solutions/2236-root-equals-sum-of-children.js
new file mode 100644
index 00000000..fa9a3cd9
--- /dev/null
+++ b/solutions/2236-root-equals-sum-of-children.js
@@ -0,0 +1,27 @@
+/**
+ * 2236. Root Equals Sum of Children
+ * https://leetcode.com/problems/root-equals-sum-of-children/
+ * Difficulty: Easy
+ *
+ * You are given the root of a binary tree that consists of exactly 3 nodes: the root, its
+ * left child, and its right child.
+ *
+ * Return true if the value of the root is equal to the sum of the values of its two children,
+ * or false otherwise.
+ */
+
+/**
+ * Definition for a binary tree node.
+ * function TreeNode(val, left, right) {
+ *     this.val = (val===undefined ? 0 : val)
+ *     this.left = (left===undefined ? null : left)
+ *     this.right = (right===undefined ? null : right)
+ * }
+ */
+/**
+ * @param {TreeNode} root
+ * @return {boolean}
+ */
+var checkTree = function(root) {
+  return root.val === root.left.val + root.right.val;
+};
diff --git a/solutions/2239-find-closest-number-to-zero.js b/solutions/2239-find-closest-number-to-zero.js
new file mode 100644
index 00000000..56d07d8e
--- /dev/null
+++ b/solutions/2239-find-closest-number-to-zero.js
@@ -0,0 +1,27 @@
+/**
+ * 2239. Find Closest Number to Zero
+ * https://leetcode.com/problems/find-closest-number-to-zero/
+ * Difficulty: Easy
+ *
+ * Given an integer array nums of size n, return the number with the value closest to 0 in nums.
+ * If there are multiple answers, return the number with the largest value.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var findClosestNumber = function(nums) {
+  let result = nums[0];
+  let minDistance = Math.abs(nums[0]);
+
+  for (const num of nums) {
+    const distance = Math.abs(num);
+    if (distance < minDistance || (distance === minDistance && num > result)) {
+      minDistance = distance;
+      result = num;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2240-number-of-ways-to-buy-pens-and-pencils.js b/solutions/2240-number-of-ways-to-buy-pens-and-pencils.js
new file mode 100644
index 00000000..b55f1cff
--- /dev/null
+++ b/solutions/2240-number-of-ways-to-buy-pens-and-pencils.js
@@ -0,0 +1,31 @@
+/**
+ * 2240. Number of Ways to Buy Pens and Pencils
+ * https://leetcode.com/problems/number-of-ways-to-buy-pens-and-pencils/
+ * Difficulty: Medium
+ *
+ * You are given an integer total indicating the amount of money you have. You are also given
+ * two integers cost1 and cost2 indicating the price of a pen and pencil respectively. You can
+ * spend part or all of your money to buy multiple quantities (or none) of each kind of writing
+ * utensil.
+ *
+ * Return the number of distinct ways you can buy some number of pens and pencils.
+ */
+
+/**
+ * @param {number} total
+ * @param {number} cost1
+ * @param {number} cost2
+ * @return {number}
+ */
+var waysToBuyPensPencils = function(total, cost1, cost2) {
+  let result = 0;
+  const maxPens = Math.floor(total / cost1);
+
+  for (let pens = 0; pens <= maxPens; pens++) {
+    const remaining = total - pens * cost1;
+    const pencils = Math.floor(remaining / cost2);
+    result += pencils + 1;
+  }
+
+  return result;
+};
diff --git a/solutions/2241-design-an-atm-machine.js b/solutions/2241-design-an-atm-machine.js
new file mode 100644
index 00000000..4a5afa87
--- /dev/null
+++ b/solutions/2241-design-an-atm-machine.js
@@ -0,0 +1,64 @@
+/**
+ * 2241. Design an ATM Machine
+ * https://leetcode.com/problems/design-an-atm-machine/
+ * Difficulty: Medium
+ *
+ * There is an ATM machine that stores banknotes of 5 denominations: 20, 50, 100, 200, and
+ * 500 dollars. Initially the ATM is empty. The user can use the machine to deposit or
+ * withdraw any amount of money.
+ *
+ * When withdrawing, the machine prioritizes using banknotes of larger values.
+ * - For example, if you want to withdraw $300 and there are 2 $50 banknotes, 1 $100 banknote,
+ *   and 1 $200 banknote, then the machine will use the $100 and $200 banknotes.
+ * - However, if you try to withdraw $600 and there are 3 $200 banknotes and 1 $500 banknote,
+ *   then the withdraw request will be rejected because the machine will first try to use the
+ *   $500 banknote and then be unable to use banknotes to complete the remaining $100. Note
+ *   that the machine is not allowed to use the $200 banknotes instead of the $500 banknote.
+ *
+ * Implement the ATM class:
+ * - ATM() Initializes the ATM object.
+ * - void deposit(int[] banknotesCount) Deposits new banknotes in the order $20, $50, $100,
+ *   $200, and $500.
+ * - int[] withdraw(int amount) Returns an array of length 5 of the number of banknotes that
+ *   will be handed to the user in the order $20, $50, $100, $200, and $500, and update the
+ *   number of banknotes in the ATM after withdrawing. Returns [-1] if it is not possible (do
+ *   not withdraw any banknotes in this case).
+ */
+
+var ATM = function() {
+  this.denominations = [20, 50, 100, 200, 500];
+  this.notes = [0, 0, 0, 0, 0];
+};
+
+/**
+ * @param {number[]} banknotesCount
+ * @return {void}
+ */
+ATM.prototype.deposit = function(banknotesCount) {
+  for (let i = 0; i < 5; i++) {
+    this.notes[i] += banknotesCount[i];
+  }
+};
+
+/**
+ * @param {number} amount
+ * @return {number[]}
+ */
+ATM.prototype.withdraw = function(amount) {
+  const result = [0, 0, 0, 0, 0];
+  let remaining = amount;
+
+  for (let i = 4; i >= 0; i--) {
+    const count = Math.min(Math.floor(remaining / this.denominations[i]), this.notes[i]);
+    result[i] = count;
+    remaining -= count * this.denominations[i];
+  }
+
+  if (remaining !== 0) return [-1];
+
+  for (let i = 0; i < 5; i++) {
+    this.notes[i] -= result[i];
+  }
+
+  return result;
+};
diff --git a/solutions/2242-maximum-score-of-a-node-sequence.js b/solutions/2242-maximum-score-of-a-node-sequence.js
new file mode 100644
index 00000000..b64c16ce
--- /dev/null
+++ b/solutions/2242-maximum-score-of-a-node-sequence.js
@@ -0,0 +1,55 @@
+/**
+ * 2242. Maximum Score of a Node Sequence
+ * https://leetcode.com/problems/maximum-score-of-a-node-sequence/
+ * Difficulty: Hard
+ *
+ * There is an undirected graph with n nodes, numbered from 0 to n - 1.
+ *
+ * You are given a 0-indexed integer array scores of length n where scores[i] denotes the score
+ * of node i. You are also given a 2D integer array edges where edges[i] = [ai, bi] denotes that
+ * there exists an undirected edge connecting nodes ai and bi.
+ *
+ * A node sequence is valid if it meets the following conditions:
+ * - There is an edge connecting every pair of adjacent nodes in the sequence.
+ * - No node appears more than once in the sequence.
+ *
+ * The score of a node sequence is defined as the sum of the scores of the nodes in the sequence.
+ *
+ * Return the maximum score of a valid node sequence with a length of 4. If no such sequence exists,
+ * return -1.
+ */
+
+/**
+ * @param {number[]} scores
+ * @param {number[][]} edges
+ * @return {number}
+ */
+var maximumScore = function(scores, edges) {
+  const n = scores.length;
+  const graph = new Array(n).fill().map(() => []);
+
+  for (const [a, b] of edges) {
+    graph[a].push(b);
+    graph[b].push(a);
+  }
+
+  for (let i = 0; i < n; i++) {
+    graph[i].sort((a, b) => scores[b] - scores[a]);
+    if (graph[i].length > 3) {
+      graph[i] = graph[i].slice(0, 3);
+    }
+  }
+
+  let result = -1;
+  for (const [a, b] of edges) {
+    for (const c of graph[a]) {
+      if (c === b) continue;
+      for (const d of graph[b]) {
+        if (d === a || d === c) continue;
+        result = Math.max(result, scores[a] + scores[b] + scores[c] + scores[d]);
+      }
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2243-calculate-digit-sum-of-a-string.js b/solutions/2243-calculate-digit-sum-of-a-string.js
new file mode 100644
index 00000000..293438ed
--- /dev/null
+++ b/solutions/2243-calculate-digit-sum-of-a-string.js
@@ -0,0 +1,36 @@
+/**
+ * 2243. Calculate Digit Sum of a String
+ * https://leetcode.com/problems/calculate-digit-sum-of-a-string/
+ * Difficulty: Easy
+ *
+ * You are given a string s consisting of digits and an integer k.
+ *
+ * A round can be completed if the length of s is greater than k. In one round, do the following:
+ * 1. Divide s into consecutive groups of size k such that the first k characters are in the first
+ *    group, the next k characters are in the second group, and so on. Note that the size of the
+ *    last group can be smaller than k.
+ * 2. Replace each group of s with a string representing the sum of all its digits. For example,
+ *    "346" is replaced with "13" because 3 + 4 + 6 = 13.
+ * 3. Merge consecutive groups together to form a new string. If the length of the string is greater
+ *    than k, repeat from step 1.
+ *
+ * Return s after all rounds have been completed.
+ */
+
+/**
+ * @param {string} s
+ * @param {number} k
+ * @return {string}
+ */
+var digitSum = function(s, k) {
+  while (s.length > k) {
+    let next = '';
+    for (let i = 0; i < s.length; i += k) {
+      const group = s.slice(i, i + k);
+      const sum = group.split('').reduce((acc, digit) => acc + Number(digit), 0);
+      next += sum;
+    }
+    s = next;
+  }
+  return s;
+};
diff --git a/solutions/2245-maximum-trailing-zeros-in-a-cornered-path.js b/solutions/2245-maximum-trailing-zeros-in-a-cornered-path.js
new file mode 100644
index 00000000..7f18ed32
--- /dev/null
+++ b/solutions/2245-maximum-trailing-zeros-in-a-cornered-path.js
@@ -0,0 +1,112 @@
+/**
+ * 2245. Maximum Trailing Zeros in a Cornered Path
+ * https://leetcode.com/problems/maximum-trailing-zeros-in-a-cornered-path/
+ * Difficulty: Medium
+ *
+ * You are given a 2D integer array grid of size m x n, where each cell contains a positive integer.
+ *
+ * A cornered path is defined as a set of adjacent cells with at most one turn. More specifically,
+ * the path should exclusively move either horizontally or vertically up to the turn (if there is
+ * one), without returning to a previously visited cell. After the turn, the path will then move
+ * exclusively in the alternate direction: move vertically if it moved horizontally, and vice versa,
+ * also without returning to a previously visited cell.
+ *
+ * The product of a path is defined as the product of all the values in the path.
+ *
+ * Return the maximum number of trailing zeros in the product of a cornered path found in grid.
+ *
+ * Note:
+ * - Horizontal movement means moving in either the left or right direction.
+ * - Vertical movement means moving in either the up or down direction.
+ */
+
+/**
+ * @param {number[][]} grid
+ * @return {number}
+ */
+var maxTrailingZeros = function(grid) {
+  const m = grid.length;
+  const n = grid[0].length;
+
+  function countFactors(num) {
+    let count2 = 0;
+    let count5 = 0;
+
+    while (num % 2 === 0) {
+      count2++;
+      num = Math.floor(num / 2);
+    }
+
+    while (num % 5 === 0) {
+      count5++;
+      num = Math.floor(num / 5);
+    }
+
+    return [count2, count5];
+  }
+
+  const factors = new Array(m).fill().map(() => new Array(n).fill().map(() => [0, 0]));
+  for (let i = 0; i < m; i++) {
+    for (let j = 0; j < n; j++) {
+      factors[i][j] = countFactors(grid[i][j]);
+    }
+  }
+
+  const rowPrefix = new Array(m).fill().map(() => new Array(n + 1).fill().map(() => [0, 0]));
+  for (let i = 0; i < m; i++) {
+    for (let j = 0; j < n; j++) {
+      rowPrefix[i][j + 1][0] = rowPrefix[i][j][0] + factors[i][j][0];
+      rowPrefix[i][j + 1][1] = rowPrefix[i][j][1] + factors[i][j][1];
+    }
+  }
+
+  const colPrefix = new Array(m + 1).fill().map(() => new Array(n).fill().map(() => [0, 0]));
+  for (let j = 0; j < n; j++) {
+    for (let i = 0; i < m; i++) {
+      colPrefix[i + 1][j][0] = colPrefix[i][j][0] + factors[i][j][0];
+      colPrefix[i + 1][j][1] = colPrefix[i][j][1] + factors[i][j][1];
+    }
+  }
+
+  let maxZeros = 0;
+  for (let i = 0; i < m; i++) {
+    for (let j = 0; j < n; j++) {
+      const [count2, count5] = factors[i][j];
+
+      const leftUp = [
+        rowPrefix[i][j][0] + colPrefix[i][j][0],
+        rowPrefix[i][j][1] + colPrefix[i][j][1]
+      ];
+
+      const leftDown = [
+        rowPrefix[i][j][0] + (colPrefix[m][j][0] - colPrefix[i + 1][j][0]),
+        rowPrefix[i][j][1] + (colPrefix[m][j][1] - colPrefix[i + 1][j][1])
+      ];
+
+      const rightUp = [
+        (rowPrefix[i][n][0] - rowPrefix[i][j + 1][0]) + colPrefix[i][j][0],
+        (rowPrefix[i][n][1] - rowPrefix[i][j + 1][1]) + colPrefix[i][j][1]
+      ];
+
+      const rightDown = [
+        (rowPrefix[i][n][0] - rowPrefix[i][j + 1][0])
+          + (colPrefix[m][j][0] - colPrefix[i + 1][j][0]),
+        (rowPrefix[i][n][1] - rowPrefix[i][j + 1][1])
+          + (colPrefix[m][j][1] - colPrefix[i + 1][j][1])
+      ];
+
+      const paths = [
+        [leftUp[0] + count2, leftUp[1] + count5],
+        [leftDown[0] + count2, leftDown[1] + count5],
+        [rightUp[0] + count2, rightUp[1] + count5],
+        [rightDown[0] + count2, rightDown[1] + count5]
+      ];
+
+      for (const [path2, path5] of paths) {
+        maxZeros = Math.max(maxZeros, Math.min(path2, path5));
+      }
+    }
+  }
+
+  return maxZeros;
+};
diff --git a/solutions/2246-longest-path-with-different-adjacent-characters.js b/solutions/2246-longest-path-with-different-adjacent-characters.js
new file mode 100644
index 00000000..4eb8cb53
--- /dev/null
+++ b/solutions/2246-longest-path-with-different-adjacent-characters.js
@@ -0,0 +1,54 @@
+/**
+ * 2246. Longest Path With Different Adjacent Characters
+ * https://leetcode.com/problems/longest-path-with-different-adjacent-characters/
+ * Difficulty: Hard
+ *
+ * You are given a tree (i.e. a connected, undirected graph that has no cycles) rooted at node
+ * 0 consisting of n nodes numbered from 0 to n - 1. The tree is represented by a 0-indexed array
+ * parent of size n, where parent[i] is the parent of node i. Since node 0 is the root,
+ * parent[0] == -1.
+ *
+ * You are also given a string s of length n, where s[i] is the character assigned to node i.
+ *
+ * Return the length of the longest path in the tree such that no pair of adjacent nodes on the path
+ * have the same character assigned to them.
+ */
+
+/**
+ * @param {number[]} parent
+ * @param {string} s
+ * @return {number}
+ */
+var longestPath = function(parent, s) {
+  const n = parent.length;
+  const children = Array.from({ length: n }, () => []);
+  let result = 1;
+
+  for (let i = 1; i < n; i++) {
+    children[parent[i]].push(i);
+  }
+
+  findLongest(0);
+
+  return result;
+
+  function findLongest(node) {
+    let longest = 0;
+    let secondLongest = 0;
+
+    for (const child of children[node]) {
+      const length = findLongest(child);
+      if (s[child] !== s[node]) {
+        if (length > longest) {
+          secondLongest = longest;
+          longest = length;
+        } else if (length > secondLongest) {
+          secondLongest = length;
+        }
+      }
+    }
+
+    result = Math.max(result, longest + secondLongest + 1);
+    return longest + 1;
+  }
+};
diff --git a/solutions/2248-intersection-of-multiple-arrays.js b/solutions/2248-intersection-of-multiple-arrays.js
new file mode 100644
index 00000000..fa162656
--- /dev/null
+++ b/solutions/2248-intersection-of-multiple-arrays.js
@@ -0,0 +1,31 @@
+/**
+ * 2248. Intersection of Multiple Arrays
+ * https://leetcode.com/problems/intersection-of-multiple-arrays/
+ * Difficulty: Easy
+ *
+ * Given a 2D integer array nums where nums[i] is a non-empty array of distinct positive integers,
+ * return the list of integers that are present in each array of nums sorted in ascending order.
+ */
+
+/**
+ * @param {number[][]} nums
+ * @return {number[]}
+ */
+var intersection = function(nums) {
+  const count = new Map();
+
+  for (const array of nums) {
+    for (const num of array) {
+      count.set(num, (count.get(num) || 0) + 1);
+    }
+  }
+
+  const result = [];
+  for (const [num, freq] of count) {
+    if (freq === nums.length) {
+      result.push(num);
+    }
+  }
+
+  return result.sort((a, b) => a - b);
+};
diff --git a/solutions/2249-count-lattice-points-inside-a-circle.js b/solutions/2249-count-lattice-points-inside-a-circle.js
new file mode 100644
index 00000000..2c762806
--- /dev/null
+++ b/solutions/2249-count-lattice-points-inside-a-circle.js
@@ -0,0 +1,33 @@
+/**
+ * 2249. Count Lattice Points Inside a Circle
+ * https://leetcode.com/problems/count-lattice-points-inside-a-circle/
+ * Difficulty: Medium
+ *
+ * Given a 2D integer array circles where circles[i] = [xi, yi, ri] represents the center (xi, yi)
+ * and radius ri of the ith circle drawn on a grid, return the number of lattice points that are
+ * present inside at least one circle.
+ *
+ * Note:
+ * - A lattice point is a point with integer coordinates.
+ * - Points that lie on the circumference of a circle are also considered to be inside it.
+ */
+
+/**
+ * @param {number[][]} circles
+ * @return {number}
+ */
+var countLatticePoints = function(circles) {
+  const set = new Set();
+
+  for (const [x, y, r] of circles) {
+    for (let i = x - r; i <= x + r; i++) {
+      for (let j = y - r; j <= y + r; j++) {
+        if ((x - i) ** 2 + (y - j) ** 2 <= r ** 2) {
+          set.add(`${i},${j}`);
+        }
+      }
+    }
+  }
+
+  return set.size;
+};
diff --git a/solutions/2250-count-number-of-rectangles-containing-each-point.js b/solutions/2250-count-number-of-rectangles-containing-each-point.js
new file mode 100644
index 00000000..79ed186c
--- /dev/null
+++ b/solutions/2250-count-number-of-rectangles-containing-each-point.js
@@ -0,0 +1,62 @@
+/**
+ * 2250. Count Number of Rectangles Containing Each Point
+ * https://leetcode.com/problems/count-number-of-rectangles-containing-each-point/
+ * Difficulty: Medium
+ *
+ * You are given a 2D integer array rectangles where rectangles[i] = [li, hi] indicates that ith
+ * rectangle has a length of li and a height of hi. You are also given a 2D integer array points
+ * where points[j] = [xj, yj] is a point with coordinates (xj, yj).
+ *
+ * The ith rectangle has its bottom-left corner point at the coordinates (0, 0) and its top-right
+ * corner point at (li, hi).
+ *
+ * Return an integer array count of length points.length where count[j] is the number of rectangles
+ * that contain the jth point.
+ *
+ * The ith rectangle contains the jth point if 0 <= xj <= li and 0 <= yj <= hi. Note that points
+ * that lie on the edges of a rectangle are also considered to be contained by that rectangle.
+ */
+
+/**
+ * @param {number[][]} rectangles
+ * @param {number[][]} points
+ * @return {number[]}
+ */
+var countRectangles = function(rectangles, points) {
+  const rectByHeight = new Array(101).fill().map(() => []);
+
+  for (const [length, height] of rectangles) {
+    rectByHeight[height].push(length);
+  }
+
+  for (let h = 0; h <= 100; h++) {
+    rectByHeight[h].sort((a, b) => a - b);
+  }
+
+  const result = new Array(points.length).fill(0);
+  for (let i = 0; i < points.length; i++) {
+    const [x, y] = points[i];
+
+    for (let h = y; h <= 100; h++) {
+      const lengths = rectByHeight[h];
+
+      let left = 0;
+      let right = lengths.length - 1;
+      let insertPos = lengths.length;
+
+      while (left <= right) {
+        const mid = Math.floor((left + right) / 2);
+        if (lengths[mid] >= x) {
+          insertPos = mid;
+          right = mid - 1;
+        } else {
+          left = mid + 1;
+        }
+      }
+
+      result[i] += lengths.length - insertPos;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2251-number-of-flowers-in-full-bloom.js b/solutions/2251-number-of-flowers-in-full-bloom.js
new file mode 100644
index 00000000..c9ae393f
--- /dev/null
+++ b/solutions/2251-number-of-flowers-in-full-bloom.js
@@ -0,0 +1,43 @@
+/**
+ * 2251. Number of Flowers in Full Bloom
+ * https://leetcode.com/problems/number-of-flowers-in-full-bloom/
+ * Difficulty: Hard
+ *
+ * You are given a 0-indexed 2D integer array flowers, where flowers[i] = [starti, endi] means
+ * the ith flower will be in full bloom from starti to endi (inclusive). You are also given a
+ * 0-indexed integer array people of size n, where people[i] is the time that the ith person
+ * will arrive to see the flowers.
+ *
+ * Return an integer array answer of size n, where answer[i] is the number of flowers that are
+ * in full bloom when the ith person arrives.
+ */
+
+/**
+ * @param {number[][]} flowers
+ * @param {number[]} people
+ * @return {number[]}
+ */
+var fullBloomFlowers = function(flowers, people) {
+  const events = [];
+  for (const [start, end] of flowers) {
+    events.push([start, 1]);
+    events.push([end + 1, -1]);
+  }
+  events.sort((a, b) => a[0] - b[0] || a[1] - b[1]);
+
+  const result = new Array(people.length).fill(0);
+  const peopleWithIndex = people.map((time, index) => [time, index]);
+  peopleWithIndex.sort((a, b) => a[0] - b[0]);
+
+  let bloomCount = 0;
+  let eventIndex = 0;
+  for (const [time, personIndex] of peopleWithIndex) {
+    while (eventIndex < events.length && events[eventIndex][0] <= time) {
+      bloomCount += events[eventIndex][1];
+      eventIndex++;
+    }
+    result[personIndex] = bloomCount;
+  }
+
+  return result;
+};
diff --git a/solutions/2255-count-prefixes-of-a-given-string.js b/solutions/2255-count-prefixes-of-a-given-string.js
new file mode 100644
index 00000000..25f3ecbf
--- /dev/null
+++ b/solutions/2255-count-prefixes-of-a-given-string.js
@@ -0,0 +1,30 @@
+/**
+ * 2255. Count Prefixes of a Given String
+ * https://leetcode.com/problems/count-prefixes-of-a-given-string/
+ * Difficulty: Easy
+ *
+ * You are given a string array words and a string s, where words[i] and s comprise only of
+ * lowercase English letters.
+ *
+ * Return the number of strings in words that are a prefix of s.
+ *
+ * A prefix of a string is a substring that occurs at the beginning of the string. A substring
+ * is a contiguous sequence of characters within a string.
+ */
+
+/**
+ * @param {string[]} words
+ * @param {string} s
+ * @return {number}
+ */
+var countPrefixes = function(words, s) {
+  let result = 0;
+
+  for (const word of words) {
+    if (word.length <= s.length && s.startsWith(word)) {
+      result++;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2256-minimum-average-difference.js b/solutions/2256-minimum-average-difference.js
new file mode 100644
index 00000000..8c7ebdde
--- /dev/null
+++ b/solutions/2256-minimum-average-difference.js
@@ -0,0 +1,46 @@
+/**
+ * 2256. Minimum Average Difference
+ * https://leetcode.com/problems/minimum-average-difference/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed integer array nums of length n.
+ *
+ * The average difference of the index i is the absolute difference between the average of the
+ * first i + 1 elements of nums and the average of the last n - i - 1 elements. Both averages
+ * should be rounded down to the nearest integer.
+ *
+ * Return the index with the minimum average difference. If there are multiple such indices,
+ * return the smallest one.
+ *
+ * Note:
+ * - The absolute difference of two numbers is the absolute value of their difference.
+ * - The average of n elements is the sum of the n elements divided (integer division) by n.
+ * - The average of 0 elements is considered to be 0.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var minimumAverageDifference = function(nums) {
+  const n = nums.length;
+  let leftSum = 0;
+  let rightSum = nums.reduce((sum, num) => sum + num, 0);
+  let minDiff = Infinity;
+  let result = 0;
+
+  for (let i = 0; i < n; i++) {
+    leftSum += nums[i];
+    rightSum -= nums[i];
+    const leftAvg = Math.floor(leftSum / (i + 1));
+    const rightAvg = i === n - 1 ? 0 : Math.floor(rightSum / (n - i - 1));
+    const diff = Math.abs(leftAvg - rightAvg);
+
+    if (diff < minDiff) {
+      minDiff = diff;
+      result = i;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2257-count-unguarded-cells-in-the-grid.js b/solutions/2257-count-unguarded-cells-in-the-grid.js
new file mode 100644
index 00000000..87cbde16
--- /dev/null
+++ b/solutions/2257-count-unguarded-cells-in-the-grid.js
@@ -0,0 +1,59 @@
+/**
+ * 2257. Count Unguarded Cells in the Grid
+ * https://leetcode.com/problems/count-unguarded-cells-in-the-grid/
+ * Difficulty: Medium
+ *
+ * You are given two integers m and n representing a 0-indexed m x n grid. You are also given two
+ * 2D integer arrays guards and walls where guards[i] = [rowi, coli] and walls[j] = [rowj, colj]
+ * represent the positions of the ith guard and jth wall respectively.
+ *
+ * A guard can see every cell in the four cardinal directions (north, east, south, or west) starting
+ * from their position unless obstructed by a wall or another guard. A cell is guarded if there is
+ * at least one guard that can see it.
+ *
+ * Return the number of unoccupied cells that are not guarded.
+ */
+
+/**
+ * @param {number} m
+ * @param {number} n
+ * @param {number[][]} guards
+ * @param {number[][]} walls
+ * @return {number}
+ */
+var countUnguarded = function(m, n, guards, walls) {
+  const grid = Array.from({ length: m }, () => Array(n).fill(0));
+
+  for (const [row, col] of walls) {
+    grid[row][col] = 1;
+  }
+  for (const [row, col] of guards) {
+    grid[row][col] = 2;
+  }
+
+  for (const [row, col] of guards) {
+    for (let i = row - 1; i >= 0 && grid[i][col] !== 1 && grid[i][col] !== 2; i--) {
+      grid[i][col] = 3;
+    }
+    for (let i = row + 1; i < m && grid[i][col] !== 1 && grid[i][col] !== 2; i++) {
+      grid[i][col] = 3;
+    }
+    for (let j = col - 1; j >= 0 && grid[row][j] !== 1 && grid[row][j] !== 2; j--) {
+      grid[row][j] = 3;
+    }
+    for (let j = col + 1; j < n && grid[row][j] !== 1 && grid[row][j] !== 2; j++) {
+      grid[row][j] = 3;
+    }
+  }
+
+  let result = 0;
+  for (let i = 0; i < m; i++) {
+    for (let j = 0; j < n; j++) {
+      if (grid[i][j] === 0) {
+        result++;
+      }
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2258-escape-the-spreading-fire.js b/solutions/2258-escape-the-spreading-fire.js
new file mode 100644
index 00000000..7e26720a
--- /dev/null
+++ b/solutions/2258-escape-the-spreading-fire.js
@@ -0,0 +1,118 @@
+/**
+ * 2258. Escape the Spreading Fire
+ * https://leetcode.com/problems/escape-the-spreading-fire/
+ * Difficulty: Hard
+ *
+ * You are given a 0-indexed 2D integer array grid of size m x n which represents a field.
+ * Each cell has one of three values:
+ * - 0 represents grass,
+ * - 1 represents fire,
+ * - 2 represents a wall that you and fire cannot pass through.
+ *
+ * You are situated in the top-left cell, (0, 0), and you want to travel to the safehouse at the
+ * bottom-right cell, (m - 1, n - 1). Every minute, you may move to an adjacent grass cell. After
+ * your move, every fire cell will spread to all adjacent cells that are not walls.
+ *
+ * Return the maximum number of minutes that you can stay in your initial position before moving
+ * while still safely reaching the safehouse. If this is impossible, return -1. If you can always
+ * reach the safehouse regardless of the minutes stayed, return 109.
+ *
+ * Note that even if the fire spreads to the safehouse immediately after you have reached it, it
+ * will be counted as safely reaching the safehouse.
+ *
+ * A cell is adjacent to another cell if the former is directly north, east, south, or west of the
+ * latter (i.e., their sides are touching).
+ */
+
+/**
+ * @param {number[][]} grid
+ * @return {number}
+ */
+var maximumMinutes = function(grid) {
+  const m = grid.length;
+  const n = grid[0].length;
+  const directions = [[0, 1], [1, 0], [0, -1], [-1, 0]];
+  const MAX_ANSWER = 1000000000;
+
+  function isValid(x, y) {
+    return x >= 0 && x < m && y >= 0 && y < n && grid[x][y] === 0;
+  }
+
+  function calculateFireTime() {
+    const fireTime = new Array(m).fill().map(() => new Array(n).fill(Infinity));
+    const queue = [];
+
+    for (let i = 0; i < m; i++) {
+      for (let j = 0; j < n; j++) {
+        if (grid[i][j] === 1) {
+          queue.push([i, j, 0]);
+          fireTime[i][j] = 0;
+        }
+      }
+    }
+
+    while (queue.length > 0) {
+      const [x, y, time] = queue.shift();
+
+      for (const [dx, dy] of directions) {
+        const nx = x + dx;
+        const ny = y + dy;
+
+        if (isValid(nx, ny) && fireTime[nx][ny] === Infinity) {
+          fireTime[nx][ny] = time + 1;
+          queue.push([nx, ny, time + 1]);
+        }
+      }
+    }
+
+    return fireTime;
+  }
+
+  function canReachSafehouse(delay) {
+    const fireTime = calculateFireTime();
+    const visited = new Array(m).fill().map(() => new Array(n).fill(false));
+    const queue = [[0, 0, delay]];
+    visited[0][0] = true;
+
+    while (queue.length > 0) {
+      const [x, y, time] = queue.shift();
+
+      for (const [dx, dy] of directions) {
+        const nx = x + dx;
+        const ny = y + dy;
+
+        if (!isValid(nx, ny) || visited[nx][ny]) continue;
+
+        if (nx === m - 1 && ny === n - 1) {
+          if (time + 1 <= fireTime[nx][ny] || fireTime[nx][ny] === Infinity) {
+            return true;
+          }
+        }
+
+        if (time + 1 < fireTime[nx][ny]) {
+          visited[nx][ny] = true;
+          queue.push([nx, ny, time + 1]);
+        }
+      }
+    }
+
+    return false;
+  }
+
+  let left = 0;
+  let right = MAX_ANSWER;
+  let result = -1;
+
+  while (left <= right) {
+    const mid = Math.floor((left + right) / 2);
+
+    if (canReachSafehouse(mid)) {
+      result = mid;
+      left = mid + 1;
+    } else {
+      right = mid - 1;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2259-remove-digit-from-number-to-maximize-result.js b/solutions/2259-remove-digit-from-number-to-maximize-result.js
new file mode 100644
index 00000000..d9ee4397
--- /dev/null
+++ b/solutions/2259-remove-digit-from-number-to-maximize-result.js
@@ -0,0 +1,31 @@
+/**
+ * 2259. Remove Digit From Number to Maximize Result
+ * https://leetcode.com/problems/remove-digit-from-number-to-maximize-result/
+ * Difficulty: Easy
+ *
+ * You are given a string number representing a positive integer and a character digit.
+ *
+ * Return the resulting string after removing exactly one occurrence of digit from number such that
+ * the value of the resulting string in decimal form is maximized. The test cases are generated such
+ * that digit occurs at least once in number.
+ */
+
+/**
+ * @param {string} number
+ * @param {character} digit
+ * @return {string}
+ */
+var removeDigit = function(number, digit) {
+  let result = '';
+
+  for (let i = 0; i < number.length; i++) {
+    if (number[i] === digit) {
+      const candidate = number.slice(0, i) + number.slice(i + 1);
+      if (candidate > result) {
+        result = candidate;
+      }
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2260-minimum-consecutive-cards-to-pick-up.js b/solutions/2260-minimum-consecutive-cards-to-pick-up.js
new file mode 100644
index 00000000..4463e10c
--- /dev/null
+++ b/solutions/2260-minimum-consecutive-cards-to-pick-up.js
@@ -0,0 +1,29 @@
+/**
+ * 2260. Minimum Consecutive Cards to Pick Up
+ * https://leetcode.com/problems/minimum-consecutive-cards-to-pick-up/
+ * Difficulty: Medium
+ *
+ * You are given an integer array cards where cards[i] represents the value of the ith card. A pair
+ * of cards are matching if the cards have the same value.
+ *
+ * Return the minimum number of consecutive cards you have to pick up to have a pair of matching
+ * cards among the picked cards. If it is impossible to have matching cards, return -1.
+ */
+
+/**
+ * @param {number[]} cards
+ * @return {number}
+ */
+var minimumCardPickup = function(cards) {
+  const map = new Map();
+  let minLength = Infinity;
+
+  for (let i = 0; i < cards.length; i++) {
+    if (map.has(cards[i])) {
+      minLength = Math.min(minLength, i - map.get(cards[i]) + 1);
+    }
+    map.set(cards[i], i);
+  }
+
+  return minLength === Infinity ? -1 : minLength;
+};
diff --git a/solutions/2261-k-divisible-elements-subarrays.js b/solutions/2261-k-divisible-elements-subarrays.js
new file mode 100644
index 00000000..72d781d1
--- /dev/null
+++ b/solutions/2261-k-divisible-elements-subarrays.js
@@ -0,0 +1,41 @@
+/**
+ * 2261. K Divisible Elements Subarrays
+ * https://leetcode.com/problems/k-divisible-elements-subarrays/
+ * Difficulty: Medium
+ *
+ * Given an integer array nums and two integers k and p, return the number of distinct subarrays,
+ * which have at most k elements that are divisible by p.
+ *
+ * Two arrays nums1 and nums2 are said to be distinct if:
+ * - They are of different lengths, or
+ * - There exists at least one index i where nums1[i] != nums2[i].
+ *
+ * A subarray is defined as a non-empty contiguous sequence of elements in an array.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @param {number} p
+ * @return {number}
+ */
+var countDistinct = function(nums, k, p) {
+  const n = nums.length;
+  const seen = new Set();
+
+  for (let start = 0; start < n; start++) {
+    const subarray = [];
+    let divisibleCount = 0;
+
+    for (let end = start; end < n; end++) {
+      subarray.push(nums[end]);
+      if (nums[end] % p === 0) divisibleCount++;
+
+      if (divisibleCount <= k) {
+        seen.add(subarray.join(','));
+      }
+    }
+  }
+
+  return seen.size;
+};
diff --git a/solutions/2262-total-appeal-of-a-string.js b/solutions/2262-total-appeal-of-a-string.js
new file mode 100644
index 00000000..20c2e2c3
--- /dev/null
+++ b/solutions/2262-total-appeal-of-a-string.js
@@ -0,0 +1,31 @@
+/**
+ * 2262. Total Appeal of A String
+ * https://leetcode.com/problems/total-appeal-of-a-string/
+ * Difficulty: Hard
+ *
+ * The appeal of a string is the number of distinct characters found in the string.
+ * - For example, the appeal of "abbca" is 3 because it has 3 distinct characters:
+ *   'a', 'b', and 'c'.
+ *
+ * Given a string s, return the total appeal of all of its substrings.
+ *
+ * A substring is a contiguous sequence of characters within a string.
+ */
+
+/**
+ * @param {string} s
+ * @return {number}
+ */
+var appealSum = function(s) {
+  const n = s.length;
+  const lastSeen = new Array(26).fill(-1);
+  let result = 0;
+
+  for (let i = 0; i < n; i++) {
+    const charIndex = s.charCodeAt(i) - 97;
+    result += (i - lastSeen[charIndex]) * (n - i);
+    lastSeen[charIndex] = i;
+  }
+
+  return result;
+};
diff --git a/solutions/2264-largest-3-same-digit-number-in-string.js b/solutions/2264-largest-3-same-digit-number-in-string.js
new file mode 100644
index 00000000..ef1df3a9
--- /dev/null
+++ b/solutions/2264-largest-3-same-digit-number-in-string.js
@@ -0,0 +1,35 @@
+/**
+ * 2264. Largest 3-Same-Digit Number in String
+ * https://leetcode.com/problems/largest-3-same-digit-number-in-string/
+ * Difficulty: Easy
+ *
+ * You are given a string num representing a large integer. An integer is good if it meets
+ * the following conditions:
+ * - It is a substring of num with length 3.
+ * - It consists of only one unique digit.
+ *
+ * Return the maximum good integer as a string or an empty string "" if no such integer exists.
+ *
+ * Note:
+ * - A substring is a contiguous sequence of characters within a string.
+ * - There may be leading zeroes in num or a good integer.
+ */
+
+/**
+ * @param {string} num
+ * @return {string}
+ */
+var largestGoodInteger = function(num) {
+  let result = '';
+
+  for (let i = 0; i <= num.length - 3; i++) {
+    const substring = num.slice(i, i + 3);
+    if (substring[0] === substring[1] && substring[1] === substring[2]) {
+      if (substring > result) {
+        result = substring;
+      }
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2265-count-nodes-equal-to-average-of-subtree.js b/solutions/2265-count-nodes-equal-to-average-of-subtree.js
new file mode 100644
index 00000000..2e3f4cb5
--- /dev/null
+++ b/solutions/2265-count-nodes-equal-to-average-of-subtree.js
@@ -0,0 +1,46 @@
+/**
+ * 2265. Count Nodes Equal to Average of Subtree
+ * https://leetcode.com/problems/count-nodes-equal-to-average-of-subtree/
+ * Difficulty: Medium
+ *
+ * Given the root of a binary tree, return the number of nodes where the value of the node is
+ * equal to the average of the values in its subtree.
+ *
+ * Note:
+ * - The average of n elements is the sum of the n elements divided by n and rounded down to
+ *   the nearest integer.
+ * - A subtree of root is a tree consisting of root and all of its descendants.
+ */
+
+/**
+ * Definition for a binary tree node.
+ * function TreeNode(val, left, right) {
+ *     this.val = (val===undefined ? 0 : val)
+ *     this.left = (left===undefined ? null : left)
+ *     this.right = (right===undefined ? null : right)
+ * }
+ */
+/**
+ * @param {TreeNode} root
+ * @return {number}
+ */
+var averageOfSubtree = function(root) {
+  let count = 0;
+  traverse(root);
+  return count;
+
+  function traverse(node) {
+    if (!node) return [0, 0];
+
+    const [leftSum, leftCount] = traverse(node.left);
+    const [rightSum, rightCount] = traverse(node.right);
+    const totalSum = leftSum + rightSum + node.val;
+    const totalCount = leftCount + rightCount + 1;
+
+    if (Math.floor(totalSum / totalCount) === node.val) {
+      count++;
+    }
+
+    return [totalSum, totalCount];
+  }
+};
diff --git a/solutions/2266-count-number-of-texts.js b/solutions/2266-count-number-of-texts.js
new file mode 100644
index 00000000..d2f9cf84
--- /dev/null
+++ b/solutions/2266-count-number-of-texts.js
@@ -0,0 +1,57 @@
+/**
+ * 2266. Count Number of Texts
+ * https://leetcode.com/problems/count-number-of-texts/
+ * Difficulty: Medium
+ *
+ * Alice is texting Bob using her phone. The mapping of digits to letters is shown in the
+ * figure below.
+ *
+ * In order to add a letter, Alice has to press the key of the corresponding digit i times,
+ * where i is the position of the letter in the key.
+ * - For example, to add the letter 's', Alice has to press '7' four times. Similarly, to
+ *   add the letter 'k', Alice has to press '5' twice.
+ * - Note that the digits '0' and '1' do not map to any letters, so Alice does not use them.
+ *
+ * However, due to an error in transmission, Bob did not receive Alice's text message but
+ * received a string of pressed keys instead.
+ * - For example, when Alice sent the message "bob", Bob received the string "2266622".
+ *
+ * Given a string pressedKeys representing the string received by Bob, return the total
+ * number of possible text messages Alice could have sent.
+ *
+ * Since the answer may be very large, return it modulo 109 + 7.
+ */
+
+/**
+ * @param {string} pressedKeys
+ * @return {number}
+ */
+var countTexts = function(pressedKeys) {
+  const mod = 1e9 + 7;
+  const maxGroup = pressedKeys.length;
+  const dp = new Array(maxGroup + 1).fill(0);
+  dp[0] = 1;
+
+  const map = new Map([
+    ['2', 3], ['3', 3], ['4', 3], ['5', 3],
+    ['6', 3], ['7', 4], ['8', 3], ['9', 4]
+  ]);
+
+  for (let i = 1; i <= maxGroup; i++) {
+    dp[i] = dp[i - 1];
+    if (i >= 2 && pressedKeys[i - 1] === pressedKeys[i - 2]) {
+      dp[i] = (dp[i] + dp[i - 2]) % mod;
+    }
+    if (i >= 3 && pressedKeys[i - 1] === pressedKeys[i - 2]
+        && pressedKeys[i - 2] === pressedKeys[i - 3]) {
+      dp[i] = (dp[i] + dp[i - 3]) % mod;
+    }
+    if (i >= 4 && pressedKeys[i - 1] === pressedKeys[i - 2]
+        && pressedKeys[i - 2] === pressedKeys[i - 3]
+        && pressedKeys[i - 3] === pressedKeys[i - 4] && map.get(pressedKeys[i - 1]) === 4) {
+      dp[i] = (dp[i] + dp[i - 4]) % mod;
+    }
+  }
+
+  return dp[maxGroup];
+};
diff --git a/solutions/2267-check-if-there-is-a-valid-parentheses-string-path.js b/solutions/2267-check-if-there-is-a-valid-parentheses-string-path.js
new file mode 100644
index 00000000..8dc163ed
--- /dev/null
+++ b/solutions/2267-check-if-there-is-a-valid-parentheses-string-path.js
@@ -0,0 +1,57 @@
+/**
+ * 2267. Check if There Is a Valid Parentheses String Path
+ * https://leetcode.com/problems/check-if-there-is-a-valid-parentheses-string-path/
+ * Difficulty: Hard
+ *
+ * A parentheses string is a non-empty string consisting only of '(' and ')'. It is valid if any of
+ * the following conditions is true:
+ * - It is ().
+ * - It can be written as AB (A concatenated with B), where A and B are valid parentheses strings.
+ * - It can be written as (A), where A is a valid parentheses string.
+ *
+ * You are given an m x n matrix of parentheses grid. A valid parentheses string path in the grid
+ * is a path satisfying all of the following conditions:
+ * - The path starts from the upper left cell (0, 0).
+ * - The path ends at the bottom-right cell (m - 1, n - 1).
+ * - The path only ever moves down or right.
+ * - The resulting parentheses string formed by the path is valid.
+ *
+ * Return true if there exists a valid parentheses string path in the grid. Otherwise, return false.
+ */
+
+/**
+* @param {character[][]} grid
+* @return {boolean}
+*/
+var hasValidPath = function(grid) {
+  const m = grid.length;
+  const n = grid[0].length;
+
+  if ((m + n - 1) % 2 !== 0) {
+    return false;
+  }
+
+  if (grid[0][0] === ')' || grid[m - 1][n - 1] === '(') {
+    return false;
+  }
+
+  const visited = new Set();
+  return dfs(0, 0, 0);
+
+  function dfs(i, j, openCount) {
+    if (i >= m || j >= n || openCount < 0) {
+      return false;
+    }
+    openCount += grid[i][j] === '(' ? 1 : -1;
+    if (i === m - 1 && j === n - 1) {
+      return openCount === 0;
+    }
+    const key = `${i},${j},${openCount}`;
+    if (visited.has(key)) {
+      return false;
+    }
+    visited.add(key);
+
+    return dfs(i + 1, j, openCount) || dfs(i, j + 1, openCount);
+  }
+};
diff --git a/solutions/2269-find-the-k-beauty-of-a-number.js b/solutions/2269-find-the-k-beauty-of-a-number.js
new file mode 100644
index 00000000..3027e4d4
--- /dev/null
+++ b/solutions/2269-find-the-k-beauty-of-a-number.js
@@ -0,0 +1,37 @@
+/**
+ * 2269. Find the K-Beauty of a Number
+ * https://leetcode.com/problems/find-the-k-beauty-of-a-number/
+ * Difficulty: Easy
+ *
+ * The k-beauty of an integer num is defined as the number of substrings of num when it is
+ * read as a string that meet the following conditions:
+ * - It has a length of k.
+ * - It is a divisor of num.
+ *
+ * Given integers num and k, return the k-beauty of num.
+ *
+ * Note:
+ * - Leading zeros are allowed.
+ * - 0 is not a divisor of any value.
+ *
+ * A substring is a contiguous sequence of characters in a string.
+ */
+
+/**
+ * @param {number} num
+ * @param {number} k
+ * @return {number}
+ */
+var divisorSubstrings = function(num, k) {
+  const numStr = num.toString();
+  let result = 0;
+
+  for (let i = 0; i <= numStr.length - k; i++) {
+    const substring = parseInt(numStr.slice(i, i + k));
+    if (substring !== 0 && num % substring === 0) {
+      result++;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2271-maximum-white-tiles-covered-by-a-carpet.js b/solutions/2271-maximum-white-tiles-covered-by-a-carpet.js
new file mode 100644
index 00000000..0af443fc
--- /dev/null
+++ b/solutions/2271-maximum-white-tiles-covered-by-a-carpet.js
@@ -0,0 +1,50 @@
+/**
+ * 2271. Maximum White Tiles Covered by a Carpet
+ * https://leetcode.com/problems/maximum-white-tiles-covered-by-a-carpet/
+ * Difficulty: Medium
+ *
+ * You are given a 2D integer array tiles where tiles[i] = [li, ri] represents that every tile
+ * j in the range li <= j <= ri is colored white.
+ *
+ * You are also given an integer carpetLen, the length of a single carpet that can be placed
+ * anywhere.
+ *
+ * Return the maximum number of white tiles that can be covered by the carpet.
+ */
+
+/**
+ * @param {number[][]} tiles
+ * @param {number} carpetLen
+ * @return {number}
+ */
+var maximumWhiteTiles = function(tiles, carpetLen) {
+  tiles.sort((a, b) => a[0] - b[0]);
+
+  let result = 0;
+  let covered = 0;
+  let j = 0;
+
+  for (let i = 0; i < tiles.length; i++) {
+    const carpetEnd = tiles[i][0] + carpetLen - 1;
+
+    while (j < tiles.length && tiles[j][0] <= carpetEnd) {
+      if (tiles[j][1] <= carpetEnd) {
+        covered += tiles[j][1] - tiles[j][0] + 1;
+        j++;
+      } else {
+        covered += carpetEnd - tiles[j][0] + 1;
+        result = Math.max(result, covered);
+        covered -= carpetEnd - tiles[j][0] + 1;
+        break;
+      }
+    }
+
+    result = Math.max(result, covered);
+
+    if (j === tiles.length) break;
+
+    covered -= tiles[i][1] - tiles[i][0] + 1;
+  }
+
+  return result;
+};
diff --git a/solutions/2272-substring-with-largest-variance.js b/solutions/2272-substring-with-largest-variance.js
new file mode 100644
index 00000000..f11361c2
--- /dev/null
+++ b/solutions/2272-substring-with-largest-variance.js
@@ -0,0 +1,84 @@
+/**
+ * 2272. Substring With Largest Variance
+ * https://leetcode.com/problems/substring-with-largest-variance/
+ * Difficulty: Hard
+ *
+ * The variance of a string is defined as the largest difference between the number of occurrences
+ * of any 2 characters present in the string. Note the two characters may or may not be the same.
+ *
+ * Given a string s consisting of lowercase English letters only, return the largest variance
+ * possible among all substrings of s.
+ *
+ * A substring is a contiguous sequence of characters within a string.
+ */
+
+/**
+ * @param {string} s
+ * @return {number}
+ */
+var largestVariance = function(s) {
+  const map = new Set(s);
+  let result = 0;
+
+  for (const charA of map) {
+    for (const charB of map) {
+      if (charA === charB) continue;
+
+      let countA = 0;
+      let countB = 0;
+      let hasA = false;
+      let hasB = false;
+
+      for (const char of s) {
+        if (char === charA) {
+          countA++;
+          hasA = true;
+        }
+        if (char === charB) {
+          countB++;
+          hasB = true;
+        }
+
+        if (hasA && hasB) {
+          result = Math.max(result, Math.abs(countA - countB));
+        }
+
+        if (countA < countB) {
+          countA = 0;
+          countB = 0;
+          hasA = false;
+          hasB = false;
+        }
+      }
+
+      countA = 0;
+      countB = 0;
+      hasA = false;
+      hasB = false;
+
+      for (let i = s.length - 1; i >= 0; i--) {
+        if (s[i] === charA) {
+          countA++;
+          hasA = true;
+        }
+        if (s[i] === charB) {
+          countB++;
+          hasB = true;
+        }
+
+        if (hasA && hasB) {
+          result = Math.max(result, Math.abs(countA - countB));
+        }
+
+        if (countA < countB) {
+          countA = 0;
+          countB = 0;
+          hasA = false;
+          hasB = false;
+        }
+      }
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2273-find-resultant-array-after-removing-anagrams.js b/solutions/2273-find-resultant-array-after-removing-anagrams.js
new file mode 100644
index 00000000..8e0ef746
--- /dev/null
+++ b/solutions/2273-find-resultant-array-after-removing-anagrams.js
@@ -0,0 +1,38 @@
+/**
+ * 2273. Find Resultant Array After Removing Anagrams
+ * https://leetcode.com/problems/find-resultant-array-after-removing-anagrams/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed string array words, where words[i] consists of lowercase
+ * English letters.
+ *
+ * In one operation, select any index i such that 0 < i < words.length and words[i - 1] and
+ * words[i] are anagrams, and delete words[i] from words. Keep performing this operation as
+ * long as you can select an index that satisfies the conditions.
+ *
+ * Return words after performing all operations. It can be shown that selecting the indices
+ * for each operation in any arbitrary order will lead to the same result.
+ *
+ * An Anagram is a word or phrase formed by rearranging the letters of a different word or
+ * phrase using all the original letters exactly once. For example, "dacb" is an anagram of
+ * "abdc".
+ */
+
+/**
+ * @param {string[]} words
+ * @return {string[]}
+ */
+var removeAnagrams = function(words) {
+  const result = [words[0]];
+
+  for (let i = 1; i < words.length; i++) {
+    const prevSorted = result[result.length - 1].split('').sort().join('');
+    const currSorted = words[i].split('').sort().join('');
+
+    if (prevSorted !== currSorted) {
+      result.push(words[i]);
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2274-maximum-consecutive-floors-without-special-floors.js b/solutions/2274-maximum-consecutive-floors-without-special-floors.js
new file mode 100644
index 00000000..6ccb00f4
--- /dev/null
+++ b/solutions/2274-maximum-consecutive-floors-without-special-floors.js
@@ -0,0 +1,31 @@
+/**
+ * 2274. Maximum Consecutive Floors Without Special Floors
+ * https://leetcode.com/problems/maximum-consecutive-floors-without-special-floors/
+ * Difficulty: Medium
+ *
+ * Alice manages a company and has rented some floors of a building as office space. Alice has
+ * decided some of these floors should be special floors, used for relaxation only.
+ *
+ * You are given two integers bottom and top, which denote that Alice has rented all the floors
+ * from bottom to top (inclusive). You are also given the integer array special, where special[i]
+ * denotes a special floor that Alice has designated for relaxation.
+ *
+ * Return the maximum number of consecutive floors without a special floor.
+ */
+
+/**
+ * @param {number} bottom
+ * @param {number} top
+ * @param {number[]} special
+ * @return {number}
+ */
+var maxConsecutive = function(bottom, top, special) {
+  special.sort((a, b) => a - b);
+  let result = Math.max(special[0] - bottom, top - special[special.length - 1]);
+
+  for (let i = 1; i < special.length; i++) {
+    result = Math.max(result, special[i] - special[i - 1] - 1);
+  }
+
+  return result;
+};
diff --git a/solutions/2275-largest-combination-with-bitwise-and-greater-than-zero.js b/solutions/2275-largest-combination-with-bitwise-and-greater-than-zero.js
new file mode 100644
index 00000000..e75f68d3
--- /dev/null
+++ b/solutions/2275-largest-combination-with-bitwise-and-greater-than-zero.js
@@ -0,0 +1,37 @@
+/**
+ * 2275. Largest Combination With Bitwise AND Greater Than Zero
+ * https://leetcode.com/problems/largest-combination-with-bitwise-and-greater-than-zero/
+ * Difficulty: Medium
+ *
+ * The bitwise AND of an array nums is the bitwise AND of all integers in nums.
+ * - For example, for nums = [1, 5, 3], the bitwise AND is equal to 1 & 5 & 3 = 1.
+ * - Also, for nums = [7], the bitwise AND is 7.
+ *
+ * You are given an array of positive integers candidates. Compute the bitwise AND for all
+ * possible combinations of elements in the candidates array.
+ *
+ * Return the size of the largest combination of candidates with a bitwise AND greater than 0.
+ */
+
+/**
+ * @param {number[]} candidates
+ * @return {number}
+ */
+var largestCombination = function(candidates) {
+  const bitCounts = new Array(32).fill(0);
+  let result = 0;
+
+  for (const num of candidates) {
+    for (let i = 0; i < 32; i++) {
+      if (num & (1 << i)) {
+        bitCounts[i]++;
+      }
+    }
+  }
+
+  for (const count of bitCounts) {
+    result = Math.max(result, count);
+  }
+
+  return result;
+};
diff --git a/solutions/2278-percentage-of-letter-in-string.js b/solutions/2278-percentage-of-letter-in-string.js
new file mode 100644
index 00000000..fb3dfdbb
--- /dev/null
+++ b/solutions/2278-percentage-of-letter-in-string.js
@@ -0,0 +1,17 @@
+/**
+ * 2278. Percentage of Letter in String
+ * https://leetcode.com/problems/percentage-of-letter-in-string/
+ * Difficulty: Easy
+ *
+ * Given a string s and a character letter, return the percentage of characters in s that equal
+ * letter rounded down to the nearest whole percent.
+ */
+
+/**
+ * @param {string} s
+ * @param {character} letter
+ * @return {number}
+ */
+var percentageLetter = function(s, letter) {
+  return Math.floor((s.split('').filter(char => char === letter).length / s.length) * 100);
+};
diff --git a/solutions/2279-maximum-bags-with-full-capacity-of-rocks.js b/solutions/2279-maximum-bags-with-full-capacity-of-rocks.js
new file mode 100644
index 00000000..77d36c1a
--- /dev/null
+++ b/solutions/2279-maximum-bags-with-full-capacity-of-rocks.js
@@ -0,0 +1,38 @@
+/**
+ * 2279. Maximum Bags With Full Capacity of Rocks
+ * https://leetcode.com/problems/maximum-bags-with-full-capacity-of-rocks/
+ * Difficulty: Medium
+ *
+ * You have n bags numbered from 0 to n - 1. You are given two 0-indexed integer arrays capacity
+ * and rocks. The ith bag can hold a maximum of capacity[i] rocks and currently contains rocks[i]
+ * rocks. You are also given an integer additionalRocks, the number of additional rocks you can
+ * place in any of the bags.
+ *
+ * Return the maximum number of bags that could have full capacity after placing the additional
+ * rocks in some bags.
+ */
+
+/**
+ * @param {number[]} capacity
+ * @param {number[]} rocks
+ * @param {number} additionalRocks
+ * @return {number}
+ */
+var maximumBags = function(capacity, rocks, additionalRocks) {
+  const remaining = capacity.map((cap, i) => cap - rocks[i]);
+  remaining.sort((a, b) => a - b);
+
+  let result = 0;
+  let rocksLeft = additionalRocks;
+
+  for (const needed of remaining) {
+    if (needed <= rocksLeft) {
+      result++;
+      rocksLeft -= needed;
+    } else {
+      break;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2280-minimum-lines-to-represent-a-line-chart.js b/solutions/2280-minimum-lines-to-represent-a-line-chart.js
new file mode 100644
index 00000000..ff401c32
--- /dev/null
+++ b/solutions/2280-minimum-lines-to-represent-a-line-chart.js
@@ -0,0 +1,38 @@
+/**
+ * 2280. Minimum Lines to Represent a Line Chart
+ * https://leetcode.com/problems/minimum-lines-to-represent-a-line-chart/
+ * Difficulty: Medium
+ *
+ * You are given a 2D integer array stockPrices where stockPrices[i] = [dayi, pricei] indicates
+ * the price of the stock on day dayi is pricei. A line chart is created from the array by
+ * plotting the points on an XY plane with the X-axis representing the day and the Y-axis
+ * representing the price and connecting adjacent points. One such example is shown below.
+ *
+ * Return the minimum number of lines needed to represent the line chart.
+ */
+
+/**
+ * @param {number[][]} stockPrices
+ * @return {number}
+ */
+var minimumLines = function(stockPrices) {
+  if (stockPrices.length <= 2) return stockPrices.length - 1;
+
+  stockPrices.sort((a, b) => a[0] - b[0]);
+
+  let lines = 1;
+  for (let i = 2; i < stockPrices.length; i++) {
+    const [x0, y0] = stockPrices[i - 2];
+    const [x1, y1] = stockPrices[i - 1];
+    const [x2, y2] = stockPrices[i];
+
+    const dx1 = BigInt(x1 - x0);
+    const dy1 = BigInt(y1 - y0);
+    const dx2 = BigInt(x2 - x1);
+    const dy2 = BigInt(y2 - y1);
+
+    if (dy1 * dx2 !== dy2 * dx1) lines++;
+  }
+
+  return lines;
+};
diff --git a/solutions/2283-check-if-number-has-equal-digit-count-and-digit-value.js b/solutions/2283-check-if-number-has-equal-digit-count-and-digit-value.js
new file mode 100644
index 00000000..ea342877
--- /dev/null
+++ b/solutions/2283-check-if-number-has-equal-digit-count-and-digit-value.js
@@ -0,0 +1,30 @@
+/**
+ * 2283. Check if Number Has Equal Digit Count and Digit Value
+ * https://leetcode.com/problems/check-if-number-has-equal-digit-count-and-digit-value/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed string num of length n consisting of digits.
+ *
+ * Return true if for every index i in the range 0 <= i < n, the digit i occurs num[i] times in num,
+ * otherwise return false.
+ */
+
+/**
+ * @param {string} num
+ * @return {boolean}
+ */
+var digitCount = function(num) {
+  const frequency = new Array(10).fill(0);
+
+  for (const digit of num) {
+    frequency[digit]++;
+  }
+
+  for (let i = 0; i < num.length; i++) {
+    if (frequency[i] !== Number(num[i])) {
+      return false;
+    }
+  }
+
+  return true;
+};
diff --git a/solutions/2284-sender-with-largest-word-count.js b/solutions/2284-sender-with-largest-word-count.js
new file mode 100644
index 00000000..d4c02260
--- /dev/null
+++ b/solutions/2284-sender-with-largest-word-count.js
@@ -0,0 +1,44 @@
+/**
+ * 2284. Sender With Largest Word Count
+ * https://leetcode.com/problems/sender-with-largest-word-count/
+ * Difficulty: Medium
+ *
+ * You have a chat log of n messages. You are given two string arrays messages and senders
+ * where messages[i] is a message sent by senders[i].
+ *
+ * A message is list of words that are separated by a single space with no leading or trailing
+ * spaces. The word count of a sender is the total number of words sent by the sender. Note
+ * that a sender may send more than one message.
+ *
+ * Return the sender with the largest word count. If there is more than one sender with the
+ * largest word count, return the one with the lexicographically largest name.
+ *
+ * Note:
+ * - Uppercase letters come before lowercase letters in lexicographical order.
+ * - "Alice" and "alice" are distinct.
+ */
+
+/**
+ * @param {string[]} messages
+ * @param {string[]} senders
+ * @return {string}
+ */
+var largestWordCount = function(messages, senders) {
+  const map = new Map();
+  let maxWords = 0;
+  let result = '';
+
+  for (let i = 0; i < messages.length; i++) {
+    const wordCount = messages[i].split(' ').length;
+    const sender = senders[i];
+    const totalWords = (map.get(sender) || 0) + wordCount;
+    map.set(sender, totalWords);
+
+    if (totalWords > maxWords || (totalWords === maxWords && sender > result)) {
+      maxWords = totalWords;
+      result = sender;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2287-rearrange-characters-to-make-target-string.js b/solutions/2287-rearrange-characters-to-make-target-string.js
new file mode 100644
index 00000000..310eb5a2
--- /dev/null
+++ b/solutions/2287-rearrange-characters-to-make-target-string.js
@@ -0,0 +1,38 @@
+/**
+ * 2287. Rearrange Characters to Make Target String
+ * https://leetcode.com/problems/rearrange-characters-to-make-target-string/
+ * Difficulty: Easy
+ *
+ * You are given two 0-indexed strings s and target. You can take some letters from s and
+ * rearrange them to form new strings.
+ *
+ * Return the maximum number of copies of target that can be formed by taking letters from
+ * s and rearranging them.
+ */
+
+/**
+ * @param {string} s
+ * @param {string} target
+ * @return {number}
+ */
+var rearrangeCharacters = function(s, target) {
+  const sourceFreq = new Array(26).fill(0);
+  const targetFreq = new Array(26).fill(0);
+
+  for (const char of s) {
+    sourceFreq[char.charCodeAt(0) - 97]++;
+  }
+
+  for (const char of target) {
+    targetFreq[char.charCodeAt(0) - 97]++;
+  }
+
+  let result = Infinity;
+  for (let i = 0; i < 26; i++) {
+    if (targetFreq[i] > 0) {
+      result = Math.min(result, Math.floor(sourceFreq[i] / targetFreq[i]));
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2288-apply-discount-to-prices.js b/solutions/2288-apply-discount-to-prices.js
new file mode 100644
index 00000000..4645204e
--- /dev/null
+++ b/solutions/2288-apply-discount-to-prices.js
@@ -0,0 +1,37 @@
+/**
+ * 2288. Apply Discount to Prices
+ * https://leetcode.com/problems/apply-discount-to-prices/
+ * Difficulty: Medium
+ *
+ * A sentence is a string of single-space separated words where each word can contain digits,
+ * lowercase letters, and the dollar sign '$'. A word represents a price if it is a sequence
+ * of digits preceded by a dollar sign.
+ * - For example, "$100", "$23", and "$6" represent prices while "100", "$", and "$1e5" do not.
+ *
+ * You are given a string sentence representing a sentence and an integer discount. For each
+ * word representing a price, apply a discount of discount% on the price and update the word
+ * in the sentence. All updated prices should be represented with exactly two decimal places.
+ *
+ * Return a string representing the modified sentence.
+ *
+ * Note that all prices will contain at most 10 digits.
+ */
+
+/**
+ * @param {string} sentence
+ * @param {number} discount
+ * @return {string}
+ */
+var discountPrices = function(sentence, discount) {
+  const words = sentence.split(' ');
+  const discountFactor = 1 - discount / 100;
+
+  for (let i = 0; i < words.length; i++) {
+    if (words[i].startsWith('$') && /^[0-9]+$/.test(words[i].slice(1))) {
+      const price = parseInt(words[i].slice(1)) * discountFactor;
+      words[i] = `$${price.toFixed(2)}`;
+    }
+  }
+
+  return words.join(' ');
+};
diff --git a/solutions/2293-min-max-game.js b/solutions/2293-min-max-game.js
new file mode 100644
index 00000000..b6952f9c
--- /dev/null
+++ b/solutions/2293-min-max-game.js
@@ -0,0 +1,43 @@
+/**
+ * 2293. Min Max Game
+ * https://leetcode.com/problems/min-max-game/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed integer array nums whose length is a power of 2.
+ *
+ * Apply the following algorithm on nums:
+ * 1. Let n be the length of nums. If n == 1, end the process. Otherwise, create a new 0-indexed
+ *    integer array newNums of length n / 2.
+ * 2. For every even index i where 0 <= i < n / 2, assign the value of newNums[i] as
+ *    min(nums[2 * i], nums[2 * i + 1]).
+ * 3. For every odd index i where 0 <= i < n / 2, assign the value of newNums[i] as
+ *    max(nums[2 * i], nums[2 * i + 1]).
+ * 4. Replace the array nums with newNums.
+ * 5. Repeat the entire process starting from step 1.
+ *
+ * Return the last number that remains in nums after applying the algorithm.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var minMaxGame = function(nums) {
+  let array = nums.slice();
+
+  while (array.length > 1) {
+    const newArray = new Array(array.length / 2);
+
+    for (let i = 0; i < newArray.length; i++) {
+      if (i % 2 === 0) {
+        newArray[i] = Math.min(array[2 * i], array[2 * i + 1]);
+      } else {
+        newArray[i] = Math.max(array[2 * i], array[2 * i + 1]);
+      }
+    }
+
+    array = newArray;
+  }
+
+  return array[0];
+};
diff --git a/solutions/2294-partition-array-such-that-maximum-difference-is-k.js b/solutions/2294-partition-array-such-that-maximum-difference-is-k.js
new file mode 100644
index 00000000..06cad3ae
--- /dev/null
+++ b/solutions/2294-partition-array-such-that-maximum-difference-is-k.js
@@ -0,0 +1,34 @@
+/**
+ * 2294. Partition Array Such That Maximum Difference Is K
+ * https://leetcode.com/problems/partition-array-such-that-maximum-difference-is-k/
+ * Difficulty: Medium
+ *
+ * You are given an integer array nums and an integer k. You may partition nums into one or more
+ * subsequences such that each element in nums appears in exactly one of the subsequences.
+ *
+ * Return the minimum number of subsequences needed such that the difference between the maximum
+ * and minimum values in each subsequence is at most k.
+ *
+ * A subsequence is a sequence that can be derived from another sequence by deleting some or no
+ * elements without changing the order of the remaining elements.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @return {number}
+ */
+var partitionArray = function(nums, k) {
+  nums.sort((a, b) => a - b);
+  let result = 1;
+  let minValue = nums[0];
+
+  for (let i = 1; i < nums.length; i++) {
+    if (nums[i] - minValue > k) {
+      result++;
+      minValue = nums[i];
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2295-replace-elements-in-an-array.js b/solutions/2295-replace-elements-in-an-array.js
new file mode 100644
index 00000000..de3bbad0
--- /dev/null
+++ b/solutions/2295-replace-elements-in-an-array.js
@@ -0,0 +1,36 @@
+/**
+ * 2295. Replace Elements in an Array
+ * https://leetcode.com/problems/replace-elements-in-an-array/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed array nums that consists of n distinct positive integers.
+ * Apply m operations to this array, where in the ith operation you replace the number
+ * operations[i][0] with operations[i][1].
+ *
+ * It is guaranteed that in the ith operation:
+ * - operations[i][0] exists in nums.
+ * - operations[i][1] does not exist in nums.
+ *
+ * Return the array obtained after applying all the operations.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number[][]} operations
+ * @return {number[]}
+ */
+var arrayChange = function(nums, operations) {
+  const map = new Map();
+  for (let i = 0; i < nums.length; i++) {
+    map.set(nums[i], i);
+  }
+
+  for (const [oldVal, newVal] of operations) {
+    const index = map.get(oldVal);
+    nums[index] = newVal;
+    map.set(newVal, index);
+    map.delete(oldVal);
+  }
+
+  return nums;
+};
diff --git a/solutions/2296-design-a-text-editor.js b/solutions/2296-design-a-text-editor.js
new file mode 100644
index 00000000..6020598d
--- /dev/null
+++ b/solutions/2296-design-a-text-editor.js
@@ -0,0 +1,78 @@
+/**
+ * 2296. Design a Text Editor
+ * https://leetcode.com/problems/design-a-text-editor/
+ * Difficulty: Hard
+ *
+ * Design a text editor with a cursor that can do the following:
+ * - Add text to where the cursor is.
+ * - Delete text from where the cursor is (simulating the backspace key).
+ * - Move the cursor either left or right.
+ *
+ * When deleting text, only characters to the left of the cursor will be deleted. The cursor
+ * will also remain within the actual text and cannot be moved beyond it. More formally,
+ * we have that 0 <= cursor.position <= currentText.length always holds.
+ *
+ * Implement the TextEditor class:
+ * - TextEditor() Initializes the object with empty text.
+ * - void addText(string text) Appends text to where the cursor is. The cursor ends to the
+ *   right of text.
+ * - int deleteText(int k) Deletes k characters to the left of the cursor. Returns the number
+ *   of characters actually deleted.
+ * - string cursorLeft(int k) Moves the cursor to the left k times. Returns the last
+ *   min(10, len) characters to the left of the cursor, where len is the number of characters
+ *   to the left of the cursor.
+ * - string cursorRight(int k) Moves the cursor to the right k times. Returns the last
+ *   min(10, len) characters to the left of the cursor, where len is the number of characters
+ *   to the left of the cursor.
+ */
+
+var TextEditor = function() {
+  this.left = [];
+  this.right = [];
+};
+
+/**
+ * @param {string} text
+ * @return {void}
+ */
+TextEditor.prototype.addText = function(text) {
+  for (const char of text) {
+    this.left.push(char);
+  }
+};
+
+/**
+ * @param {number} k
+ * @return {number}
+ */
+TextEditor.prototype.deleteText = function(k) {
+  const deleteCount = Math.min(k, this.left.length);
+  for (let i = 0; i < deleteCount; i++) {
+    this.left.pop();
+  }
+  return deleteCount;
+};
+
+/**
+ * @param {number} k
+ * @return {string}
+ */
+TextEditor.prototype.cursorLeft = function(k) {
+  for (let i = 0; i < k && this.left.length; i++) {
+    this.right.push(this.left.pop());
+  }
+  const start = Math.max(0, this.left.length - 10);
+  return this.left.slice(start).join('');
+};
+
+/**
+ * @param {number} k
+ * @return {string}
+ */
+TextEditor.prototype.cursorRight = function(k) {
+  for (let i = 0; i < k && this.right.length; i++) {
+    this.left.push(this.right.pop());
+  }
+  const start = Math.max(0, this.left.length - 10);
+  return this.left.slice(start).join('');
+};
diff --git a/solutions/2299-strong-password-checker-ii.js b/solutions/2299-strong-password-checker-ii.js
new file mode 100644
index 00000000..f96fac07
--- /dev/null
+++ b/solutions/2299-strong-password-checker-ii.js
@@ -0,0 +1,43 @@
+/**
+ * 2299. Strong Password Checker II
+ * https://leetcode.com/problems/strong-password-checker-ii/
+ * Difficulty: Easy
+ *
+ * A password is said to be strong if it satisfies all the following criteria:
+ * - It has at least 8 characters.
+ * - It contains at least one lowercase letter.
+ * - It contains at least one uppercase letter.
+ * - It contains at least one digit.
+ * - It contains at least one special character. The special characters are the characters
+ *   in the following string: "!@#$%^&*()-+".
+ * - It does not contain 2 of the same character in adjacent positions (i.e., "aab" violates
+ *   this condition, but "aba" does not).
+ *
+ * Given a string password, return true if it is a strong password. Otherwise, return false.
+ */
+
+/**
+ * @param {string} password
+ * @return {boolean}
+ */
+var strongPasswordCheckerII = function(password) {
+  if (password.length < 8) return false;
+
+  let hasLower = false;
+  let hasUpper = false;
+  let hasDigit = false;
+  let hasSpecial = false;
+  const set = new Set(['!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '-', '+']);
+
+  for (let i = 0; i < password.length; i++) {
+    if (i > 0 && password[i] === password[i - 1]) return false;
+
+    const char = password[i];
+    if (/[a-z]/.test(char)) hasLower = true;
+    else if (/[A-Z]/.test(char)) hasUpper = true;
+    else if (/\d/.test(char)) hasDigit = true;
+    else if (set.has(char)) hasSpecial = true;
+  }
+
+  return hasLower && hasUpper && hasDigit && hasSpecial;
+};
diff --git a/solutions/2301-match-substring-after-replacement.js b/solutions/2301-match-substring-after-replacement.js
new file mode 100644
index 00000000..fc7e5a91
--- /dev/null
+++ b/solutions/2301-match-substring-after-replacement.js
@@ -0,0 +1,50 @@
+/**
+ * 2301. Match Substring After Replacement
+ * https://leetcode.com/problems/match-substring-after-replacement/
+ * Difficulty: Hard
+ *
+ * You are given two strings s and sub. You are also given a 2D character array mappings where
+ * mappings[i] = [oldi, newi] indicates that you may perform the following operation any number
+ * of times:
+ * - Replace a character oldi of sub with newi.
+ *
+ * Each character in sub cannot be replaced more than once.
+ *
+ * Return true if it is possible to make sub a substring of s by replacing zero or more characters
+ * according to mappings. Otherwise, return false.
+ *
+ * A substring is a contiguous non-empty sequence of characters within a string.
+ */
+
+/**
+ * @param {string} s
+ * @param {string} sub
+ * @param {character[][]} mappings
+ * @return {boolean}
+ */
+var matchReplacement = function(s, sub, mappings) {
+  const map = new Map();
+
+  for (const [oldChar, newChar] of mappings) {
+    if (!map.has(oldChar)) {
+      map.set(oldChar, new Set());
+    }
+    map.get(oldChar).add(newChar);
+  }
+
+  const subLen = sub.length;
+  for (let i = 0; i <= s.length - subLen; i++) {
+    let isValid = true;
+    for (let j = 0; j < subLen; j++) {
+      const sChar = s[i + j];
+      const subChar = sub[j];
+      if (sChar !== subChar && (!map.has(subChar) || !map.get(subChar).has(sChar))) {
+        isValid = false;
+        break;
+      }
+    }
+    if (isValid) return true;
+  }
+
+  return false;
+};
diff --git a/solutions/2303-calculate-amount-paid-in-taxes.js b/solutions/2303-calculate-amount-paid-in-taxes.js
new file mode 100644
index 00000000..6944f54b
--- /dev/null
+++ b/solutions/2303-calculate-amount-paid-in-taxes.js
@@ -0,0 +1,41 @@
+/**
+ * 2303. Calculate Amount Paid in Taxes
+ * https://leetcode.com/problems/calculate-amount-paid-in-taxes/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed 2D integer array brackets where brackets[i] = [upperi, percenti]
+ * means that the ith tax bracket has an upper bound of upperi and is taxed at a rate of percenti.
+ * The brackets are sorted by upper bound (i.e. upperi-1 < upperi for 0 < i < brackets.length).
+ *
+ * Tax is calculated as follows:
+ * - The first upper0 dollars earned are taxed at a rate of percent0.
+ * - The next upper1 - upper0 dollars earned are taxed at a rate of percent1.
+ * - The next upper2 - upper1 dollars earned are taxed at a rate of percent2.
+ * - And so on.
+ *
+ * You are given an integer income representing the amount of money you earned. Return the
+ * amount of money that you have to pay in taxes. Answers within 10-5 of the actual answer
+ * will be accepted.
+ */
+
+/**
+ * @param {number[][]} brackets
+ * @param {number} income
+ * @return {number}
+ */
+var calculateTax = function(brackets, income) {
+  let result = 0;
+  let previousUpper = 0;
+
+  for (const [upper, percent] of brackets) {
+    if (income > previousUpper) {
+      const taxable = Math.min(income, upper) - previousUpper;
+      result += taxable * (percent / 100);
+      previousUpper = upper;
+    } else {
+      break;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2304-minimum-path-cost-in-a-grid.js b/solutions/2304-minimum-path-cost-in-a-grid.js
new file mode 100644
index 00000000..eb1f10c4
--- /dev/null
+++ b/solutions/2304-minimum-path-cost-in-a-grid.js
@@ -0,0 +1,48 @@
+/**
+ * 2304. Minimum Path Cost in a Grid
+ * https://leetcode.com/problems/minimum-path-cost-in-a-grid/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed m x n integer matrix grid consisting of distinct integers from
+ * 0 to m * n - 1. You can move in this matrix from a cell to any other cell in the next row.
+ * That is, if you are in cell (x, y) such that x < m - 1, you can move to any of the cells
+ * (x + 1, 0), (x + 1, 1), ..., (x + 1, n - 1). Note that it is not possible to move from
+ * cells in the last row.
+ *
+ * Each possible move has a cost given by a 0-indexed 2D array moveCost of size (m * n) x n,
+ * where moveCost[i][j] is the cost of moving from a cell with value i to a cell in column j
+ * of the next row. The cost of moving from cells in the last row of grid can be ignored.
+ *
+ * The cost of a path in grid is the sum of all values of cells visited plus the sum of costs
+ * of all the moves made. Return the minimum cost of a path that starts from any cell in the
+ * first row and ends at any cell in the last row.
+ */
+
+/**
+ * @param {number[][]} grid
+ * @param {number[][]} moveCost
+ * @return {number}
+ */
+var minPathCost = function(grid, moveCost) {
+  const m = grid.length;
+  const n = grid[0].length;
+  const dp = Array.from({ length: m }, () => new Array(n).fill(Infinity));
+
+  for (let j = 0; j < n; j++) {
+    dp[0][j] = grid[0][j];
+  }
+
+  for (let i = 0; i < m - 1; i++) {
+    for (let j = 0; j < n; j++) {
+      const value = grid[i][j];
+      for (let k = 0; k < n; k++) {
+        dp[i + 1][k] = Math.min(
+          dp[i + 1][k],
+          dp[i][j] + grid[i + 1][k] + moveCost[value][k]
+        );
+      }
+    }
+  }
+
+  return Math.min(...dp[m - 1]);
+};
diff --git a/solutions/2305-fair-distribution-of-cookies.js b/solutions/2305-fair-distribution-of-cookies.js
new file mode 100644
index 00000000..dffcb4a4
--- /dev/null
+++ b/solutions/2305-fair-distribution-of-cookies.js
@@ -0,0 +1,46 @@
+/**
+ * 2305. Fair Distribution of Cookies
+ * https://leetcode.com/problems/fair-distribution-of-cookies/
+ * Difficulty: Medium
+ *
+ * You are given an integer array cookies, where cookies[i] denotes the number of cookies in the
+ * ith bag. You are also given an integer k that denotes the number of children to distribute
+ * all the bags of cookies to. All the cookies in the same bag must go to the same child and
+ * cannot be split up.
+ *
+ * The unfairness of a distribution is defined as the maximum total cookies obtained by a single
+ * child in the distribution.
+ *
+ * Return the minimum unfairness of all distributions.
+ */
+
+/**
+ * @param {number[]} cookies
+ * @param {number} k
+ * @return {number}
+ */
+var distributeCookies = function(cookies, k) {
+  const distribution = new Array(k).fill(0);
+  let result = Infinity;
+
+  distribute(0);
+
+  return result;
+
+  function distribute(index) {
+    if (index === cookies.length) {
+      result = Math.min(result, Math.max(...distribution));
+      return;
+    }
+
+    for (let i = 0; i < k; i++) {
+      distribution[i] += cookies[index];
+      if (distribution[i] < result) {
+        distribute(index + 1);
+      }
+      distribution[i] -= cookies[index];
+
+      if (distribution[i] === 0) break;
+    }
+  }
+};
diff --git a/solutions/2306-naming-a-company.js b/solutions/2306-naming-a-company.js
new file mode 100644
index 00000000..bef81dfe
--- /dev/null
+++ b/solutions/2306-naming-a-company.js
@@ -0,0 +1,37 @@
+/**
+ * 2306. Naming a Company
+ * https://leetcode.com/problems/naming-a-company/
+ * Difficulty: Hard
+ *
+ * You are given an array of strings ideas that represents a list of names to be used in the
+ * process of naming a company. The process of naming a company is as follows:
+ * 1. Choose 2 distinct names from ideas, call them ideaA and ideaB.
+ * 2. Swap the first letters of ideaA and ideaB with each other.
+ * 3. If both of the new names are not found in the original ideas, then the name ideaA ideaB
+ *    (the concatenation of ideaA and ideaB, separated by a space) is a valid company name.
+ * 4. Otherwise, it is not a valid name.
+ *
+ * Return the number of distinct valid names for the company.
+ */
+
+/**
+ * @param {string[]} ideas
+ * @return {number}
+ */
+var distinctNames = function(ideas) {
+  const groups = Array.from({ length: 26 }, () => new Set());
+  let result = 0;
+
+  for (const idea of ideas) {
+    groups[idea.charCodeAt(0) - 97].add(idea.slice(1));
+  }
+
+  for (let i = 0; i < 25; i++) {
+    for (let j = i + 1; j < 26; j++) {
+      const mutualCount = [...groups[i]].filter(suffix => groups[j].has(suffix)).length;
+      result += 2 * (groups[i].size - mutualCount) * (groups[j].size - mutualCount);
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2309-greatest-english-letter-in-upper-and-lower-case.js b/solutions/2309-greatest-english-letter-in-upper-and-lower-case.js
new file mode 100644
index 00000000..b86b8f8b
--- /dev/null
+++ b/solutions/2309-greatest-english-letter-in-upper-and-lower-case.js
@@ -0,0 +1,38 @@
+/**
+ * 2309. Greatest English Letter in Upper and Lower Case
+ * https://leetcode.com/problems/greatest-english-letter-in-upper-and-lower-case/
+ * Difficulty: Easy
+ *
+ * Given a string of English letters s, return the greatest English letter which occurs as both
+ * a lowercase and uppercase letter in s. The returned letter should be in uppercase. If no such
+ * letter exists, return an empty string.
+ *
+ * An English letter b is greater than another letter a if b appears after a in the English
+ * alphabet.
+ */
+
+/**
+ * @param {string} s
+ * @return {string}
+ */
+var greatestLetter = function(s) {
+  const lowerSet = new Set();
+  const upperSet = new Set();
+
+  for (const char of s) {
+    if (char >= 'a' && char <= 'z') {
+      lowerSet.add(char);
+    } else {
+      upperSet.add(char.toLowerCase());
+    }
+  }
+
+  let maxLetter = '';
+  for (const char of lowerSet) {
+    if (upperSet.has(char) && char > maxLetter) {
+      maxLetter = char;
+    }
+  }
+
+  return maxLetter.toUpperCase();
+};
diff --git a/solutions/2312-selling-pieces-of-wood.js b/solutions/2312-selling-pieces-of-wood.js
new file mode 100644
index 00000000..6edab3a0
--- /dev/null
+++ b/solutions/2312-selling-pieces-of-wood.js
@@ -0,0 +1,46 @@
+/**
+ * 2312. Selling Pieces of Wood
+ * https://leetcode.com/problems/selling-pieces-of-wood/
+ * Difficulty: Hard
+ *
+ * You are given two integers m and n that represent the height and width of a rectangular piece
+ * of wood. You are also given a 2D integer array prices, where prices[i] = [hi, wi, pricei]
+ * indicates you can sell a rectangular piece of wood of height hi and width wi for pricei dollars.
+ *
+ * To cut a piece of wood, you must make a vertical or horizontal cut across the entire height
+ * or width of the piece to split it into two smaller pieces. After cutting a piece of wood into
+ * some number of smaller pieces, you can sell pieces according to prices. You may sell multiple
+ * pieces of the same shape, and you do not have to sell all the shapes. The grain of the wood
+ * makes a difference, so you cannot rotate a piece to swap its height and width.
+ *
+ * Return the maximum money you can earn after cutting an m x n piece of wood.
+ *
+ * Note that you can cut the piece of wood as many times as you want.
+ */
+
+/**
+ * @param {number} m
+ * @param {number} n
+ * @param {number[][]} prices
+ * @return {number}
+ */
+var sellingWood = function(m, n, prices) {
+  const dp = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
+
+  for (const [h, w, price] of prices) {
+    dp[h][w] = price;
+  }
+
+  for (let i = 1; i <= m; i++) {
+    for (let j = 1; j <= n; j++) {
+      for (let k = 1; k < i; k++) {
+        dp[i][j] = Math.max(dp[i][j], dp[k][j] + dp[i - k][j]);
+      }
+      for (let k = 1; k < j; k++) {
+        dp[i][j] = Math.max(dp[i][j], dp[i][k] + dp[i][j - k]);
+      }
+    }
+  }
+
+  return dp[m][n];
+};
diff --git a/solutions/2315-count-asterisks.js b/solutions/2315-count-asterisks.js
new file mode 100644
index 00000000..650055eb
--- /dev/null
+++ b/solutions/2315-count-asterisks.js
@@ -0,0 +1,32 @@
+/**
+ * 2315. Count Asterisks
+ * https://leetcode.com/problems/count-asterisks/
+ * Difficulty: Easy
+ *
+ * You are given a string s, where every two consecutive vertical bars '|' are grouped into
+ * a pair. In other words, the 1st and 2nd '|' make a pair, the 3rd and 4th '|' make a pair,
+ * and so forth.
+ *
+ * Return the number of '*' in s, excluding the '*' between each pair of '|'.
+ *
+ * Note that each '|' will belong to exactly one pair.
+ */
+
+/**
+ * @param {string} s
+ * @return {number}
+ */
+var countAsterisks = function(s) {
+  let isInsidePair = false;
+  let result = 0;
+
+  for (const char of s) {
+    if (char === '|') {
+      isInsidePair = !isInsidePair;
+    } else if (char === '*' && !isInsidePair) {
+      result++;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2316-count-unreachable-pairs-of-nodes-in-an-undirected-graph.js b/solutions/2316-count-unreachable-pairs-of-nodes-in-an-undirected-graph.js
new file mode 100644
index 00000000..4de0c07b
--- /dev/null
+++ b/solutions/2316-count-unreachable-pairs-of-nodes-in-an-undirected-graph.js
@@ -0,0 +1,48 @@
+/**
+ * 2316. Count Unreachable Pairs of Nodes in an Undirected Graph
+ * https://leetcode.com/problems/count-unreachable-pairs-of-nodes-in-an-undirected-graph/
+ * Difficulty: Medium
+ *
+ * You are given an integer n. There is an undirected graph with n nodes, numbered from 0
+ * to n - 1. You are given a 2D integer array edges where edges[i] = [ai, bi] denotes that
+ * there exists an undirected edge connecting nodes ai and bi.
+ *
+ * Return the number of pairs of different nodes that are unreachable from each other.
+ */
+
+/**
+ * @param {number} n
+ * @param {number[][]} edges
+ * @return {number}
+ */
+var countPairs = function(n, edges) {
+  const graph = Array.from({ length: n }, () => []);
+  for (const [a, b] of edges) {
+    graph[a].push(b);
+    graph[b].push(a);
+  }
+
+  const visited = new Array(n).fill(false);
+  let result = 0;
+
+  let totalNodes = 0;
+  for (let node = 0; node < n; node++) {
+    if (!visited[node]) {
+      const componentSize = exploreComponent(node);
+      result += totalNodes * componentSize;
+      totalNodes += componentSize;
+    }
+  }
+
+  return result;
+
+  function exploreComponent(node) {
+    if (visited[node]) return 0;
+    visited[node] = true;
+    let size = 1;
+    for (const neighbor of graph[node]) {
+      size += exploreComponent(neighbor);
+    }
+    return size;
+  }
+};
diff --git a/solutions/2317-maximum-xor-after-operations.js b/solutions/2317-maximum-xor-after-operations.js
new file mode 100644
index 00000000..7049675b
--- /dev/null
+++ b/solutions/2317-maximum-xor-after-operations.js
@@ -0,0 +1,27 @@
+/**
+ * 2317. Maximum XOR After Operations
+ * https://leetcode.com/problems/maximum-xor-after-operations/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed integer array nums. In one operation, select any non-negative
+ * integer x and an index i, then update nums[i] to be equal to nums[i] AND (nums[i] XOR x).
+ *
+ * Note that AND is the bitwise AND operation and XOR is the bitwise XOR operation.
+ *
+ * Return the maximum possible bitwise XOR of all elements of nums after applying the operation
+ * any number of times.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var maximumXOR = function(nums) {
+  let maxXor = 0;
+
+  for (const num of nums) {
+    maxXor |= num;
+  }
+
+  return maxXor;
+};
diff --git a/solutions/2318-number-of-distinct-roll-sequences.js b/solutions/2318-number-of-distinct-roll-sequences.js
new file mode 100644
index 00000000..5f67f5c0
--- /dev/null
+++ b/solutions/2318-number-of-distinct-roll-sequences.js
@@ -0,0 +1,55 @@
+/**
+ * 2318. Number of Distinct Roll Sequences
+ * https://leetcode.com/problems/number-of-distinct-roll-sequences/
+ * Difficulty: Hard
+ *
+ * You are given an integer n. You roll a fair 6-sided dice n times. Determine the total number
+ * of distinct sequences of rolls possible such that the following conditions are satisfied:
+ * 1. The greatest common divisor of any adjacent values in the sequence is equal to 1.
+ * 2. There is at least a gap of 2 rolls between equal valued rolls. More formally, if the
+ *    value of the ith roll is equal to the value of the jth roll, then abs(i - j) > 2.
+ *
+ * Return the total number of distinct sequences possible. Since the answer may be very large,
+ * return it modulo 109 + 7.
+ *
+ * Two sequences are considered distinct if at least one element is different.
+ */
+
+/**
+ * @param {number} n
+ * @return {number}
+ */
+var distinctSequences = function(n) {
+  const MOD = 1e9 + 7;
+  const gcd = (a, b) => b === 0 ? a : gcd(b, a % b);
+
+  const dp = new Array(n + 1)
+    .fill()
+    .map(() => new Array(7).fill().map(() => new Array(7).fill(0)));
+
+  for (let i = 1; i <= 6; i++) {
+    dp[1][i][0] = 1;
+  }
+
+  for (let len = 2; len <= n; len++) {
+    for (let curr = 1; curr <= 6; curr++) {
+      for (let prev = 0; prev <= 6; prev++) {
+        for (let prevPrev = 0; prevPrev <= 6; prevPrev++) {
+          if (dp[len - 1][prev][prevPrev] === 0) continue;
+          if (curr === prev || curr === prevPrev) continue;
+          if (prev !== 0 && gcd(curr, prev) !== 1) continue;
+          dp[len][curr][prev] = (dp[len][curr][prev] + dp[len - 1][prev][prevPrev]) % MOD;
+        }
+      }
+    }
+  }
+
+  let result = 0;
+  for (let curr = 1; curr <= 6; curr++) {
+    for (let prev = 0; prev <= 6; prev++) {
+      result = (result + dp[n][curr][prev]) % MOD;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2319-check-if-matrix-is-x-matrix.js b/solutions/2319-check-if-matrix-is-x-matrix.js
new file mode 100644
index 00000000..ee45ca42
--- /dev/null
+++ b/solutions/2319-check-if-matrix-is-x-matrix.js
@@ -0,0 +1,32 @@
+/**
+ * 2319. Check if Matrix Is X-Matrix
+ * https://leetcode.com/problems/check-if-matrix-is-x-matrix/
+ * Difficulty: Easy
+ *
+ * A square matrix is said to be an X-Matrix if both of the following conditions hold:
+ * 1. All the elements in the diagonals of the matrix are non-zero.
+ * 2. All other elements are 0.
+ *
+ * Given a 2D integer array grid of size n x n representing a square matrix, return true if grid
+ * is an X-Matrix. Otherwise, return false.
+ */
+
+/**
+ * @param {number[][]} grid
+ * @return {boolean}
+ */
+var checkXMatrix = function(grid) {
+  const size = grid.length;
+
+  for (let row = 0; row < size; row++) {
+    for (let col = 0; col < size; col++) {
+      const isDiagonal = row === col || row + col === size - 1;
+      const isNonZero = grid[row][col] !== 0;
+
+      if (isDiagonal && !isNonZero) return false;
+      if (!isDiagonal && isNonZero) return false;
+    }
+  }
+
+  return true;
+};
diff --git a/solutions/2320-count-number-of-ways-to-place-houses.js b/solutions/2320-count-number-of-ways-to-place-houses.js
new file mode 100644
index 00000000..39c28f72
--- /dev/null
+++ b/solutions/2320-count-number-of-ways-to-place-houses.js
@@ -0,0 +1,34 @@
+/**
+ * 2320. Count Number of Ways to Place Houses
+ * https://leetcode.com/problems/count-number-of-ways-to-place-houses/
+ * Difficulty: Medium
+ *
+ * There is a street with n * 2 plots, where there are n plots on each side of the street. The plots
+ * on each side are numbered from 1 to n. On each plot, a house can be placed.
+ *
+ * Return the number of ways houses can be placed such that no two houses are adjacent to each other
+ * on the same side of the street. Since the answer may be very large, return it modulo 109 + 7.
+ *
+ * Note that if a house is placed on the ith plot on one side of the street, a house can also be
+ * placed on the ith plot on the other side of the street.
+ */
+
+/**
+ * @param {number} n
+ * @return {number}
+ */
+var countHousePlacements = function(n) {
+  const MOD = 1e9 + 7;
+  let empty = 1n;
+  let house = 1n;
+
+  for (let i = 2; i <= n; i++) {
+    const nextEmpty = (empty + house) % BigInt(MOD);
+    const nextHouse = empty;
+    empty = nextEmpty;
+    house = nextHouse;
+  }
+
+  const sideWays = (empty + house) % BigInt(MOD);
+  return Number((sideWays * sideWays) % BigInt(MOD));
+};
diff --git a/solutions/2321-maximum-score-of-spliced-array.js b/solutions/2321-maximum-score-of-spliced-array.js
new file mode 100644
index 00000000..3ecf5068
--- /dev/null
+++ b/solutions/2321-maximum-score-of-spliced-array.js
@@ -0,0 +1,52 @@
+/**
+ * 2321. Maximum Score Of Spliced Array
+ * https://leetcode.com/problems/maximum-score-of-spliced-array/
+ * Difficulty: Hard
+ *
+ * You are given two 0-indexed integer arrays nums1 and nums2, both of length n.
+ *
+ * You can choose two integers left and right where 0 <= left <= right < n and swap the subarray
+ * nums1[left...right] with the subarray nums2[left...right].
+ * - For example, if nums1 = [1,2,3,4,5] and nums2 = [11,12,13,14,15] and you choose left = 1 and
+ *   right = 2, nums1 becomes [1,12,13,4,5] and nums2 becomes [11,2,3,14,15].
+ *
+ * You may choose to apply the mentioned operation once or not do anything.
+ *
+ * The score of the arrays is the maximum of sum(nums1) and sum(nums2), where sum(arr) is the sum
+ * of all the elements in the array arr.
+ *
+ * Return the maximum possible score.
+ *
+ * A subarray is a contiguous sequence of elements within an array. arr[left...right] denotes the
+ * subarray that contains the elements of nums between indices left and right (inclusive).
+ */
+
+/**
+ * @param {number[]} nums1
+ * @param {number[]} nums2
+ * @return {number}
+ */
+var maximumsSplicedArray = function(nums1, nums2) {
+  const length = nums1.length;
+  let sum1 = 0;
+  let sum2 = 0;
+
+  for (let i = 0; i < length; i++) {
+    sum1 += nums1[i];
+    sum2 += nums2[i];
+  }
+
+  let maxGain1 = 0;
+  let maxGain2 = 0;
+  let currGain1 = 0;
+  let currGain2 = 0;
+
+  for (let i = 0; i < length; i++) {
+    currGain1 = Math.max(0, currGain1 + nums2[i] - nums1[i]);
+    currGain2 = Math.max(0, currGain2 + nums1[i] - nums2[i]);
+    maxGain1 = Math.max(maxGain1, currGain1);
+    maxGain2 = Math.max(maxGain2, currGain2);
+  }
+
+  return Math.max(sum1 + maxGain1, sum2 + maxGain2);
+};
diff --git a/solutions/2322-minimum-score-after-removals-on-a-tree.js b/solutions/2322-minimum-score-after-removals-on-a-tree.js
new file mode 100644
index 00000000..4b0b6cd0
--- /dev/null
+++ b/solutions/2322-minimum-score-after-removals-on-a-tree.js
@@ -0,0 +1,112 @@
+/**
+ * 2322. Minimum Score After Removals on a Tree
+ * https://leetcode.com/problems/minimum-score-after-removals-on-a-tree/
+ * Difficulty: Hard
+ *
+ * There is an undirected connected tree with n nodes labeled from 0 to n - 1 and n - 1 edges.
+ *
+ * You are given a 0-indexed integer array nums of length n where nums[i] represents the value
+ * of the ith node. You are also given a 2D integer array edges of length n - 1 where
+ * edges[i] = [ai, bi] indicates that there is an edge between nodes ai and bi in the tree.
+ *
+ * Remove two distinct edges of the tree to form three connected components. For a pair of
+ * removed edges, the following steps are defined:
+ * 1. Get the XOR of all the values of the nodes for each of the three components respectively.
+ * 2. The difference between the largest XOR value and the smallest XOR value is the score of
+ *    the pair.
+ * 3. For example, say the three components have the node values: [4,5,7], [1,9], and [3,3,3].
+ *    The three XOR values are 4 ^ 5 ^ 7 = 6, 1 ^ 9 = 8, and 3 ^ 3 ^ 3 = 3. The largest XOR
+ *    value is 8 and the smallest XOR value is 3. The score is then 8 - 3 = 5.
+ *
+ * Return the minimum score of any possible pair of edge removals on the given tree.
+ */
+
+/**
+* @param {number[]} nums
+* @param {number[][]} edges
+* @return {number}
+*/
+var minimumScore = function(nums, edges) {
+  const n = nums.length;
+  const graph = Array.from({ length: n }, () => []);
+
+  for (const [a, b] of edges) {
+    graph[a].push(b);
+    graph[b].push(a);
+  }
+
+  const totalXor = nums.reduce((acc, num) => acc ^ num, 0);
+
+  const subtreeXor = new Array(n).fill(0);
+
+  const tin = new Array(n);
+  const tout = new Array(n);
+  let timer = 0;
+
+  function dfs(node, parent) {
+    tin[node] = timer++;
+    subtreeXor[node] = nums[node];
+
+    for (const neighbor of graph[node]) {
+      if (neighbor !== parent) {
+        dfs(neighbor, node);
+        subtreeXor[node] ^= subtreeXor[neighbor];
+      }
+    }
+
+    tout[node] = timer++;
+  }
+
+  dfs(0, -1);
+
+  function isAncestor(a, b) {
+    return tin[a] <= tin[b] && tout[a] >= tout[b];
+  }
+
+  let result = Infinity;
+  for (let i = 0; i < n - 1; i++) {
+    for (let j = i + 1; j < n - 1; j++) {
+      const edge1 = edges[i];
+      const edge2 = edges[j];
+
+      let node1;
+      if (isAncestor(edge1[0], edge1[1])) {
+        node1 = edge1[1];
+      } else {
+        node1 = edge1[0];
+      }
+      const subtree1 = subtreeXor[node1];
+
+      let node2;
+      if (isAncestor(edge2[0], edge2[1])) {
+        node2 = edge2[1];
+      } else {
+        node2 = edge2[0];
+      }
+      const subtree2 = subtreeXor[node2];
+
+      let component1;
+      let component2;
+      let component3;
+      if (isAncestor(node1, node2)) {
+        component1 = subtree2;
+        component2 = subtree1 ^ component1;
+        component3 = totalXor ^ subtree1;
+      } else if (isAncestor(node2, node1)) {
+        component1 = subtree1;
+        component2 = subtree2 ^ component1;
+        component3 = totalXor ^ subtree2;
+      } else {
+        component1 = subtree1;
+        component2 = subtree2;
+        component3 = totalXor ^ component1 ^ component2;
+      }
+
+      const maxXor = Math.max(component1, component2, component3);
+      const minXor = Math.min(component1, component2, component3);
+      result = Math.min(result, maxXor - minXor);
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2325-decode-the-message.js b/solutions/2325-decode-the-message.js
new file mode 100644
index 00000000..bde90e23
--- /dev/null
+++ b/solutions/2325-decode-the-message.js
@@ -0,0 +1,41 @@
+/**
+ * 2325. Decode the Message
+ * https://leetcode.com/problems/decode-the-message/
+ * Difficulty: Easy
+ *
+ * You are given the strings key and message, which represent a cipher key and a secret message,
+ * respectively. The steps to decode message are as follows:
+ * 1. Use the first appearance of all 26 lowercase English letters in key as the order of the
+ *    substitution table.
+ * 2. Align the substitution table with the regular English alphabet.
+ * 3. Each letter in message is then substituted using the table.
+ * 4. Spaces ' ' are transformed to themselves.
+ * 5. For example, given key = "happy boy" (actual key would have at least one instance of each
+ *    letter in the alphabet), we have the partial substitution table of ('h' -> 'a', 'a' -> 'b',
+ *    'p' -> 'c', 'y' -> 'd', 'b' -> 'e', 'o' -> 'f').
+ *
+ * Return the decoded message.
+ */
+
+/**
+ * @param {string} key
+ * @param {string} message
+ * @return {string}
+ */
+var decodeMessage = function(key, message) {
+  const substitution = new Map();
+  let alphabetIndex = 0;
+
+  for (const char of key) {
+    if (char !== ' ' && !substitution.has(char)) {
+      substitution.set(char, String.fromCharCode(97 + alphabetIndex++));
+    }
+  }
+
+  let result = '';
+  for (const char of message) {
+    result += char === ' ' ? ' ' : substitution.get(char);
+  }
+
+  return result;
+};
diff --git a/solutions/2326-spiral-matrix-iv.js b/solutions/2326-spiral-matrix-iv.js
new file mode 100644
index 00000000..1fa98050
--- /dev/null
+++ b/solutions/2326-spiral-matrix-iv.js
@@ -0,0 +1,65 @@
+/**
+ * 2326. Spiral Matrix IV
+ * https://leetcode.com/problems/spiral-matrix-iv/
+ * Difficulty: Medium
+ *
+ * You are given two integers m and n, which represent the dimensions of a matrix.
+ *
+ * You are also given the head of a linked list of integers.
+ *
+ * Generate an m x n matrix that contains the integers in the linked list presented in spiral
+ * order (clockwise), starting from the top-left of the matrix. If there are remaining empty
+ * spaces, fill them with -1.
+ *
+ * Return the generated matrix.
+ */
+
+/**
+ * Definition for singly-linked list.
+ * function ListNode(val, next) {
+ *     this.val = (val===undefined ? 0 : val)
+ *     this.next = (next===undefined ? null : next)
+ * }
+ */
+/**
+ * @param {number} m
+ * @param {number} n
+ * @param {ListNode} head
+ * @return {number[][]}
+ */
+var spiralMatrix = function(m, n, head) {
+  const matrix = new Array(m).fill().map(() => new Array(n).fill(-1));
+  let top = 0;
+  let bottom = m - 1;
+  let left = 0;
+  let right = n - 1;
+  let current = head;
+
+  while (top <= bottom && left <= right && current) {
+    for (let col = left; col <= right && current; col++) {
+      matrix[top][col] = current.val;
+      current = current.next;
+    }
+    top++;
+
+    for (let row = top; row <= bottom && current; row++) {
+      matrix[row][right] = current.val;
+      current = current.next;
+    }
+    right--;
+
+    for (let col = right; col >= left && current; col--) {
+      matrix[bottom][col] = current.val;
+      current = current.next;
+    }
+    bottom--;
+
+    for (let row = bottom; row >= top && current; row--) {
+      matrix[row][left] = current.val;
+      current = current.next;
+    }
+    left++;
+  }
+
+  return matrix;
+};
diff --git a/solutions/2328-number-of-increasing-paths-in-a-grid.js b/solutions/2328-number-of-increasing-paths-in-a-grid.js
new file mode 100644
index 00000000..f239c80c
--- /dev/null
+++ b/solutions/2328-number-of-increasing-paths-in-a-grid.js
@@ -0,0 +1,53 @@
+/**
+ * 2328. Number of Increasing Paths in a Grid
+ * https://leetcode.com/problems/number-of-increasing-paths-in-a-grid/
+ * Difficulty: Hard
+ *
+ * You are given an m x n integer matrix grid, where you can move from a cell to any adjacent
+ * cell in all 4 directions.
+ *
+ * Return the number of strictly increasing paths in the grid such that you can start from any
+ * cell and end at any cell. Since the answer may be very large, return it modulo 109 + 7.
+ *
+ * Two paths are considered different if they do not have exactly the same sequence of visited
+ * cells.
+ */
+
+/**
+ * @param {number[][]} grid
+ * @return {number}
+ */
+var countPaths = function(grid) {
+  const MOD = 1e9 + 7;
+  const rows = grid.length;
+  const cols = grid[0].length;
+  const cache = new Array(rows).fill().map(() => new Array(cols).fill(0));
+  const directions = [[0, 1], [1, 0], [0, -1], [-1, 0]];
+
+  function explore(row, col) {
+    if (cache[row][col]) return cache[row][col];
+
+    let paths = 1;
+    for (const [dr, dc] of directions) {
+      const newRow = row + dr;
+      const newCol = col + dc;
+      if (
+        newRow >= 0 && newRow < rows && newCol >= 0
+        && newCol < cols && grid[newRow][newCol] > grid[row][col]
+      ) {
+        paths = (paths + explore(newRow, newCol)) % MOD;
+      }
+    }
+
+    return cache[row][col] = paths;
+  }
+
+  let total = 0;
+  for (let i = 0; i < rows; i++) {
+    for (let j = 0; j < cols; j++) {
+      total = (total + explore(i, j)) % MOD;
+    }
+  }
+
+  return total;
+};
diff --git a/solutions/2331-evaluate-boolean-binary-tree.js b/solutions/2331-evaluate-boolean-binary-tree.js
new file mode 100644
index 00000000..d6f4d851
--- /dev/null
+++ b/solutions/2331-evaluate-boolean-binary-tree.js
@@ -0,0 +1,42 @@
+/**
+ * 2331. Evaluate Boolean Binary Tree
+ * https://leetcode.com/problems/evaluate-boolean-binary-tree/
+ * Difficulty: Easy
+ *
+ * You are given the root of a full binary tree with the following properties:
+ * - Leaf nodes have either the value 0 or 1, where 0 represents False and 1 represents True.
+ * - Non-leaf nodes have either the value 2 or 3, where 2 represents the boolean OR and 3 represents
+ *   the boolean AND.
+ *
+ * The evaluation of a node is as follows:
+ * - If the node is a leaf node, the evaluation is the value of the node, i.e. True or False.
+ * - Otherwise, evaluate the node's two children and apply the boolean operation of its value with
+ *   the children's evaluations.
+ *
+ * Return the boolean result of evaluating the root node.
+ *
+ * A full binary tree is a binary tree where each node has either 0 or 2 children.
+ *
+ * A leaf node is a node that has zero children.
+ */
+
+/**
+ * Definition for a binary tree node.
+ * function TreeNode(val, left, right) {
+ *     this.val = (val===undefined ? 0 : val)
+ *     this.left = (left===undefined ? null : left)
+ *     this.right = (right===undefined ? null : right)
+ * }
+ */
+/**
+ * @param {TreeNode} root
+ * @return {boolean}
+ */
+var evaluateTree = function(root) {
+  if (!root.left && !root.right) return root.val === 1;
+
+  const leftResult = evaluateTree(root.left);
+  const rightResult = evaluateTree(root.right);
+
+  return root.val === 2 ? leftResult || rightResult : leftResult && rightResult;
+};
diff --git a/solutions/2334-subarray-with-elements-greater-than-varying-threshold.js b/solutions/2334-subarray-with-elements-greater-than-varying-threshold.js
new file mode 100644
index 00000000..789a5ff3
--- /dev/null
+++ b/solutions/2334-subarray-with-elements-greater-than-varying-threshold.js
@@ -0,0 +1,43 @@
+/**
+ * 2334. Subarray With Elements Greater Than Varying Threshold
+ * https://leetcode.com/problems/subarray-with-elements-greater-than-varying-threshold/
+ * Difficulty: Hard
+ *
+ * You are given an integer array nums and an integer threshold.
+ *
+ * Find any subarray of nums of length k such that every element in the subarray is greater
+ * than threshold / k.
+ *
+ * Return the size of any such subarray. If there is no such subarray, return -1.
+ *
+ * A subarray is a contiguous non-empty sequence of elements within an array.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} threshold
+ * @return {number}
+ */
+var validSubarraySize = function(nums, threshold) {
+  const n = nums.length;
+  const stack = [];
+  const nextSmaller = new Array(n).fill(n);
+  const prevSmaller = new Array(n).fill(-1);
+
+  for (let i = 0; i < n; i++) {
+    while (stack.length && nums[stack[stack.length - 1]] >= nums[i]) {
+      nextSmaller[stack.pop()] = i;
+    }
+    if (stack.length) prevSmaller[i] = stack[stack.length - 1];
+    stack.push(i);
+  }
+
+  for (let i = 0; i < n; i++) {
+    const k = nextSmaller[i] - prevSmaller[i] - 1;
+    if (k > 0 && nums[i] > threshold / k) {
+      return k;
+    }
+  }
+
+  return -1;
+};
diff --git a/solutions/2337-move-pieces-to-obtain-a-string.js b/solutions/2337-move-pieces-to-obtain-a-string.js
new file mode 100644
index 00000000..64f29a9a
--- /dev/null
+++ b/solutions/2337-move-pieces-to-obtain-a-string.js
@@ -0,0 +1,41 @@
+/**
+ * 2337. Move Pieces to Obtain a String
+ * https://leetcode.com/problems/move-pieces-to-obtain-a-string/
+ * Difficulty: Medium
+ *
+ * You are given two strings start and target, both of length n. Each string consists only of
+ * the characters 'L', 'R', and '_' where:
+ * - The characters 'L' and 'R' represent pieces, where a piece 'L' can move to the left only if
+ *   there is a blank space directly to its left, and a piece 'R' can move to the right only if
+ *   there is a blank space directly to its right.
+ * - The character '_' represents a blank space that can be occupied by any of the 'L' or 'R'
+ *   pieces.
+ *
+ * Return true if it is possible to obtain the string target by moving the pieces of the string
+ * start any number of times. Otherwise, return false.
+ */
+
+/**
+ * @param {string} start
+ * @param {string} target
+ * @return {boolean}
+ */
+var canChange = function(start, target) {
+  const pieces = [];
+  const targetPieces = [];
+
+  for (let i = 0; i < start.length; i++) {
+    if (start[i] !== '_') pieces.push([start[i], i]);
+    if (target[i] !== '_') targetPieces.push([target[i], i]);
+  }
+
+  if (pieces.length !== targetPieces.length) return false;
+
+  for (let i = 0; i < pieces.length; i++) {
+    if (pieces[i][0] !== targetPieces[i][0]) return false;
+    if (pieces[i][0] === 'L' && pieces[i][1] < targetPieces[i][1]) return false;
+    if (pieces[i][0] === 'R' && pieces[i][1] > targetPieces[i][1]) return false;
+  }
+
+  return true;
+};
diff --git a/solutions/2341-maximum-number-of-pairs-in-array.js b/solutions/2341-maximum-number-of-pairs-in-array.js
new file mode 100644
index 00000000..2cdcce2c
--- /dev/null
+++ b/solutions/2341-maximum-number-of-pairs-in-array.js
@@ -0,0 +1,35 @@
+/**
+ * 2341. Maximum Number of Pairs in Array
+ * https://leetcode.com/problems/maximum-number-of-pairs-in-array/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed integer array nums. In one operation, you may do the following:
+ * - Choose two integers in nums that are equal.
+ * - Remove both integers from nums, forming a pair.
+ *
+ * The operation is done on nums as many times as possible.
+ *
+ * Return a 0-indexed integer array answer of size 2 where answer[0] is the number of pairs that
+ * are formed and answer[1] is the number of leftover integers in nums after doing the operation
+ * as many times as possible.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number[]}
+ */
+var numberOfPairs = function(nums) {
+  const frequency = new Map();
+  let pairs = 0;
+
+  for (const num of nums) {
+    frequency.set(num, (frequency.get(num) || 0) + 1);
+    if (frequency.get(num) === 2) {
+      pairs++;
+      frequency.set(num, 0);
+    }
+  }
+
+  const leftovers = nums.length - pairs * 2;
+  return [pairs, leftovers];
+};
diff --git a/solutions/2347-best-poker-hand.js b/solutions/2347-best-poker-hand.js
new file mode 100644
index 00000000..586dcda2
--- /dev/null
+++ b/solutions/2347-best-poker-hand.js
@@ -0,0 +1,41 @@
+/**
+ * 2347. Best Poker Hand
+ * https://leetcode.com/problems/best-poker-hand/
+ * Difficulty: Easy
+ *
+ * You are given an integer array ranks and a character array suits. You have 5 cards where the
+ * ith card has a rank of ranks[i] and a suit of suits[i].
+ *
+ * The following are the types of poker hands you can make from best to worst:
+ * 1. "Flush": Five cards of the same suit.
+ * 2. "Three of a Kind": Three cards of the same rank.
+ * 3. "Pair": Two cards of the same rank.
+ * 4. "High Card": Any single card.
+ *
+ * Return a string representing the best type of poker hand you can make with the given cards.
+ *
+ * Note that the return values are case-sensitive.
+ */
+
+/**
+ * @param {number[]} ranks
+ * @param {character[]} suits
+ * @return {string}
+ */
+var bestHand = function(ranks, suits) {
+  const suitCount = new Map();
+  const rankCount = new Map();
+
+  for (let i = 0; i < 5; i++) {
+    suitCount.set(suits[i], (suitCount.get(suits[i]) || 0) + 1);
+    rankCount.set(ranks[i], (rankCount.get(ranks[i]) || 0) + 1);
+  }
+
+  if (suitCount.size === 1) return 'Flush';
+
+  const maxRankCount = Math.max(...rankCount.values());
+  if (maxRankCount >= 3) return 'Three of a Kind';
+  if (maxRankCount === 2) return 'Pair';
+
+  return 'High Card';
+};
diff --git a/solutions/2348-number-of-zero-filled-subarrays.js b/solutions/2348-number-of-zero-filled-subarrays.js
new file mode 100644
index 00000000..fa93ec19
--- /dev/null
+++ b/solutions/2348-number-of-zero-filled-subarrays.js
@@ -0,0 +1,29 @@
+/**
+ * 2348. Number of Zero-Filled Subarrays
+ * https://leetcode.com/problems/number-of-zero-filled-subarrays/
+ * Difficulty: Medium
+ *
+ * Given an integer array nums, return the number of subarrays filled with 0.
+ *
+ * A subarray is a contiguous non-empty sequence of elements within an array.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var zeroFilledSubarray = function(nums) {
+  let result = 0;
+  let zeroCount = 0;
+
+  for (const num of nums) {
+    if (num === 0) {
+      zeroCount++;
+      result += zeroCount;
+    } else {
+      zeroCount = 0;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2350-shortest-impossible-sequence-of-rolls.js b/solutions/2350-shortest-impossible-sequence-of-rolls.js
new file mode 100644
index 00000000..ea27a604
--- /dev/null
+++ b/solutions/2350-shortest-impossible-sequence-of-rolls.js
@@ -0,0 +1,32 @@
+/**
+ * 2350. Shortest Impossible Sequence of Rolls
+ * https://leetcode.com/problems/shortest-impossible-sequence-of-rolls/
+ * Difficulty: Hard
+ *
+ * You are given an integer array rolls of length n and an integer k. You roll a k sided dice
+ * numbered from 1 to k, n times, where the result of the ith roll is rolls[i].
+ *
+ * Return the length of the shortest sequence of rolls so that there's no such subsequence in rolls.
+ *
+ * A sequence of rolls of length len is the result of rolling a k sided dice len times.
+ */
+
+/**
+ * @param {number[]} rolls
+ * @param {number} k
+ * @return {number}
+ */
+var shortestSequence = function(rolls, k) {
+  const set = new Set();
+  let sequences = 0;
+
+  for (const roll of rolls) {
+    set.add(roll);
+    if (set.size === k) {
+      sequences++;
+      set.clear();
+    }
+  }
+
+  return sequences + 1;
+};
diff --git a/solutions/2351-first-letter-to-appear-twice.js b/solutions/2351-first-letter-to-appear-twice.js
new file mode 100644
index 00000000..b5fff8f5
--- /dev/null
+++ b/solutions/2351-first-letter-to-appear-twice.js
@@ -0,0 +1,26 @@
+/**
+ * 2351. First Letter to Appear Twice
+ * https://leetcode.com/problems/first-letter-to-appear-twice/
+ * Difficulty: Easy
+ *
+ * Given a string s consisting of lowercase English letters, return the first letter
+ * to appear twice.
+ *
+ * Note:
+ * - A letter a appears twice before another letter b if the second occurrence of a is before
+ *   the second occurrence of b.
+ * - s will contain at least one letter that appears twice.
+ */
+
+/**
+ * @param {string} s
+ * @return {character}
+ */
+var repeatedCharacter = function(s) {
+  const set = new Set();
+
+  for (const char of s) {
+    if (set.has(char)) return char;
+    set.add(char);
+  }
+};
diff --git a/solutions/2354-number-of-excellent-pairs.js b/solutions/2354-number-of-excellent-pairs.js
new file mode 100644
index 00000000..bf60424a
--- /dev/null
+++ b/solutions/2354-number-of-excellent-pairs.js
@@ -0,0 +1,46 @@
+/**
+ * 2354. Number of Excellent Pairs
+ * https://leetcode.com/problems/number-of-excellent-pairs/
+ * Difficulty: Hard
+ *
+ * You are given a 0-indexed positive integer array nums and a positive integer k.
+ *
+ * A pair of numbers (num1, num2) is called excellent if the following conditions are satisfied:
+ * - Both the numbers num1 and num2 exist in the array nums.
+ * - The sum of the number of set bits in num1 OR num2 and num1 AND num2 is greater than or equal
+ *   to k, where OR is the bitwise OR operation and AND is the bitwise AND operation.
+ *
+ * Return the number of distinct excellent pairs.
+ *
+ * Two pairs (a, b) and (c, d) are considered distinct if either a != c or b != d. For example,
+ * (1, 2) and (2, 1) are distinct.
+ *
+ * Note that a pair (num1, num2) such that num1 == num2 can also be excellent if you have at least
+ * one occurrence of num1 in the array.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @return {number}
+ */
+var countExcellentPairs = function(nums, k) {
+  const map = new Map();
+  const set = new Set(nums);
+
+  for (const num of set) {
+    const bits = num.toString(2).split('0').join('').length;
+    map.set(bits, (map.get(bits) || 0) + 1);
+  }
+
+  let result = 0;
+  for (const [i, countI] of map) {
+    for (const [j, countJ] of map) {
+      if (i + j >= k) {
+        result += countI * countJ;
+      }
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2358-maximum-number-of-groups-entering-a-competition.js b/solutions/2358-maximum-number-of-groups-entering-a-competition.js
new file mode 100644
index 00000000..2637927b
--- /dev/null
+++ b/solutions/2358-maximum-number-of-groups-entering-a-competition.js
@@ -0,0 +1,31 @@
+/**
+ * 2358. Maximum Number of Groups Entering a Competition
+ * https://leetcode.com/problems/maximum-number-of-groups-entering-a-competition/
+ * Difficulty: Medium
+ *
+ * You are given a positive integer array grades which represents the grades of students in
+ * a university. You would like to enter all these students into a competition in ordered
+ * non-empty groups, such that the ordering meets the following conditions:
+ * - The sum of the grades of students in the ith group is less than the sum of the grades of
+ *   students in the (i + 1)th group, for all groups (except the last).
+ * - The total number of students in the ith group is less than the total number of students
+ *   in the (i + 1)th group, for all groups (except the last).
+ *
+ * Return the maximum number of groups that can be formed.
+ */
+
+/**
+ * @param {number[]} grades
+ * @return {number}
+ */
+var maximumGroups = function(grades) {
+  let result = 0;
+  let studentsUsed = 0;
+
+  while (studentsUsed + result + 1 <= grades.length) {
+    result++;
+    studentsUsed += result;
+  }
+
+  return result;
+};
diff --git a/solutions/2359-find-closest-node-to-given-two-nodes.js b/solutions/2359-find-closest-node-to-given-two-nodes.js
new file mode 100644
index 00000000..c048153f
--- /dev/null
+++ b/solutions/2359-find-closest-node-to-given-two-nodes.js
@@ -0,0 +1,63 @@
+/**
+ * 2359. Find Closest Node to Given Two Nodes
+ * https://leetcode.com/problems/find-closest-node-to-given-two-nodes/
+ * Difficulty: Medium
+ *
+ * You are given a directed graph of n nodes numbered from 0 to n - 1, where each node has at
+ * most one outgoing edge.
+ *
+ * The graph is represented with a given 0-indexed array edges of size n, indicating that there
+ * is a directed edge from node i to node edges[i]. If there is no outgoing edge from i, then
+ * edges[i] == -1.
+ *
+ * You are also given two integers node1 and node2.
+ *
+ * Return the index of the node that can be reached from both node1 and node2, such that the maximum
+ * between the distance from node1 to that node, and from node2 to that node is minimized. If there
+ * are multiple answers, return the node with the smallest index, and if no possible answer exists,
+ * return -1.
+ *
+ * Note that edges may contain cycles.
+ */
+
+/**
+ * @param {number[]} edges
+ * @param {number} node1
+ * @param {number} node2
+ * @return {number}
+ */
+var closestMeetingNode = function(edges, node1, node2) {
+  const n = edges.length;
+  const dist1 = new Array(n).fill(Infinity);
+  const dist2 = new Array(n).fill(Infinity);
+
+  computeDistances(node1, dist1);
+  computeDistances(node2, dist2);
+
+  let minDist = Infinity;
+  let result = -1;
+
+  for (let i = 0; i < n; i++) {
+    if (dist1[i] !== Infinity && dist2[i] !== Infinity) {
+      const maxDist = Math.max(dist1[i], dist2[i]);
+      if (maxDist < minDist) {
+        minDist = maxDist;
+        result = i;
+      }
+    }
+  }
+
+  return result;
+
+  function computeDistances(start, distances) {
+    let current = start;
+    let steps = 0;
+    const visited = new Set();
+
+    while (current !== -1 && !visited.has(current)) {
+      distances[current] = steps++;
+      visited.add(current);
+      current = edges[current];
+    }
+  }
+};
diff --git a/solutions/2360-longest-cycle-in-a-graph.js b/solutions/2360-longest-cycle-in-a-graph.js
new file mode 100644
index 00000000..6da96750
--- /dev/null
+++ b/solutions/2360-longest-cycle-in-a-graph.js
@@ -0,0 +1,53 @@
+/**
+ * 2360. Longest Cycle in a Graph
+ * https://leetcode.com/problems/longest-cycle-in-a-graph/
+ * Difficulty: Hard
+ *
+ * You are given a directed graph of n nodes numbered from 0 to n - 1, where each node has at
+ * most one outgoing edge.
+ *
+ * The graph is represented with a given 0-indexed array edges of size n, indicating that
+ * there is a directed edge from node i to node edges[i]. If there is no outgoing edge from
+ * node i, then edges[i] == -1.
+ *
+ * Return the length of the longest cycle in the graph. If no cycle exists, return -1.
+ *
+ * A cycle is a path that starts and ends at the same node.
+ */
+
+/**
+ * @param {number[]} edges
+ * @return {number}
+ */
+var longestCycle = function(edges) {
+  const n = edges.length;
+  const visited = new Array(n).fill(false);
+  let result = -1;
+
+  for (let i = 0; i < n; i++) {
+    if (!visited[i]) {
+      findCycle(i, 0, []);
+    }
+  }
+
+  return result;
+
+  function findCycle(node, steps, path) {
+    if (visited[node]) {
+      const cycleStart = path.indexOf(node);
+      if (cycleStart !== -1) {
+        result = Math.max(result, steps - cycleStart);
+      }
+      return;
+    }
+
+    visited[node] = true;
+    path.push(node);
+
+    if (edges[node] !== -1) {
+      findCycle(edges[node], steps + 1, path);
+    }
+
+    path.pop();
+  }
+};
diff --git a/solutions/2363-merge-similar-items.js b/solutions/2363-merge-similar-items.js
new file mode 100644
index 00000000..da16c478
--- /dev/null
+++ b/solutions/2363-merge-similar-items.js
@@ -0,0 +1,40 @@
+/**
+ * 2363. Merge Similar Items
+ * https://leetcode.com/problems/merge-similar-items/
+ * Difficulty: Easy
+ *
+ * You are given two 2D integer arrays, items1 and items2, representing two sets of items.
+ * Each array items has the following properties:
+ * - items[i] = [valuei, weighti] where valuei represents the value and weighti represents
+ *   the weight of the ith item.
+ * - The value of each item in items is unique.
+ *
+ * Return a 2D integer array ret where ret[i] = [valuei, weighti], with weighti being the sum of
+ * weights of all items with value valuei.
+ *
+ * Note: ret should be returned in ascending order by value.
+ */
+
+/**
+ * @param {number[][]} items1
+ * @param {number[][]} items2
+ * @return {number[][]}
+ */
+var mergeSimilarItems = function(items1, items2) {
+  const map = new Map();
+
+  for (const [value, weight] of items1) {
+    map.set(value, (map.get(value) || 0) + weight);
+  }
+
+  for (const [value, weight] of items2) {
+    map.set(value, (map.get(value) || 0) + weight);
+  }
+
+  const merged = [];
+  for (const [value, weight] of map) {
+    merged.push([value, weight]);
+  }
+
+  return merged.sort((a, b) => a[0] - b[0]);
+};
diff --git a/solutions/2365-task-scheduler-ii.js b/solutions/2365-task-scheduler-ii.js
new file mode 100644
index 00000000..166fdfdf
--- /dev/null
+++ b/solutions/2365-task-scheduler-ii.js
@@ -0,0 +1,41 @@
+/**
+ * 2365. Task Scheduler II
+ * https://leetcode.com/problems/task-scheduler-ii/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed array of positive integers tasks, representing tasks that need
+ * to be completed in order, where tasks[i] represents the type of the ith task.
+ *
+ * You are also given a positive integer space, which represents the minimum number of days
+ * that must pass after the completion of a task before another task of the same type can be
+ * performed.
+ *
+ * Each day, until all tasks have been completed, you must either:
+ * - Complete the next task from tasks, or
+ * - Take a break.
+ *
+ * Return the minimum number of days needed to complete all tasks.
+ */
+
+/**
+ * @param {number[]} tasks
+ * @param {number} space
+ * @return {number}
+ */
+var taskSchedulerII = function(tasks, space) {
+  const map = new Map();
+  let result = 0;
+
+  for (const task of tasks) {
+    result++;
+    if (map.has(task)) {
+      const lastDay = map.get(task);
+      if (result - lastDay <= space) {
+        result = lastDay + space + 1;
+      }
+    }
+    map.set(task, result);
+  }
+
+  return result;
+};
diff --git a/solutions/2366-minimum-replacements-to-sort-the-array.js b/solutions/2366-minimum-replacements-to-sort-the-array.js
new file mode 100644
index 00000000..422d21f6
--- /dev/null
+++ b/solutions/2366-minimum-replacements-to-sort-the-array.js
@@ -0,0 +1,33 @@
+/**
+ * 2366. Minimum Replacements to Sort the Array
+ * https://leetcode.com/problems/minimum-replacements-to-sort-the-array/
+ * Difficulty: Hard
+ *
+ * You are given a 0-indexed integer array nums. In one operation you can replace any element
+ * of the array with any two elements that sum to it.
+ * - For example, consider nums = [5,6,7]. In one operation, we can replace nums[1] with 2 and 4
+ *   and convert nums to [5,2,4,7].
+ *
+ * Return the minimum number of operations to make an array that is sorted in non-decreasing order.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var minimumReplacement = function(nums) {
+  let result = 0;
+  let prev = nums[nums.length - 1];
+
+  for (let i = nums.length - 2; i >= 0; i--) {
+    if (nums[i] > prev) {
+      const splits = Math.ceil(nums[i] / prev);
+      result += splits - 1;
+      prev = Math.floor(nums[i] / splits);
+    } else {
+      prev = nums[i];
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2367-number-of-arithmetic-triplets.js b/solutions/2367-number-of-arithmetic-triplets.js
new file mode 100644
index 00000000..21c02a86
--- /dev/null
+++ b/solutions/2367-number-of-arithmetic-triplets.js
@@ -0,0 +1,41 @@
+/**
+ * 2367. Number of Arithmetic Triplets
+ * https://leetcode.com/problems/number-of-arithmetic-triplets/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed, strictly increasing integer array nums and a positive integer diff.
+ * A triplet (i, j, k) is an arithmetic triplet if the following conditions are met:
+ * - i < j < k,
+ * - nums[j] - nums[i] == diff, and
+ * - nums[k] - nums[j] == diff.
+ *
+ * Return the number of unique arithmetic triplets.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} diff
+ * @return {number}
+ */
+var arithmeticTriplets = function(nums, diff) {
+  let result = 0;
+
+  for (let j = 1; j < nums.length - 1; j++) {
+    let i = j - 1;
+    let k = j + 1;
+
+    while (i >= 0 && nums[j] - nums[i] <= diff) {
+      if (nums[j] - nums[i] === diff) {
+        while (k < nums.length && nums[k] - nums[j] <= diff) {
+          if (nums[k] - nums[j] === diff) {
+            result++;
+          }
+          k++;
+        }
+      }
+      i--;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2368-reachable-nodes-with-restrictions.js b/solutions/2368-reachable-nodes-with-restrictions.js
new file mode 100644
index 00000000..1ecd0821
--- /dev/null
+++ b/solutions/2368-reachable-nodes-with-restrictions.js
@@ -0,0 +1,43 @@
+/**
+ * 2368. Reachable Nodes With Restrictions
+ * https://leetcode.com/problems/reachable-nodes-with-restrictions/
+ * Difficulty: Medium
+ *
+ * There is an undirected tree with n nodes labeled from 0 to n - 1 and n - 1 edges.
+ *
+ * You are given a 2D integer array edges of length n - 1 where edges[i] = [ai, bi] indicates
+ * that there is an edge between nodes ai and bi in the tree. You are also given an integer
+ * array restricted which represents restricted nodes.
+ *
+ * Return the maximum number of nodes you can reach from node 0 without visiting a restricted node.
+ *
+ * Note that node 0 will not be a restricted node.
+ */
+
+/**
+ * @param {number} n
+ * @param {number[][]} edges
+ * @param {number[]} restricted
+ * @return {number}
+ */
+var reachableNodes = function(n, edges, restricted) {
+  const graph = Array(n).fill().map(() => []);
+  const restrictedSet = new Set(restricted);
+  const visited = new Set();
+
+  for (const [u, v] of edges) {
+    graph[u].push(v);
+    graph[v].push(u);
+  }
+
+  explore(0);
+  return visited.size;
+
+  function explore(node) {
+    if (visited.has(node) || restrictedSet.has(node)) return;
+    visited.add(node);
+    for (const neighbor of graph[node]) {
+      explore(neighbor);
+    }
+  }
+};
diff --git a/solutions/2369-check-if-there-is-a-valid-partition-for-the-array.js b/solutions/2369-check-if-there-is-a-valid-partition-for-the-array.js
new file mode 100644
index 00000000..be0e9844
--- /dev/null
+++ b/solutions/2369-check-if-there-is-a-valid-partition-for-the-array.js
@@ -0,0 +1,44 @@
+/**
+ * 2369. Check if There is a Valid Partition For The Array
+ * https://leetcode.com/problems/check-if-there-is-a-valid-partition-for-the-array/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed integer array nums. You have to partition the array into one or
+ * more contiguous subarrays.
+ *
+ * We call a partition of the array valid if each of the obtained subarrays satisfies one of
+ * the following conditions:
+ * 1. The subarray consists of exactly 2, equal elements. For example, the subarray [2,2] is good.
+ * 2. The subarray consists of exactly 3, equal elements. For example, the subarray [4,4,4] is good.
+ * 3. The subarray consists of exactly 3 consecutive increasing elements, that is, the difference
+ *    between adjacent elements is 1. For example, the subarray [3,4,5] is good, but the subarray
+ *    [1,3,5] is not.
+ *
+ * Return true if the array has at least one valid partition. Otherwise, return false.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {boolean}
+ */
+var validPartition = function(nums) {
+  const n = nums.length;
+  const dp = new Array(n + 1).fill(false);
+  dp[0] = true;
+
+  for (let i = 2; i <= n; i++) {
+    if (nums[i - 1] === nums[i - 2]) {
+      dp[i] = dp[i] || dp[i - 2];
+    }
+    if (i >= 3) {
+      if (nums[i - 1] === nums[i - 2] && nums[i - 2] === nums[i - 3]) {
+        dp[i] = dp[i] || dp[i - 3];
+      }
+      if (nums[i - 1] === nums[i - 2] + 1 && nums[i - 2] === nums[i - 3] + 1) {
+        dp[i] = dp[i] || dp[i - 3];
+      }
+    }
+  }
+
+  return dp[n];
+};
diff --git a/solutions/2370-longest-ideal-subsequence.js b/solutions/2370-longest-ideal-subsequence.js
new file mode 100644
index 00000000..c07e27f9
--- /dev/null
+++ b/solutions/2370-longest-ideal-subsequence.js
@@ -0,0 +1,43 @@
+/**
+ * 2370. Longest Ideal Subsequence
+ * https://leetcode.com/problems/longest-ideal-subsequence/
+ * Difficulty: Medium
+ *
+ * You are given a string s consisting of lowercase letters and an integer k. We call a string
+ * t ideal if the following conditions are satisfied:
+ * - t is a subsequence of the string s.
+ * - The absolute difference in the alphabet order of every two adjacent letters in t is less
+ *   than or equal to k.
+ *
+ * Return the length of the longest ideal string.
+ *
+ * A subsequence is a string that can be derived from another string by deleting some or no
+ * characters without changing the order of the remaining characters.
+ *
+ * Note that the alphabet order is not cyclic. For example, the absolute difference in the
+ * alphabet order of 'a' and 'z' is 25, not 1.
+ */
+
+/**
+ * @param {string} s
+ * @param {number} k
+ * @return {number}
+ */
+var longestIdealString = function(s, k) {
+  const dp = new Array(26).fill(0);
+  let result = 0;
+
+  for (const char of s) {
+    const idx = char.charCodeAt(0) - 97;
+    let currentMax = 0;
+
+    for (let i = Math.max(0, idx - k); i <= Math.min(25, idx + k); i++) {
+      currentMax = Math.max(currentMax, dp[i]);
+    }
+
+    dp[idx] = currentMax + 1;
+    result = Math.max(result, dp[idx]);
+  }
+
+  return result;
+};
diff --git a/solutions/2373-largest-local-values-in-a-matrix.js b/solutions/2373-largest-local-values-in-a-matrix.js
new file mode 100644
index 00000000..46a65c45
--- /dev/null
+++ b/solutions/2373-largest-local-values-in-a-matrix.js
@@ -0,0 +1,38 @@
+/**
+ * 2373. Largest Local Values in a Matrix
+ * https://leetcode.com/problems/largest-local-values-in-a-matrix/
+ * Difficulty: Easy
+ *
+ * You are given an n x n integer matrix grid.
+ *
+ * Generate an integer matrix maxLocal of size (n - 2) x (n - 2) such that:
+ * - maxLocal[i][j] is equal to the largest value of the 3 x 3 matrix in grid centered around
+ *   row i + 1 and column j + 1.
+ *
+ * In other words, we want to find the largest value in every contiguous 3 x 3 matrix in grid.
+ *
+ * Return the generated matrix.
+ */
+
+/**
+ * @param {number[][]} grid
+ * @return {number[][]}
+ */
+var largestLocal = function(grid) {
+  const n = grid.length;
+  const result = new Array(n - 2).fill().map(() => new Array(n - 2).fill(0));
+
+  for (let i = 0; i < n - 2; i++) {
+    for (let j = 0; j < n - 2; j++) {
+      let maxVal = 0;
+      for (let r = i; r < i + 3; r++) {
+        for (let c = j; c < j + 3; c++) {
+          maxVal = Math.max(maxVal, grid[r][c]);
+        }
+      }
+      result[i][j] = maxVal;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2374-node-with-highest-edge-score.js b/solutions/2374-node-with-highest-edge-score.js
new file mode 100644
index 00000000..b8597422
--- /dev/null
+++ b/solutions/2374-node-with-highest-edge-score.js
@@ -0,0 +1,39 @@
+/**
+ * 2374. Node With Highest Edge Score
+ * https://leetcode.com/problems/node-with-highest-edge-score/
+ * Difficulty: Medium
+ *
+ * You are given a directed graph with n nodes labeled from 0 to n - 1, where each node has
+ * exactly one outgoing edge.
+ *
+ * The graph is represented by a given 0-indexed integer array edges of length n, where edges[i]
+ * indicates that there is a directed edge from node i to node edges[i].
+ *
+ * The edge score of a node i is defined as the sum of the labels of all the nodes that have an
+ * edge pointing to i.
+ *
+ * Return the node with the highest edge score. If multiple nodes have the same edge score, return
+ * the node with the smallest index.
+ */
+
+/**
+ * @param {number[]} edges
+ * @return {number}
+ */
+var edgeScore = function(edges) {
+  const scores = new Array(edges.length).fill(0);
+
+  for (let i = 0; i < edges.length; i++) {
+    scores[edges[i]] += i;
+  }
+  let maxScore = 0;
+  let result = 0;
+  for (let i = 0; i < scores.length; i++) {
+    if (scores[i] > maxScore) {
+      maxScore = scores[i];
+      result = i;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2376-count-special-integers.js b/solutions/2376-count-special-integers.js
new file mode 100644
index 00000000..977b5730
--- /dev/null
+++ b/solutions/2376-count-special-integers.js
@@ -0,0 +1,47 @@
+/**
+ * 2376. Count Special Integers
+ * https://leetcode.com/problems/count-special-integers/
+ * Difficulty: Hard
+ *
+ * We call a positive integer special if all of its digits are distinct.
+ *
+ * Given a positive integer n, return the number of special integers that belong to the
+ * interval [1, n].
+ */
+
+/**
+ * @param {number} n
+ * @return {number}
+ */
+var countSpecialNumbers = function(n) {
+  const digits = String(n).split('').map(Number);
+  const len = digits.length;
+  let total = 0;
+
+  for (let i = 1; i < len; i++) {
+    let count = 9;
+    for (let j = 0; j < i - 1; j++) {
+      count *= (10 - j - 1);
+    }
+    total += count;
+  }
+
+  const used = new Set();
+  for (let i = 0; i < len; i++) {
+    for (let d = (i === 0 ? 1 : 0); d < digits[i]; d++) {
+      if (!used.has(d)) {
+        let count = 1;
+        for (let j = i + 1; j < len; j++) {
+          count *= (10 - used.size - (j - i));
+        }
+        total += count;
+      }
+    }
+    if (used.has(digits[i]) || digits[i] === 0 && i === 0) break;
+    used.add(digits[i]);
+  }
+
+  if (used.size === len) total++;
+
+  return total;
+};
diff --git a/solutions/2380-time-needed-to-rearrange-a-binary-string.js b/solutions/2380-time-needed-to-rearrange-a-binary-string.js
new file mode 100644
index 00000000..d85d2234
--- /dev/null
+++ b/solutions/2380-time-needed-to-rearrange-a-binary-string.js
@@ -0,0 +1,32 @@
+/**
+ * 2380. Time Needed to Rearrange a Binary String
+ * https://leetcode.com/problems/time-needed-to-rearrange-a-binary-string/
+ * Difficulty: Medium
+ *
+ * You are given a binary string s. In one second, all occurrences of "01" are simultaneously
+ * replaced with "10". This process repeats until no occurrences of "01" exist.
+ *
+ * Return the number of seconds needed to complete this process.
+ */
+
+/**
+ * @param {string} s
+ * @return {number}
+ */
+var secondsToRemoveOccurrences = function(s) {
+  const binary = s.split('');
+  let result = 0;
+
+  while (binary.join('').includes('01')) {
+    for (let i = 0; i < binary.length - 1; i++) {
+      if (binary[i] === '0' && binary[i + 1] === '1') {
+        binary[i] = '1';
+        binary[i + 1] = '0';
+        i++;
+      }
+    }
+    result++;
+  }
+
+  return result;
+};
diff --git a/solutions/2382-maximum-segment-sum-after-removals.js b/solutions/2382-maximum-segment-sum-after-removals.js
new file mode 100644
index 00000000..78065c5e
--- /dev/null
+++ b/solutions/2382-maximum-segment-sum-after-removals.js
@@ -0,0 +1,84 @@
+/**
+ * 2382. Maximum Segment Sum After Removals
+ * https://leetcode.com/problems/maximum-segment-sum-after-removals/
+ * Difficulty: Hard
+ *
+ * You are given two 0-indexed integer arrays nums and removeQueries, both of length n. For
+ * the ith query, the element in nums at the index removeQueries[i] is removed, splitting
+ * nums into different segments.
+ *
+ * A segment is a contiguous sequence of positive integers in nums. A segment sum is the sum
+ * of every element in a segment.
+ *
+ * Return an integer array answer, of length n, where answer[i] is the maximum segment sum after
+ * applying the ith removal.
+ *
+ * Note: The same index will not be removed more than once.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number[]} removeQueries
+ * @return {number[]}
+ */
+var maximumSegmentSum = function(nums, removeQueries) {
+  const n = nums.length;
+  const result = new Array(n);
+  const prefixSum = new Array(n + 1).fill(0);
+  const parents = new Array(n).fill(-1);
+  const sizes = new Array(n).fill(0);
+  const sums = new Array(n).fill(0);
+  let maxSum = 0;
+
+  for (let i = 0; i < n; i++) {
+    prefixSum[i + 1] = prefixSum[i] + nums[i];
+  }
+
+  for (let i = n - 1; i >= 0; i--) {
+    result[i] = maxSum;
+    const index = removeQueries[i];
+
+    parents[index] = index;
+    sizes[index] = 1;
+    sums[index] = nums[index];
+
+    if (index > 0 && parents[index - 1] !== -1) {
+      const leftRoot = findRoot(parents, index - 1);
+      const segmentSum = sums[leftRoot] + sums[index];
+
+      parents[index] = leftRoot;
+      sizes[leftRoot] += sizes[index];
+      sums[leftRoot] = segmentSum;
+    }
+
+    if (index < n - 1 && parents[index + 1] !== -1) {
+      const root = findRoot(parents, index);
+      const rightRoot = findRoot(parents, index + 1);
+
+      if (root !== rightRoot) {
+        const segmentSum = sums[root] + sums[rightRoot];
+
+        if (sizes[root] < sizes[rightRoot]) {
+          parents[root] = rightRoot;
+          sizes[rightRoot] += sizes[root];
+          sums[rightRoot] = segmentSum;
+        } else {
+          parents[rightRoot] = root;
+          sizes[root] += sizes[rightRoot];
+          sums[root] = segmentSum;
+        }
+      }
+    }
+
+    maxSum = Math.max(maxSum, sums[findRoot(parents, index)]);
+  }
+
+  return result;
+};
+
+function findRoot(parents, x) {
+  if (parents[x] !== x) {
+    parents[x] = findRoot(parents, parents[x]);
+  }
+  return parents[x];
+}
diff --git a/solutions/2383-minimum-hours-of-training-to-win-a-competition.js b/solutions/2383-minimum-hours-of-training-to-win-a-competition.js
new file mode 100644
index 00000000..0699fdcc
--- /dev/null
+++ b/solutions/2383-minimum-hours-of-training-to-win-a-competition.js
@@ -0,0 +1,55 @@
+/**
+ * 2383. Minimum Hours of Training to Win a Competition
+ * https://leetcode.com/problems/minimum-hours-of-training-to-win-a-competition/
+ * Difficulty: Easy
+ *
+ * You are entering a competition, and are given two positive integers initialEnergy and
+ * initialExperience denoting your initial energy and initial experience respectively.
+ *
+ * You are also given two 0-indexed integer arrays energy and experience, both of length n.
+ *
+ * You will face n opponents in order. The energy and experience of the ith opponent is
+ * denoted by energy[i] and experience[i] respectively. When you face an opponent, you need
+ * to have both strictly greater experience and energy to defeat them and move to the next
+ * opponent if available.
+ *
+ * Defeating the ith opponent increases your experience by experience[i], but decreases your
+ * energy by energy[i].
+ *
+ * Before starting the competition, you can train for some number of hours. After each hour
+ * of training, you can either choose to increase your initial experience by one, or increase
+ * your initial energy by one.
+ *
+ * Return the minimum number of training hours required to defeat all n opponents.
+ */
+
+/**
+ * @param {number} initialEnergy
+ * @param {number} initialExperience
+ * @param {number[]} energy
+ * @param {number[]} experience
+ * @return {number}
+ */
+var minNumberOfHours = function(initialEnergy, initialExperience, energy, experience) {
+  let energyNeeded = 0;
+  let experienceNeeded = 0;
+  let currentEnergy = initialEnergy;
+  let currentExperience = initialExperience;
+
+  for (let i = 0; i < energy.length; i++) {
+    if (currentEnergy <= energy[i]) {
+      const deficit = energy[i] - currentEnergy + 1;
+      energyNeeded += deficit;
+      currentEnergy += deficit;
+    }
+    if (currentExperience <= experience[i]) {
+      const deficit = experience[i] - currentExperience + 1;
+      experienceNeeded += deficit;
+      currentExperience += deficit;
+    }
+    currentEnergy -= energy[i];
+    currentExperience += experience[i];
+  }
+
+  return energyNeeded + experienceNeeded;
+};
diff --git a/solutions/2385-amount-of-time-for-binary-tree-to-be-infected.js b/solutions/2385-amount-of-time-for-binary-tree-to-be-infected.js
new file mode 100644
index 00000000..00bd2ddd
--- /dev/null
+++ b/solutions/2385-amount-of-time-for-binary-tree-to-be-infected.js
@@ -0,0 +1,70 @@
+/**
+ * 2385. Amount of Time for Binary Tree to Be Infected
+ * https://leetcode.com/problems/amount-of-time-for-binary-tree-to-be-infected/
+ * Difficulty: Medium
+ *
+ * You are given the root of a binary tree with unique values, and an integer start.
+ * At minute 0, an infection starts from the node with value start.
+ *
+ * Each minute, a node becomes infected if:
+ * - The node is currently uninfected.
+ * - The node is adjacent to an infected node.
+ *
+ * Return the number of minutes needed for the entire tree to be infected.
+ */
+
+/**
+ * Definition for a binary tree node.
+ * function TreeNode(val, left, right) {
+ *     this.val = (val===undefined ? 0 : val)
+ *     this.left = (left===undefined ? null : left)
+ *     this.right = (right===undefined ? null : right)
+ * }
+ */
+/**
+ * @param {TreeNode} root
+ * @param {number} start
+ * @return {number}
+ */
+var amountOfTime = function(root, start) {
+  const graph = new Map();
+  const queue = [start];
+  const visited = new Set([start]);
+  let result = -1;
+
+  buildGraph(root, null);
+
+  while (queue.length) {
+    result++;
+    const levelSize = queue.length;
+    for (let i = 0; i < levelSize; i++) {
+      const current = queue.shift();
+      for (const neighbor of graph.get(current) || []) {
+        if (!visited.has(neighbor)) {
+          visited.add(neighbor);
+          queue.push(neighbor);
+        }
+      }
+    }
+  }
+
+  return result;
+
+  function buildGraph(node, parent) {
+    if (!node) return;
+    if (!graph.has(node.val)) graph.set(node.val, []);
+    if (parent) graph.get(node.val).push(parent.val);
+    if (node.left) {
+      graph.get(node.val).push(node.left.val);
+      graph.set(node.left.val, graph.get(node.left.val) || []);
+      graph.get(node.left.val).push(node.val);
+    }
+    if (node.right) {
+      graph.get(node.val).push(node.right.val);
+      graph.set(node.right.val, graph.get(node.right.val) || []);
+      graph.get(node.right.val).push(node.val);
+    }
+    buildGraph(node.left, node);
+    buildGraph(node.right, node);
+  }
+};
diff --git a/solutions/2389-longest-subsequence-with-limited-sum.js b/solutions/2389-longest-subsequence-with-limited-sum.js
new file mode 100644
index 00000000..a498b7c8
--- /dev/null
+++ b/solutions/2389-longest-subsequence-with-limited-sum.js
@@ -0,0 +1,43 @@
+/**
+ * 2389. Longest Subsequence With Limited Sum
+ * https://leetcode.com/problems/longest-subsequence-with-limited-sum/
+ * Difficulty: Easy
+ *
+ * You are given an integer array nums of length n, and an integer array queries of length m.
+ *
+ * Return an array answer of length m where answer[i] is the maximum size of a subsequence that
+ * you can take from nums such that the sum of its elements is less than or equal to queries[i].
+ *
+ * A subsequence is an array that can be derived from another array by deleting some or no elements
+ * without changing the order of the remaining elements.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number[]} queries
+ * @return {number[]}
+ */
+var answerQueries = function(nums, queries) {
+  nums.sort((a, b) => a - b);
+  const prefixSums = [0];
+  for (const num of nums) {
+    prefixSums.push(prefixSums.at(-1) + num);
+  }
+
+  const result = new Array(queries.length);
+  for (let i = 0; i < queries.length; i++) {
+    let left = 0;
+    let right = nums.length;
+    while (left < right) {
+      const mid = Math.floor((left + right + 1) / 2);
+      if (prefixSums[mid] <= queries[i]) {
+        left = mid;
+      } else {
+        right = mid - 1;
+      }
+    }
+    result[i] = left;
+  }
+
+  return result;
+};
diff --git a/solutions/2391-minimum-amount-of-time-to-collect-garbage.js b/solutions/2391-minimum-amount-of-time-to-collect-garbage.js
new file mode 100644
index 00000000..bbddfc01
--- /dev/null
+++ b/solutions/2391-minimum-amount-of-time-to-collect-garbage.js
@@ -0,0 +1,50 @@
+/**
+ * 2391. Minimum Amount of Time to Collect Garbage
+ * https://leetcode.com/problems/minimum-amount-of-time-to-collect-garbage/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed array of strings garbage where garbage[i] represents the assortment
+ * of garbage at the ith house. garbage[i] consists only of the characters 'M', 'P' and 'G'
+ * representing one unit of metal, paper and glass garbage respectively. Picking up one unit of
+ * any type of garbage takes 1 minute.
+ *
+ * You are also given a 0-indexed integer array travel where travel[i] is the number of minutes
+ * needed to go from house i to house i + 1.
+ *
+ * There are three garbage trucks in the city, each responsible for picking up one type of garbage.
+ * Each garbage truck starts at house 0 and must visit each house in order; however, they do not
+ * need to visit every house.
+ *
+ * Only one garbage truck may be used at any given moment. While one truck is driving or picking up
+ * garbage, the other two trucks cannot do anything.
+ *
+ * Return the minimum number of minutes needed to pick up all the garbage.
+ */
+
+/**
+ * @param {string[]} garbage
+ * @param {number[]} travel
+ * @return {number}
+ */
+var garbageCollection = function(garbage, travel) {
+  let result = 0;
+  const lastHouse = {'M': 0, 'P': 0, 'G': 0};
+
+  for (let i = 0; i < garbage.length; i++) {
+    result += garbage[i].length;
+    for (const type of garbage[i]) {
+      lastHouse[type] = i;
+    }
+  }
+
+  const prefixTravel = [0];
+  for (const time of travel) {
+    prefixTravel.push(prefixTravel.at(-1) + time);
+  }
+
+  Object.keys(lastHouse).forEach(type => {
+    result += prefixTravel[lastHouse[type]];
+  });
+
+  return result;
+};
diff --git a/solutions/2392-build-a-matrix-with-conditions.js b/solutions/2392-build-a-matrix-with-conditions.js
new file mode 100644
index 00000000..b55cdd0f
--- /dev/null
+++ b/solutions/2392-build-a-matrix-with-conditions.js
@@ -0,0 +1,76 @@
+/**
+ * 2392. Build a Matrix With Conditions
+ * https://leetcode.com/problems/build-a-matrix-with-conditions/
+ * Difficulty: Hard
+ *
+ * You are given a positive integer k. You are also given:
+ * - a 2D integer array rowConditions of size n where rowConditions[i] = [abovei, belowi], and
+ * - a 2D integer array colConditions of size m where colConditions[i] = [lefti, righti].
+ *
+ * The two arrays contain integers from 1 to k.
+ *
+ * You have to build a k x k matrix that contains each of the numbers from 1 to k exactly once.
+ * The remaining cells should have the value 0.
+ *
+ * The matrix should also satisfy the following conditions:
+ * - The number abovei should appear in a row that is strictly above the row at which the number
+ *   belowi appears for all i from 0 to n - 1.
+ * - The number lefti should appear in a column that is strictly left of the column at which the
+ *   number righti appears for all i from 0 to m - 1.
+ *
+ * Return any matrix that satisfies the conditions. If no answer exists, return an empty matrix.
+ */
+
+/**
+ * @param {number} k
+ * @param {number[][]} rowConditions
+ * @param {number[][]} colConditions
+ * @return {number[][]}
+ */
+var buildMatrix = function(k, rowConditions, colConditions) {
+  const rowOrder = helper(rowConditions, k);
+  if (!rowOrder.length) return [];
+
+  const colOrder = helper(colConditions, k);
+  if (!colOrder.length) return [];
+
+  const matrix = Array.from({ length: k }, () => new Array(k).fill(0));
+  const rowIndex = new Array(k + 1).fill(0);
+  const colIndex = new Array(k + 1).fill(0);
+
+  for (let i = 0; i < k; i++) {
+    rowIndex[rowOrder[i]] = i;
+    colIndex[colOrder[i]] = i;
+  }
+
+  for (let num = 1; num <= k; num++) {
+    matrix[rowIndex[num]][colIndex[num]] = num;
+  }
+
+  return matrix;
+
+  function helper(edges, size) {
+    const graph = Array.from({ length: size + 1 }, () => []);
+    const inDegree = new Array(size + 1).fill(0);
+    for (const [u, v] of edges) {
+      graph[u].push(v);
+      inDegree[v]++;
+    }
+
+    const queue = [];
+    for (let i = 1; i <= size; i++) {
+      if (inDegree[i] === 0) queue.push(i);
+    }
+
+    const order = [];
+    while (queue.length) {
+      const node = queue.shift();
+      order.push(node);
+      for (const next of graph[node]) {
+        if (--inDegree[next] === 0) queue.push(next);
+      }
+    }
+
+    return order.length === size ? order : [];
+  }
+};
diff --git a/solutions/2395-find-subarrays-with-equal-sum.js b/solutions/2395-find-subarrays-with-equal-sum.js
new file mode 100644
index 00000000..9b4ec520
--- /dev/null
+++ b/solutions/2395-find-subarrays-with-equal-sum.js
@@ -0,0 +1,28 @@
+/**
+ * 2395. Find Subarrays With Equal Sum
+ * https://leetcode.com/problems/find-subarrays-with-equal-sum/
+ * Difficulty: Easy
+ *
+ * Given a 0-indexed integer array nums, determine whether there exist two subarrays of length
+ * 2 with equal sum. Note that the two subarrays must begin at different indices.
+ *
+ * Return true if these subarrays exist, and false otherwise.
+ *
+ * A subarray is a contiguous non-empty sequence of elements within an array.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {boolean}
+ */
+var findSubarrays = function(nums) {
+  const set = new Set();
+
+  for (let i = 0; i < nums.length - 1; i++) {
+    const sum = nums[i] + nums[i + 1];
+    if (set.has(sum)) return true;
+    set.add(sum);
+  }
+
+  return false;
+};
diff --git a/solutions/2397-maximum-rows-covered-by-columns.js b/solutions/2397-maximum-rows-covered-by-columns.js
new file mode 100644
index 00000000..0fa68a2b
--- /dev/null
+++ b/solutions/2397-maximum-rows-covered-by-columns.js
@@ -0,0 +1,61 @@
+/**
+ * 2397. Maximum Rows Covered by Columns
+ * https://leetcode.com/problems/maximum-rows-covered-by-columns/
+ * Difficulty: Medium
+ *
+ * You are given an m x n binary matrix matrix and an integer numSelect.
+ *
+ * Your goal is to select exactly numSelect distinct columns from matrix such that you cover
+ * as many rows as possible.
+ *
+ * A row is considered covered if all the 1's in that row are also part of a column that you
+ * have selected. If a row does not have any 1s, it is also considered covered.
+ *
+ * More formally, let us consider selected = {c1, c2, ...., cnumSelect} as the set of columns
+ * selected by you. A row i is covered by selected if:
+ * - For each cell where matrix[i][j] == 1, the column j is in selected.
+ * - Or, no cell in row i has a value of 1.
+ *
+ * Return the maximum number of rows that can be covered by a set of numSelect columns.
+ */
+
+/**
+ * @param {number[][]} matrix
+ * @param {number} numSelect
+ * @return {number}
+ */
+var maximumRows = function(matrix, numSelect) {
+  const rows = matrix.length;
+  const cols = matrix[0].length;
+  let result = 0;
+
+  backtrack(0, 0, 0);
+
+  return result;
+
+  function countCovered(selected) {
+    let covered = 0;
+    for (let i = 0; i < rows; i++) {
+      let isCovered = true;
+      for (let j = 0; j < cols; j++) {
+        if (matrix[i][j] === 1 && !(selected & (1 << j))) {
+          isCovered = false;
+          break;
+        }
+      }
+      if (isCovered) covered++;
+    }
+    return covered;
+  }
+
+  function backtrack(index, selected, count) {
+    if (count === numSelect) {
+      result = Math.max(result, countCovered(selected));
+      return;
+    }
+    if (index >= cols || cols - index + count < numSelect) return;
+
+    backtrack(index + 1, selected | (1 << index), count + 1);
+    backtrack(index + 1, selected, count);
+  }
+};
diff --git a/solutions/2399-check-distances-between-same-letters.js b/solutions/2399-check-distances-between-same-letters.js
new file mode 100644
index 00000000..7f977d1e
--- /dev/null
+++ b/solutions/2399-check-distances-between-same-letters.js
@@ -0,0 +1,44 @@
+/**
+ * 2399. Check Distances Between Same Letters
+ * https://leetcode.com/problems/check-distances-between-same-letters/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed string s consisting of only lowercase English letters, where each
+ * letter in s appears exactly twice. You are also given a 0-indexed integer array distance of
+ * length 26.
+ *
+ * Each letter in the alphabet is numbered from 0 to 25 (i.e. 'a' -> 0, 'b' -> 1,
+ * 'c' -> 2, ... , 'z' -> 25).
+ *
+ * In a well-spaced string, the number of letters between the two occurrences of the ith letter
+ * is distance[i]. If the ith letter does not appear in s, then distance[i] can be ignored.
+ *
+ * Return true if s is a well-spaced string, otherwise return false.
+ */
+
+/**
+ * @param {string} s
+ * @param {number[]} distance
+ * @return {boolean}
+ */
+var checkDistances = function(s, distance) {
+  const map = new Map();
+
+  for (let i = 0; i < s.length; i++) {
+    const char = s[i];
+    if (map.has(char)) {
+      map.get(char).push(i);
+    } else {
+      map.set(char, [i]);
+    }
+  }
+
+  for (const [char, positions] of map) {
+    const letterIndex = char.charCodeAt(0) - 'a'.charCodeAt(0);
+    if (positions[1] - positions[0] - 1 !== distance[letterIndex]) {
+      return false;
+    }
+  }
+
+  return true;
+};
diff --git a/solutions/2404-most-frequent-even-element.js b/solutions/2404-most-frequent-even-element.js
new file mode 100644
index 00000000..e5fcd0c6
--- /dev/null
+++ b/solutions/2404-most-frequent-even-element.js
@@ -0,0 +1,33 @@
+/**
+ * 2404. Most Frequent Even Element
+ * https://leetcode.com/problems/most-frequent-even-element/
+ * Difficulty: Easy
+ *
+ * Given an integer array nums, return the most frequent even element.
+ *
+ * If there is a tie, return the smallest one. If there is no such element, return -1.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var mostFrequentEven = function(nums) {
+  const map = new Map();
+  let maxCount = 0;
+  let result = -1;
+
+  for (const num of nums) {
+    if (num % 2 === 0) {
+      const count = (map.get(num) || 0) + 1;
+      map.set(num, count);
+      if (count > maxCount || (count === maxCount && num < result)) {
+        maxCount = count;
+        result = num;
+      }
+    }
+  }
+
+  return result;
+};
+
diff --git a/solutions/2405-optimal-partition-of-string.js b/solutions/2405-optimal-partition-of-string.js
new file mode 100644
index 00000000..eb2849bc
--- /dev/null
+++ b/solutions/2405-optimal-partition-of-string.js
@@ -0,0 +1,31 @@
+/**
+ * 2405. Optimal Partition of String
+ * https://leetcode.com/problems/optimal-partition-of-string/
+ * Difficulty: Medium
+ *
+ * Given a string s, partition the string into one or more substrings such that the characters
+ * in each substring are unique. That is, no letter appears in a single substring more than once.
+ *
+ * Return the minimum number of substrings in such a partition.
+ *
+ * Note that each character should belong to exactly one substring in a partition.
+ */
+
+/**
+ * @param {string} s
+ * @return {number}
+ */
+var partitionString = function(s) {
+  const set = new Set();
+  let result = 1;
+
+  for (const char of s) {
+    if (set.has(char)) {
+      set.clear();
+      result++;
+    }
+    set.add(char);
+  }
+
+  return result;
+};
diff --git a/solutions/2409-count-days-spent-together.js b/solutions/2409-count-days-spent-together.js
new file mode 100644
index 00000000..1047ab0b
--- /dev/null
+++ b/solutions/2409-count-days-spent-together.js
@@ -0,0 +1,48 @@
+/**
+ * 2409. Count Days Spent Together
+ * https://leetcode.com/problems/count-days-spent-together/
+ * Difficulty: Easy
+ *
+ * Alice and Bob are traveling to Rome for separate business meetings.
+ *
+ * You are given 4 strings arriveAlice, leaveAlice, arriveBob, and leaveBob. Alice will be in
+ * the city from the dates arriveAlice to leaveAlice (inclusive), while Bob will be in the city
+ * from the dates arriveBob to leaveBob (inclusive). Each will be a 5-character string in the
+ * format "MM-DD", corresponding to the month and day of the date.
+ *
+ * Return the total number of days that Alice and Bob are in Rome together.
+ *
+ * You can assume that all dates occur in the same calendar year, which is not a leap year. Note
+ * that the number of days per month can be represented as: [31, 28, 31, 30, 31, 30, 31, 31, 30,
+ * 31, 30, 31].
+ */
+
+/**
+ * @param {string} arriveAlice
+ * @param {string} leaveAlice
+ * @param {string} arriveBob
+ * @param {string} leaveBob
+ * @return {number}
+ */
+var countDaysTogether = function(arriveAlice, leaveAlice, arriveBob, leaveBob) {
+  const daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
+
+  function toDays(date) {
+    const [month, day] = date.split('-').map(Number);
+    let totalDays = 0;
+    for (let i = 0; i < month - 1; i++) {
+      totalDays += daysInMonth[i];
+    }
+    return totalDays + day;
+  }
+
+  const aliceStart = toDays(arriveAlice);
+  const aliceEnd = toDays(leaveAlice);
+  const bobStart = toDays(arriveBob);
+  const bobEnd = toDays(leaveBob);
+
+  const overlapStart = Math.max(aliceStart, bobStart);
+  const overlapEnd = Math.min(aliceEnd, bobEnd);
+
+  return Math.max(0, overlapEnd - overlapStart + 1);
+};
diff --git a/solutions/2410-maximum-matching-of-players-with-trainers.js b/solutions/2410-maximum-matching-of-players-with-trainers.js
new file mode 100644
index 00000000..885db445
--- /dev/null
+++ b/solutions/2410-maximum-matching-of-players-with-trainers.js
@@ -0,0 +1,35 @@
+/**
+ * 2410. Maximum Matching of Players With Trainers
+ * https://leetcode.com/problems/maximum-matching-of-players-with-trainers/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed integer array players, where players[i] represents the ability of
+ * the ith player. You are also given a 0-indexed integer array trainers, where trainers[j]
+ * represents the training capacity of the jth trainer.
+ *
+ * The ith player can match with the jth trainer if the player's ability is less than or equal
+ * to the trainer's training capacity. Additionally, the ith player can be matched with at most
+ * one trainer, and the jth trainer can be matched with at most one player.
+ *
+ * Return the maximum number of matchings between players and trainers that satisfy these
+ * conditions.
+ */
+
+/**
+ * @param {number[]} players
+ * @param {number[]} trainers
+ * @return {number}
+ */
+var matchPlayersAndTrainers = function(players, trainers) {
+  players.sort((a, b) => a - b);
+  trainers.sort((a, b) => a - b);
+
+  let result = 0;
+  for (let j = 0; result < players.length && j < trainers.length; j++) {
+    if (trainers[j] >= players[result]) {
+      result++;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2411-smallest-subarrays-with-maximum-bitwise-or.js b/solutions/2411-smallest-subarrays-with-maximum-bitwise-or.js
new file mode 100644
index 00000000..784cf5d2
--- /dev/null
+++ b/solutions/2411-smallest-subarrays-with-maximum-bitwise-or.js
@@ -0,0 +1,46 @@
+/**
+ * 2411. Smallest Subarrays With Maximum Bitwise OR
+ * https://leetcode.com/problems/smallest-subarrays-with-maximum-bitwise-or/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed array nums of length n, consisting of non-negative integers. For
+ * each index i from 0 to n - 1, you must determine the size of the minimum sized non-empty
+ * subarray of nums starting at i (inclusive) that has the maximum possible bitwise OR.
+ * - In other words, let Bij be the bitwise OR of the subarray nums[i...j]. You need to find
+ *   the smallest subarray starting at i, such that bitwise OR of this subarray is equal to
+ *   max(Bik) where i <= k <= n - 1.
+ *
+ * The bitwise OR of an array is the bitwise OR of all the numbers in it.
+ *
+ * Return an integer array answer of size n where answer[i] is the length of the minimum sized
+ * subarray starting at i with maximum bitwise OR.
+ *
+ * A subarray is a contiguous non-empty sequence of elements within an array.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number[]}
+ */
+var smallestSubarrays = function(nums) {
+  const n = nums.length;
+  const result = new Array(n).fill(1);
+  const bitPositions = new Array(32).fill(0);
+
+  for (let i = n - 1; i >= 0; i--) {
+    for (let bit = 0; bit < 32; bit++) {
+      if (nums[i] & (1 << bit)) {
+        bitPositions[bit] = i;
+      }
+    }
+
+    let maxIndex = i;
+    for (let bit = 0; bit < 32; bit++) {
+      maxIndex = Math.max(maxIndex, bitPositions[bit]);
+    }
+
+    result[i] = maxIndex - i + 1;
+  }
+
+  return result;
+};
diff --git a/solutions/2412-minimum-money-required-before-transactions.js b/solutions/2412-minimum-money-required-before-transactions.js
new file mode 100644
index 00000000..240ca6ca
--- /dev/null
+++ b/solutions/2412-minimum-money-required-before-transactions.js
@@ -0,0 +1,36 @@
+/**
+ * 2412. Minimum Money Required Before Transactions
+ * https://leetcode.com/problems/minimum-money-required-before-transactions/
+ * Difficulty: Hard
+ *
+ * You are given a 0-indexed 2D integer array transactions, where
+ * transactions[i] = [costi, cashbacki].
+ *
+ * The array describes transactions, where each transaction must be completed exactly once
+ * in some order. At any given moment, you have a certain amount of money. In order to
+ * complete transaction i, money >= costi must hold true. After performing a transaction,
+ * money becomes money - costi + cashbacki.
+ *
+ * Return the minimum amount of money required before any transaction so that all of the
+ * transactions can be completed regardless of the order of the transactions.
+ */
+
+/**
+ * @param {number[][]} transactions
+ * @return {number}
+ */
+var minimumMoney = function(transactions) {
+  let totalLoss = 0;
+  let maxCost = 0;
+
+  for (const [cost, cashback] of transactions) {
+    if (cost > cashback) {
+      totalLoss += cost - cashback;
+      maxCost = Math.max(maxCost, cashback);
+    } else {
+      maxCost = Math.max(maxCost, cost);
+    }
+  }
+
+  return totalLoss + maxCost;
+};
diff --git a/solutions/2414-length-of-the-longest-alphabetical-continuous-substring.js b/solutions/2414-length-of-the-longest-alphabetical-continuous-substring.js
new file mode 100644
index 00000000..afb44c82
--- /dev/null
+++ b/solutions/2414-length-of-the-longest-alphabetical-continuous-substring.js
@@ -0,0 +1,32 @@
+/**
+ * 2414. Length of the Longest Alphabetical Continuous Substring
+ * https://leetcode.com/problems/length-of-the-longest-alphabetical-continuous-substring/
+ * Difficulty: Medium
+ *
+ * An alphabetical continuous string is a string consisting of consecutive letters in the alphabet.
+ * In other words, it is any substring of the string "abcdefghijklmnopqrstuvwxyz".
+ * - For example, "abc" is an alphabetical continuous string, while "acb" and "za" are not.
+ *
+ * Given a string s consisting of lowercase letters only, return the length of the longest
+ * alphabetical continuous substring.
+ */
+
+/**
+ * @param {string} s
+ * @return {number}
+ */
+var longestContinuousSubstring = function(s) {
+  let result = 1;
+  let currentLength = 1;
+
+  for (let i = 1; i < s.length; i++) {
+    if (s.charCodeAt(i) - s.charCodeAt(i - 1) === 1) {
+      currentLength++;
+      result = Math.max(result, currentLength);
+    } else {
+      currentLength = 1;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2415-reverse-odd-levels-of-binary-tree.js b/solutions/2415-reverse-odd-levels-of-binary-tree.js
new file mode 100644
index 00000000..9c70383b
--- /dev/null
+++ b/solutions/2415-reverse-odd-levels-of-binary-tree.js
@@ -0,0 +1,51 @@
+/**
+ * 2415. Reverse Odd Levels of Binary Tree
+ * https://leetcode.com/problems/reverse-odd-levels-of-binary-tree/
+ * Difficulty: Medium
+ *
+ * Given the root of a perfect binary tree, reverse the node values at each odd level of the tree.
+ * - For example, suppose the node values at level 3 are [2,1,3,4,7,11,29,18], then it should
+ *   become [18,29,11,7,4,3,1,2].
+ *
+ * Return the root of the reversed tree.
+ *
+ * A binary tree is perfect if all parent nodes have two children and all leaves are on the same
+ * level.
+ *
+ * The level of a node is the number of edges along the path between it and the root node.
+ */
+
+/**
+ * Definition for a binary tree node.
+ * function TreeNode(val, left, right) {
+ *     this.val = (val===undefined ? 0 : val)
+ *     this.left = (left===undefined ? null : left)
+ *     this.right = (right===undefined ? null : right)
+ * }
+ */
+/**
+ * @param {TreeNode} root
+ * @return {TreeNode}
+ */
+var reverseOddLevels = function(root) {
+  reverseLevel([root], 0);
+  return root;
+
+  function reverseLevel(nodes, level) {
+    if (!nodes.length) return;
+
+    if (level % 2 === 1) {
+      for (let i = 0, j = nodes.length - 1; i < j; i++, j--) {
+        [nodes[i].val, nodes[j].val] = [nodes[j].val, nodes[i].val];
+      }
+    }
+
+    const nextLevel = [];
+    for (const node of nodes) {
+      if (node.left) nextLevel.push(node.left);
+      if (node.right) nextLevel.push(node.right);
+    }
+
+    reverseLevel(nextLevel, level + 1);
+  }
+};
diff --git a/solutions/2416-sum-of-prefix-scores-of-strings.js b/solutions/2416-sum-of-prefix-scores-of-strings.js
new file mode 100644
index 00000000..45d3a184
--- /dev/null
+++ b/solutions/2416-sum-of-prefix-scores-of-strings.js
@@ -0,0 +1,56 @@
+/**
+ * 2416. Sum of Prefix Scores of Strings
+ * https://leetcode.com/problems/sum-of-prefix-scores-of-strings/
+ * Difficulty: Hard
+ *
+ * You are given an array words of size n consisting of non-empty strings.
+ *
+ * We define the score of a string term as the number of strings words[i] such that term is
+ * a prefix of words[i].
+ * - For example, if words = ["a", "ab", "abc", "cab"], then the score of "ab" is 2, since
+ *   "ab" is a prefix of both "ab" and "abc".
+ *
+ * Return an array answer of size n where answer[i] is the sum of scores of every non-empty
+ * prefix of words[i].
+ *
+ * Note that a string is considered as a prefix of itself.
+ */
+
+/**
+ * @param {string[]} words
+ * @return {number[]}
+ */
+var sumPrefixScores = function(words) {
+  class TrieNode {
+    constructor() {
+      this.children = new Map();
+      this.count = 0;
+    }
+  }
+
+  const root = new TrieNode();
+
+  for (const word of words) {
+    let node = root;
+    for (const char of word) {
+      if (!node.children.has(char)) {
+        node.children.set(char, new TrieNode());
+      }
+      node = node.children.get(char);
+      node.count++;
+    }
+  }
+
+  const result = [];
+  for (const word of words) {
+    let node = root;
+    let score = 0;
+    for (const char of word) {
+      node = node.children.get(char);
+      score += node.count;
+    }
+    result.push(score);
+  }
+
+  return result;
+};
diff --git a/solutions/2418-sort-the-people.js b/solutions/2418-sort-the-people.js
new file mode 100644
index 00000000..c0477a6a
--- /dev/null
+++ b/solutions/2418-sort-the-people.js
@@ -0,0 +1,23 @@
+/**
+ * 2418. Sort the People
+ * https://leetcode.com/problems/sort-the-people/
+ * Difficulty: Easy
+ *
+ * You are given an array of strings names, and an array heights that consists of distinct
+ * positive integers. Both arrays are of length n.
+ *
+ * For each index i, names[i] and heights[i] denote the name and height of the ith person.
+ *
+ * Return names sorted in descending order by the people's heights.
+ */
+
+/**
+ * @param {string[]} names
+ * @param {number[]} heights
+ * @return {string[]}
+ */
+var sortPeople = function(names, heights) {
+  const people = names.map((name, index) => ({name, height: heights[index]}));
+  people.sort((a, b) => b.height - a.height);
+  return people.map(person => person.name);
+};
diff --git a/solutions/2419-longest-subarray-with-maximum-bitwise-and.js b/solutions/2419-longest-subarray-with-maximum-bitwise-and.js
new file mode 100644
index 00000000..c6a26711
--- /dev/null
+++ b/solutions/2419-longest-subarray-with-maximum-bitwise-and.js
@@ -0,0 +1,38 @@
+/**
+ * 2419. Longest Subarray With Maximum Bitwise AND
+ * https://leetcode.com/problems/longest-subarray-with-maximum-bitwise-and/
+ * Difficulty: Medium
+ *
+ * You are given an integer array nums of size n.
+ *
+ * Consider a non-empty subarray from nums that has the maximum possible bitwise AND.
+ * - In other words, let k be the maximum value of the bitwise AND of any subarray of nums.
+ *   Then, only subarrays with a bitwise AND equal to k should be considered.
+ *
+ * Return the length of the longest such subarray.
+ *
+ * The bitwise AND of an array is the bitwise AND of all the numbers in it.
+ *
+ * A subarray is a contiguous sequence of elements within an array.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var longestSubarray = function(nums) {
+  const maxValue = Math.max(...nums);
+  let result = 0;
+  let currentLength = 0;
+
+  for (const num of nums) {
+    if (num === maxValue) {
+      currentLength++;
+      result = Math.max(result, currentLength);
+    } else {
+      currentLength = 0;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2420-find-all-good-indices.js b/solutions/2420-find-all-good-indices.js
new file mode 100644
index 00000000..e3216e6e
--- /dev/null
+++ b/solutions/2420-find-all-good-indices.js
@@ -0,0 +1,42 @@
+/**
+ * 2420. Find All Good Indices
+ * https://leetcode.com/problems/find-all-good-indices/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed integer array nums of size n and a positive integer k.
+ *
+ * We call an index i in the range k <= i < n - k good if the following conditions are satisfied:
+ * - The k elements that are just before the index i are in non-increasing order.
+ * - The k elements that are just after the index i are in non-decreasing order.
+ *
+ * Return an array of all good indices sorted in increasing order.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @return {number[]}
+ */
+var goodIndices = function(nums, k) {
+  const n = nums.length;
+  const nonIncreasing = new Array(n).fill(1);
+  const nonDecreasing = new Array(n).fill(1);
+  const result = [];
+
+  for (let i = 1; i < n; i++) {
+    if (nums[i - 1] >= nums[i]) {
+      nonIncreasing[i] = nonIncreasing[i - 1] + 1;
+    }
+    if (nums[n - i] >= nums[n - i - 1]) {
+      nonDecreasing[n - i - 1] = nonDecreasing[n - i] + 1;
+    }
+  }
+
+  for (let i = k; i < n - k; i++) {
+    if (nonIncreasing[i - 1] >= k && nonDecreasing[i + 1] >= k) {
+      result.push(i);
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2421-number-of-good-paths.js b/solutions/2421-number-of-good-paths.js
new file mode 100644
index 00000000..c0f7d606
--- /dev/null
+++ b/solutions/2421-number-of-good-paths.js
@@ -0,0 +1,86 @@
+/**
+ * 2421. Number of Good Paths
+ * https://leetcode.com/problems/number-of-good-paths/
+ * Difficulty: Hard
+ *
+ * There is a tree (i.e. a connected, undirected graph with no cycles) consisting of n nodes
+ * numbered from 0 to n - 1 and exactly n - 1 edges.
+ *
+ * You are given a 0-indexed integer array vals of length n where vals[i] denotes the value
+ * of the ith node. You are also given a 2D integer array edges where edges[i] = [ai, bi]
+ * denotes that there exists an undirected edge connecting nodes ai and bi.
+ *
+ * A good path is a simple path that satisfies the following conditions:
+ * 1. The starting node and the ending node have the same value.
+ * 2. All nodes between the starting node and the ending node have values less than or equal
+ *    to the starting node (i.e. the starting node's value should be the maximum value along
+ *    the path).
+ *
+ * Return the number of distinct good paths.
+ *
+ * Note that a path and its reverse are counted as the same path. For example, 0 -> 1 is
+ * considered to be the same as 1 -> 0. A single node is also considered as a valid path.
+ */
+
+/**
+ * @param {number[]} vals
+ * @param {number[][]} edges
+ * @return {number}
+ */
+var numberOfGoodPaths = function(vals, edges) {
+  const n = vals.length;
+  const graph = Array.from({length: n}, () => []);
+  for (const [u, v] of edges) {
+    graph[u].push(v);
+    graph[v].push(u);
+  }
+
+  const parent = new Array(n).fill(-1);
+  const rank = new Array(n).fill(0);
+  function find(x) {
+    if (parent[x] === -1) return x;
+    return parent[x] = find(parent[x]);
+  }
+
+  function union(x, y) {
+    let px = find(x);
+    let py = find(y);
+    if (px === py) return;
+    if (rank[px] < rank[py]) [px, py] = [py, px];
+    parent[py] = px;
+    if (rank[px] === rank[py]) rank[px]++;
+  }
+
+  const valueGroups = new Map();
+  for (let i = 0; i < n; i++) {
+    if (!valueGroups.has(vals[i])) {
+      valueGroups.set(vals[i], []);
+    }
+    valueGroups.get(vals[i]).push(i);
+  }
+
+  let result = 0;
+  for (const value of [...valueGroups.keys()].sort((a, b) => a - b)) {
+    const nodes = valueGroups.get(value);
+
+    for (const node of nodes) {
+      for (const neighbor of graph[node]) {
+        if (vals[neighbor] <= value) {
+          union(node, neighbor);
+        }
+      }
+    }
+
+    const groupCount = new Map();
+    for (const node of nodes) {
+      const root = find(node);
+      groupCount.set(root, (groupCount.get(root) || 0) + 1);
+    }
+
+    for (const count of groupCount.values()) {
+      result += (count * (count + 1)) / 2;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2426-number-of-pairs-satisfying-inequality.js b/solutions/2426-number-of-pairs-satisfying-inequality.js
new file mode 100644
index 00000000..e24957fd
--- /dev/null
+++ b/solutions/2426-number-of-pairs-satisfying-inequality.js
@@ -0,0 +1,66 @@
+/**
+ * 2426. Number of Pairs Satisfying Inequality
+ * https://leetcode.com/problems/number-of-pairs-satisfying-inequality/
+ * Difficulty: Hard
+ *
+ * You are given two 0-indexed integer arrays nums1 and nums2, each of size n, and an
+ * integer diff. Find the number of pairs (i, j) such that:
+ * - 0 <= i < j <= n - 1 and
+ * - nums1[i] - nums1[j] <= nums2[i] - nums2[j] + diff.
+ *
+ * Return the number of pairs that satisfy the conditions.
+ */
+
+/**
+ * @param {number[]} nums1
+ * @param {number[]} nums2
+ * @param {number} diff
+ * @return {number}
+ */
+var numberOfPairs = function(nums1, nums2, diff) {
+  const n = nums1.length;
+  const differences = new Array(n);
+  for (let i = 0; i < n; i++) {
+    differences[i] = nums1[i] - nums2[i];
+  }
+  let result = 0;
+  mergeSort(0, n);
+  return result;
+
+  function mergeSort(left, right) {
+    if (right - left <= 1) return;
+
+    const mid = Math.floor((left + right) / 2);
+    mergeSort(left, mid);
+    mergeSort(mid, right);
+
+    let i = left;
+    let j = mid;
+    while (i < mid && j < right) {
+      if (differences[i] <= differences[j] + diff) {
+        result += right - j;
+        i++;
+      } else {
+        j++;
+      }
+    }
+
+    const sorted = new Array(right - left);
+    let k = 0;
+    i = left;
+    j = mid;
+    while (i < mid && j < right) {
+      if (differences[i] <= differences[j]) {
+        sorted[k++] = differences[i++];
+      } else {
+        sorted[k++] = differences[j++];
+      }
+    }
+    while (i < mid) sorted[k++] = differences[i++];
+    while (j < right) sorted[k++] = differences[j++];
+
+    for (let p = 0; p < sorted.length; p++) {
+      differences[left + p] = sorted[p];
+    }
+  }
+};
diff --git a/solutions/2428-maximum-sum-of-an-hourglass.js b/solutions/2428-maximum-sum-of-an-hourglass.js
new file mode 100644
index 00000000..f6cb5a39
--- /dev/null
+++ b/solutions/2428-maximum-sum-of-an-hourglass.js
@@ -0,0 +1,33 @@
+/**
+ * 2428. Maximum Sum of an Hourglass
+ * https://leetcode.com/problems/maximum-sum-of-an-hourglass/
+ * Difficulty: Medium
+ *
+ * You are given an m x n integer matrix grid.
+ *
+ * We define an hourglass as a part of the matrix with the following form.
+ *
+ * Return the maximum sum of the elements of an hourglass.
+ *
+ * Note that an hourglass cannot be rotated and must be entirely contained within the matrix.
+ */
+
+/**
+ * @param {number[][]} grid
+ * @return {number}
+ */
+var maxSum = function(grid) {
+  let result = 0;
+  const rows = grid.length;
+  const cols = grid[0].length;
+
+  for (let i = 0; i <= rows - 3; i++) {
+    for (let j = 0; j <= cols - 3; j++) {
+      const hourglassSum = grid[i][j] + grid[i][j+1] + grid[i][j+2] + grid[i+1][j+1]
+        + grid[i+2][j] + grid[i+2][j+1] + grid[i+2][j+2];
+      result = Math.max(result, hourglassSum);
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2432-the-employee-that-worked-on-the-longest-task.js b/solutions/2432-the-employee-that-worked-on-the-longest-task.js
new file mode 100644
index 00000000..acab1a87
--- /dev/null
+++ b/solutions/2432-the-employee-that-worked-on-the-longest-task.js
@@ -0,0 +1,40 @@
+/**
+ * 2432. The Employee That Worked on the Longest Task
+ * https://leetcode.com/problems/the-employee-that-worked-on-the-longest-task/
+ * Difficulty: Easy
+ *
+ * There are n employees, each with a unique id from 0 to n - 1.
+ *
+ * You are given a 2D integer array logs where logs[i] = [idi, leaveTimei] where:
+ * - idi is the id of the employee that worked on the ith task, and
+ * - leaveTimei is the time at which the employee finished the ith task. All the values
+ *   leaveTimei are unique.
+ *
+ * Note that the ith task starts the moment right after the (i - 1)th task ends, and the 0th
+ * task starts at time 0.
+ *
+ * Return the id of the employee that worked the task with the longest time. If there is a tie
+ * between two or more employees, return the smallest id among them.
+ */
+
+/**
+ * @param {number} n
+ * @param {number[][]} logs
+ * @return {number}
+ */
+var hardestWorker = function(n, logs) {
+  let maxDuration = 0;
+  let result = n;
+  let startTime = 0;
+
+  for (const [employeeId, endTime] of logs) {
+    const duration = endTime - startTime;
+    if (duration > maxDuration || (duration === maxDuration && employeeId < result)) {
+      maxDuration = duration;
+      result = employeeId;
+    }
+    startTime = endTime;
+  }
+
+  return result;
+};
diff --git a/solutions/2433-find-the-original-array-of-prefix-xor.js b/solutions/2433-find-the-original-array-of-prefix-xor.js
new file mode 100644
index 00000000..0f41ebeb
--- /dev/null
+++ b/solutions/2433-find-the-original-array-of-prefix-xor.js
@@ -0,0 +1,28 @@
+/**
+ * 2433. Find The Original Array of Prefix Xor
+ * https://leetcode.com/problems/find-the-original-array-of-prefix-xor/
+ * Difficulty: Medium
+ *
+ * You are given an integer array pref of size n. Find and return the array arr of size
+ * n that satisfies:
+ * - pref[i] = arr[0] ^ arr[1] ^ ... ^ arr[i].
+ *
+ * Note that ^ denotes the bitwise-xor operation.
+ *
+ * It can be proven that the answer is unique.
+ */
+
+/**
+ * @param {number[]} pref
+ * @return {number[]}
+ */
+var findArray = function(pref) {
+  const result = new Array(pref.length);
+  result[0] = pref[0];
+
+  for (let i = 1; i < pref.length; i++) {
+    result[i] = pref[i] ^ pref[i - 1];
+  }
+
+  return result;
+};
diff --git a/solutions/2434-using-a-robot-to-print-the-lexicographically-smallest-string.js b/solutions/2434-using-a-robot-to-print-the-lexicographically-smallest-string.js
new file mode 100644
index 00000000..430e0fa6
--- /dev/null
+++ b/solutions/2434-using-a-robot-to-print-the-lexicographically-smallest-string.js
@@ -0,0 +1,49 @@
+/**
+ * 2434. Using a Robot to Print the Lexicographically Smallest String
+ * https://leetcode.com/problems/using-a-robot-to-print-the-lexicographically-smallest-string/
+ * Difficulty: Medium
+ *
+ * You are given a string s and a robot that currently holds an empty string t. Apply one of the
+ * following operations until s and t are both empty:
+ * - Remove the first character of a string s and give it to the robot. The robot will append
+ *   this character to the string t.
+ * - Remove the last character of a string t and give it to the robot. The robot will write
+ *   this character on paper.
+ *
+ * Return the lexicographically smallest string that can be written on the paper.
+ */
+
+/**
+ * @param {string} s
+ * @return {string}
+ */
+var robotWithString = function(s) {
+  const charCount = Array(26).fill(0);
+  for (const char of s) {
+    charCount[char.charCodeAt(0) - 97]++;
+  }
+
+  const stack = [];
+  let minCharIndex = 0;
+  let result = '';
+
+  for (const char of s) {
+    stack.push(char);
+    charCount[char.charCodeAt(0) - 97]--;
+
+    while (minCharIndex < 26 && charCount[minCharIndex] === 0) {
+      minCharIndex++;
+    }
+
+    while (stack.length
+      && (minCharIndex === 26 || stack[stack.length - 1].charCodeAt(0) - 97 <= minCharIndex)) {
+      result += stack.pop();
+    }
+  }
+
+  while (stack.length) {
+    result += stack.pop();
+  }
+
+  return result;
+};
diff --git a/solutions/2435-paths-in-matrix-whose-sum-is-divisible-by-k.js b/solutions/2435-paths-in-matrix-whose-sum-is-divisible-by-k.js
new file mode 100644
index 00000000..741526c7
--- /dev/null
+++ b/solutions/2435-paths-in-matrix-whose-sum-is-divisible-by-k.js
@@ -0,0 +1,45 @@
+/**
+ * 2435. Paths in Matrix Whose Sum Is Divisible by K
+ * https://leetcode.com/problems/paths-in-matrix-whose-sum-is-divisible-by-k/
+ * Difficulty: Hard
+ *
+ * You are given a 0-indexed m x n integer matrix grid and an integer k. You are currently at
+ * position (0, 0) and you want to reach position (m - 1, n - 1) moving only down or right.
+ *
+ * Return the number of paths where the sum of the elements on the path is divisible by k.
+ * Since the answer may be very large, return it modulo 109 + 7.
+ */
+
+/**
+ * @param {number[][]} grid
+ * @param {number} k
+ * @return {number}
+ */
+var numberOfPaths = function(grid, k) {
+  const rows = grid.length;
+  const cols = grid[0].length;
+  const modulo = 1e9 + 7;
+  const dp = Array.from({ length: rows }, () => {
+    return Array.from({ length: cols }, () => Array(k).fill(0));
+  });
+
+  dp[0][0][grid[0][0] % k] = 1;
+
+  for (let row = 0; row < rows; row++) {
+    for (let col = 0; col < cols; col++) {
+      const currentValue = grid[row][col] % k;
+      for (let sum = 0; sum < k; sum++) {
+        if (row > 0) {
+          const prevSum = (sum - currentValue + k) % k;
+          dp[row][col][sum] = (dp[row][col][sum] + dp[row - 1][col][prevSum]) % modulo;
+        }
+        if (col > 0) {
+          const prevSum = (sum - currentValue + k) % k;
+          dp[row][col][sum] = (dp[row][col][sum] + dp[row][col - 1][prevSum]) % modulo;
+        }
+      }
+    }
+  }
+
+  return dp[rows - 1][cols - 1][0];
+};
diff --git a/solutions/2437-number-of-valid-clock-times.js b/solutions/2437-number-of-valid-clock-times.js
new file mode 100644
index 00000000..8b4d26bb
--- /dev/null
+++ b/solutions/2437-number-of-valid-clock-times.js
@@ -0,0 +1,42 @@
+/**
+ * 2437. Number of Valid Clock Times
+ * https://leetcode.com/problems/number-of-valid-clock-times/
+ * Difficulty: Easy
+ *
+ * You are given a string of length 5 called time, representing the current time on a digital
+ * clock in the format "hh:mm". The earliest possible time is "00:00" and the latest possible
+ * time is "23:59".
+ *
+ * In the string time, the digits represented by the ? symbol are unknown, and must be replaced
+ * with a digit from 0 to 9.
+ *
+ * Return an integer answer, the number of valid clock times that can be created by replacing
+ * every ? with a digit from 0 to 9.
+ */
+
+/**
+ * @param {string} time
+ * @return {number}
+ */
+var countTime = function(time) {
+  let hourChoices = 1;
+  let minuteChoices = 1;
+
+  if (time[0] === '?' && time[1] === '?') {
+    hourChoices = 24;
+  } else if (time[0] === '?') {
+    hourChoices = time[1] <= '3' ? 3 : 2;
+  } else if (time[1] === '?') {
+    hourChoices = time[0] === '2' ? 4 : 10;
+  }
+
+  if (time[3] === '?' && time[4] === '?') {
+    minuteChoices = 60;
+  } else if (time[3] === '?') {
+    minuteChoices = 6;
+  } else if (time[4] === '?') {
+    minuteChoices = 10;
+  }
+
+  return hourChoices * minuteChoices;
+};
diff --git a/solutions/2438-range-product-queries-of-powers.js b/solutions/2438-range-product-queries-of-powers.js
new file mode 100644
index 00000000..ebebead8
--- /dev/null
+++ b/solutions/2438-range-product-queries-of-powers.js
@@ -0,0 +1,45 @@
+/**
+ * 2438. Range Product Queries of Powers
+ * https://leetcode.com/problems/range-product-queries-of-powers/
+ * Difficulty: Medium
+ *
+ * Given a positive integer n, there exists a 0-indexed array called powers, composed of the
+ * minimum number of powers of 2 that sum to n. The array is sorted in non-decreasing order,
+ * and there is only one way to form the array.
+ *
+ * You are also given a 0-indexed 2D integer array queries, where queries[i] = [lefti, righti].
+ * Each queries[i] represents a query where you have to find the product of all powers[j] with
+ * lefti <= j <= righti.
+ *
+ * Return an array answers, equal in length to queries, where answers[i] is the answer to the
+ * ith query. Since the answer to the ith query may be too large, each answers[i] should be
+ * returned modulo 109 + 7.
+ */
+
+/**
+ * @param {number} n
+ * @param {number[][]} queries
+ * @return {number[]}
+ */
+var productQueries = function(n, queries) {
+  const modulo = 1e9 + 7;
+  const powers = [];
+  while (n > 0) {
+    const power = Math.floor(Math.log2(n));
+    powers.push(1 << power);
+    n -= 1 << power;
+  }
+  powers.reverse();
+
+  const result = new Array(queries.length);
+  for (let i = 0; i < queries.length; i++) {
+    const [start, end] = queries[i];
+    let product = 1;
+    for (let j = start; j <= end; j++) {
+      product = (product * powers[j]) % modulo;
+    }
+    result[i] = product;
+  }
+
+  return result;
+};
diff --git a/solutions/2439-minimize-maximum-of-array.js b/solutions/2439-minimize-maximum-of-array.js
new file mode 100644
index 00000000..5d147f37
--- /dev/null
+++ b/solutions/2439-minimize-maximum-of-array.js
@@ -0,0 +1,53 @@
+/**
+ * 2439. Minimize Maximum of Array
+ * https://leetcode.com/problems/minimize-maximum-of-array/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed array nums comprising of n non-negative integers.
+ *
+ * In one operation, you must:
+ * - Choose an integer i such that 1 <= i < n and nums[i] > 0.
+ * - Decrease nums[i] by 1.
+ * - Increase nums[i - 1] by 1.
+ *
+ * Return the minimum possible value of the maximum integer of nums after performing
+ * any number of operations.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var minimizeArrayValue = function(nums) {
+  let left = 0;
+  let right = Math.max(...nums);
+  let result = right;
+
+  while (left <= right) {
+    const mid = Math.floor((left + right) / 2);
+    let carry = 0;
+    let valid = true;
+
+    for (let i = nums.length - 1; i >= 0; i--) {
+      const total = nums[i] + carry;
+      if (total > mid) {
+        if (i === 0) {
+          valid = false;
+          break;
+        }
+        carry = total - mid;
+      } else {
+        carry = 0;
+      }
+    }
+
+    if (valid) {
+      result = mid;
+      right = mid - 1;
+    } else {
+      left = mid + 1;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2440-create-components-with-same-value.js b/solutions/2440-create-components-with-same-value.js
new file mode 100644
index 00000000..d0a6391f
--- /dev/null
+++ b/solutions/2440-create-components-with-same-value.js
@@ -0,0 +1,64 @@
+/**
+ * 2440. Create Components With Same Value
+ * https://leetcode.com/problems/create-components-with-same-value/
+ * Difficulty: Hard
+ *
+ * There is an undirected tree with n nodes labeled from 0 to n - 1.
+ *
+ * You are given a 0-indexed integer array nums of length n where nums[i] represents the value
+ * of the ith node. You are also given a 2D integer array edges of length n - 1 where
+ * edges[i] = [ai, bi] indicates that there is an edge between nodes ai and bi in the tree.
+ *
+ * You are allowed to delete some edges, splitting the tree into multiple connected components.
+ * Let the value of a component be the sum of all nums[i] for which node i is in the component.
+ *
+ * Return the maximum number of edges you can delete, such that every connected component in
+ * the tree has the same value.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number[][]} edges
+ * @return {number}
+ */
+var componentValue = function(nums, edges) {
+  const n = nums.length;
+  const graph = Array.from({ length: n }, () => []);
+  const totalSum = nums.reduce((sum, val) => sum + val, 0);
+
+  for (const [u, v] of edges) {
+    graph[u].push(v);
+    graph[v].push(u);
+  }
+
+  for (let i = n; i >= 1; i--) {
+    if (totalSum % i === 0) {
+      const target = totalSum / i;
+      const [, components] = countNodes(0, -1, target);
+      if (components === i) {
+        return i - 1;
+      }
+    }
+  }
+
+  return 0;
+
+  function countNodes(node, parent, target) {
+    let sum = nums[node];
+    let components = 0;
+
+    for (const neighbor of graph[node]) {
+      if (neighbor !== parent) {
+        const [childSum, childComponents] = countNodes(neighbor, node, target);
+        sum += childSum;
+        components += childComponents;
+      }
+    }
+
+    if (sum === target) {
+      return [0, components + 1];
+    }
+
+    return [sum, components];
+  }
+};
diff --git a/solutions/2441-largest-positive-integer-that-exists-with-its-negative.js b/solutions/2441-largest-positive-integer-that-exists-with-its-negative.js
new file mode 100644
index 00000000..e80f0ac9
--- /dev/null
+++ b/solutions/2441-largest-positive-integer-that-exists-with-its-negative.js
@@ -0,0 +1,28 @@
+/**
+ * 2441. Largest Positive Integer That Exists With Its Negative
+ * https://leetcode.com/problems/largest-positive-integer-that-exists-with-its-negative/
+ * Difficulty: Easy
+ *
+ * Given an integer array nums that does not contain any zeros, find the largest positive
+ * integer k such that -k also exists in the array.
+ *
+ * Return the positive integer k. If there is no such integer, return -1.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var findMaxK = function(nums) {
+  const set = new Set();
+  let result = -1;
+
+  for (const num of nums) {
+    if (set.has(-num)) {
+      result = Math.max(result, Math.abs(num));
+    }
+    set.add(num);
+  }
+
+  return result;
+};
diff --git a/solutions/2442-count-number-of-distinct-integers-after-reverse-operations.js b/solutions/2442-count-number-of-distinct-integers-after-reverse-operations.js
new file mode 100644
index 00000000..d1cc0abd
--- /dev/null
+++ b/solutions/2442-count-number-of-distinct-integers-after-reverse-operations.js
@@ -0,0 +1,32 @@
+/**
+ * 2442. Count Number of Distinct Integers After Reverse Operations
+ * https://leetcode.com/problems/count-number-of-distinct-integers-after-reverse-operations/
+ * Difficulty: Medium
+ *
+ * You are given an array nums consisting of positive integers.
+ *
+ * You have to take each integer in the array, reverse its digits, and add it to the end of the
+ * array. You should apply this operation to the original integers in nums.
+ *
+ * Return the number of distinct integers in the final array.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var countDistinctIntegers = function(nums) {
+  const set = new Set(nums);
+
+  for (const num of nums) {
+    let reversed = 0;
+    let temp = num;
+    while (temp > 0) {
+      reversed = reversed * 10 + temp % 10;
+      temp = Math.floor(temp / 10);
+    }
+    set.add(reversed);
+  }
+
+  return set.size;
+};
diff --git a/solutions/2443-sum-of-number-and-its-reverse.js b/solutions/2443-sum-of-number-and-its-reverse.js
new file mode 100644
index 00000000..7e17944a
--- /dev/null
+++ b/solutions/2443-sum-of-number-and-its-reverse.js
@@ -0,0 +1,28 @@
+/**
+ * 2443. Sum of Number and Its Reverse
+ * https://leetcode.com/problems/sum-of-number-and-its-reverse/
+ * Difficulty: Medium
+ *
+ * Given a non-negative integer num, return true if num can be expressed as the sum of any
+ * non-negative integer and its reverse, or false otherwise.
+ */
+
+/**
+ * @param {number} num
+ * @return {boolean}
+ */
+var sumOfNumberAndReverse = function(num) {
+  for (let i = 0; i <= num; i++) {
+    let reversed = 0;
+    let temp = i;
+    while (temp > 0) {
+      reversed = reversed * 10 + temp % 10;
+      temp = Math.floor(temp / 10);
+    }
+    if (i + reversed === num) {
+      return true;
+    }
+  }
+
+  return false;
+};
diff --git a/solutions/2446-determine-if-two-events-have-conflict.js b/solutions/2446-determine-if-two-events-have-conflict.js
new file mode 100644
index 00000000..3a70a834
--- /dev/null
+++ b/solutions/2446-determine-if-two-events-have-conflict.js
@@ -0,0 +1,28 @@
+/**
+ * 2446. Determine if Two Events Have Conflict
+ * https://leetcode.com/problems/determine-if-two-events-have-conflict/
+ * Difficulty: Easy
+ *
+ * You are given two arrays of strings that represent two inclusive events that happened on the
+ * same day, event1 and event2, where:
+ * - event1 = [startTime1, endTime1] and
+ * - event2 = [startTime2, endTime2].
+ *
+ * Event times are valid 24 hours format in the form of HH:MM.
+ *
+ * A conflict happens when two events have some non-empty intersection (i.e., some moment is common
+ * to both events).
+ *
+ * Return true if there is a conflict between two events. Otherwise, return false.
+ */
+
+/**
+ * @param {string[]} event1
+ * @param {string[]} event2
+ * @return {boolean}
+ */
+var haveConflict = function(event1, event2) {
+  const [start1, end1] = event1;
+  const [start2, end2] = event2;
+  return start1 <= end2 && start2 <= end1;
+};
diff --git a/solutions/2447-number-of-subarrays-with-gcd-equal-to-k.js b/solutions/2447-number-of-subarrays-with-gcd-equal-to-k.js
new file mode 100644
index 00000000..efc4339c
--- /dev/null
+++ b/solutions/2447-number-of-subarrays-with-gcd-equal-to-k.js
@@ -0,0 +1,41 @@
+/**
+ * 2447. Number of Subarrays With GCD Equal to K
+ * https://leetcode.com/problems/number-of-subarrays-with-gcd-equal-to-k/
+ * Difficulty: Medium
+ *
+ * Given an integer array nums and an integer k, return the number of subarrays of nums where
+ * the greatest common divisor of the subarray's elements is k.
+ *
+ * A subarray is a contiguous non-empty sequence of elements within an array.
+ *
+ * The greatest common divisor of an array is the largest integer that evenly divides all the
+ * array elements.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @return {number}
+ */
+var subarrayGCD = function(nums, k) {
+  let result = 0;
+  for (let start = 0; start < nums.length; start++) {
+    let currentGCD = nums[start];
+    for (let end = start; end < nums.length; end++) {
+      currentGCD = gcd(currentGCD, nums[end]);
+      if (currentGCD === k) {
+        result++;
+      }
+    }
+  }
+
+  return result;
+
+  function gcd(a, b) {
+    while (b) {
+      a %= b;
+      [a, b] = [b, a];
+    }
+    return a;
+  }
+};
diff --git a/solutions/2448-minimum-cost-to-make-array-equal.js b/solutions/2448-minimum-cost-to-make-array-equal.js
new file mode 100644
index 00000000..1bf9d6fd
--- /dev/null
+++ b/solutions/2448-minimum-cost-to-make-array-equal.js
@@ -0,0 +1,45 @@
+/**
+ * 2448. Minimum Cost to Make Array Equal
+ * https://leetcode.com/problems/minimum-cost-to-make-array-equal/
+ * Difficulty: Hard
+ *
+ * You are given two 0-indexed arrays nums and cost consisting each of n positive integers.
+ *
+ * You can do the following operation any number of times:
+ * - Increase or decrease any element of the array nums by 1.
+ *
+ * The cost of doing one operation on the ith element is cost[i].
+ *
+ * Return the minimum total cost such that all the elements of the array nums become equal.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number[]} cost
+ * @return {number}
+ */
+var minCost = function(nums, cost) {
+  const pairs = nums.map((num, i) => [num, cost[i]]).sort((a, b) => a[0] - b[0]);
+  const n = nums.length;
+  const prefixSum = Array(n).fill(0);
+  const prefixCost = Array(n).fill(0);
+
+  prefixSum[0] = pairs[0][0] * pairs[0][1];
+  prefixCost[0] = pairs[0][1];
+
+  for (let i = 1; i < n; i++) {
+    prefixSum[i] = prefixSum[i - 1] + pairs[i][0] * pairs[i][1];
+    prefixCost[i] = prefixCost[i - 1] + pairs[i][1];
+  }
+
+  let result = Infinity;
+  for (let i = 0; i < n; i++) {
+    const target = pairs[i][0];
+    const leftCost = i > 0 ? target * prefixCost[i - 1] - prefixSum[i - 1] : 0;
+    const rightCost = i < n - 1 ? prefixSum[n - 1] - prefixSum[i]
+      - target * (prefixCost[n - 1] - prefixCost[i]) : 0;
+    result = Math.min(result, leftCost + rightCost);
+  }
+
+  return result;
+};
diff --git a/solutions/2449-minimum-number-of-operations-to-make-arrays-similar.js b/solutions/2449-minimum-number-of-operations-to-make-arrays-similar.js
new file mode 100644
index 00000000..29c2cacf
--- /dev/null
+++ b/solutions/2449-minimum-number-of-operations-to-make-arrays-similar.js
@@ -0,0 +1,44 @@
+/**
+ * 2449. Minimum Number of Operations to Make Arrays Similar
+ * https://leetcode.com/problems/minimum-number-of-operations-to-make-arrays-similar/
+ * Difficulty: Hard
+ *
+ * You are given two positive integer arrays nums and target, of the same length.
+ *
+ * In one operation, you can choose any two distinct indices i and j where 0 <= i,
+ * j < nums.length and:
+ * - set nums[i] = nums[i] + 2 and
+ * - set nums[j] = nums[j] - 2.
+ *
+ * Two arrays are considered to be similar if the frequency of each element is the same.
+ *
+ * Return the minimum number of operations required to make nums similar to target. The
+ * test cases are generated such that nums can always be similar to target.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number[]} target
+ * @return {number}
+ */
+var makeSimilar = function(nums, target) {
+  const evenNums = nums.filter(num => num % 2 === 0).sort((a, b) => a - b);
+  const oddNums = nums.filter(num => num % 2 === 1).sort((a, b) => a - b);
+  const evenTarget = target.filter(num => num % 2 === 0).sort((a, b) => a - b);
+  const oddTarget = target.filter(num => num % 2 === 1).sort((a, b) => a - b);
+
+  let result = 0;
+  for (let i = 0; i < evenNums.length; i++) {
+    if (evenNums[i] > evenTarget[i]) {
+      result += (evenNums[i] - evenTarget[i]) / 2;
+    }
+  }
+
+  for (let i = 0; i < oddNums.length; i++) {
+    if (oddNums[i] > oddTarget[i]) {
+      result += (oddNums[i] - oddTarget[i]) / 2;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2451-odd-string-difference.js b/solutions/2451-odd-string-difference.js
new file mode 100644
index 00000000..8556415c
--- /dev/null
+++ b/solutions/2451-odd-string-difference.js
@@ -0,0 +1,53 @@
+/**
+ * 2451. Odd String Difference
+ * https://leetcode.com/problems/odd-string-difference/
+ * Difficulty: Easy
+ *
+ * You are given an array of equal-length strings words. Assume that the length of each
+ * string is n.
+ *
+ * Each string words[i] can be converted into a difference integer array difference[i] of
+ * length n - 1 where difference[i][j] = words[i][j+1] - words[i][j] where 0 <= j <= n - 2.
+ * Note that the difference between two letters is the difference between their positions in
+ * the alphabet i.e. the position of 'a' is 0, 'b' is 1, and 'z' is 25.
+ * - For example, for the string "acb", the difference integer array is [2 - 0, 1 - 2] = [2, -1].
+ *
+ * All the strings in words have the same difference integer array, except one. You should find
+ * that string.
+ *
+ * Return the string in words that has different difference integer array.
+ */
+
+/**
+ * @param {string[]} words
+ * @return {string}
+ */
+var oddString = function(words) {
+  const map = new Map();
+  for (const word of words) {
+    const diff = getDiff(word);
+    map.set(diff, (map.get(diff) || 0) + 1);
+  }
+
+  let oddDiff;
+  for (const [diff, count] of map) {
+    if (count === 1) {
+      oddDiff = diff;
+      break;
+    }
+  }
+
+  for (const word of words) {
+    if (getDiff(word) === oddDiff) {
+      return word;
+    }
+  }
+
+  function getDiff(word) {
+    const diff = [];
+    for (let i = 1; i < word.length; i++) {
+      diff.push(word.charCodeAt(i) - word.charCodeAt(i - 1));
+    }
+    return diff.join(',');
+  }
+};
diff --git a/solutions/2452-words-within-two-edits-of-dictionary.js b/solutions/2452-words-within-two-edits-of-dictionary.js
new file mode 100644
index 00000000..237dac21
--- /dev/null
+++ b/solutions/2452-words-within-two-edits-of-dictionary.js
@@ -0,0 +1,41 @@
+/**
+ * 2452. Words Within Two Edits of Dictionary
+ * https://leetcode.com/problems/words-within-two-edits-of-dictionary/
+ * Difficulty: Medium
+ *
+ * You are given two string arrays, queries and dictionary. All words in each array comprise of
+ * lowercase English letters and have the same length.
+ *
+ * In one edit you can take a word from queries, and change any letter in it to any other letter.
+ * Find all words from queries that, after a maximum of two edits, equal some word from dictionary.
+ *
+ * Return a list of all words from queries, that match with some word from dictionary after a
+ * maximum of two edits. Return the words in the same order they appear in queries.
+ */
+
+/**
+ * @param {string[]} queries
+ * @param {string[]} dictionary
+ * @return {string[]}
+ */
+var twoEditWords = function(queries, dictionary) {
+  const result = [];
+
+  for (const query of queries) {
+    for (const word of dictionary) {
+      let edits = 0;
+      for (let i = 0; i < query.length; i++) {
+        if (query[i] !== word[i]) {
+          edits++;
+          if (edits > 2) break;
+        }
+      }
+      if (edits <= 2) {
+        result.push(query);
+        break;
+      }
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2453-destroy-sequential-targets.js b/solutions/2453-destroy-sequential-targets.js
new file mode 100644
index 00000000..d1c9f856
--- /dev/null
+++ b/solutions/2453-destroy-sequential-targets.js
@@ -0,0 +1,40 @@
+/**
+ * 2453. Destroy Sequential Targets
+ * https://leetcode.com/problems/destroy-sequential-targets/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed array nums consisting of positive integers, representing targets
+ * on a number line. You are also given an integer space.
+ *
+ * You have a machine which can destroy targets. Seeding the machine with some nums[i] allows
+ * it to destroy all targets with values that can be represented as nums[i] + c * space, where
+ * c is any non-negative integer. You want to destroy the maximum number of targets in nums.
+ *
+ * Return the minimum value of nums[i] you can seed the machine with to destroy the maximum
+ * number of targets.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} space
+ * @return {number}
+ */
+var destroyTargets = function(nums, space) {
+  const map = new Map();
+  let maxCount = 0;
+
+  for (const num of nums) {
+    const remainder = num % space;
+    map.set(remainder, (map.get(remainder) || 0) + 1);
+    maxCount = Math.max(maxCount, map.get(remainder));
+  }
+
+  let result = Infinity;
+  for (const num of nums) {
+    if (map.get(num % space) === maxCount) {
+      result = Math.min(result, num);
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2455-average-value-of-even-numbers-that-are-divisible-by-three.js b/solutions/2455-average-value-of-even-numbers-that-are-divisible-by-three.js
new file mode 100644
index 00000000..e793e8fe
--- /dev/null
+++ b/solutions/2455-average-value-of-even-numbers-that-are-divisible-by-three.js
@@ -0,0 +1,29 @@
+/**
+ * 2455. Average Value of Even Numbers That Are Divisible by Three
+ * https://leetcode.com/problems/average-value-of-even-numbers-that-are-divisible-by-three/
+ * Difficulty: Easy
+ *
+ * Given an integer array nums of positive integers, return the average value of all even integers
+ * that are divisible by 3.
+ *
+ * Note that the average of n elements is the sum of the n elements divided by n and rounded down
+ * to the nearest integer.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var averageValue = function(nums) {
+  let sum = 0;
+  let count = 0;
+
+  for (const num of nums) {
+    if (num % 2 === 0 && num % 3 === 0) {
+      sum += num;
+      count++;
+    }
+  }
+
+  return count > 0 ? Math.floor(sum / count) : 0;
+};
diff --git a/solutions/2458-height-of-binary-tree-after-subtree-removal-queries.js b/solutions/2458-height-of-binary-tree-after-subtree-removal-queries.js
new file mode 100644
index 00000000..418ee0ff
--- /dev/null
+++ b/solutions/2458-height-of-binary-tree-after-subtree-removal-queries.js
@@ -0,0 +1,68 @@
+/**
+ * 2458. Height of Binary Tree After Subtree Removal Queries
+ * https://leetcode.com/problems/height-of-binary-tree-after-subtree-removal-queries/
+ * Difficulty: Hard
+ *
+ * You are given the root of a binary tree with n nodes. Each node is assigned a unique value
+ * from 1 to n. You are also given an array queries of size m.
+ *
+ * You have to perform m independent queries on the tree where in the ith query you do the
+ * following:
+ * - Remove the subtree rooted at the node with the value queries[i] from the tree. It is
+ *   guaranteed that queries[i] will not be equal to the value of the root.
+ *
+ * Return an array answer of size m where answer[i] is the height of the tree after performing
+ * the ith query.
+ *
+ * Note:
+ * - The queries are independent, so the tree returns to its initial state after each query.
+ * - The height of a tree is the number of edges in the longest simple path from the root to
+ *   some node in the tree.
+ */
+
+/**
+ * Definition for a binary tree node.
+ * function TreeNode(val, left, right) {
+ *     this.val = (val===undefined ? 0 : val)
+ *     this.left = (left===undefined ? null : left)
+ *     this.right = (right===undefined ? null : right)
+ * }
+ */
+/**
+ * @param {TreeNode} root
+ * @param {number[]} queries
+ * @return {number[]}
+ */
+var treeQueries = function(root, queries) {
+  const heights = new Map();
+  const maxHeightWithout = new Map();
+
+  computeHeight(root);
+  computeMaxHeight(root, 0, -1);
+
+  const result = new Array(queries.length);
+  for (let i = 0; i < queries.length; i++) {
+    result[i] = maxHeightWithout.get(queries[i]);
+  }
+
+  return result;
+
+  function computeHeight(node) {
+    if (!node) return -1;
+    const leftHeight = computeHeight(node.left);
+    const rightHeight = computeHeight(node.right);
+    heights.set(node.val, Math.max(leftHeight, rightHeight) + 1);
+    return heights.get(node.val);
+  }
+
+  function computeMaxHeight(node, depth, cousinHeight) {
+    if (!node) return;
+    const leftHeight = node.left ? heights.get(node.left.val) : -1;
+    const rightHeight = node.right ? heights.get(node.right.val) : -1;
+    const maxAlternative = Math.max(cousinHeight, depth - 1);
+    maxHeightWithout.set(node.val, maxAlternative);
+
+    computeMaxHeight(node.left, depth + 1, Math.max(cousinHeight, rightHeight + depth + 1));
+    computeMaxHeight(node.right, depth + 1, Math.max(cousinHeight, leftHeight + depth + 1));
+  }
+};
diff --git a/solutions/2461-maximum-sum-of-distinct-subarrays-with-length-k.js b/solutions/2461-maximum-sum-of-distinct-subarrays-with-length-k.js
new file mode 100644
index 00000000..a1212952
--- /dev/null
+++ b/solutions/2461-maximum-sum-of-distinct-subarrays-with-length-k.js
@@ -0,0 +1,45 @@
+/**
+ * 2461. Maximum Sum of Distinct Subarrays With Length K
+ * https://leetcode.com/problems/maximum-sum-of-distinct-subarrays-with-length-k/
+ * Difficulty: Medium
+ *
+ * You are given an integer array nums and an integer k. Find the maximum subarray sum of all the
+ * subarrays of nums that meet the following conditions:
+ * - The length of the subarray is k, and
+ * - All the elements of the subarray are distinct.
+ *
+ * Return the maximum subarray sum of all the subarrays that meet the conditions. If no subarray
+ * meets the conditions, return 0.
+ *
+ * A subarray is a contiguous non-empty sequence of elements within an array.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @return {number}
+ */
+var maximumSubarraySum = function(nums, k) {
+  let result = 0;
+  const seen = new Map();
+  let windowSum = 0;
+
+  for (let i = 0; i < nums.length; i++) {
+    seen.set(nums[i], (seen.get(nums[i]) || 0) + 1);
+    windowSum += nums[i];
+
+    if (i >= k - 1) {
+      if (seen.size === k) {
+        result = Math.max(result, windowSum);
+      }
+      const leftNum = nums[i - k + 1];
+      windowSum -= leftNum;
+      seen.set(leftNum, seen.get(leftNum) - 1);
+      if (seen.get(leftNum) === 0) {
+        seen.delete(leftNum);
+      }
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2463-minimum-total-distance-traveled.js b/solutions/2463-minimum-total-distance-traveled.js
new file mode 100644
index 00000000..cb71bbc0
--- /dev/null
+++ b/solutions/2463-minimum-total-distance-traveled.js
@@ -0,0 +1,71 @@
+/**
+ * 2463. Minimum Total Distance Traveled
+ * https://leetcode.com/problems/minimum-total-distance-traveled/
+ * Difficulty: Hard
+ *
+ * There are some robots and factories on the X-axis. You are given an integer array robot where
+ * robot[i] is the position of the ith robot. You are also given a 2D integer array factory where
+ * factory[j] = [positionj, limitj] indicates that positionj is the position of the jth factory
+ * and that the jth factory can repair at most limitj robots.
+ *
+ * The positions of each robot are unique. The positions of each factory are also unique. Note
+ * that a robot can be in the same position as a factory initially.
+ *
+ * All the robots are initially broken; they keep moving in one direction. The direction could be
+ * the negative or the positive direction of the X-axis. When a robot reaches a factory that did
+ * not reach its limit, the factory repairs the robot, and it stops moving.
+ *
+ * At any moment, you can set the initial direction of moving for some robot. Your target is to
+ * minimize the total distance traveled by all the robots.
+ *
+ * Return the minimum total distance traveled by all the robots. The test cases are generated
+ * such that all the robots can be repaired.
+ *
+ * Note that:
+ * - All robots move at the same speed.
+ * - If two robots move in the same direction, they will never collide.
+ * - If two robots move in opposite directions and they meet at some point, they do not collide.
+ *   They cross each other.
+ * - If a robot passes by a factory that reached its limits, it crosses it as if it does not exist.
+ * - If the robot moved from a position x to a position y, the distance it moved is |y - x|.
+ */
+
+/**
+ * @param {number[]} robot
+ * @param {number[][]} factory
+ * @return {number}
+ */
+var minimumTotalDistance = function(robot, factory) {
+  robot.sort((a, b) => a - b);
+  factory.sort((a, b) => a[0] - b[0]);
+
+  const robotCount = robot.length;
+  const factoryCount = factory.length;
+  const memo = new Array(robotCount + 1).fill(null).map(() => new Array(factoryCount + 1).fill(-1));
+
+  return calculateMinDistance(0, 0);
+
+  function calculateMinDistance(robotIndex, factoryIndex) {
+    if (robotIndex === robotCount) return 0;
+    if (factoryIndex === factoryCount) return 1e18;
+
+    if (memo[robotIndex][factoryIndex] !== -1) {
+      return memo[robotIndex][factoryIndex];
+    }
+
+    let result = calculateMinDistance(robotIndex, factoryIndex + 1);
+
+    let totalDistance = 0;
+    for (let robotsTaken = 0; robotsTaken < factory[factoryIndex][1]
+         && robotIndex + robotsTaken < robotCount; robotsTaken++) {
+      totalDistance += Math.abs(robot[robotIndex + robotsTaken] - factory[factoryIndex][0]);
+      result = Math.min(
+        result,
+        totalDistance + calculateMinDistance(robotIndex + robotsTaken + 1, factoryIndex + 1)
+      );
+    }
+
+    memo[robotIndex][factoryIndex] = result;
+    return result;
+  }
+};
diff --git a/solutions/2465-number-of-distinct-averages.js b/solutions/2465-number-of-distinct-averages.js
new file mode 100644
index 00000000..768feffd
--- /dev/null
+++ b/solutions/2465-number-of-distinct-averages.js
@@ -0,0 +1,34 @@
+/**
+ * 2465. Number of Distinct Averages
+ * https://leetcode.com/problems/number-of-distinct-averages/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed integer array nums of even length.
+ *
+ * As long as nums is not empty, you must repetitively:
+ * - Find the minimum number in nums and remove it.
+ * - Find the maximum number in nums and remove it.
+ * - Calculate the average of the two removed numbers.
+ *
+ * The average of two numbers a and b is (a + b) / 2.
+ * - For example, the average of 2 and 3 is (2 + 3) / 2 = 2.5.
+ *
+ * Return the number of distinct averages calculated using the above process.
+ *
+ * Note that when there is a tie for a minimum or maximum number, any can be removed.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var distinctAverages = function(nums) {
+  nums.sort((a, b) => a - b);
+  const averages = new Set();
+
+  for (let i = 0, j = nums.length - 1; i < j; i++, j--) {
+    averages.add((nums[i] + nums[j]) / 2);
+  }
+
+  return averages.size;
+};
diff --git a/solutions/2466-count-ways-to-build-good-strings.js b/solutions/2466-count-ways-to-build-good-strings.js
new file mode 100644
index 00000000..5bea8af2
--- /dev/null
+++ b/solutions/2466-count-ways-to-build-good-strings.js
@@ -0,0 +1,47 @@
+/**
+ * 2466. Count Ways To Build Good Strings
+ * https://leetcode.com/problems/count-ways-to-build-good-strings/
+ * Difficulty: Medium
+ *
+ * Given the integers zero, one, low, and high, we can construct a string by starting with an
+ * empty string, and then at each step perform either of the following:
+ * - Append the character '0' zero times.
+ * - Append the character '1' one times.
+ *
+ * This can be performed any number of times.
+ *
+ * A good string is a string constructed by the above process having a length between low and
+ * high (inclusive).
+ *
+ * Return the number of different good strings that can be constructed satisfying these properties.
+ * Since the answer can be large, return it modulo 109 + 7.
+ */
+
+/**
+ * @param {number} low
+ * @param {number} high
+ * @param {number} zero
+ * @param {number} one
+ * @return {number}
+ */
+var countGoodStrings = function(low, high, zero, one) {
+  const modulo = 1e9 + 7;
+  const dp = new Array(high + 1).fill(0);
+  dp[0] = 1;
+
+  for (let length = 1; length <= high; length++) {
+    if (length >= zero) {
+      dp[length] = (dp[length] + dp[length - zero]) % modulo;
+    }
+    if (length >= one) {
+      dp[length] = (dp[length] + dp[length - one]) % modulo;
+    }
+  }
+
+  let result = 0;
+  for (let length = low; length <= high; length++) {
+    result = (result + dp[length]) % modulo;
+  }
+
+  return result;
+};
diff --git a/solutions/2468-split-message-based-on-limit.js b/solutions/2468-split-message-based-on-limit.js
new file mode 100644
index 00000000..71fc5d00
--- /dev/null
+++ b/solutions/2468-split-message-based-on-limit.js
@@ -0,0 +1,52 @@
+/**
+ * 2468. Split Message Based on Limit
+ * https://leetcode.com/problems/split-message-based-on-limit/
+ * Difficulty: Hard
+ *
+ * You are given a string, message, and a positive integer, limit.
+ *
+ * You must split message into one or more parts based on limit. Each resulting part should have
+ * the suffix "", where "b" is to be replaced with the total number of parts and "a" is to
+ * be replaced with the index of the part, starting from 1 and going up to b. Additionally, the
+ * length of each resulting part (including its suffix) should be equal to limit, except for the
+ * last part whose length can be at most limit.
+ *
+ * The resulting parts should be formed such that when their suffixes are removed and they are
+ * all concatenated in order, they should be equal to message. Also, the result should contain
+ * as few parts as possible.
+ *
+ * Return the parts message would be split into as an array of strings. If it is impossible to
+ * split message as required, return an empty array.
+ */
+
+/**
+ * @param {string} message
+ * @param {number} limit
+ * @return {string[]}
+ */
+var splitMessage = function(message, limit) {
+  const n = message.length;
+  let digitSum = 0;
+
+  for (let parts = 1; parts <= n; parts++) {
+    digitSum += String(parts).length;
+    const indexLength = String(parts).length * parts;
+    const formatLength = 3 * parts;
+
+    if (limit * parts - (digitSum + indexLength + formatLength) >= n) {
+      const result = [];
+      let index = 0;
+
+      for (let i = 1; i <= parts; i++) {
+        const suffix = `<${i}/${parts}>`;
+        const chars = limit - suffix.length;
+        result.push(message.slice(index, index + chars) + suffix);
+        index += chars;
+      }
+
+      return result;
+    }
+  }
+
+  return [];
+};
diff --git a/solutions/2470-number-of-subarrays-with-lcm-equal-to-k.js b/solutions/2470-number-of-subarrays-with-lcm-equal-to-k.js
new file mode 100644
index 00000000..41edda1d
--- /dev/null
+++ b/solutions/2470-number-of-subarrays-with-lcm-equal-to-k.js
@@ -0,0 +1,45 @@
+/**
+ * 2470. Number of Subarrays With LCM Equal to K
+ * https://leetcode.com/problems/number-of-subarrays-with-lcm-equal-to-k/
+ * Difficulty: Medium
+ *
+ * Given an integer array nums and an integer k, return the number of subarrays of nums
+ * where the least common multiple of the subarray's elements is k.
+ *
+ * A subarray is a contiguous non-empty sequence of elements within an array.
+ *
+ * The least common multiple of an array is the smallest positive integer that is divisible
+ * by all the array elements.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @return {number}
+ */
+var subarrayLCM = function(nums, k) {
+  let count = 0;
+
+  for (let start = 0; start < nums.length; start++) {
+    let currentLCM = nums[start];
+    for (let end = start; end < nums.length; end++) {
+      currentLCM = lcm(currentLCM, nums[end]);
+      if (currentLCM > k) break;
+      if (currentLCM === k) count++;
+    }
+  }
+
+  return count;
+
+  function gcd(a, b) {
+    while (b) {
+      a %= b;
+      [a, b] = [b, a];
+    }
+    return a;
+  }
+
+  function lcm(a, b) {
+    return (a * b) / gcd(a, b);
+  }
+};
diff --git a/solutions/2471-minimum-number-of-operations-to-sort-a-binary-tree-by-level.js b/solutions/2471-minimum-number-of-operations-to-sort-a-binary-tree-by-level.js
new file mode 100644
index 00000000..7d26a4c1
--- /dev/null
+++ b/solutions/2471-minimum-number-of-operations-to-sort-a-binary-tree-by-level.js
@@ -0,0 +1,66 @@
+/**
+ * 2471. Minimum Number of Operations to Sort a Binary Tree by Level
+ * https://leetcode.com/problems/minimum-number-of-operations-to-sort-a-binary-tree-by-level/
+ * Difficulty: Medium
+ *
+ * You are given the root of a binary tree with unique values.
+ *
+ * In one operation, you can choose any two nodes at the same level and swap their values.
+ *
+ * Return the minimum number of operations needed to make the values at each level sorted in a
+ * strictly increasing order.
+ *
+ * The level of a node is the number of edges along the path between it and the root node.
+ */
+
+/**
+ * Definition for a binary tree node.
+ * function TreeNode(val, left, right) {
+ *     this.val = (val===undefined ? 0 : val)
+ *     this.left = (left===undefined ? null : left)
+ *     this.right = (right===undefined ? null : right)
+ * }
+ */
+/**
+ * @param {TreeNode} root
+ * @return {number}
+ */
+var minimumOperations = function(root) {
+  let result = 0;
+  const queue = [root];
+  const levelValues = [];
+
+  while (queue.length) {
+    const levelSize = queue.length;
+    const values = [];
+
+    for (let i = 0; i < levelSize; i++) {
+      const node = queue.shift();
+      values.push(node.val);
+      if (node.left) queue.push(node.left);
+      if (node.right) queue.push(node.right);
+    }
+
+    levelValues.push(values);
+  }
+
+  for (const values of levelValues) {
+    const sorted = [...values].sort((a, b) => a - b);
+    const indexMap = new Map(values.map((val, i) => [val, i]));
+    let swaps = 0;
+
+    for (let i = 0; i < values.length; i++) {
+      if (values[i] !== sorted[i]) {
+        const targetIndex = indexMap.get(sorted[i]);
+        [values[i], values[targetIndex]] = [values[targetIndex], values[i]];
+        indexMap.set(values[targetIndex], targetIndex);
+        indexMap.set(values[i], i);
+        swaps++;
+      }
+    }
+
+    result += swaps;
+  }
+
+  return result;
+};
diff --git a/solutions/2472-maximum-number-of-non-overlapping-palindrome-substrings.js b/solutions/2472-maximum-number-of-non-overlapping-palindrome-substrings.js
new file mode 100644
index 00000000..6244a364
--- /dev/null
+++ b/solutions/2472-maximum-number-of-non-overlapping-palindrome-substrings.js
@@ -0,0 +1,51 @@
+/**
+ * 2472. Maximum Number of Non-overlapping Palindrome Substrings
+ * https://leetcode.com/problems/maximum-number-of-non-overlapping-palindrome-substrings/
+ * Difficulty: Hard
+ *
+ * You are given a string s and a positive integer k.
+ *
+ * Select a set of non-overlapping substrings from the string s that satisfy the following
+ * conditions:
+ * - The length of each substring is at least k.
+ * - Each substring is a palindrome.
+ *
+ * Return the maximum number of substrings in an optimal selection.
+ *
+ * A substring is a contiguous sequence of characters within a string.
+ */
+
+/**
+ * @param {string} s
+ * @param {number} k
+ * @return {number}
+ */
+var maxPalindromes = function(s, k) {
+  const n = s.length;
+  const isPal = new Array(n).fill().map(() => new Array(n).fill(false));
+  const dp = new Array(n + 1).fill(0);
+
+  for (let len = 1; len <= n; len++) {
+    for (let start = 0; start + len <= n; start++) {
+      const end = start + len - 1;
+      if (len === 1) {
+        isPal[start][end] = true;
+      } else if (len === 2) {
+        isPal[start][end] = s[start] === s[end];
+      } else {
+        isPal[start][end] = s[start] === s[end] && isPal[start + 1][end - 1];
+      }
+    }
+  }
+
+  for (let end = k; end <= n; end++) {
+    dp[end] = dp[end - 1];
+    for (let start = end - k; start >= 0; start--) {
+      if (isPal[start][end - 1]) {
+        dp[end] = Math.max(dp[end], dp[start] + 1);
+      }
+    }
+  }
+
+  return dp[n];
+};
diff --git a/solutions/2475-number-of-unequal-triplets-in-array.js b/solutions/2475-number-of-unequal-triplets-in-array.js
new file mode 100644
index 00000000..8717363b
--- /dev/null
+++ b/solutions/2475-number-of-unequal-triplets-in-array.js
@@ -0,0 +1,36 @@
+/**
+ * 2475. Number of Unequal Triplets in Array
+ * https://leetcode.com/problems/number-of-unequal-triplets-in-array/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed array of positive integers nums. Find the number of
+ * triplets (i, j, k) that meet the following conditions:
+ * - 0 <= i < j < k < nums.length
+ * - nums[i], nums[j], and nums[k] are pairwise distinct.
+ *   - In other words, nums[i] != nums[j], nums[i] != nums[k], and nums[j] != nums[k].
+ *
+ * Return the number of triplets that meet the conditions.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var unequalTriplets = function(nums) {
+  const map = new Map();
+  for (const num of nums) {
+    map.set(num, (map.get(num) || 0) + 1);
+  }
+
+  let result = 0;
+  let left = 0;
+  const total = nums.length;
+
+  for (const count of map.values()) {
+    const right = total - count - left;
+    result += left * count * right;
+    left += count;
+  }
+
+  return result;
+};
diff --git a/solutions/2476-closest-nodes-queries-in-a-binary-search-tree.js b/solutions/2476-closest-nodes-queries-in-a-binary-search-tree.js
new file mode 100644
index 00000000..8f9a487a
--- /dev/null
+++ b/solutions/2476-closest-nodes-queries-in-a-binary-search-tree.js
@@ -0,0 +1,67 @@
+/**
+ * 2476. Closest Nodes Queries in a Binary Search Tree
+ * https://leetcode.com/problems/closest-nodes-queries-in-a-binary-search-tree/
+ * Difficulty: Medium
+ *
+ * You are given the root of a binary search tree and an array queries of size n consisting of
+ * positive integers.
+ *
+ * Find a 2D array answer of size n where answer[i] = [mini, maxi]:
+ * - mini is the largest value in the tree that is smaller than or equal to queries[i]. If a such
+ *   value does not exist, add -1 instead.
+ * - maxi is the smallest value in the tree that is greater than or equal to queries[i]. If a such
+ *   value does not exist, add -1 instead.
+ *
+ * Return the array answer.
+ */
+
+/**
+ * Definition for a binary tree node.
+ * function TreeNode(val, left, right) {
+ *     this.val = (val===undefined ? 0 : val)
+ *     this.left = (left===undefined ? null : left)
+ *     this.right = (right===undefined ? null : right)
+ * }
+ */
+/**
+ * @param {TreeNode} root
+ * @param {number[]} queries
+ * @return {number[][]}
+ */
+var closestNodes = function(root, queries) {
+  const values = [];
+
+  inorder(root);
+
+  const result = queries.map(query => {
+    let minVal = -1;
+    let maxVal = -1;
+
+    let left = 0;
+    let right = values.length - 1;
+
+    while (left <= right) {
+      const mid = Math.floor((left + right) / 2);
+      if (values[mid] === query) {
+        return [query, query];
+      } else if (values[mid] < query) {
+        minVal = values[mid];
+        left = mid + 1;
+      } else {
+        maxVal = values[mid];
+        right = mid - 1;
+      }
+    }
+
+    return [minVal, maxVal];
+  });
+
+  return result;
+
+  function inorder(node) {
+    if (!node) return;
+    inorder(node.left);
+    values.push(node.val);
+    inorder(node.right);
+  }
+};
diff --git a/solutions/2477-minimum-fuel-cost-to-report-to-the-capital.js b/solutions/2477-minimum-fuel-cost-to-report-to-the-capital.js
new file mode 100644
index 00000000..fe195062
--- /dev/null
+++ b/solutions/2477-minimum-fuel-cost-to-report-to-the-capital.js
@@ -0,0 +1,51 @@
+/**
+ * 2477. Minimum Fuel Cost to Report to the Capital
+ * https://leetcode.com/problems/minimum-fuel-cost-to-report-to-the-capital/
+ * Difficulty: Medium
+ *
+ * There is a tree (i.e., a connected, undirected graph with no cycles) structure country network
+ * consisting of n cities numbered from 0 to n - 1 and exactly n - 1 roads. The capital city is
+ * city 0. You are given a 2D integer array roads where roads[i] = [ai, bi] denotes that there
+ * exists a bidirectional road connecting cities ai and bi.
+ *
+ * There is a meeting for the representatives of each city. The meeting is in the capital city.
+ *
+ * There is a car in each city. You are given an integer seats that indicates the number of seats
+ * in each car.
+ *
+ * A representative can use the car in their city to travel or change the car and ride with another
+ * representative. The cost of traveling between two cities is one liter of fuel.
+ *
+ * Return the minimum number of liters of fuel to reach the capital city.
+ */
+
+/**
+ * @param {number[][]} roads
+ * @param {number} seats
+ * @return {number}
+ */
+var minimumFuelCost = function(roads, seats) {
+  const n = roads.length + 1;
+  const graph = Array.from({ length: n }, () => []);
+  for (const [a, b] of roads) {
+    graph[a].push(b);
+    graph[b].push(a);
+  }
+
+  let fuel = 0;
+  dfs(0, -1);
+  return fuel;
+
+  function dfs(node, parent) {
+    let representatives = 1;
+    for (const neighbor of graph[node]) {
+      if (neighbor !== parent) {
+        representatives += dfs(neighbor, node);
+      }
+    }
+    if (node !== 0) {
+      fuel += Math.ceil(representatives / seats);
+    }
+    return representatives;
+  }
+};
diff --git a/solutions/2481-minimum-cuts-to-divide-a-circle.js b/solutions/2481-minimum-cuts-to-divide-a-circle.js
new file mode 100644
index 00000000..805ed6ac
--- /dev/null
+++ b/solutions/2481-minimum-cuts-to-divide-a-circle.js
@@ -0,0 +1,24 @@
+/**
+ * 2481. Minimum Cuts to Divide a Circle
+ * https://leetcode.com/problems/minimum-cuts-to-divide-a-circle/
+ * Difficulty: Easy
+ *
+ * A valid cut in a circle can be:
+ * - A cut that is represented by a straight line that touches two points on the edge of the
+ *   circle and passes through its center, or
+ * - A cut that is represented by a straight line that touches one point on the edge of the
+ *   circle and its center.
+ *
+ * Some valid and invalid cuts are shown in the figures below.
+ *
+ * Given the integer n, return the minimum number of cuts needed to divide a circle into n
+ * equal slices.
+ */
+
+/**
+ * @param {number} n
+ * @return {number}
+ */
+var numberOfCuts = function(n) {
+  return n === 1 ? 0 : n % 2 === 0 ? n / 2 : n;
+};
diff --git a/solutions/2483-minimum-penalty-for-a-shop.js b/solutions/2483-minimum-penalty-for-a-shop.js
new file mode 100644
index 00000000..0819d961
--- /dev/null
+++ b/solutions/2483-minimum-penalty-for-a-shop.js
@@ -0,0 +1,38 @@
+/**
+ * 2483. Minimum Penalty for a Shop
+ * https://leetcode.com/problems/minimum-penalty-for-a-shop/
+ * Difficulty: Medium
+ *
+ * You are given the customer visit log of a shop represented by a 0-indexed string customers
+ * consisting only of characters 'N' and 'Y':
+ * - if the ith character is 'Y', it means that customers come at the ith hour
+ * - whereas 'N' indicates that no customers come at the ith hour.
+ *
+ * If the shop closes at the jth hour (0 <= j <= n), the penalty is calculated as follows:
+ * - For every hour when the shop is open and no customers come, the penalty increases by 1.
+ * - For every hour when the shop is closed and customers come, the penalty increases by 1.
+ *
+ * Return the earliest hour at which the shop must be closed to incur a minimum penalty.
+ *
+ * Note that if a shop closes at the jth hour, it means the shop is closed at the hour j.
+ */
+
+/**
+ * @param {string} customers
+ * @return {number}
+ */
+var bestClosingTime = function(customers) {
+  let minPenalty = 0;
+  let currentPenalty = 0;
+  let result = 0;
+
+  for (let i = 0; i < customers.length; i++) {
+    currentPenalty += customers[i] === 'Y' ? -1 : 1;
+    if (currentPenalty < minPenalty) {
+      minPenalty = currentPenalty;
+      result = i + 1;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2484-count-palindromic-subsequences.js b/solutions/2484-count-palindromic-subsequences.js
new file mode 100644
index 00000000..a6c3851c
--- /dev/null
+++ b/solutions/2484-count-palindromic-subsequences.js
@@ -0,0 +1,59 @@
+/**
+ * 2484. Count Palindromic Subsequences
+ * https://leetcode.com/problems/count-palindromic-subsequences/
+ * Difficulty: Hard
+ *
+ * Given a string of digits s, return the number of palindromic subsequences of s having length 5.
+ * Since the answer may be very large, return it modulo 109 + 7.
+ *
+ * Note:
+ * - A string is palindromic if it reads the same forward and backward.
+ * - A subsequence is a string that can be derived from another string by deleting some or no
+ *   characters without changing the order of the remaining characters.
+ */
+
+/**
+ * @param {string} s
+ * @return {number}
+ */
+var countPalindromes = function(s) {
+  const MOD = 1e9 + 7;
+  const n = s.length;
+
+  const prefixPairs = new Array(n).fill(0).map(() => new Array(100).fill(0));
+  const suffixPairs = new Array(n).fill(0).map(() => new Array(100).fill(0));
+
+  for (let i = 1; i < n; i++) {
+    for (let pair = 0; pair < 100; pair++) {
+      prefixPairs[i][pair] = prefixPairs[i - 1][pair];
+    }
+    for (let j = 0; j < i; j++) {
+      const pair = parseInt(s[j]) * 10 + parseInt(s[i]);
+      prefixPairs[i][pair]++;
+    }
+  }
+
+  for (let i = n - 2; i >= 0; i--) {
+    for (let pair = 0; pair < 100; pair++) {
+      suffixPairs[i][pair] = suffixPairs[i + 1][pair];
+    }
+    for (let j = i + 1; j < n; j++) {
+      const pair = parseInt(s[i]) * 10 + parseInt(s[j]);
+      suffixPairs[i][pair]++;
+    }
+  }
+
+  let result = 0;
+  for (let i = 2; i < n - 2; i++) {
+    for (let first = 0; first < 10; first++) {
+      for (let second = 0; second < 10; second++) {
+        const leftPair = first * 10 + second;
+        const rightPair = second * 10 + first;
+        result = (result + (prefixPairs[i - 1][leftPair]
+          * suffixPairs[i + 1][rightPair]) % MOD) % MOD;
+      }
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2485-find-the-pivot-integer.js b/solutions/2485-find-the-pivot-integer.js
new file mode 100644
index 00000000..73a95a4a
--- /dev/null
+++ b/solutions/2485-find-the-pivot-integer.js
@@ -0,0 +1,22 @@
+/**
+ * 2485. Find the Pivot Integer
+ * https://leetcode.com/problems/find-the-pivot-integer/
+ * Difficulty: Easy
+ *
+ * Given a positive integer n, find the pivot integer x such that:
+ * - The sum of all elements between 1 and x inclusively equals the sum of all elements between
+ *   x and n inclusively.
+ *
+ * Return the pivot integer x. If no such integer exists, return -1. It is guaranteed that there
+ * will be at most one pivot index for the given input.
+ */
+
+/**
+ * @param {number} n
+ * @return {number}
+ */
+var pivotInteger = function(n) {
+  const totalSum = n * (n + 1) / 2;
+  const pivot = Math.sqrt(totalSum);
+  return Number.isInteger(pivot) && pivot <= n ? pivot : -1;
+};
diff --git a/solutions/2486-append-characters-to-string-to-make-subsequence.js b/solutions/2486-append-characters-to-string-to-make-subsequence.js
new file mode 100644
index 00000000..09bfb362
--- /dev/null
+++ b/solutions/2486-append-characters-to-string-to-make-subsequence.js
@@ -0,0 +1,32 @@
+/**
+ * 2486. Append Characters to String to Make Subsequence
+ * https://leetcode.com/problems/append-characters-to-string-to-make-subsequence/
+ * Difficulty: Medium
+ *
+ * You are given two strings s and t consisting of only lowercase English letters.
+ *
+ * Return the minimum number of characters that need to be appended to the end of s so that
+ * t becomes a subsequence of s.
+ *
+ * A subsequence is a string that can be derived from another string by deleting some or no
+ * characters without changing the order of the remaining characters.
+ */
+
+/**
+ * @param {string} s
+ * @param {string} t
+ * @return {number}
+ */
+var appendCharacters = function(s, t) {
+  let sIndex = 0;
+  let tIndex = 0;
+
+  while (sIndex < s.length && tIndex < t.length) {
+    if (s[sIndex] === t[tIndex]) {
+      tIndex++;
+    }
+    sIndex++;
+  }
+
+  return t.length - tIndex;
+};
diff --git a/solutions/2487-remove-nodes-from-linked-list.js b/solutions/2487-remove-nodes-from-linked-list.js
new file mode 100644
index 00000000..b6d6cb2c
--- /dev/null
+++ b/solutions/2487-remove-nodes-from-linked-list.js
@@ -0,0 +1,44 @@
+/**
+ * 2487. Remove Nodes From Linked List
+ * https://leetcode.com/problems/remove-nodes-from-linked-list/
+ * Difficulty: Medium
+ *
+ * You are given the head of a linked list.
+ *
+ * Remove every node which has a node with a greater value anywhere to the right side of it.
+ *
+ * Return the head of the modified linked list.
+ */
+
+/**
+ * Definition for singly-linked list.
+ * function ListNode(val, next) {
+ *     this.val = (val===undefined ? 0 : val)
+ *     this.next = (next===undefined ? null : next)
+ * }
+ */
+/**
+ * @param {ListNode} head
+ * @return {ListNode}
+ */
+var removeNodes = function(head) {
+  const stack = [];
+  let current = head;
+
+  while (current) {
+    while (stack.length && stack[stack.length - 1].val < current.val) {
+      stack.pop();
+    }
+    stack.push(current);
+    current = current.next;
+  }
+
+  let result = null;
+  while (stack.length) {
+    current = stack.pop();
+    current.next = result;
+    result = current;
+  }
+
+  return result;
+};
diff --git a/solutions/2488-count-subarrays-with-median-k.js b/solutions/2488-count-subarrays-with-median-k.js
new file mode 100644
index 00000000..694d9ea9
--- /dev/null
+++ b/solutions/2488-count-subarrays-with-median-k.js
@@ -0,0 +1,43 @@
+/**
+ * 2488. Count Subarrays With Median K
+ * https://leetcode.com/problems/count-subarrays-with-median-k/
+ * Difficulty: Hard
+ *
+ * You are given an array nums of size n consisting of distinct integers from 1 to n and
+ * a positive integer k.
+ *
+ * Return the number of non-empty subarrays in nums that have a median equal to k.
+ *
+ * Note:
+ * - The median of an array is the middle element after sorting the array in ascending order.
+ *   If the array is of even length, the median is the left middle element.
+ *   - For example, the median of [2,3,1,4] is 2, and the median of [8,4,3,5,1] is 4.
+ * - A subarray is a contiguous part of an array.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @return {number}
+ */
+var countSubarrays = function(nums, k) {
+  const n = nums.length;
+  const kIndex = nums.indexOf(k);
+  const balanceMap = new Map([[0, 1]]);
+  let balance = 0;
+  let result = 0;
+
+  for (let i = kIndex + 1; i < n; i++) {
+    balance += nums[i] > k ? 1 : -1;
+    balanceMap.set(balance, (balanceMap.get(balance) || 0) + 1);
+  }
+
+  balance = 0;
+  for (let i = kIndex; i >= 0; i--) {
+    balance += nums[i] > k ? -1 : nums[i] < k ? 1 : 0;
+    result += balanceMap.get(balance) || 0;
+    result += balanceMap.get(balance + 1) || 0;
+  }
+
+  return result;
+};
diff --git a/solutions/2491-divide-players-into-teams-of-equal-skill.js b/solutions/2491-divide-players-into-teams-of-equal-skill.js
new file mode 100644
index 00000000..5f481cf0
--- /dev/null
+++ b/solutions/2491-divide-players-into-teams-of-equal-skill.js
@@ -0,0 +1,32 @@
+/**
+ * 2491. Divide Players Into Teams of Equal Skill
+ * https://leetcode.com/problems/divide-players-into-teams-of-equal-skill/
+ * Difficulty: Medium
+ *
+ * You are given a positive integer array skill of even length n where skill[i] denotes the
+ * skill of the ith player. Divide the players into n / 2 teams of size 2 such that the total
+ * skill of each team is equal.
+ *
+ * The chemistry of a team is equal to the product of the skills of the players on that team.
+ *
+ * Return the sum of the chemistry of all the teams, or return -1 if there is no way to divide
+ * the players into teams such that the total skill of each team is equal.
+ */
+
+/**
+ * @param {number[]} skill
+ * @return {number}
+ */
+var dividePlayers = function(skill) {
+  skill.sort((a, b) => a - b);
+  const n = skill.length;
+  const targetSum = skill[0] + skill[n - 1];
+  let result = 0;
+
+  for (let i = 0, j = n - 1; i < j; i++, j--) {
+    if (skill[i] + skill[j] !== targetSum) return -1;
+    result += skill[i] * skill[j];
+  }
+
+  return result;
+};
diff --git a/solutions/2492-minimum-score-of-a-path-between-two-cities.js b/solutions/2492-minimum-score-of-a-path-between-two-cities.js
new file mode 100644
index 00000000..f5cbc0f5
--- /dev/null
+++ b/solutions/2492-minimum-score-of-a-path-between-two-cities.js
@@ -0,0 +1,53 @@
+/**
+ * 2492. Minimum Score of a Path Between Two Cities
+ * https://leetcode.com/problems/minimum-score-of-a-path-between-two-cities/
+ * Difficulty: Medium
+ *
+ * You are given a positive integer n representing n cities numbered from 1 to n. You are also
+ * given a 2D array roads where roads[i] = [ai, bi, distancei] indicates that there is a
+ * bidirectional road between cities ai and bi with a distance equal to distancei. The cities
+ * graph is not necessarily connected.
+ *
+ * The score of a path between two cities is defined as the minimum distance of a road in this
+ * path.
+ *
+ * Return the minimum possible score of a path between cities 1 and n.
+ *
+ * Note:
+ * - A path is a sequence of roads between two cities.
+ * - It is allowed for a path to contain the same road multiple times, and you can visit cities 1
+ *   and n multiple times along the path.
+ * - The test cases are generated such that there is at least one path between 1 and n.
+ */
+
+/**
+ * @param {number} n
+ * @param {number[][]} roads
+ * @return {number}
+ */
+var minScore = function(n, roads) {
+  const graph = Array.from({ length: n + 1 }, () => []);
+  for (const [a, b, dist] of roads) {
+    graph[a].push([b, dist]);
+    graph[b].push([a, dist]);
+  }
+
+  const visited = new Set();
+  const queue = [1];
+  let result = Infinity;
+
+  while (queue.length) {
+    const city = queue.shift();
+    if (visited.has(city)) continue;
+    visited.add(city);
+
+    for (const [nextCity, dist] of graph[city]) {
+      result = Math.min(result, dist);
+      if (!visited.has(nextCity)) {
+        queue.push(nextCity);
+      }
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2496-maximum-value-of-a-string-in-an-array.js b/solutions/2496-maximum-value-of-a-string-in-an-array.js
new file mode 100644
index 00000000..3d78d50f
--- /dev/null
+++ b/solutions/2496-maximum-value-of-a-string-in-an-array.js
@@ -0,0 +1,27 @@
+/**
+ * 2496. Maximum Value of a String in an Array
+ * https://leetcode.com/problems/maximum-value-of-a-string-in-an-array/
+ * Difficulty: Easy
+ *
+ * The value of an alphanumeric string can be defined as:
+ * - The numeric representation of the string in base 10, if it comprises of digits only.
+ * - The length of the string, otherwise.
+ *
+ * Given an array strs of alphanumeric strings, return the maximum value of any string in strs.
+ */
+
+/**
+ * @param {string[]} strs
+ * @return {number}
+ */
+var maximumValue = function(strs) {
+  let result = 0;
+
+  for (const str of strs) {
+    const isNumeric = /^[0-9]+$/.test(str);
+    const value = isNumeric ? parseInt(str) : str.length;
+    result = Math.max(result, value);
+  }
+
+  return result;
+};
diff --git a/solutions/2498-frog-jump-ii.js b/solutions/2498-frog-jump-ii.js
new file mode 100644
index 00000000..573192a9
--- /dev/null
+++ b/solutions/2498-frog-jump-ii.js
@@ -0,0 +1,33 @@
+/**
+ * 2498. Frog Jump II
+ * https://leetcode.com/problems/frog-jump-ii/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed integer array stones sorted in strictly increasing order representing
+ * the positions of stones in a river.
+ *
+ * A frog, initially on the first stone, wants to travel to the last stone and then return to the
+ * first stone. However, it can jump to any stone at most once.
+ *
+ * The length of a jump is the absolute difference between the position of the stone the frog is
+ * currently on and the position of the stone to which the frog jumps.
+ *
+ * - More formally, if the frog is at stones[i] and is jumping to stones[j], the length of the jump
+ *   is |stones[i] - stones[j]|.
+ *
+ * The cost of a path is the maximum length of a jump among all jumps in the path.
+ *
+ * Return the minimum cost of a path for the frog.
+ */
+
+/**
+ * @param {number[]} stones
+ * @return {number}
+ */
+var maxJump = function(stones) {
+  let result = stones[1];
+  for (let i = 2; i < stones.length; i++) {
+    result = Math.max(result, stones[i] - stones[i - 2]);
+  }
+  return result;
+};
diff --git a/solutions/2499-minimum-total-cost-to-make-arrays-unequal.js b/solutions/2499-minimum-total-cost-to-make-arrays-unequal.js
new file mode 100644
index 00000000..8a8e8e9a
--- /dev/null
+++ b/solutions/2499-minimum-total-cost-to-make-arrays-unequal.js
@@ -0,0 +1,69 @@
+/**
+ * 2499. Minimum Total Cost to Make Arrays Unequal
+ * https://leetcode.com/problems/minimum-total-cost-to-make-arrays-unequal/
+ * Difficulty: Hard
+ *
+ * You are given two 0-indexed integer arrays nums1 and nums2, of equal length n.
+ *
+ * In one operation, you can swap the values of any two indices of nums1. The cost of this
+ * operation is the sum of the indices.
+ *
+ * Find the minimum total cost of performing the given operation any number of times such
+ * that nums1[i] != nums2[i] for all 0 <= i <= n - 1 after performing all the operations.
+ *
+ * Return the minimum total cost such that nums1 and nums2 satisfy the above condition.
+ * In case it is not possible, return -1.
+ */
+
+/**
+ * @param {number[]} nums1
+ * @param {number[]} nums2
+ * @return {number}
+ */
+var minimumTotalCost = function(nums1, nums2) {
+  const n = nums1.length;
+  const conflictIndices = [];
+  const valueCount = new Map();
+
+  for (let i = 0; i < n; i++) {
+    if (nums1[i] === nums2[i]) {
+      conflictIndices.push(i);
+      valueCount.set(nums1[i], (valueCount.get(nums1[i]) || 0) + 1);
+    }
+  }
+
+  if (conflictIndices.length === 0) return 0;
+
+  let dominantValue = -1;
+  let maxCount = 0;
+
+  for (const [value, count] of valueCount) {
+    if (count > maxCount) {
+      maxCount = count;
+      dominantValue = value;
+    }
+  }
+
+  const swapsNeeded = conflictIndices.length;
+  let helpersNeeded = Math.max(0, 2 * maxCount - swapsNeeded);
+
+  const helperIndices = [];
+  for (let i = 0; i < n && helpersNeeded > 0; i++) {
+    if (nums1[i] !== nums2[i] && nums1[i] !== dominantValue && nums2[i] !== dominantValue) {
+      helperIndices.push(i);
+      helpersNeeded--;
+    }
+  }
+
+  if (helpersNeeded > 0) return -1;
+
+  const allIndices = [...conflictIndices, ...helperIndices];
+  allIndices.sort((a, b) => a - b);
+
+  let result = 0;
+  for (let i = 0; i < allIndices.length; i++) {
+    result += allIndices[i];
+  }
+
+  return result;
+};
diff --git a/solutions/2501-longest-square-streak-in-an-array.js b/solutions/2501-longest-square-streak-in-an-array.js
new file mode 100644
index 00000000..ee667541
--- /dev/null
+++ b/solutions/2501-longest-square-streak-in-an-array.js
@@ -0,0 +1,41 @@
+/**
+ * 2501. Longest Square Streak in an Array
+ * https://leetcode.com/problems/longest-square-streak-in-an-array/
+ * Difficulty: Medium
+ *
+ * You are given an integer array nums. A subsequence of nums is called a square streak if:
+ * - The length of the subsequence is at least 2, and
+ * - after sorting the subsequence, each element (except the first element) is the square of
+ *   the previous number.
+ *
+ * Return the length of the longest square streak in nums, or return -1 if there is no square
+ * streak.
+ *
+ * A subsequence is an array that can be derived from another array by deleting some or no
+ * elements without changing the order of the remaining elements.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var longestSquareStreak = function(nums) {
+  const set = new Set(nums);
+  let result = -1;
+
+  for (const num of nums) {
+    let current = num;
+    let length = 1;
+
+    while (current <= 100000 && set.has(current * current)) {
+      current *= current;
+      length++;
+    }
+
+    if (length >= 2) {
+      result = Math.max(result, length);
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2502-design-memory-allocator.js b/solutions/2502-design-memory-allocator.js
new file mode 100644
index 00000000..b09fcbb0
--- /dev/null
+++ b/solutions/2502-design-memory-allocator.js
@@ -0,0 +1,76 @@
+/**
+ * 2502. Design Memory Allocator
+ * https://leetcode.com/problems/design-memory-allocator/
+ * Difficulty: Medium
+ *
+ * You are given an integer n representing the size of a 0-indexed memory array. All memory
+ * units are initially free.
+ *
+ * You have a memory allocator with the following functionalities:
+ * 1. Allocate a block of size consecutive free memory units and assign it the id mID.
+ * 2. Free all memory units with the given id mID.
+ *
+ * Note that:
+ * - Multiple blocks can be allocated to the same mID.
+ * - You should free all the memory units with mID, even if they were allocated in different blocks.
+ *
+ * Implement the Allocator class:
+ * - Allocator(int n) Initializes an Allocator object with a memory array of size n.
+ * - int allocate(int size, int mID) Find the leftmost block of size consecutive free memory units
+ *   and allocate it with the id mID. Return the block's first index. If such a block does not
+ *   exist, return -1.
+ * - int freeMemory(int mID) Free all memory units with the id mID. Return the number of memory
+ *   units you have freed.
+ */
+
+/**
+ * @param {number} n
+ */
+var Allocator = function(n) {
+  this.memory = Array(n).fill(0);
+};
+
+/**
+ * @param {number} size
+ * @param {number} mID
+ * @return {number}
+ */
+Allocator.prototype.allocate = function(size, mID) {
+  let start = -1;
+  let count = 0;
+
+  for (let i = 0; i < this.memory.length; i++) {
+    if (this.memory[i] === 0) {
+      if (start === -1) start = i;
+      count++;
+      if (count === size) {
+        for (let j = start; j < start + size; j++) {
+          this.memory[j] = mID;
+        }
+        return start;
+      }
+    } else {
+      start = -1;
+      count = 0;
+    }
+  }
+
+  return -1;
+};
+
+/**
+ * @param {number} mID
+ * @return {number}
+ */
+Allocator.prototype.freeMemory = function(mID) {
+  let result = 0;
+
+  for (let i = 0; i < this.memory.length; i++) {
+    if (this.memory[i] === mID) {
+      this.memory[i] = 0;
+      result++;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2506-count-pairs-of-similar-strings.js b/solutions/2506-count-pairs-of-similar-strings.js
new file mode 100644
index 00000000..3a4d78ef
--- /dev/null
+++ b/solutions/2506-count-pairs-of-similar-strings.js
@@ -0,0 +1,36 @@
+/**
+ * 2506. Count Pairs Of Similar Strings
+ * https://leetcode.com/problems/count-pairs-of-similar-strings/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed string array words.
+ *
+ * Two strings are similar if they consist of the same characters.
+ * - For example, "abca" and "cba" are similar since both consist of characters 'a', 'b', and 'c'.
+ * - However, "abacba" and "bcfd" are not similar since they do not consist of the same characters.
+ *
+ * Return the number of pairs (i, j) such that 0 <= i < j <= word.length - 1 and the two strings
+ * words[i] and words[j] are similar.
+ */
+
+/**
+ * @param {string[]} words
+ * @return {number}
+ */
+var similarPairs = function(words) {
+  const map = new Map();
+  let result = 0;
+
+  for (const word of words) {
+    const charSet = [...new Set(word.split(''))].sort().join('');
+    map.set(charSet, (map.get(charSet) || 0) + 1);
+  }
+
+  for (const count of map.values()) {
+    if (count > 1) {
+      result += (count * (count - 1)) / 2;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2507-smallest-value-after-replacing-with-sum-of-prime-factors.js b/solutions/2507-smallest-value-after-replacing-with-sum-of-prime-factors.js
new file mode 100644
index 00000000..d77f5c3a
--- /dev/null
+++ b/solutions/2507-smallest-value-after-replacing-with-sum-of-prime-factors.js
@@ -0,0 +1,37 @@
+/**
+ * 2507. Smallest Value After Replacing With Sum of Prime Factors
+ * https://leetcode.com/problems/smallest-value-after-replacing-with-sum-of-prime-factors/
+ * Difficulty: Medium
+ *
+ * You are given a positive integer n.
+ *
+ * Continuously replace n with the sum of its prime factors.
+ * - Note that if a prime factor divides n multiple times, it should be included in the sum as many
+ *   times as it divides n.
+ *
+ * Return the smallest value n will take on.
+ */
+
+/**
+ * @param {number} n
+ * @return {number}
+ */
+var smallestValue = function(n) {
+  while (true) {
+    const next = sumPrimeFactors(n);
+    if (next === n) return n;
+    n = next;
+  }
+
+  function sumPrimeFactors(num) {
+    let sum = 0;
+    for (let i = 2; i * i <= num; i++) {
+      while (num % i === 0) {
+        sum += i;
+        num /= i;
+      }
+    }
+    if (num > 1) sum += num;
+    return sum;
+  }
+};
diff --git a/solutions/2509-cycle-length-queries-in-a-tree.js b/solutions/2509-cycle-length-queries-in-a-tree.js
new file mode 100644
index 00000000..180c2a6c
--- /dev/null
+++ b/solutions/2509-cycle-length-queries-in-a-tree.js
@@ -0,0 +1,54 @@
+/**
+ * 2509. Cycle Length Queries in a Tree
+ * https://leetcode.com/problems/cycle-length-queries-in-a-tree/
+ * Difficulty: Hard
+ *
+ * You are given an integer n. There is a complete binary tree with 2n - 1 nodes. The root of
+ * that tree is the node with the value 1, and every node with a value val in the range
+ * [1, 2n - 1 - 1] has two children where:
+ * - The left node has the value 2 * val, and
+ * - The right node has the value 2 * val + 1.
+ *
+ * You are also given a 2D integer array queries of length m, where queries[i] = [ai, bi]. For
+ * each query, solve the following problem:
+ * 1. Add an edge between the nodes with values ai and bi.
+ * 2. Find the length of the cycle in the graph.
+ * 3. Remove the added edge between nodes with values ai and bi.
+ *
+ * Note that:
+ * - A cycle is a path that starts and ends at the same node, and each edge in the path is
+ *   visited only once.
+ * - The length of a cycle is the number of edges visited in the cycle.
+ * - There could be multiple edges between two nodes in the tree after adding the edge of
+ *   the query.
+ *
+ * Return an array answer of length m where answer[i] is the answer to the ith query.
+ */
+
+/**
+ * @param {number} n
+ * @param {number[][]} queries
+ * @return {number[]}
+ */
+var cycleLengthQueries = function(n, queries) {
+  const result = [];
+
+  for (const [a, b] of queries) {
+    let x = a;
+    let y = b;
+    let pathLength = 1;
+
+    while (x !== y) {
+      if (x > y) {
+        x = Math.floor(x / 2);
+      } else {
+        y = Math.floor(y / 2);
+      }
+      pathLength++;
+    }
+
+    result.push(pathLength);
+  }
+
+  return result;
+};
diff --git a/solutions/2511-maximum-enemy-forts-that-can-be-captured.js b/solutions/2511-maximum-enemy-forts-that-can-be-captured.js
new file mode 100644
index 00000000..7a7b5045
--- /dev/null
+++ b/solutions/2511-maximum-enemy-forts-that-can-be-captured.js
@@ -0,0 +1,42 @@
+/**
+ * 2511. Maximum Enemy Forts That Can Be Captured
+ * https://leetcode.com/problems/maximum-enemy-forts-that-can-be-captured/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed integer array forts of length n representing the positions of
+ * several forts. forts[i] can be -1, 0, or 1 where:
+ * - -1 represents there is no fort at the ith position.
+ * - 0 indicates there is an enemy fort at the ith position.
+ * - 1 indicates the fort at the ith the position is under your command.
+ *
+ * Now you have decided to move your army from one of your forts at position i to an empty
+ * position j such that:
+ * - 0 <= i, j <= n - 1
+ * - The army travels over enemy forts only. Formally, for all k where min(i,j) < k < max(i,j),
+ *   forts[k] == 0.
+ *
+ * While moving the army, all the enemy forts that come in the way are captured.
+ *
+ * Return the maximum number of enemy forts that can be captured. In case it is impossible to
+ * move your army, or you do not have any fort under your command, return 0.
+ */
+
+/**
+ * @param {number[]} forts
+ * @return {number}
+ */
+var captureForts = function(forts) {
+  let result = 0;
+  let start = -1;
+
+  for (let i = 0; i < forts.length; i++) {
+    if (forts[i] === 1 || forts[i] === -1) {
+      if (start !== -1 && forts[start] !== forts[i]) {
+        result = Math.max(result, i - start - 1);
+      }
+      start = i;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2515-shortest-distance-to-target-string-in-a-circular-array.js b/solutions/2515-shortest-distance-to-target-string-in-a-circular-array.js
new file mode 100644
index 00000000..5c315a34
--- /dev/null
+++ b/solutions/2515-shortest-distance-to-target-string-in-a-circular-array.js
@@ -0,0 +1,37 @@
+/**
+ * 2515. Shortest Distance to Target String in a Circular Array
+ * https://leetcode.com/problems/shortest-distance-to-target-string-in-a-circular-array/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed circular string array words and a string target. A circular array
+ * means that the array's end connects to the array's beginning.
+ * - Formally, the next element of words[i] is words[(i + 1) % n] and the previous element of
+ *   words[i] is words[(i - 1 + n) % n], where n is the length of words.
+ *
+ * Starting from startIndex, you can move to either the next word or the previous word with 1
+ * step at a time.
+ *
+ * Return the shortest distance needed to reach the string target. If the string target does not
+ * exist in words, return -1.
+ */
+
+/**
+ * @param {string[]} words
+ * @param {string} target
+ * @param {number} startIndex
+ * @return {number}
+ */
+var closestTarget = function(words, target, startIndex) {
+  const n = words.length;
+  let minDistance = Infinity;
+
+  for (let i = 0; i < n; i++) {
+    if (words[i] === target) {
+      const forward = Math.abs(i - startIndex);
+      const backward = n - forward;
+      minDistance = Math.min(minDistance, forward, backward);
+    }
+  }
+
+  return minDistance === Infinity ? -1 : minDistance;
+};
diff --git a/solutions/2516-take-k-of-each-character-from-left-and-right.js b/solutions/2516-take-k-of-each-character-from-left-and-right.js
new file mode 100644
index 00000000..a37d84a9
--- /dev/null
+++ b/solutions/2516-take-k-of-each-character-from-left-and-right.js
@@ -0,0 +1,46 @@
+/**
+ * 2516. Take K of Each Character From Left and Right
+ * https://leetcode.com/problems/take-k-of-each-character-from-left-and-right/
+ * Difficulty: Medium
+ *
+ * You are given a string s consisting of the characters 'a', 'b', and 'c' and a non-negative
+ * integer k. Each minute, you may take either the leftmost character of s, or the rightmost
+ * character of s.
+ *
+ * Return the minimum number of minutes needed for you to take at least k of each character,
+ * or return -1 if it is not possible to take k of each character.
+ */
+
+/**
+ * @param {string} s
+ * @param {number} k
+ * @return {number}
+ */
+var takeCharacters = function(s, k) {
+  const n = s.length;
+  const counts = { a: 0, b: 0, c: 0 };
+
+  for (const char of s) {
+    counts[char]++;
+  }
+
+  if (counts.a < k || counts.b < k || counts.c < k) return -1;
+
+  let maxWindow = 0;
+  let left = 0;
+  const windowCounts = { a: 0, b: 0, c: 0 };
+
+  for (let right = 0; right < n; right++) {
+    windowCounts[s[right]]++;
+
+    while (windowCounts.a > counts.a - k || windowCounts.b > counts.b - k
+          || windowCounts.c > counts.c - k) {
+      windowCounts[s[left]]--;
+      left++;
+    }
+
+    maxWindow = Math.max(maxWindow, right - left + 1);
+  }
+
+  return n - maxWindow;
+};
diff --git a/solutions/2517-maximum-tastiness-of-candy-basket.js b/solutions/2517-maximum-tastiness-of-candy-basket.js
new file mode 100644
index 00000000..6ef4a383
--- /dev/null
+++ b/solutions/2517-maximum-tastiness-of-candy-basket.js
@@ -0,0 +1,47 @@
+/**
+ * 2517. Maximum Tastiness of Candy Basket
+ * https://leetcode.com/problems/maximum-tastiness-of-candy-basket/
+ * Difficulty: Medium
+ *
+ * You are given an array of positive integers price where price[i] denotes the price of the ith
+ * candy and a positive integer k.
+ *
+ * The store sells baskets of k distinct candies. The tastiness of a candy basket is the smallest
+ * absolute difference of the prices of any two candies in the basket.
+ *
+ * Return the maximum tastiness of a candy basket.
+ */
+
+/**
+ * @param {number[]} price
+ * @param {number} k
+ * @return {number}
+ */
+var maximumTastiness = function(price, k) {
+  price.sort((a, b) => a - b);
+  let left = 0;
+  let right = price[price.length - 1] - price[0];
+  let result = 0;
+
+  while (left <= right) {
+    const mid = Math.floor((left + right) / 2);
+    let count = 1;
+    let prev = price[0];
+
+    for (let i = 1; i < price.length; i++) {
+      if (price[i] - prev >= mid) {
+        count++;
+        prev = price[i];
+      }
+    }
+
+    if (count >= k) {
+      result = mid;
+      left = mid + 1;
+    } else {
+      right = mid - 1;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2520-count-the-digits-that-divide-a-number.js b/solutions/2520-count-the-digits-that-divide-a-number.js
new file mode 100644
index 00000000..614d3add
--- /dev/null
+++ b/solutions/2520-count-the-digits-that-divide-a-number.js
@@ -0,0 +1,25 @@
+/**
+ * 2520. Count the Digits That Divide a Number
+ * https://leetcode.com/problems/count-the-digits-that-divide-a-number/
+ * Difficulty: Easy
+ *
+ * Given an integer num, return the number of digits in num that divide num.
+ *
+ * An integer val divides nums if nums % val == 0.
+ */
+
+/**
+ * @param {number} num
+ * @return {number}
+ */
+var countDigits = function(num) {
+  let result = 0;
+  let n = num;
+
+  while (n > 0) {
+    if (num % (n % 10) === 0) result++;
+    n = Math.floor(n / 10);
+  }
+
+  return result;
+};
diff --git a/solutions/2521-distinct-prime-factors-of-product-of-array.js b/solutions/2521-distinct-prime-factors-of-product-of-array.js
new file mode 100644
index 00000000..6d723c46
--- /dev/null
+++ b/solutions/2521-distinct-prime-factors-of-product-of-array.js
@@ -0,0 +1,36 @@
+/**
+ * 2521. Distinct Prime Factors of Product of Array
+ * https://leetcode.com/problems/distinct-prime-factors-of-product-of-array/
+ * Difficulty: Medium
+ *
+ * Given an array of positive integers nums, return the number of distinct prime factors in the
+ * product of the elements of nums.
+ *
+ * Note that:
+ * - A number greater than 1 is called prime if it is divisible by only 1 and itself.
+ * - An integer val1 is a factor of another integer val2 if val2 / val1 is an integer.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var distinctPrimeFactors = function(nums) {
+  const set = new Set();
+
+  for (const num of nums) {
+    factorize(num);
+  }
+
+  return set.size;
+
+  function factorize(num) {
+    for (let i = 2; i * i <= num; i++) {
+      while (num % i === 0) {
+        set.add(i);
+        num /= i;
+      }
+    }
+    if (num > 1) set.add(num);
+  }
+};
diff --git a/solutions/2522-partition-string-into-substrings-with-values-at-most-k.js b/solutions/2522-partition-string-into-substrings-with-values-at-most-k.js
new file mode 100644
index 00000000..f5777dcf
--- /dev/null
+++ b/solutions/2522-partition-string-into-substrings-with-values-at-most-k.js
@@ -0,0 +1,42 @@
+/**
+ * 2522. Partition String Into Substrings With Values at Most K
+ * https://leetcode.com/problems/partition-string-into-substrings-with-values-at-most-k/
+ * Difficulty: Medium
+ *
+ * You are given a string s consisting of digits from 1 to 9 and an integer k.
+ *
+ * A partition of a string s is called good if:
+ * - Each digit of s is part of exactly one substring.
+ * - The value of each substring is less than or equal to k.
+ *
+ * Return the minimum number of substrings in a good partition of s. If no good partition of
+ * s exists, return -1.
+ *
+ * Note that:
+ * - The value of a string is its result when interpreted as an integer. For example, the value
+ *   of "123" is 123 and the value of "1" is 1.
+ * - A substring is a contiguous sequence of characters within a string.
+ */
+
+/**
+ * @param {string} s
+ * @param {number} k
+ * @return {number}
+ */
+var minimumPartition = function(s, k) {
+  let result = 1;
+  let current = 0;
+
+  for (const digit of s) {
+    const value = current * 10 + Number(digit);
+    if (value <= k) {
+      current = value;
+    } else {
+      if (Number(digit) > k) return -1;
+      current = Number(digit);
+      result++;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2527-find-xor-beauty-of-array.js b/solutions/2527-find-xor-beauty-of-array.js
new file mode 100644
index 00000000..172eb3e2
--- /dev/null
+++ b/solutions/2527-find-xor-beauty-of-array.js
@@ -0,0 +1,30 @@
+/**
+ * 2527. Find Xor-Beauty of Array
+ * https://leetcode.com/problems/find-xor-beauty-of-array/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed integer array nums.
+ *
+ * The effective value of three indices i, j, and k is defined as ((nums[i] | nums[j]) & nums[k]).
+ *
+ * The xor-beauty of the array is the XORing of the effective values of all the possible triplets
+ * of indices (i, j, k) where 0 <= i, j, k < n.
+ *
+ * Return the xor-beauty of nums.
+ *
+ * Note that:
+ * - val1 | val2 is bitwise OR of val1 and val2.
+ * - val1 & val2 is bitwise AND of val1 and val2.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var xorBeauty = function(nums) {
+  let result = 0;
+  for (const num of nums) {
+    result ^= num;
+  }
+  return result;
+};
diff --git a/solutions/2536-increment-submatrices-by-one.js b/solutions/2536-increment-submatrices-by-one.js
new file mode 100644
index 00000000..c5acdddd
--- /dev/null
+++ b/solutions/2536-increment-submatrices-by-one.js
@@ -0,0 +1,46 @@
+/**
+ * 2536. Increment Submatrices by One
+ * https://leetcode.com/problems/increment-submatrices-by-one/
+ * Difficulty: Medium
+ *
+ * You are given a positive integer n, indicating that we initially have an n x n 0-indexed integer
+ * matrix mat filled with zeroes.
+ *
+ * You are also given a 2D integer array query. For each query[i] = [row1i, col1i, row2i, col2i],
+ * you should do the following operation:
+ * - Add 1 to every element in the submatrix with the top left corner (row1i, col1i) and the bottom
+ *   right corner (row2i, col2i). That is, add 1 to mat[x][y] for all row1i <= x <= row2i and
+ *   col1i <= y <= col2i.
+ *
+ * Return the matrix mat after performing every query.
+ */
+
+/**
+ * @param {number} n
+ * @param {number[][]} queries
+ * @return {number[][]}
+ */
+var rangeAddQueries = function(n, queries) {
+  const matrix = new Array(n).fill().map(() => new Array(n).fill(0));
+
+  for (const [row1, col1, row2, col2] of queries) {
+    matrix[row1][col1]++;
+    if (row2 + 1 < n) matrix[row2 + 1][col1]--;
+    if (col2 + 1 < n) matrix[row1][col2 + 1]--;
+    if (row2 + 1 < n && col2 + 1 < n) matrix[row2 + 1][col2 + 1]++;
+  }
+
+  for (let i = 0; i < n; i++) {
+    for (let j = 1; j < n; j++) {
+      matrix[i][j] += matrix[i][j - 1];
+    }
+  }
+
+  for (let i = 1; i < n; i++) {
+    for (let j = 0; j < n; j++) {
+      matrix[i][j] += matrix[i - 1][j];
+    }
+  }
+
+  return matrix;
+};
diff --git a/solutions/2540-minimum-common-value.js b/solutions/2540-minimum-common-value.js
new file mode 100644
index 00000000..32b8dea1
--- /dev/null
+++ b/solutions/2540-minimum-common-value.js
@@ -0,0 +1,29 @@
+/**
+ * 2540. Minimum Common Value
+ * https://leetcode.com/problems/minimum-common-value/
+ * Difficulty: Easy
+ *
+ * Given two integer arrays nums1 and nums2, sorted in non-decreasing order, return the minimum
+ * integer common to both arrays. If there is no common integer amongst nums1 and nums2, return -1.
+ *
+ * Note that an integer is said to be common to nums1 and nums2 if both arrays have at least one
+ * occurrence of that integer.
+ */
+
+/**
+ * @param {number[]} nums1
+ * @param {number[]} nums2
+ * @return {number}
+ */
+var getCommon = function(nums1, nums2) {
+  let i = 0;
+  let j = 0;
+
+  while (i < nums1.length && j < nums2.length) {
+    if (nums1[i] === nums2[j]) return nums1[i];
+    if (nums1[i] < nums2[j]) i++;
+    else j++;
+  }
+
+  return -1;
+};
diff --git a/solutions/2543-check-if-point-is-reachable.js b/solutions/2543-check-if-point-is-reachable.js
new file mode 100644
index 00000000..31d51902
--- /dev/null
+++ b/solutions/2543-check-if-point-is-reachable.js
@@ -0,0 +1,40 @@
+/**
+ * 2543. Check if Point Is Reachable
+ * https://leetcode.com/problems/check-if-point-is-reachable/
+ * Difficulty: Hard
+ *
+ * There exists an infinitely large grid. You are currently at point (1, 1), and you need
+ * to reach the point (targetX, targetY) using a finite number of steps.
+ *
+ * In one step, you can move from point (x, y) to any one of the following points:
+ * - (x, y - x)
+ * - (x - y, y)
+ * - (2 * x, y)
+ * - (x, 2 * y)
+ *
+ * Given two integers targetX and targetY representing the X-coordinate and Y-coordinate of
+ * your final position, return true if you can reach the point from (1, 1) using some number
+ * of steps, and false otherwise.
+ */
+
+/**
+ * @param {number} targetX
+ * @param {number} targetY
+ * @return {boolean}
+ */
+var isReachable = function(targetX, targetY) {
+  let g = gcd(targetX, targetY);
+  while (g % 2 === 0) {
+    g /= 2;
+  }
+
+  return g === 1;
+};
+
+function gcd(a, b) {
+  while (b) {
+    a %= b;
+    [a, b] = [b, a];
+  }
+  return a;
+}
diff --git a/solutions/2544-alternating-digit-sum.js b/solutions/2544-alternating-digit-sum.js
new file mode 100644
index 00000000..49aa7939
--- /dev/null
+++ b/solutions/2544-alternating-digit-sum.js
@@ -0,0 +1,29 @@
+/**
+ * 2544. Alternating Digit Sum
+ * https://leetcode.com/problems/alternating-digit-sum/
+ * Difficulty: Easy
+ *
+ * You are given a positive integer n. Each digit of n has a sign according to the following rules:
+ * - The most significant digit is assigned a positive sign.
+ * - Each other digit has an opposite sign to its adjacent digits.
+ *
+ * Return the sum of all digits with their corresponding sign.
+ */
+
+/**
+ * @param {number} n
+ * @return {number}
+ */
+var alternateDigitSum = function(n) {
+  let sum = 0;
+  let isPositive = true;
+
+  while (n > 0) {
+    const digit = n % 10;
+    sum += isPositive ? digit : -digit;
+    isPositive = !isPositive;
+    n = Math.floor(n / 10);
+  }
+
+  return isPositive ? -sum : sum;
+};
diff --git a/solutions/2545-sort-the-students-by-their-kth-score.js b/solutions/2545-sort-the-students-by-their-kth-score.js
new file mode 100644
index 00000000..55464ba9
--- /dev/null
+++ b/solutions/2545-sort-the-students-by-their-kth-score.js
@@ -0,0 +1,23 @@
+/**
+ * 2545. Sort the Students by Their Kth Score
+ * https://leetcode.com/problems/sort-the-students-by-their-kth-score/
+ * Difficulty: Medium
+ *
+ * There is a class with m students and n exams. You are given a 0-indexed m x n integer matrix
+ * score, where each row represents one student and score[i][j] denotes the score the ith student
+ * got in the jth exam. The matrix score contains distinct integers only.
+ *
+ * You are also given an integer k. Sort the students (i.e., the rows of the matrix) by their
+ * scores in the kth (0-indexed) exam from the highest to the lowest.
+ *
+ * Return the matrix after sorting it.
+ */
+
+/**
+ * @param {number[][]} score
+ * @param {number} k
+ * @return {number[][]}
+ */
+var sortTheStudents = function(score, k) {
+  return score.sort((studentA, studentB) => studentB[k] - studentA[k]);
+};
diff --git a/solutions/2546-apply-bitwise-operations-to-make-strings-equal.js b/solutions/2546-apply-bitwise-operations-to-make-strings-equal.js
new file mode 100644
index 00000000..e3b401a5
--- /dev/null
+++ b/solutions/2546-apply-bitwise-operations-to-make-strings-equal.js
@@ -0,0 +1,25 @@
+/**
+ * 2546. Apply Bitwise Operations to Make Strings Equal
+ * https://leetcode.com/problems/apply-bitwise-operations-to-make-strings-equal/
+ * Difficulty: Medium
+ *
+ * You are given two 0-indexed binary strings s and target of the same length n. You can do the
+ * following operation on s any number of times:
+ * - Choose two different indices i and j where 0 <= i, j < n.
+ * - Simultaneously, replace s[i] with (s[i] OR s[j]) and s[j] with (s[i] XOR s[j]).
+ *
+ * For example, if s = "0110", you can choose i = 0 and j = 2, then simultaneously replace s[0]
+ * with (s[0] OR s[2] = 0 OR 1 = 1), and s[2] with (s[0] XOR s[2] = 0 XOR 1 = 1), so we will
+ * have s = "1110".
+ *
+ * Return true if you can make the string s equal to target, or false otherwise.
+ */
+
+/**
+ * @param {string} s
+ * @param {string} target
+ * @return {boolean}
+ */
+var makeStringsEqual = function(s, target) {
+  return (s.includes('1') === target.includes('1'));
+};
diff --git a/solutions/2547-minimum-cost-to-split-an-array.js b/solutions/2547-minimum-cost-to-split-an-array.js
new file mode 100644
index 00000000..04732298
--- /dev/null
+++ b/solutions/2547-minimum-cost-to-split-an-array.js
@@ -0,0 +1,48 @@
+/**
+ * 2547. Minimum Cost to Split an Array
+ * https://leetcode.com/problems/minimum-cost-to-split-an-array/
+ * Difficulty: Hard
+ *
+ * You are given an integer array nums and an integer k.
+ *
+ * Split the array into some number of non-empty subarrays. The cost of a split is the sum of
+ * the importance value of each subarray in the split.
+ *
+ * Let trimmed(subarray) be the version of the subarray where all numbers which appear only
+ * once are removed.
+ * - For example, trimmed([3,1,2,4,3,4]) = [3,4,3,4].
+ *
+ * The importance value of a subarray is k + trimmed(subarray).length.
+ * - For example, if a subarray is [1,2,3,3,3,4,4], then trimmed([1,2,3,3,3,4,4]) = [3,3,3,4,4].
+ *   The importance value of this subarray will be k + 5.
+ *
+ * Return the minimum possible cost of a split of nums.
+ *
+ * A subarray is a contiguous non-empty sequence of elements within an array.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @return {number}
+ */
+var minCost = function(nums, k) {
+  const n = nums.length;
+  const dp = new Array(n + 1).fill(Infinity);
+  dp[0] = 0;
+
+  for (let end = 1; end <= n; end++) {
+    const freq = new Map();
+    let trimLen = 0;
+    for (let start = end - 1; start >= 0; start--) {
+      const num = nums[start];
+      const count = (freq.get(num) || 0) + 1;
+      freq.set(num, count);
+      if (count === 1) trimLen++;
+      if (count === 2) trimLen--;
+      dp[end] = Math.min(dp[end], dp[start] + k + (end - start - trimLen));
+    }
+  }
+
+  return dp[n];
+};
diff --git a/solutions/2549-count-distinct-numbers-on-board.js b/solutions/2549-count-distinct-numbers-on-board.js
new file mode 100644
index 00000000..861cd59d
--- /dev/null
+++ b/solutions/2549-count-distinct-numbers-on-board.js
@@ -0,0 +1,24 @@
+/**
+ * 2549. Count Distinct Numbers on Board
+ * https://leetcode.com/problems/count-distinct-numbers-on-board/
+ * Difficulty: Easy
+ *
+ * You are given a positive integer n, that is initially placed on a board. Every day, for
+ * 109 days, you perform the following procedure:
+ * - For each number x present on the board, find all numbers 1 <= i <= n such that x % i == 1.
+ * - Then, place those numbers on the board.
+ *
+ * Return the number of distinct integers present on the board after 109 days have elapsed.
+ *
+ * Note:
+ * - Once a number is placed on the board, it will remain on it until the end.
+ * - % stands for the modulo operation. For example, 14 % 3 is 2.
+ */
+
+/**
+ * @param {number} n
+ * @return {number}
+ */
+var distinctIntegers = function(n) {
+  return n === 1 ? 1 : n - 1;
+};
diff --git a/solutions/2553-separate-the-digits-in-an-array.js b/solutions/2553-separate-the-digits-in-an-array.js
new file mode 100644
index 00000000..1255dfb6
--- /dev/null
+++ b/solutions/2553-separate-the-digits-in-an-array.js
@@ -0,0 +1,19 @@
+/**
+ * 2553. Separate the Digits in an Array
+ * https://leetcode.com/problems/separate-the-digits-in-an-array/
+ * Difficulty: Easy
+ *
+ * Given an array of positive integers nums, return an array answer that consists of the digits
+ * of each integer in nums after separating them in the same order they appear in nums.
+ *
+ * To separate the digits of an integer is to get all the digits it has in the same order.
+ * - For example, for the integer 10921, the separation of its digits is [1,0,9,2,1].
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number[]}
+ */
+var separateDigits = function(nums) {
+  return nums.flatMap(num => String(num).split('').map(Number));
+};
diff --git a/solutions/2554-maximum-number-of-integers-to-choose-from-a-range-i.js b/solutions/2554-maximum-number-of-integers-to-choose-from-a-range-i.js
new file mode 100644
index 00000000..bb160607
--- /dev/null
+++ b/solutions/2554-maximum-number-of-integers-to-choose-from-a-range-i.js
@@ -0,0 +1,35 @@
+/**
+ * 2554. Maximum Number of Integers to Choose From a Range I
+ * https://leetcode.com/problems/maximum-number-of-integers-to-choose-from-a-range-i/
+ * Difficulty: Medium
+ *
+ * You are given an integer array banned and two integers n and maxSum. You are choosing some
+ * number of integers following the below rules:
+ * - The chosen integers have to be in the range [1, n].
+ * - Each integer can be chosen at most once.
+ * - The chosen integers should not be in the array banned.
+ * - The sum of the chosen integers should not exceed maxSum.
+ *
+ * Return the maximum number of integers you can choose following the mentioned rules.
+ */
+
+/**
+ * @param {number[]} banned
+ * @param {number} n
+ * @param {number} maxSum
+ * @return {number}
+ */
+var maxCount = function(banned, n, maxSum) {
+  const set = new Set(banned);
+  let result = 0;
+  let currentSum = 0;
+
+  for (let num = 1; num <= n; num++) {
+    if (!set.has(num) && currentSum + num <= maxSum) {
+      result++;
+      currentSum += num;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2562-find-the-array-concatenation-value.js b/solutions/2562-find-the-array-concatenation-value.js
new file mode 100644
index 00000000..b35decfc
--- /dev/null
+++ b/solutions/2562-find-the-array-concatenation-value.js
@@ -0,0 +1,42 @@
+/**
+ * 2562. Find the Array Concatenation Value
+ * https://leetcode.com/problems/find-the-array-concatenation-value/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed integer array nums.
+ *
+ * The concatenation of two numbers is the number formed by concatenating their numerals.
+ * - For example, the concatenation of 15, 49 is 1549.
+ *
+ * The concatenation value of nums is initially equal to 0. Perform this operation until nums
+ * becomes empty:
+ * - If nums has a size greater than one, add the value of the concatenation of the first and
+ *   the last element to the concatenation value of nums, and remove those two elements from
+ *   nums. For example, if the nums was [1, 2, 4, 5, 6], add 16 to the concatenation value.
+ * - If only one element exists in nums, add its value to the concatenation value of nums,
+ *   then remove it.
+ *
+ * Return the concatenation value of nums.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var findTheArrayConcVal = function(nums) {
+  let result = 0;
+  let left = 0;
+  let right = nums.length - 1;
+
+  while (left <= right) {
+    if (left === right) {
+      result += nums[left];
+    } else {
+      result += Number(`${nums[left]}${nums[right]}`);
+    }
+    left++;
+    right--;
+  }
+
+  return result;
+};
diff --git a/solutions/2566-maximum-difference-by-remapping-a-digit.js b/solutions/2566-maximum-difference-by-remapping-a-digit.js
new file mode 100644
index 00000000..55898513
--- /dev/null
+++ b/solutions/2566-maximum-difference-by-remapping-a-digit.js
@@ -0,0 +1,40 @@
+/**
+ * 2566. Maximum Difference by Remapping a Digit
+ * https://leetcode.com/problems/maximum-difference-by-remapping-a-digit/
+ * Difficulty: Easy
+ *
+ * You are given an integer num. You know that Bob will sneakily remap one of the 10 possible
+ * digits (0 to 9) to another digit.
+ *
+ * Return the difference between the maximum and minimum values Bob can make by remapping
+ * exactly one digit in num.
+ *
+ * Notes:
+ * - When Bob remaps a digit d1 to another digit d2, Bob replaces all occurrences of d1 in
+ *   num with d2.
+ * - Bob can remap a digit to itself, in which case num does not change.
+ * - Bob can remap different digits for obtaining minimum and maximum values respectively.
+ * - The resulting number after remapping can contain leading zeroes.
+ */
+
+/**
+ * @param {number} num
+ * @return {number}
+ */
+var minMaxDifference = function(num) {
+  const digits = String(num).split('');
+  let maxNum = num;
+  let minNum = num;
+
+  for (let i = 0; i < 10; i++) {
+    const digit = String(i);
+    if (digits.includes(digit)) {
+      const maxCandidate = Number(digits.join('').replaceAll(digit, '9'));
+      const minCandidate = Number(digits.join('').replaceAll(digit, '0'));
+      maxNum = Math.max(maxNum, maxCandidate);
+      minNum = Math.min(minNum, minCandidate);
+    }
+  }
+
+  return maxNum - minNum;
+};
diff --git a/solutions/2567-minimum-score-by-changing-two-elements.js b/solutions/2567-minimum-score-by-changing-two-elements.js
new file mode 100644
index 00000000..a5f5d1c5
--- /dev/null
+++ b/solutions/2567-minimum-score-by-changing-two-elements.js
@@ -0,0 +1,26 @@
+/**
+ * 2567. Minimum Score by Changing Two Elements
+ * https://leetcode.com/problems/minimum-score-by-changing-two-elements/
+ * Difficulty: Medium
+ *
+ * You are given an integer array nums.
+ * - The low score of nums is the minimum absolute difference between any two integers.
+ * - The high score of nums is the maximum absolute difference between any two integers.
+ * - The score of nums is the sum of the high and low scores.
+ *
+ * Return the minimum score after changing two elements of nums.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var minimizeSum = function(nums) {
+  const sorted = nums.sort((a, b) => a - b);
+
+  return Math.min(
+    sorted[sorted.length - 2] - sorted[1],
+    sorted[sorted.length - 1] - sorted[2],
+    sorted[sorted.length - 3] - sorted[0]
+  );
+};
diff --git a/solutions/2568-minimum-impossible-or.js b/solutions/2568-minimum-impossible-or.js
new file mode 100644
index 00000000..6cb1df58
--- /dev/null
+++ b/solutions/2568-minimum-impossible-or.js
@@ -0,0 +1,30 @@
+/**
+ * 2568. Minimum Impossible OR
+ * https://leetcode.com/problems/minimum-impossible-or/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed integer array nums.
+ *
+ * We say that an integer x is expressible from nums if there exist some integers
+ * 0 <= index1 < index2 < ... < indexk < nums.length for which
+ * nums[index1] | nums[index2] | ... | nums[indexk] = x. In other words, an
+ * integer is expressible if it can be written as the bitwise OR of some subsequence
+ * of nums.
+ *
+ * Return the minimum positive non-zero integer that is not expressible from nums.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var minImpossibleOR = function(nums) {
+  const set = new Set(nums);
+  let result = 1;
+
+  while (set.has(result)) {
+    result <<= 1;
+  }
+
+  return result;
+};
diff --git a/solutions/2571-minimum-operations-to-reduce-an-integer-to-0.js b/solutions/2571-minimum-operations-to-reduce-an-integer-to-0.js
new file mode 100644
index 00000000..0ee9bb23
--- /dev/null
+++ b/solutions/2571-minimum-operations-to-reduce-an-integer-to-0.js
@@ -0,0 +1,34 @@
+/**
+ * 2571. Minimum Operations to Reduce an Integer to 0
+ * https://leetcode.com/problems/minimum-operations-to-reduce-an-integer-to-0/
+ * Difficulty: Medium
+ *
+ * You are given a positive integer n, you can do the following operation any number of times:
+ * - Add or subtract a power of 2 from n.
+ *
+ * Return the minimum number of operations to make n equal to 0.
+ *
+ * A number x is power of 2 if x == 2i where i >= 0.
+ */
+
+/**
+ * @param {number} n
+ * @return {number}
+ */
+var minOperations = function(n) {
+  let result = 0;
+
+  while (n > 0) {
+    if ((n & 1) === 0) {
+      n >>= 1;
+    } else if ((n & 3) === 3) {
+      n += 1;
+      result++;
+    } else {
+      n -= 1;
+      result++;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2574-left-and-right-sum-differences.js b/solutions/2574-left-and-right-sum-differences.js
new file mode 100644
index 00000000..e3292140
--- /dev/null
+++ b/solutions/2574-left-and-right-sum-differences.js
@@ -0,0 +1,34 @@
+/**
+ * 2574. Left and Right Sum Differences
+ * https://leetcode.com/problems/left-and-right-sum-differences/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed integer array nums of size n.
+ *
+ * Define two arrays leftSum and rightSum where:
+ * - leftSum[i] is the sum of elements to the left of the index i in the array nums.
+ *   If there is no such element, leftSum[i] = 0.
+ * - rightSum[i] is the sum of elements to the right of the index i in the array nums.
+ *   If there is no such element, rightSum[i] = 0.
+ *
+ * Return an integer array answer of size n where answer[i] = |leftSum[i] - rightSum[i]|.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number[]}
+ */
+var leftRightDifference = function(nums) {
+  const n = nums.length;
+  const result = new Array(n).fill(0);
+  let leftSum = 0;
+  let rightSum = nums.reduce((sum, num) => sum + num, 0);
+
+  for (let i = 0; i < n; i++) {
+    rightSum -= nums[i];
+    result[i] = Math.abs(leftSum - rightSum);
+    leftSum += nums[i];
+  }
+
+  return result;
+};
diff --git a/solutions/2576-find-the-maximum-number-of-marked-indices.js b/solutions/2576-find-the-maximum-number-of-marked-indices.js
new file mode 100644
index 00000000..73f0f859
--- /dev/null
+++ b/solutions/2576-find-the-maximum-number-of-marked-indices.js
@@ -0,0 +1,38 @@
+/**
+ * 2576. Find the Maximum Number of Marked Indices
+ * https://leetcode.com/problems/find-the-maximum-number-of-marked-indices/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed integer array nums.
+ *
+ * Initially, all of the indices are unmarked. You are allowed to make this operation any
+ * number of times:
+ * - Pick two different unmarked indices i and j such that 2 * nums[i] <= nums[j], then
+ *   mark i and j.
+ *
+ * Return the maximum possible number of marked indices in nums using the above operation
+ * any number of times.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var maxNumOfMarkedIndices = function(nums) {
+  nums.sort((a, b) => a - b);
+  let result = 0;
+  let left = 0;
+  let right = Math.floor(nums.length / 2);
+
+  while (left < Math.floor(nums.length / 2) && right < nums.length) {
+    if (2 * nums[left] <= nums[right]) {
+      result += 2;
+      left++;
+      right++;
+    } else {
+      right++;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2578-split-with-minimum-sum.js b/solutions/2578-split-with-minimum-sum.js
new file mode 100644
index 00000000..3d81e46c
--- /dev/null
+++ b/solutions/2578-split-with-minimum-sum.js
@@ -0,0 +1,38 @@
+/**
+ * 2578. Split With Minimum Sum
+ * https://leetcode.com/problems/split-with-minimum-sum/
+ * Difficulty: Easy
+ *
+ * Given a positive integer num, split it into two non-negative integers num1 and num2 such that:
+ * - The concatenation of num1 and num2 is a permutation of num.
+ *   - In other words, the sum of the number of occurrences of each digit in num1 and num2 is equal
+ *     to the number of occurrences of that digit in num.
+ * - num1 and num2 can contain leading zeros.
+ *
+ * Return the minimum possible sum of num1 and num2.
+ *
+ * Notes:
+ * - It is guaranteed that num does not contain any leading zeros.
+ * - The order of occurrence of the digits in num1 and num2 may differ from the order of occurrence
+ *   of num.
+ */
+
+/**
+ * @param {number} num
+ * @return {number}
+ */
+var splitNum = function(num) {
+  const digits = String(num).split('').sort((a, b) => a - b);
+  let num1 = '';
+  let num2 = '';
+
+  for (let i = 0; i < digits.length; i++) {
+    if (i % 2 === 0) {
+      num1 += digits[i];
+    } else {
+      num2 += digits[i];
+    }
+  }
+
+  return Number(num1) + Number(num2);
+};
diff --git a/solutions/2581-count-number-of-possible-root-nodes.js b/solutions/2581-count-number-of-possible-root-nodes.js
new file mode 100644
index 00000000..4d879928
--- /dev/null
+++ b/solutions/2581-count-number-of-possible-root-nodes.js
@@ -0,0 +1,78 @@
+/**
+ * 2581. Count Number of Possible Root Nodes
+ * https://leetcode.com/problems/count-number-of-possible-root-nodes/
+ * Difficulty: Hard
+ *
+ * Alice has an undirected tree with n nodes labeled from 0 to n - 1. The tree is represented as a
+ * 2D integer array edges of length n - 1 where edges[i] = [ai, bi] indicates that there is an edge
+ * between nodes ai and bi in the tree.
+ *
+ * Alice wants Bob to find the root of the tree. She allows Bob to make several guesses about her
+ * tree. In one guess, he does the following:
+ * - Chooses two distinct integers u and v such that there exists an edge [u, v] in the tree.
+ * - He tells Alice that u is the parent of v in the tree.
+ *
+ * Bob's guesses are represented by a 2D integer array guesses where guesses[j] = [uj, vj] indicates
+ * Bob guessed uj to be the parent of vj.
+ *
+ * Alice being lazy, does not reply to each of Bob's guesses, but just says that at least k of his
+ * guesses are true.
+ *
+ * Given the 2D integer arrays edges, guesses and the integer k, return the number of possible
+ * nodes that can be the root of Alice's tree. If there is no such tree, return 0.
+ */
+
+/**
+ * @param {number[][]} edges
+ * @param {number[][]} guesses
+ * @param {number} k
+ * @return {number}
+ */
+var rootCount = function(edges, guesses, k) {
+  const n = edges.length + 1;
+  const adj = Array.from({ length: n }, () => new Set());
+  const set = new Set();
+
+  for (const [u, v] of edges) {
+    adj[u].add(v);
+    adj[v].add(u);
+  }
+
+  for (const [u, v] of guesses) {
+    set.add(u * n + v);
+  }
+
+  const rootCorrect = dfs(0, -1);
+  let result = rootCorrect >= k ? 1 : 0;
+
+  for (const neighbor of adj[0]) {
+    helper(neighbor, 0, rootCorrect);
+  }
+
+  return result;
+
+  function helper(node, parent, parentCorrect) {
+    let count = parentCorrect;
+    if (set.has(parent * n + node)) count--;
+    if (set.has(node * n + parent)) count++;
+
+    if (count >= k) result++;
+
+    for (const neighbor of adj[node]) {
+      if (neighbor !== parent) {
+        helper(neighbor, node, count);
+      }
+    }
+  }
+
+  function dfs(node, parent) {
+    let count = 0;
+    for (const neighbor of adj[node]) {
+      if (neighbor !== parent) {
+        if (set.has(node * n + neighbor)) count++;
+        count += dfs(neighbor, node);
+      }
+    }
+    return count;
+  }
+};
diff --git a/solutions/2582-pass-the-pillow.js b/solutions/2582-pass-the-pillow.js
new file mode 100644
index 00000000..6f1a17a9
--- /dev/null
+++ b/solutions/2582-pass-the-pillow.js
@@ -0,0 +1,25 @@
+/**
+ * 2582. Pass the Pillow
+ * https://leetcode.com/problems/pass-the-pillow/
+ * Difficulty: Easy
+ *
+ * There are n people standing in a line labeled from 1 to n. The first person in the line is
+ * holding a pillow initially. Every second, the person holding the pillow passes it to the
+ * next person standing in the line. Once the pillow reaches the end of the line, the direction
+ * changes, and people continue passing the pillow in the opposite direction.
+ * - For example, once the pillow reaches the nth person they pass it to the n - 1th person,
+ *   then to the n - 2th person and so on.
+ *
+ * Given the two positive integers n and time, return the index of the person holding the pillow
+ * after time seconds.
+ */
+
+/**
+ * @param {number} n
+ * @param {number} time
+ * @return {number}
+ */
+var passThePillow = function(n, time) {
+  const position = time % (2 * (n - 1));
+  return position < n ? position + 1 : 2 * n - position - 1;
+};
diff --git a/solutions/2583-kth-largest-sum-in-a-binary-tree.js b/solutions/2583-kth-largest-sum-in-a-binary-tree.js
new file mode 100644
index 00000000..b8759f23
--- /dev/null
+++ b/solutions/2583-kth-largest-sum-in-a-binary-tree.js
@@ -0,0 +1,50 @@
+/**
+ * 2583. Kth Largest Sum in a Binary Tree
+ * https://leetcode.com/problems/kth-largest-sum-in-a-binary-tree/
+ * Difficulty: Medium
+ *
+ * You are given the root of a binary tree and a positive integer k.
+ *
+ * The level sum in the tree is the sum of the values of the nodes that are on the same level.
+ *
+ * Return the kth largest level sum in the tree (not necessarily distinct). If there are fewer
+ * than k levels in the tree, return -1.
+ *
+ * Note that two nodes are on the same level if they have the same distance from the root.
+ */
+
+/**
+ * Definition for a binary tree node.
+ * function TreeNode(val, left, right) {
+ *     this.val = (val===undefined ? 0 : val)
+ *     this.left = (left===undefined ? null : left)
+ *     this.right = (right===undefined ? null : right)
+ * }
+ */
+/**
+ * @param {TreeNode} root
+ * @param {number} k
+ * @return {number}
+ */
+var kthLargestLevelSum = function(root, k) {
+  const levelSums = [];
+  const queue = [root];
+
+  while (queue.length) {
+    let levelSize = queue.length;
+    let levelSum = 0;
+
+    while (levelSize--) {
+      const node = queue.shift();
+      levelSum += node.val;
+      if (node.left) queue.push(node.left);
+      if (node.right) queue.push(node.right);
+    }
+
+    levelSums.push(levelSum);
+  }
+
+  if (levelSums.length < k) return -1;
+
+  return levelSums.sort((a, b) => b - a)[k - 1];
+};
diff --git a/solutions/2585-number-of-ways-to-earn-points.js b/solutions/2585-number-of-ways-to-earn-points.js
new file mode 100644
index 00000000..a88d5050
--- /dev/null
+++ b/solutions/2585-number-of-ways-to-earn-points.js
@@ -0,0 +1,37 @@
+/**
+ * 2585. Number of Ways to Earn Points
+ * https://leetcode.com/problems/number-of-ways-to-earn-points/
+ * Difficulty: Hard
+ *
+ * There is a test that has n types of questions. You are given an integer target and a 0-indexed
+ * 2D integer array types where types[i] = [counti, marksi] indicates that there are counti
+ * questions of the ith type, and each one of them is worth marksi points.
+ *
+ * Return the number of ways you can earn exactly target points in the exam. Since the answer may
+ * be too large, return it modulo 109 + 7.
+ *
+ * Note that questions of the same type are indistinguishable.
+ * - For example, if there are 3 questions of the same type, then solving the 1st and 2nd questions
+ *   is the same as solving the 1st and 3rd questions, or the 2nd and 3rd questions.
+ */
+
+/**
+ * @param {number} target
+ * @param {number[][]} types
+ * @return {number}
+ */
+var waysToReachTarget = function(target, types) {
+  const MOD = 1e9 + 7;
+  const dp = new Array(target + 1).fill(0);
+  dp[0] = 1;
+
+  for (const [count, marks] of types) {
+    for (let points = target; points >= 0; points--) {
+      for (let k = 1; k <= count && points >= k * marks; k++) {
+        dp[points] = (dp[points] + dp[points - k * marks]) % MOD;
+      }
+    }
+  }
+
+  return dp[target];
+};
diff --git a/solutions/2586-count-the-number-of-vowel-strings-in-range.js b/solutions/2586-count-the-number-of-vowel-strings-in-range.js
new file mode 100644
index 00000000..feff0ca4
--- /dev/null
+++ b/solutions/2586-count-the-number-of-vowel-strings-in-range.js
@@ -0,0 +1,32 @@
+/**
+ * 2586. Count the Number of Vowel Strings in Range
+ * https://leetcode.com/problems/count-the-number-of-vowel-strings-in-range/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed array of string words and two integers left and right.
+ *
+ * A string is called a vowel string if it starts with a vowel character and ends with
+ * a vowel character where vowel characters are 'a', 'e', 'i', 'o', and 'u'.
+ *
+ * Return the number of vowel strings words[i] where i belongs to the inclusive range [left, right].
+ */
+
+/**
+ * @param {string[]} words
+ * @param {number} left
+ * @param {number} right
+ * @return {number}
+ */
+var vowelStrings = function(words, left, right) {
+  const vowels = new Set(['a', 'e', 'i', 'o', 'u']);
+  let result = 0;
+
+  for (let i = left; i <= right; i++) {
+    const word = words[i];
+    if (vowels.has(word[0]) && vowels.has(word[word.length - 1])) {
+      result++;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2587-rearrange-array-to-maximize-prefix-score.js b/solutions/2587-rearrange-array-to-maximize-prefix-score.js
new file mode 100644
index 00000000..585a0d04
--- /dev/null
+++ b/solutions/2587-rearrange-array-to-maximize-prefix-score.js
@@ -0,0 +1,32 @@
+/**
+ * 2587. Rearrange Array to Maximize Prefix Score
+ * https://leetcode.com/problems/rearrange-array-to-maximize-prefix-score/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed integer array nums. You can rearrange the elements of nums to any
+ * order (including the given order).
+ *
+ * Let prefix be the array containing the prefix sums of nums after rearranging it. In other words,
+ * prefix[i] is the sum of the elements from 0 to i in nums after rearranging it. The score of nums
+ * is the number of positive integers in the array prefix.
+ *
+ * Return the maximum score you can achieve.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var maxScore = function(nums) {
+  const sorted = nums.sort((a, b) => b - a);
+  let prefixSum = 0;
+  let result = 0;
+
+  for (const num of sorted) {
+    prefixSum += num;
+    if (prefixSum > 0) result++;
+    else break;
+  }
+
+  return result;
+};
diff --git a/solutions/2588-count-the-number-of-beautiful-subarrays.js b/solutions/2588-count-the-number-of-beautiful-subarrays.js
new file mode 100644
index 00000000..122bc329
--- /dev/null
+++ b/solutions/2588-count-the-number-of-beautiful-subarrays.js
@@ -0,0 +1,36 @@
+/**
+ * 2588. Count the Number of Beautiful Subarrays
+ * https://leetcode.com/problems/count-the-number-of-beautiful-subarrays/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed integer array nums. In one operation, you can:
+ * - Choose two different indices i and j such that 0 <= i, j < nums.length.
+ * - Choose a non-negative integer k such that the kth bit (0-indexed) in the binary representation
+ *   of nums[i] and nums[j] is 1.
+ * - Subtract 2k from nums[i] and nums[j].
+ *
+ * A subarray is beautiful if it is possible to make all of its elements equal to 0 after applying
+ * the above operation any number of times.
+ *
+ * Return the number of beautiful subarrays in the array nums.
+ *
+ * A subarray is a contiguous non-empty sequence of elements within an array.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var beautifulSubarrays = function(nums) {
+  let result = 0;
+  const prefixXOR = new Map([[0, 1]]);
+  let currentXOR = 0;
+
+  for (const num of nums) {
+    currentXOR ^= num;
+    result += prefixXOR.get(currentXOR) || 0;
+    prefixXOR.set(currentXOR, (prefixXOR.get(currentXOR) || 0) + 1);
+  }
+
+  return result;
+};
diff --git a/solutions/2592-maximize-greatness-of-an-array.js b/solutions/2592-maximize-greatness-of-an-array.js
new file mode 100644
index 00000000..07b1edea
--- /dev/null
+++ b/solutions/2592-maximize-greatness-of-an-array.js
@@ -0,0 +1,36 @@
+/**
+ * 2592. Maximize Greatness of an Array
+ * https://leetcode.com/problems/maximize-greatness-of-an-array/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed integer array nums. You are allowed to permute nums into a new
+ * array perm of your choosing.
+ *
+ * We define the greatness of nums be the number of indices 0 <= i < nums.length for which
+ * perm[i] > nums[i].
+ *
+ * Return the maximum possible greatness you can achieve after permuting nums.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var maximizeGreatness = function(nums) {
+  nums.sort((a, b) => a - b);
+  let result = 0;
+  let i = 0;
+  let j = 1;
+
+  while (j < nums.length) {
+    if (nums[j] > nums[i]) {
+      result++;
+      i++;
+      j++;
+    } else {
+      j++;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2595-number-of-even-and-odd-bits.js b/solutions/2595-number-of-even-and-odd-bits.js
new file mode 100644
index 00000000..e4508491
--- /dev/null
+++ b/solutions/2595-number-of-even-and-odd-bits.js
@@ -0,0 +1,36 @@
+/**
+ * 2595. Number of Even and Odd Bits
+ * https://leetcode.com/problems/number-of-even-and-odd-bits/
+ * Difficulty: Easy
+ *
+ * You are given a positive integer n.
+ *
+ * Let even denote the number of even indices in the binary representation of n with value 1.
+ *
+ * Let odd denote the number of odd indices in the binary representation of n with value 1.
+ *
+ * Note that bits are indexed from right to left in the binary representation of a number.
+ *
+ * Return the array [even, odd].
+ */
+
+/**
+ * @param {number} n
+ * @return {number[]}
+ */
+var evenOddBit = function(n) {
+  let evenCount = 0;
+  let oddCount = 0;
+  let index = 0;
+
+  while (n > 0) {
+    if (n & 1) {
+      if (index % 2 === 0) evenCount++;
+      else oddCount++;
+    }
+    n >>= 1;
+    index++;
+  }
+
+  return [evenCount, oddCount];
+};
diff --git a/solutions/2596-check-knight-tour-configuration.js b/solutions/2596-check-knight-tour-configuration.js
new file mode 100644
index 00000000..d75bc66a
--- /dev/null
+++ b/solutions/2596-check-knight-tour-configuration.js
@@ -0,0 +1,52 @@
+/**
+ * 2596. Check Knight Tour Configuration
+ * https://leetcode.com/problems/check-knight-tour-configuration/
+ * Difficulty: Medium
+ *
+ * There is a knight on an n x n chessboard. In a valid configuration, the knight starts at the
+ * top-left cell of the board and visits every cell on the board exactly once.
+ *
+ * You are given an n x n integer matrix grid consisting of distinct integers from the range
+ * [0, n * n - 1] where grid[row][col] indicates that the cell (row, col) is the grid[row][col]th
+ * cell that the knight visited. The moves are 0-indexed.
+ *
+ * Return true if grid represents a valid configuration of the knight's movements or false
+ * otherwise.
+ *
+ * Note that a valid knight move consists of moving two squares vertically and one square
+ * horizontally, or two squares horizontally and one square vertically. The figure below
+ * illustrates all the possible eight moves of a knight from some cell.
+ */
+
+/**
+ * @param {number[][]} grid
+ * @return {boolean}
+ */
+var checkValidGrid = function(grid) {
+  const n = grid.length;
+  const moves = [[-2, -1], [-2, 1], [-1, -2], [-1, 2], [1, -2], [1, 2], [2, -1], [2, 1]];
+
+  if (grid[0][0] !== 0) return false;
+
+  const isValidMove = (fromRow, fromCol, toRow, toCol) => {
+    for (const [dr, dc] of moves) {
+      if (fromRow + dr === toRow && fromCol + dc === toCol) return true;
+    }
+    return false;
+  };
+
+  const positions = new Array(n * n).fill(0).map(() => [0, 0]);
+  for (let row = 0; row < n; row++) {
+    for (let col = 0; col < n; col++) {
+      positions[grid[row][col]] = [row, col];
+    }
+  }
+
+  for (let i = 1; i < n * n; i++) {
+    const [prevRow, prevCol] = positions[i - 1];
+    const [currRow, currCol] = positions[i];
+    if (!isValidMove(prevRow, prevCol, currRow, currCol)) return false;
+  }
+
+  return true;
+};
diff --git a/solutions/2597-the-number-of-beautiful-subsets.js b/solutions/2597-the-number-of-beautiful-subsets.js
new file mode 100644
index 00000000..9f72486d
--- /dev/null
+++ b/solutions/2597-the-number-of-beautiful-subsets.js
@@ -0,0 +1,42 @@
+/**
+ * 2597. The Number of Beautiful Subsets
+ * https://leetcode.com/problems/the-number-of-beautiful-subsets/
+ * Difficulty: Medium
+ *
+ * You are given an array nums of positive integers and a positive integer k.
+ *
+ * A subset of nums is beautiful if it does not contain two integers with an absolute difference
+ * equal to k.
+ *
+ * Return the number of non-empty beautiful subsets of the array nums.
+ *
+ * A subset of nums is an array that can be obtained by deleting some (possibly none) elements
+ * from nums. Two subsets are different if and only if the chosen indices to delete are different.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @return {number}
+ */
+var beautifulSubsets = function(nums, k) {
+  const n = nums.length;
+  let count = 0;
+  backtrack(0, []);
+  return count;
+
+  function backtrack(index, selected) {
+    if (index === n) {
+      if (selected.length > 0) count++;
+      return;
+    }
+
+    const isValid = selected.every(num => Math.abs(num - nums[index]) !== k);
+
+    backtrack(index + 1, selected);
+
+    if (isValid) {
+      backtrack(index + 1, [...selected, nums[index]]);
+    }
+  }
+};
diff --git a/solutions/2598-smallest-missing-non-negative-integer-after-operations.js b/solutions/2598-smallest-missing-non-negative-integer-after-operations.js
new file mode 100644
index 00000000..fe19438b
--- /dev/null
+++ b/solutions/2598-smallest-missing-non-negative-integer-after-operations.js
@@ -0,0 +1,40 @@
+/**
+ * 2598. Smallest Missing Non-negative Integer After Operations
+ * https://leetcode.com/problems/smallest-missing-non-negative-integer-after-operations/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed integer array nums and an integer value.
+ *
+ * In one operation, you can add or subtract value from any element of nums.
+ * - For example, if nums = [1,2,3] and value = 2, you can choose to subtract value from nums[0]
+ *   to make nums = [-1,2,3].
+ *
+ * The MEX (minimum excluded) of an array is the smallest missing non-negative integer in it.
+ * - For example, the MEX of [-1,2,3] is 0 while the MEX of [1,0,3] is 2.
+ *
+ * Return the maximum MEX of nums after applying the mentioned operation any number of times.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} value
+ * @return {number}
+ */
+var findSmallestInteger = function(nums, value) {
+  const remainderCount = new Map();
+
+  for (const num of nums) {
+    const remainder = ((num % value) + value) % value;
+    remainderCount.set(remainder, (remainderCount.get(remainder) || 0) + 1);
+  }
+
+  for (let mex = 0; mex <= nums.length; mex++) {
+    const remainder = mex % value;
+    if (!remainderCount.has(remainder) || remainderCount.get(remainder) === 0) {
+      return mex;
+    }
+    remainderCount.set(remainder, remainderCount.get(remainder) - 1);
+  }
+
+  return nums.length;
+};
diff --git a/solutions/2600-k-items-with-the-maximum-sum.js b/solutions/2600-k-items-with-the-maximum-sum.js
new file mode 100644
index 00000000..c6952fe3
--- /dev/null
+++ b/solutions/2600-k-items-with-the-maximum-sum.js
@@ -0,0 +1,38 @@
+/**
+ * 2600. K Items With the Maximum Sum
+ * https://leetcode.com/problems/k-items-with-the-maximum-sum/
+ * Difficulty: Easy
+ *
+ * There is a bag that consists of items, each item has a number 1, 0, or -1 written on it.
+ *
+ * You are given four non-negative integers numOnes, numZeros, numNegOnes, and k.
+ *
+ * The bag initially contains:
+ * - numOnes items with 1s written on them.
+ * - numZeroes items with 0s written on them.
+ * - numNegOnes items with -1s written on them.
+ *
+ * We want to pick exactly k items among the available items. Return the maximum possible sum
+ * of numbers written on the items.
+ */
+
+/**
+ * @param {number} numOnes
+ * @param {number} numZeros
+ * @param {number} numNegOnes
+ * @param {number} k
+ * @return {number}
+ */
+var kItemsWithMaximumSum = function(numOnes, numZeros, numNegOnes, k) {
+  let result = 0;
+
+  if (k <= numOnes) {
+    result = k;
+  } else if (k <= numOnes + numZeros) {
+    result = numOnes;
+  } else {
+    result = numOnes - (k - numOnes - numZeros);
+  }
+
+  return result;
+};
diff --git a/solutions/2601-prime-subtraction-operation.js b/solutions/2601-prime-subtraction-operation.js
new file mode 100644
index 00000000..c9fbc184
--- /dev/null
+++ b/solutions/2601-prime-subtraction-operation.js
@@ -0,0 +1,62 @@
+/**
+ * 2601. Prime Subtraction Operation
+ * https://leetcode.com/problems/prime-subtraction-operation/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed integer array nums of length n.
+ *
+ * You can perform the following operation as many times as you want:
+ * - Pick an index i that you haven’t picked before, and pick a prime p strictly less than
+ *   nums[i], then subtract p from nums[i].
+ *
+ * Return true if you can make nums a strictly increasing array using the above operation
+ * and false otherwise.
+ *
+ * A strictly increasing array is an array whose each element is strictly greater than its
+ * preceding element.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {boolean}
+ */
+var primeSubOperation = function(nums) {
+  const primes = generatePrimes(1000);
+  const adjusted = [...nums];
+  let prev = 0;
+
+  for (let i = 0; i < adjusted.length; i++) {
+    const curr = adjusted[i];
+    let maxPrime = 0;
+
+    for (const prime of primes) {
+      if (prime >= curr) break;
+      if (curr - prime > prev && (i === adjusted.length - 1 || curr - prime < adjusted[i + 1])) {
+        maxPrime = prime;
+      }
+    }
+
+    adjusted[i] -= maxPrime;
+    if (adjusted[i] <= prev) return false;
+    prev = adjusted[i];
+  }
+
+  return true;
+
+  function generatePrimes(limit) {
+    const group = new Array(limit + 1).fill(true);
+    const primes = [];
+    group[0] = group[1] = false;
+
+    for (let i = 2; i <= limit; i++) {
+      if (group[i]) {
+        primes.push(i);
+        for (let j = i * i; j <= limit; j += i) {
+          group[j] = false;
+        }
+      }
+    }
+
+    return primes;
+  }
+};
diff --git a/solutions/2605-form-smallest-number-from-two-digit-arrays.js b/solutions/2605-form-smallest-number-from-two-digit-arrays.js
new file mode 100644
index 00000000..4892b564
--- /dev/null
+++ b/solutions/2605-form-smallest-number-from-two-digit-arrays.js
@@ -0,0 +1,31 @@
+/**
+ * 2605. Form Smallest Number From Two Digit Arrays
+ * https://leetcode.com/problems/form-smallest-number-from-two-digit-arrays/
+ * Difficulty: Easy
+ *
+ * Given two arrays of unique digits nums1 and nums2, return the smallest number that contains
+ * at least one digit from each array.
+ */
+
+/**
+ * @param {number[]} nums1
+ * @param {number[]} nums2
+ * @return {number}
+ */
+var minNumber = function(nums1, nums2) {
+  const set1 = new Set(nums1);
+  const set2 = new Set(nums2);
+  const min1 = Math.min(...nums1);
+  const min2 = Math.min(...nums2);
+  let smallestCommon = 10;
+
+  for (const digit of set1) {
+    if (set2.has(digit) && digit < smallestCommon) {
+      smallestCommon = digit;
+    }
+  }
+
+  if (smallestCommon !== 10) return smallestCommon;
+
+  return min1 < min2 ? min1 * 10 + min2 : min2 * 10 + min1;
+};
diff --git a/solutions/2606-find-the-substring-with-maximum-cost.js b/solutions/2606-find-the-substring-with-maximum-cost.js
new file mode 100644
index 00000000..0a4572c5
--- /dev/null
+++ b/solutions/2606-find-the-substring-with-maximum-cost.js
@@ -0,0 +1,42 @@
+/**
+ * 2606. Find the Substring With Maximum Cost
+ * https://leetcode.com/problems/find-the-substring-with-maximum-cost/
+ * Difficulty: Medium
+ *
+ * You are given a string s, a string chars of distinct characters and an integer array vals of
+ * the same length as chars.
+ *
+ * The cost of the substring is the sum of the values of each character in the substring. The
+ * cost of an empty string is considered 0.
+ *
+ * The value of the character is defined in the following way:
+ * - If the character is not in the string chars, then its value is its corresponding position
+ *   (1-indexed) in the alphabet.
+ *   - For example, the value of 'a' is 1, the value of 'b' is 2, and so on. The value of 'z' is 26.
+ * - Otherwise, assuming i is the index where the character occurs in the string chars, then its
+ *   value is vals[i].
+ *
+ * Return the maximum cost among all substrings of the string s.
+ */
+
+/**
+ * @param {string} s
+ * @param {string} chars
+ * @param {number[]} vals
+ * @return {number}
+ */
+var maximumCostSubstring = function(s, chars, vals) {
+  const charValues = new Array(26).fill().map((_, i) => i + 1);
+  for (let i = 0; i < chars.length; i++) {
+    charValues[chars.charCodeAt(i) - 97] = vals[i];
+  }
+
+  let result = 0;
+  let currentCost = 0;
+  for (const char of s) {
+    currentCost = Math.max(0, currentCost + charValues[char.charCodeAt(0) - 97]);
+    result = Math.max(result, currentCost);
+  }
+
+  return result;
+};
diff --git a/solutions/2609-find-the-longest-balanced-substring-of-a-binary-string.js b/solutions/2609-find-the-longest-balanced-substring-of-a-binary-string.js
new file mode 100644
index 00000000..3884e54e
--- /dev/null
+++ b/solutions/2609-find-the-longest-balanced-substring-of-a-binary-string.js
@@ -0,0 +1,45 @@
+/**
+ * 2609. Find the Longest Balanced Substring of a Binary String
+ * https://leetcode.com/problems/find-the-longest-balanced-substring-of-a-binary-string/
+ * Difficulty: Easy
+ *
+ * You are given a binary string s consisting only of zeroes and ones.
+ *
+ * A substring of s is considered balanced if all zeroes are before ones and the number of zeroes
+ * is equal to the number of ones inside the substring. Notice that the empty substring is
+ * considered a balanced substring.
+ *
+ * Return the length of the longest balanced substring of s.
+ *
+ * A substring is a contiguous sequence of characters within a string.
+ */
+
+/**
+ * @param {string} s
+ * @return {number}
+ */
+var findTheLongestBalancedSubstring = function(s) {
+  let result = 0;
+  let zeros = 0;
+  let ones = 0;
+
+  for (let i = 0; i < s.length; i++) {
+    if (s[i] === '0') {
+      if (ones > 0) {
+        zeros = 0;
+        ones = 0;
+      }
+      zeros++;
+    } else {
+      if (zeros >= ones + 1) {
+        ones++;
+        result = Math.max(result, 2 * ones);
+      } else {
+        zeros = 0;
+        ones = 0;
+      }
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2610-convert-an-array-into-a-2d-array-with-conditions.js b/solutions/2610-convert-an-array-into-a-2d-array-with-conditions.js
new file mode 100644
index 00000000..7c584818
--- /dev/null
+++ b/solutions/2610-convert-an-array-into-a-2d-array-with-conditions.js
@@ -0,0 +1,42 @@
+/**
+ * 2610. Convert an Array Into a 2D Array With Conditions
+ * https://leetcode.com/problems/convert-an-array-into-a-2d-array-with-conditions/
+ * Difficulty: Medium
+ *
+ * You are given an integer array nums. You need to create a 2D array from nums satisfying
+ * the following conditions:
+ * - The 2D array should contain only the elements of the array nums.
+ * - Each row in the 2D array contains distinct integers.
+ * - The number of rows in the 2D array should be minimal.
+ *
+ * Return the resulting array. If there are multiple answers, return any of them.
+ *
+ * Note that the 2D array can have a different number of elements on each row.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number[][]}
+ */
+var findMatrix = function(nums) {
+  const frequency = new Map();
+  for (const num of nums) {
+    frequency.set(num, (frequency.get(num) || 0) + 1);
+  }
+
+  const result = [];
+  while (frequency.size) {
+    const row = [];
+    for (const [num, count] of frequency) {
+      row.push(num);
+      if (count === 1) {
+        frequency.delete(num);
+      } else {
+        frequency.set(num, count - 1);
+      }
+    }
+    result.push(row);
+  }
+
+  return result;
+};
diff --git a/solutions/2615-sum-of-distances.js b/solutions/2615-sum-of-distances.js
new file mode 100644
index 00000000..470c10cf
--- /dev/null
+++ b/solutions/2615-sum-of-distances.js
@@ -0,0 +1,44 @@
+/**
+ * 2615. Sum of Distances
+ * https://leetcode.com/problems/sum-of-distances/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed integer array nums. There exists an array arr of length nums.length,
+ * where arr[i] is the sum of |i - j| over all j such that nums[j] == nums[i] and j != i. If there
+ * is no such j, set arr[i] to be 0.
+ *
+ * Return the array arr.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number[]}
+ */
+var distance = function(nums) {
+  const valueIndices = new Map();
+  const result = new Array(nums.length).fill(0);
+
+  for (let i = 0; i < nums.length; i++) {
+    if (!valueIndices.has(nums[i])) {
+      valueIndices.set(nums[i], []);
+    }
+    valueIndices.get(nums[i]).push(i);
+  }
+
+  for (const indices of valueIndices.values()) {
+    let prefixSum = 0;
+    for (let i = 1; i < indices.length; i++) {
+      prefixSum += indices[i] - indices[0];
+    }
+
+    result[indices[0]] = prefixSum;
+
+    for (let i = 1; i < indices.length; i++) {
+      const diff = indices[i] - indices[i - 1];
+      prefixSum += diff * (i - (indices.length - i));
+      result[indices[i]] = prefixSum;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2616-minimize-the-maximum-difference-of-pairs.js b/solutions/2616-minimize-the-maximum-difference-of-pairs.js
new file mode 100644
index 00000000..691f2e60
--- /dev/null
+++ b/solutions/2616-minimize-the-maximum-difference-of-pairs.js
@@ -0,0 +1,53 @@
+/**
+ * 2616. Minimize the Maximum Difference of Pairs
+ * https://leetcode.com/problems/minimize-the-maximum-difference-of-pairs/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed integer array nums and an integer p. Find p pairs of indices
+ * of nums such that the maximum difference amongst all the pairs is minimized. Also, ensure
+ * no index appears more than once amongst the p pairs.
+ *
+ * Note that for a pair of elements at the index i and j, the difference of this pair is
+ * |nums[i] - nums[j]|, where |x| represents the absolute value of x.
+ *
+ * Return the minimum maximum difference among all p pairs. We define the maximum of an empty
+ * set to be zero.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} p
+ * @return {number}
+ */
+var minimizeMax = function(nums, p) {
+  nums.sort((a, b) => a - b);
+  const n = nums.length;
+
+  let left = 0;
+  let right = nums[n - 1] - nums[0];
+  let result = 0;
+
+  while (left <= right) {
+    const mid = Math.floor((left + right) / 2);
+    if (canFormPairs(mid)) {
+      result = mid;
+      right = mid - 1;
+    } else {
+      left = mid + 1;
+    }
+  }
+
+  return result;
+
+  function canFormPairs(maxDiff) {
+    let pairs = 0;
+    for (let i = 0; i < n - 1 && pairs < p; i += 2) {
+      if (nums[i + 1] - nums[i] <= maxDiff) {
+        pairs++;
+      } else {
+        i--;
+      }
+    }
+    return pairs >= p;
+  }
+};
diff --git a/solutions/2628-json-deep-equal.js b/solutions/2628-json-deep-equal.js
new file mode 100644
index 00000000..2f0cf372
--- /dev/null
+++ b/solutions/2628-json-deep-equal.js
@@ -0,0 +1,43 @@
+/**
+ * 2628. JSON Deep Equal
+ * https://leetcode.com/problems/json-deep-equal/
+ * Difficulty: Medium
+ *
+ * Given two values o1 and o2, return a boolean value indicating whether two values, o1 and o2,
+ * are deeply equal.
+ *
+ * For two values to be deeply equal, the following conditions must be met:
+ * - If both values are primitive types, they are deeply equal if they pass the === equality check.
+ * - If both values are arrays, they are deeply equal if they have the same elements in the same
+ *   order, and each element is also deeply equal according to these conditions.
+ * - If both values are objects, they are deeply equal if they have the same keys, and the
+ *   associated values for each key are also deeply equal according to these conditions.
+ *
+ * You may assume both values are the output of JSON.parse. In other words, they are valid JSON.
+ *
+ * Please solve it without using lodash's _.isEqual() function
+ */
+
+/**
+ * @param {null|boolean|number|string|Array|Object} o1
+ * @param {null|boolean|number|string|Array|Object} o2
+ * @return {boolean}
+ */
+var areDeeplyEqual = function(o1, o2) {
+  if (o1 === o2) return true;
+  if (o1 == null || o2 == null) return false;
+  if (typeof o1 !== 'object' || typeof o2 !== 'object') return false;
+
+  if (Array.isArray(o1) !== Array.isArray(o2)) return false;
+
+  if (Array.isArray(o1)) {
+    if (o1.length !== o2.length) return false;
+    return o1.every((item, index) => areDeeplyEqual(item, o2[index]));
+  }
+
+  const keys1 = Object.keys(o1);
+  const keys2 = Object.keys(o2);
+  if (keys1.length !== keys2.length) return false;
+
+  return keys1.every(key => keys2.includes(key) && areDeeplyEqual(o1[key], o2[key]));
+};
diff --git a/solutions/2632-curry.js b/solutions/2632-curry.js
new file mode 100644
index 00000000..23b54c9f
--- /dev/null
+++ b/solutions/2632-curry.js
@@ -0,0 +1,28 @@
+/**
+ * 2632. Curry
+ * https://leetcode.com/problems/curry/
+ * Difficulty: Medium
+ *
+ * Given a function fn, return a curried version of that function.
+ *
+ * A curried function is a function that accepts fewer or an equal number of parameters as the
+ * original function and returns either another curried function or the same value the original
+ * function would have returned.
+ *
+ * In practical terms, if you called the original function like sum(1,2,3), you would call the
+ * curried version like csum(1)(2)(3), csum(1)(2,3), csum(1,2)(3), or csum(1,2,3). All these
+ * methods of calling the curried function should return the same value as the original.
+ */
+
+/**
+ * @param {Function} fn
+ * @return {Function}
+ */
+var curry = function(fn) {
+  return function curried(...args) {
+    if (args.length >= fn.length) {
+      return fn(...args);
+    }
+    return (...nextArgs) => curried(...args, ...nextArgs);
+  };
+};
diff --git a/solutions/2633-convert-object-to-json-string.js b/solutions/2633-convert-object-to-json-string.js
new file mode 100644
index 00000000..90fd0f2e
--- /dev/null
+++ b/solutions/2633-convert-object-to-json-string.js
@@ -0,0 +1,29 @@
+/**
+ * 2633. Convert Object to JSON String
+ * https://leetcode.com/problems/convert-object-to-json-string/
+ * Difficulty: Medium
+ *
+ * Given a value, return a valid JSON string of that value. The value can be a string, number,
+ * array, object, boolean, or null. The returned string should not include extra spaces. The
+ * order of keys should be the same as the order returned by Object.keys().
+ *
+ * Please solve it without using the built-in JSON.stringify method.
+ */
+
+/**
+ * @param {null|boolean|number|string|Array|Object} object
+ * @return {string}
+ */
+var jsonStringify = function(object) {
+  if (object === null) return 'null';
+  if (typeof object === 'boolean' || typeof object === 'number') return String(object);
+  if (typeof object === 'string') return `"${object}"`;
+
+  if (Array.isArray(object)) {
+    const elements = object.map(item => jsonStringify(item));
+    return `[${elements.join(',')}]`;
+  }
+
+  const pairs = Object.keys(object).map(key => `"${key}":${jsonStringify(object[key])}`);
+  return `{${pairs.join(',')}}`;
+};
diff --git a/solutions/2636-promise-pool.js b/solutions/2636-promise-pool.js
new file mode 100644
index 00000000..c2bde850
--- /dev/null
+++ b/solutions/2636-promise-pool.js
@@ -0,0 +1,32 @@
+/**
+ * 2636. Promise Pool
+ * https://leetcode.com/problems/promise-pool/
+ * Difficulty: Medium
+ *
+ * Given an array of asynchronous functions functions and a pool limit n, return an asynchronous
+ * function promisePool. It should return a promise that resolves when all the input functions
+ * resolve.
+ *
+ * Pool limit is defined as the maximum number promises that can be pending at once. promisePool
+ * should begin execution of as many functions as possible and continue executing new functions
+ * when old promises resolve. promisePool should execute functions[i] then functions[i + 1] then
+ * functions[i + 2], etc. When the last promise resolves, promisePool should also resolve.
+ *
+ * For example, if n = 1, promisePool will execute one function at a time in series. However,
+ * if n = 2, it first executes two functions. When either of the two functions resolve, a 3rd
+ * function should be executed (if available), and so on until there are no functions left to
+ * execute.
+ *
+ * You can assume all functions never reject. It is acceptable for promisePool to return a promise
+ * that resolves any value.
+ */
+
+/**
+ * @param {Function[]} functions
+ * @param {number} n
+ * @return {Promise}
+ */
+var promisePool = async function(functions, n) {
+  const next = () => functions[n++]?.().then(next);
+  return Promise.all(functions.slice(0, n).map(f => f().then(next)));
+};
diff --git a/solutions/2639-find-the-width-of-columns-of-a-grid.js b/solutions/2639-find-the-width-of-columns-of-a-grid.js
new file mode 100644
index 00000000..e544bc23
--- /dev/null
+++ b/solutions/2639-find-the-width-of-columns-of-a-grid.js
@@ -0,0 +1,34 @@
+/**
+ * 2639. Find the Width of Columns of a Grid
+ * https://leetcode.com/problems/find-the-width-of-columns-of-a-grid/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed m x n integer matrix grid. The width of a column is the
+ * maximum length of its integers.
+ * - For example, if grid = [[-10], [3], [12]], the width of the only column is 3
+ *   since -10 is of length 3.
+ *
+ * Return an integer array ans of size n where ans[i] is the width of the ith column.
+ *
+ * The length of an integer x with len digits is equal to len if x is non-negative, and
+ * len + 1 otherwise.
+ */
+
+/**
+ * @param {number[][]} grid
+ * @return {number[]}
+ */
+var findColumnWidth = function(grid) {
+  const rows = grid.length;
+  const cols = grid[0].length;
+  const result = new Array(cols).fill(0);
+
+  for (let col = 0; col < cols; col++) {
+    for (let row = 0; row < rows; row++) {
+      const num = grid[row][col];
+      result[col] = Math.max(result[col], String(num).length);
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2640-find-the-score-of-all-prefixes-of-an-array.js b/solutions/2640-find-the-score-of-all-prefixes-of-an-array.js
new file mode 100644
index 00000000..9ec56b99
--- /dev/null
+++ b/solutions/2640-find-the-score-of-all-prefixes-of-an-array.js
@@ -0,0 +1,32 @@
+/**
+ * 2640. Find the Score of All Prefixes of an Array
+ * https://leetcode.com/problems/find-the-score-of-all-prefixes-of-an-array/
+ * Difficulty: Medium
+ *
+ * We define the conversion array conver of an array arr as follows:
+ * - conver[i] = arr[i] + max(arr[0..i]) where max(arr[0..i]) is the maximum value of
+ *   arr[j] over 0 <= j <= i.
+ *
+ * We also define the score of an array arr as the sum of the values of the conversion array of arr.
+ *
+ * Given a 0-indexed integer array nums of length n, return an array ans of length n where ans[i]
+ * is the score of the prefix nums[0..i].
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number[]}
+ */
+var findPrefixScore = function(nums) {
+  const result = new Array(nums.length);
+  let maxSoFar = 0;
+  let total = 0;
+
+  for (let i = 0; i < nums.length; i++) {
+    maxSoFar = Math.max(maxSoFar, nums[i]);
+    total += nums[i] + maxSoFar;
+    result[i] = total;
+  }
+
+  return result;
+};
diff --git a/solutions/2641-cousins-in-binary-tree-ii.js b/solutions/2641-cousins-in-binary-tree-ii.js
new file mode 100644
index 00000000..07faea41
--- /dev/null
+++ b/solutions/2641-cousins-in-binary-tree-ii.js
@@ -0,0 +1,53 @@
+/**
+ * 2641. Cousins in Binary Tree II
+ * https://leetcode.com/problems/cousins-in-binary-tree-ii/
+ * Difficulty: Medium
+ *
+ * Given the root of a binary tree, replace the value of each node in the tree with the
+ * sum of all its cousins' values.
+ *
+ * Two nodes of a binary tree are cousins if they have the same depth with different parents.
+ *
+ * Return the root of the modified tree.
+ *
+ * Note that the depth of a node is the number of edges in the path from the root node to it.
+ */
+
+/**
+ * Definition for a binary tree node.
+ * function TreeNode(val, left, right) {
+ *     this.val = (val===undefined ? 0 : val)
+ *     this.left = (left===undefined ? null : left)
+ *     this.right = (right===undefined ? null : right)
+ * }
+ */
+/**
+ * @param {TreeNode} root
+ * @return {TreeNode}
+ */
+var replaceValueInTree = function(root) {
+  const levelSums = [];
+
+  collectSums(root, 0);
+  replaceValues(root, 0, 0);
+
+  return root;
+
+  function collectSums(node, depth) {
+    if (!node) return;
+    if (levelSums.length <= depth) levelSums.push(0);
+    levelSums[depth] += node.val;
+    collectSums(node.left, depth + 1);
+    collectSums(node.right, depth + 1);
+  }
+
+  function replaceValues(node, depth, siblingSum) {
+    if (!node) return;
+    node.val = levelSums[depth] - node.val - siblingSum;
+
+    const leftVal = node.left ? node.left.val : 0;
+    const rightVal = node.right ? node.right.val : 0;
+    replaceValues(node.left, depth + 1, rightVal);
+    replaceValues(node.right, depth + 1, leftVal);
+  }
+};
diff --git a/solutions/2643-row-with-maximum-ones.js b/solutions/2643-row-with-maximum-ones.js
new file mode 100644
index 00000000..aaa37e79
--- /dev/null
+++ b/solutions/2643-row-with-maximum-ones.js
@@ -0,0 +1,32 @@
+/**
+ * 2643. Row With Maximum Ones
+ * https://leetcode.com/problems/row-with-maximum-ones/
+ * Difficulty: Easy
+ *
+ * Given a m x n binary matrix mat, find the 0-indexed position of the row that contains
+ * the maximum count of ones, and the number of ones in that row.
+ *
+ * In case there are multiple rows that have the maximum count of ones, the row with the
+ * smallest row number should be selected.
+ *
+ * Return an array containing the index of the row, and the number of ones in it.
+ */
+
+/**
+ * @param {number[][]} mat
+ * @return {number[]}
+ */
+var rowAndMaximumOnes = function(mat) {
+  let maxOnes = 0;
+  let maxRow = 0;
+
+  for (let row = 0; row < mat.length; row++) {
+    const ones = mat[row].reduce((sum, val) => sum + val, 0);
+    if (ones > maxOnes) {
+      maxOnes = ones;
+      maxRow = row;
+    }
+  }
+
+  return [maxRow, maxOnes];
+};
diff --git a/solutions/2644-find-the-maximum-divisibility-score.js b/solutions/2644-find-the-maximum-divisibility-score.js
new file mode 100644
index 00000000..ac5c2e02
--- /dev/null
+++ b/solutions/2644-find-the-maximum-divisibility-score.js
@@ -0,0 +1,38 @@
+/**
+ * 2644. Find the Maximum Divisibility Score
+ * https://leetcode.com/problems/find-the-maximum-divisibility-score/
+ * Difficulty: Easy
+ *
+ * You are given two integer arrays nums and divisors.
+ *
+ * The divisibility score of divisors[i] is the number of indices j such that nums[j] is
+ * divisible by divisors[i].
+ *
+ * Return the integer divisors[i] with the maximum divisibility score. If multiple integers
+ * have the maximum score, return the smallest one.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number[]} divisors
+ * @return {number}
+ */
+var maxDivScore = function(nums, divisors) {
+  let maxScore = 0;
+  let result = divisors[0];
+
+  for (const divisor of divisors) {
+    let score = 0;
+    for (const num of nums) {
+      if (num % divisor === 0) {
+        score++;
+      }
+    }
+    if (score > maxScore || (score === maxScore && divisor < result)) {
+      maxScore = score;
+      result = divisor;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2645-minimum-additions-to-make-valid-string.js b/solutions/2645-minimum-additions-to-make-valid-string.js
new file mode 100644
index 00000000..fd6bec83
--- /dev/null
+++ b/solutions/2645-minimum-additions-to-make-valid-string.js
@@ -0,0 +1,49 @@
+/**
+ * 2645. Minimum Additions to Make Valid String
+ * https://leetcode.com/problems/minimum-additions-to-make-valid-string/
+ * Difficulty: Medium
+ *
+ * Given a string word to which you can insert letters "a", "b" or "c" anywhere and any number
+ * of times, return the minimum number of letters that must be inserted so that word becomes valid.
+ *
+ * A string is called valid if it can be formed by concatenating the string "abc" several times.
+ */
+
+/**
+ * @param {string} word
+ * @return {number}
+ */
+var addMinimum = function(word) {
+  let result = 0;
+  let index = 0;
+
+  while (index < word.length) {
+    if (word[index] === 'a') {
+      if (word[index + 1] === 'b' && word[index + 2] === 'c') {
+        index += 3;
+      } else if (word[index + 1] === 'b') {
+        result += 1;
+        index += 2;
+      } else if (word[index + 1] === 'c') {
+        result += 1;
+        index += 2;
+      } else {
+        result += 2;
+        index += 1;
+      }
+    } else if (word[index] === 'b') {
+      if (word[index + 1] === 'c') {
+        result += 1;
+        index += 2;
+      } else {
+        result += 2;
+        index += 1;
+      }
+    } else {
+      result += 2;
+      index += 1;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2646-minimize-the-total-price-of-the-trips.js b/solutions/2646-minimize-the-total-price-of-the-trips.js
new file mode 100644
index 00000000..08bb9cfd
--- /dev/null
+++ b/solutions/2646-minimize-the-total-price-of-the-trips.js
@@ -0,0 +1,81 @@
+/**
+ * 2646. Minimize the Total Price of the Trips
+ * https://leetcode.com/problems/minimize-the-total-price-of-the-trips/
+ * Difficulty: Hard
+ *
+ * There exists an undirected and unrooted tree with n nodes indexed from 0 to n - 1. You are
+ * given the integer n and a 2D integer array edges of length n - 1, where edges[i] = [ai, bi]
+ * indicates that there is an edge between nodes ai and bi in the tree.
+ *
+ * Each node has an associated price. You are given an integer array price, where price[i] is
+ * the price of the ith node.
+ *
+ * The price sum of a given path is the sum of the prices of all nodes lying on that path.
+ *
+ * Additionally, you are given a 2D integer array trips, where trips[i] = [starti, endi]
+ * indicates that you start the ith trip from the node starti and travel to the node endi
+ * by any path you like.
+ *
+ * Before performing your first trip, you can choose some non-adjacent nodes and halve the
+ * prices.
+ *
+ * Return the minimum total price sum to perform all the given trips.
+ */
+
+/**
+ * @param {number} n
+ * @param {number[][]} edges
+ * @param {number[]} price
+ * @param {number[][]} trips
+ * @return {number}
+ */
+var minimumTotalPrice = function(n, edges, price, trips) {
+  const graph = Array.from({ length: n }, () => []);
+  for (const [u, v] of edges) {
+    graph[u].push(v);
+    graph[v].push(u);
+  }
+
+  const count = new Array(n).fill(0);
+
+  for (const [start, end] of trips) {
+    dfsPath(start, end, -1, []);
+  }
+
+  return dp(0, -1, true)[1];
+
+  function dp(node, parent, canHalve) {
+    const full = count[node] * price[node];
+    const half = full / 2;
+    let childrenFull = 0;
+    let childrenHalf = 0;
+
+    for (const child of graph[node]) {
+      if (child !== parent) {
+        const [childFull, childHalf] = dp(child, node, canHalve && node !== -1);
+        childrenFull += childFull;
+        childrenHalf += childHalf;
+      }
+    }
+
+    if (canHalve) {
+      return [full + childrenHalf, Math.min(full + childrenHalf, half + childrenFull)];
+    }
+    return [full + childrenHalf, full + childrenHalf];
+  }
+
+  function dfsPath(start, end, parent, path) {
+    path.push(start);
+    if (start === end) {
+      for (const node of path) count[node]++;
+      return true;
+    }
+    for (const next of graph[start]) {
+      if (next !== parent && dfsPath(next, end, start, path)) {
+        return true;
+      }
+    }
+    path.pop();
+    return false;
+  }
+};
diff --git a/solutions/2651-calculate-delayed-arrival-time.js b/solutions/2651-calculate-delayed-arrival-time.js
new file mode 100644
index 00000000..09571897
--- /dev/null
+++ b/solutions/2651-calculate-delayed-arrival-time.js
@@ -0,0 +1,21 @@
+/**
+ * 2651. Calculate Delayed Arrival Time
+ * https://leetcode.com/problems/calculate-delayed-arrival-time/
+ * Difficulty: Easy
+ *
+ * You are given a positive integer arrivalTime denoting the arrival time of a train in
+ * hours, and another positive integer delayedTime denoting the amount of delay in hours.
+ *
+ * Return the time when the train will arrive at the station.
+ *
+ * Note that the time in this problem is in 24-hours format.
+ */
+
+/**
+ * @param {number} arrivalTime
+ * @param {number} delayedTime
+ * @return {number}
+ */
+var findDelayedArrivalTime = function(arrivalTime, delayedTime) {
+  return (arrivalTime + delayedTime) % 24;
+};
diff --git a/solutions/2652-sum-multiples.js b/solutions/2652-sum-multiples.js
new file mode 100644
index 00000000..340dbd2a
--- /dev/null
+++ b/solutions/2652-sum-multiples.js
@@ -0,0 +1,25 @@
+/**
+ * 2652. Sum Multiples
+ * https://leetcode.com/problems/sum-multiples/
+ * Difficulty: Easy
+ *
+ * Given a positive integer n, find the sum of all integers in the range [1, n] inclusive
+ * that are divisible by 3, 5, or 7.
+ *
+ * Return an integer denoting the sum of all numbers in the given range satisfying the constraint.
+ */
+
+/**
+ * @param {number} n
+ * @return {number}
+ */
+var sumOfMultiples = function(n) {
+  return sumDivisibleBy(3) + sumDivisibleBy(5) + sumDivisibleBy(7)
+    - sumDivisibleBy(15) - sumDivisibleBy(21) - sumDivisibleBy(35)
+    + sumDivisibleBy(105);
+
+  function sumDivisibleBy(divisor) {
+    const count = Math.floor(n / divisor);
+    return divisor * count * (count + 1) / 2;
+  }
+};
diff --git a/solutions/2656-maximum-sum-with-exactly-k-elements.js b/solutions/2656-maximum-sum-with-exactly-k-elements.js
new file mode 100644
index 00000000..fdac61de
--- /dev/null
+++ b/solutions/2656-maximum-sum-with-exactly-k-elements.js
@@ -0,0 +1,23 @@
+/**
+ * 2656. Maximum Sum With Exactly K Elements
+ * https://leetcode.com/problems/maximum-sum-with-exactly-k-elements/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed integer array nums and an integer k. Your task is to perform
+ * the following operation exactly k times in order to maximize your score:
+ * 1. Select an element m from nums.
+ * 2. Remove the selected element m from the array.
+ * 3. Add a new element with a value of m + 1 to the array.
+ * 4. Increase your score by m.
+ *
+ * Return the maximum score you can achieve after performing the operation exactly k times.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @return {number}
+ */
+var maximizeSum = function(nums, k) {
+  return k * Math.max(...nums) + k * (k - 1) / 2;
+};
diff --git a/solutions/2670-find-the-distinct-difference-array.js b/solutions/2670-find-the-distinct-difference-array.js
new file mode 100644
index 00000000..fc3ddaea
--- /dev/null
+++ b/solutions/2670-find-the-distinct-difference-array.js
@@ -0,0 +1,46 @@
+/**
+ * 2670. Find the Distinct Difference Array
+ * https://leetcode.com/problems/find-the-distinct-difference-array/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed array nums of length n.
+ *
+ * The distinct difference array of nums is an array diff of length n such that diff[i] is
+ * equal to the number of distinct elements in the suffix nums[i + 1, ..., n - 1] subtracted
+ * from the number of distinct elements in the prefix nums[0, ..., i].
+ *
+ * Return the distinct difference array of nums.
+ *
+ * Note that nums[i, ..., j] denotes the subarray of nums starting at index i and ending at
+ * index j inclusive. Particularly, if i > j then nums[i, ..., j] denotes an empty subarray.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number[]}
+ */
+var distinctDifferenceArray = function(nums) {
+  const n = nums.length;
+  const result = new Array(n);
+  const prefixSet = new Set();
+  const suffixCount = new Map();
+
+  for (const num of nums) {
+    suffixCount.set(num, (suffixCount.get(num) || 0) + 1);
+  }
+
+  let suffixDistinct = suffixCount.size;
+
+  for (let i = 0; i < n; i++) {
+    prefixSet.add(nums[i]);
+    const count = suffixCount.get(nums[i]);
+    suffixCount.set(nums[i], count - 1);
+    if (count === 1) {
+      suffixCount.delete(nums[i]);
+      suffixDistinct--;
+    }
+    result[i] = prefixSet.size - suffixDistinct;
+  }
+
+  return result;
+};
diff --git a/solutions/2672-number-of-adjacent-elements-with-the-same-color.js b/solutions/2672-number-of-adjacent-elements-with-the-same-color.js
new file mode 100644
index 00000000..257d4270
--- /dev/null
+++ b/solutions/2672-number-of-adjacent-elements-with-the-same-color.js
@@ -0,0 +1,44 @@
+/**
+ * 2672. Number of Adjacent Elements With the Same Color
+ * https://leetcode.com/problems/number-of-adjacent-elements-with-the-same-color/
+ * Difficulty: Medium
+ *
+ * You are given an integer n representing an array colors of length n where all elements
+ * are set to 0's meaning uncolored. You are also given a 2D integer array queries where
+ * queries[i] = [indexi, colori]. For the ith query:
+ * - Set colors[indexi] to colori.
+ * - Count the number of adjacent pairs in colors which have the same color (regardless of colori).
+ *
+ * Return an array answer of the same length as queries where answer[i] is the answer to the ith
+ * query.
+ */
+
+/**
+ * @param {number} n
+ * @param {number[][]} queries
+ * @return {number[]}
+ */
+var colorTheArray = function(n, queries) {
+  const colors = new Array(n).fill(0);
+  const result = new Array(queries.length).fill(0);
+  let sameColorPairs = 0;
+
+  for (let i = 0; i < queries.length; i++) {
+    const [index, color] = queries[i];
+    const prevColor = colors[index];
+
+    if (prevColor !== 0) {
+      if (index > 0 && colors[index - 1] === prevColor) sameColorPairs--;
+      if (index < n - 1 && colors[index + 1] === prevColor) sameColorPairs--;
+    }
+
+    colors[index] = color;
+
+    if (index > 0 && colors[index - 1] === color) sameColorPairs++;
+    if (index < n - 1 && colors[index + 1] === color) sameColorPairs++;
+
+    result[i] = sameColorPairs;
+  }
+
+  return result;
+};
diff --git a/solutions/2673-make-costs-of-paths-equal-in-a-binary-tree.js b/solutions/2673-make-costs-of-paths-equal-in-a-binary-tree.js
new file mode 100644
index 00000000..7d60cdb5
--- /dev/null
+++ b/solutions/2673-make-costs-of-paths-equal-in-a-binary-tree.js
@@ -0,0 +1,41 @@
+/**
+ * 2673. Make Costs of Paths Equal in a Binary Tree
+ * https://leetcode.com/problems/make-costs-of-paths-equal-in-a-binary-tree/
+ * Difficulty: Medium
+ *
+ * You are given an integer n representing the number of nodes in a perfect binary tree consisting
+ * of nodes numbered from 1 to n. The root of the tree is node 1 and each node i in the tree has
+ * two children where the left child is the node 2 * i and the right child is 2 * i + 1.
+ *
+ * Each node in the tree also has a cost represented by a given 0-indexed integer array cost of
+ * size n where cost[i] is the cost of node i + 1. You are allowed to increment the cost of any
+ * node by 1 any number of times.
+ *
+ * Return the minimum number of increments you need to make the cost of paths from the root to
+ * each leaf node equal.
+ *
+ * Note:
+ * - A perfect binary tree is a tree where each node, except the leaf nodes, has exactly 2 children.
+ * - The cost of a path is the sum of costs of nodes in the path.
+ */
+
+/**
+ * @param {number} n
+ * @param {number[]} cost
+ * @return {number}
+ */
+var minIncrements = function(n, cost) {
+  let result = 0;
+
+  for (let i = Math.floor(n / 2) - 1; i >= 0; i--) {
+    const left = 2 * i + 1;
+    const right = 2 * i + 2;
+    if (left < n && right < n) {
+      const maxChildCost = Math.max(cost[left], cost[right]);
+      result += maxChildCost - cost[left] + maxChildCost - cost[right];
+      cost[i] += maxChildCost;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2676-throttle.js b/solutions/2676-throttle.js
new file mode 100644
index 00000000..a17f27b2
--- /dev/null
+++ b/solutions/2676-throttle.js
@@ -0,0 +1,55 @@
+/**
+ * 2676. Throttle
+ * https://leetcode.com/problems/throttle/
+ * Difficulty: Medium
+ *
+ * Given a function fn and a time in milliseconds t, return a throttled version of that
+ * function.
+ *
+ * A throttled function is first called without delay and then, for a time interval of
+ * t milliseconds, can't be executed but should store the latest function arguments provided
+ * to call fn with them after the end of the delay.
+ *
+ * For instance, t = 50ms, and the function was called at 30ms, 40ms, and 60ms.
+ *
+ * At 30ms, without delay, the throttled function fn should be called with the arguments,
+ * and calling the throttled function fn should be blocked for the following t milliseconds.
+ *
+ * At 40ms, the function should just save arguments.
+ *
+ * At 60ms, arguments should overwrite currently stored arguments from the second call because
+ * the second and third calls are made before 80ms. Once the delay has passed, the throttled
+ * function fn should be called with the latest arguments provided during the delay period,
+ * and it should also create another delay period of 80ms + t.
+ */
+
+/**
+ * @param {Function} fn
+ * @param {number} t
+ * @return {Function}
+ */
+var throttle = function(fn, t) {
+  let isThrottled = false;
+  let nextArgs = null;
+
+  function invoke() {
+    if (nextArgs) {
+      fn(...nextArgs);
+      nextArgs = null;
+      setTimeout(invoke, t);
+    } else {
+      isThrottled = false;
+    }
+  }
+
+  return function(...args) {
+    if (isThrottled) {
+      nextArgs = args;
+      return;
+    }
+
+    fn(...args);
+    isThrottled = true;
+    setTimeout(invoke, t);
+  };
+};
diff --git a/solutions/2678-number-of-senior-citizens.js b/solutions/2678-number-of-senior-citizens.js
new file mode 100644
index 00000000..7c599c9f
--- /dev/null
+++ b/solutions/2678-number-of-senior-citizens.js
@@ -0,0 +1,30 @@
+/**
+ * 2678. Number of Senior Citizens
+ * https://leetcode.com/problems/number-of-senior-citizens/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed array of strings details. Each element of details provides
+ * information about a given passenger compressed into a string of length 15. The system
+ * is such that:
+ * - The first ten characters consist of the phone number of passengers.
+ * - The next character denotes the gender of the person.
+ * - The following two characters are used to indicate the age of the person.
+ * - The last two characters determine the seat allotted to that person.
+ *
+ * Return the number of passengers who are strictly more than 60 years old.
+ */
+
+/**
+ * @param {string[]} details
+ * @return {number}
+ */
+var countSeniors = function(details) {
+  let result = 0;
+
+  for (const detail of details) {
+    const age = parseInt(detail.slice(11, 13));
+    if (age > 60) result++;
+  }
+
+  return result;
+};
diff --git a/solutions/2680-maximum-or.js b/solutions/2680-maximum-or.js
new file mode 100644
index 00000000..fb53a9c9
--- /dev/null
+++ b/solutions/2680-maximum-or.js
@@ -0,0 +1,41 @@
+/**
+ * 2680. Maximum OR
+ * https://leetcode.com/problems/maximum-or/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed integer array nums of length n and an integer k. In an operation,
+ * you can choose an element and multiply it by 2.
+ *
+ * Return the maximum possible value of nums[0] | nums[1] | ... | nums[n - 1] that can be obtained
+ * after applying the operation on nums at most k times.
+ *
+ * Note that a | b denotes the bitwise or between two integers a and b.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @return {number}
+ */
+var maximumOr = function(nums, k) {
+  const n = nums.length;
+  const prefixOr = new Array(n + 1).fill(0n);
+  const suffixOr = new Array(n + 1).fill(0n);
+
+  for (let i = 0; i < n; i++) {
+    prefixOr[i + 1] = prefixOr[i] | BigInt(nums[i]);
+  }
+
+  for (let i = n - 1; i >= 0; i--) {
+    suffixOr[i] = suffixOr[i + 1] | BigInt(nums[i]);
+  }
+
+  let maxOr = 0n;
+  for (let i = 0; i < n; i++) {
+    maxOr = maxOr > (prefixOr[i] | (BigInt(nums[i]) << BigInt(k)) | suffixOr[i + 1])
+      ? maxOr
+      : (prefixOr[i] | (BigInt(nums[i]) << BigInt(k)) | suffixOr[i + 1]);
+  }
+
+  return Number(maxOr);
+};
diff --git a/solutions/2682-find-the-losers-of-the-circular-game.js b/solutions/2682-find-the-losers-of-the-circular-game.js
new file mode 100644
index 00000000..8536fa0b
--- /dev/null
+++ b/solutions/2682-find-the-losers-of-the-circular-game.js
@@ -0,0 +1,56 @@
+/**
+ * 2682. Find the Losers of the Circular Game
+ * https://leetcode.com/problems/find-the-losers-of-the-circular-game/
+ * Difficulty: Easy
+ *
+ * There are n friends that are playing a game. The friends are sitting in a circle and are numbered
+ * from 1 to n in clockwise order. More formally, moving clockwise from the ith friend brings you to
+ * the (i+1)th friend for 1 <= i < n, and moving clockwise from the nth friend brings you to the 1st
+ * friend.
+ *
+ * The rules of the game are as follows:
+ *
+ * 1st friend receives the ball.
+ * - After that, 1st friend passes it to the friend who is k steps away from them in the clockwise
+ *   direction.
+ * - After that, the friend who receives the ball should pass it to the friend who is 2 * k steps
+ *   away from them in the clockwise direction.
+ * - After that, the friend who receives the ball should pass it to the friend who is 3 * k steps
+ *   away from them in the clockwise direction, and so on and so forth.
+ *
+ * In other words, on the ith turn, the friend holding the ball should pass it to the friend who
+ * is i * k steps away from them in the clockwise direction.
+ *
+ * The game is finished when some friend receives the ball for the second time.
+ *
+ * The losers of the game are friends who did not receive the ball in the entire game.
+ *
+ * Given the number of friends, n, and an integer k, return the array answer, which contains the
+ * losers of the game in the ascending order.
+ */
+
+/**
+ * @param {number} n
+ * @param {number} k
+ * @return {number[]}
+ */
+var circularGameLosers = function(n, k) {
+  const visited = new Set();
+  let current = 0;
+  let step = 1;
+
+  while (!visited.has(current)) {
+    visited.add(current);
+    current = (current + step * k) % n;
+    step++;
+  }
+
+  const result = [];
+  for (let i = 0; i < n; i++) {
+    if (!visited.has(i)) {
+      result.push(i + 1);
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2684-maximum-number-of-moves-in-a-grid.js b/solutions/2684-maximum-number-of-moves-in-a-grid.js
new file mode 100644
index 00000000..65b4464f
--- /dev/null
+++ b/solutions/2684-maximum-number-of-moves-in-a-grid.js
@@ -0,0 +1,53 @@
+/**
+ * 2684. Maximum Number of Moves in a Grid
+ * https://leetcode.com/problems/maximum-number-of-moves-in-a-grid/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed m x n matrix grid consisting of positive integers.
+ *
+ * You can start at any cell in the first column of the matrix, and traverse the grid in the
+ * following way:
+ * - From a cell (row, col), you can move to any of the cells: (row - 1, col + 1), (row, col + 1)
+ *   and (row + 1, col + 1) such that the value of the cell you move to, should be strictly bigger
+ *   than the value of the current cell.
+ *
+ * Return the maximum number of moves that you can perform.
+ */
+
+/**
+ * @param {number[][]} grid
+ * @return {number}
+ */
+var maxMoves = function(grid) {
+  const rows = grid.length;
+  const cols = grid[0].length;
+  const memo = Array.from({ length: rows }, () => new Array(cols).fill(-1));
+
+  let result = 0;
+  for (let row = 0; row < rows; row++) {
+    result = Math.max(result, explore(row, 0));
+  }
+
+  return result;
+
+  function explore(row, col) {
+    if (col === cols - 1) return 0;
+    if (memo[row][col] !== -1) return memo[row][col];
+
+    let maxSteps = 0;
+    const current = grid[row][col];
+
+    if (row > 0 && col + 1 < cols && grid[row - 1][col + 1] > current) {
+      maxSteps = Math.max(maxSteps, 1 + explore(row - 1, col + 1));
+    }
+    if (col + 1 < cols && grid[row][col + 1] > current) {
+      maxSteps = Math.max(maxSteps, 1 + explore(row, col + 1));
+    }
+    if (row + 1 < rows && col + 1 < cols && grid[row + 1][col + 1] > current) {
+      maxSteps = Math.max(maxSteps, 1 + explore(row + 1, col + 1));
+    }
+
+    memo[row][col] = maxSteps;
+    return maxSteps;
+  }
+};
diff --git a/solutions/2696-minimum-string-length-after-removing-substrings.js b/solutions/2696-minimum-string-length-after-removing-substrings.js
new file mode 100644
index 00000000..de51fb8f
--- /dev/null
+++ b/solutions/2696-minimum-string-length-after-removing-substrings.js
@@ -0,0 +1,34 @@
+/**
+ * 2696. Minimum String Length After Removing Substrings
+ * https://leetcode.com/problems/minimum-string-length-after-removing-substrings/
+ * Difficulty: Easy
+ *
+ * You are given a string s consisting only of uppercase English letters.
+ *
+ * You can apply some operations to this string where, in one operation, you can remove any
+ * occurrence of one of the substrings "AB" or "CD" from s.
+ *
+ * Return the minimum possible length of the resulting string that you can obtain.
+ *
+ * Note that the string concatenates after removing the substring and could produce new "AB"
+ * or "CD" substrings.
+ */
+
+/**
+ * @param {string} s
+ * @return {number}
+ */
+var minLength = function(s) {
+  const stack = [];
+
+  for (const char of s) {
+    if (stack.length && ((stack[stack.length - 1] === 'A' && char === 'B')
+        || (stack[stack.length - 1] === 'C' && char === 'D'))) {
+      stack.pop();
+    } else {
+      stack.push(char);
+    }
+  }
+
+  return stack.length;
+};
diff --git a/solutions/2697-lexicographically-smallest-palindrome.js b/solutions/2697-lexicographically-smallest-palindrome.js
new file mode 100644
index 00000000..2489eb32
--- /dev/null
+++ b/solutions/2697-lexicographically-smallest-palindrome.js
@@ -0,0 +1,39 @@
+/**
+ * 2697. Lexicographically Smallest Palindrome
+ * https://leetcode.com/problems/lexicographically-smallest-palindrome/
+ * Difficulty: Easy
+ *
+ * You are given a string s consisting of lowercase English letters, and you are allowed to
+ * perform operations on it. In one operation, you can replace a character in s with another
+ * lowercase English letter.
+ *
+ * Your task is to make s a palindrome with the minimum number of operations possible. If there
+ * are multiple palindromes that can be made using the minimum number of operations, make the
+ * lexicographically smallest one.
+ *
+ * A string a is lexicographically smaller than a string b (of the same length) if in the first
+ * position where a and b differ, string a has a letter that appears earlier in the alphabet
+ * than the corresponding letter in b.
+ *
+ * Return the resulting palindrome string.
+ */
+
+/**
+ * @param {string} s
+ * @return {string}
+ */
+var makeSmallestPalindrome = function(s) {
+  const chars = s.split('');
+  let left = 0;
+  let right = s.length - 1;
+
+  while (left < right) {
+    if (chars[left] !== chars[right]) {
+      chars[left] = chars[right] = chars[left] < chars[right] ? chars[left] : chars[right];
+    }
+    left++;
+    right--;
+  }
+
+  return chars.join('');
+};
diff --git a/solutions/2706-buy-two-chocolates.js b/solutions/2706-buy-two-chocolates.js
new file mode 100644
index 00000000..8c77f0e5
--- /dev/null
+++ b/solutions/2706-buy-two-chocolates.js
@@ -0,0 +1,28 @@
+/**
+ * 2706. Buy Two Chocolates
+ * https://leetcode.com/problems/buy-two-chocolates/
+ * Difficulty: Easy
+ *
+ * You are given an integer array prices representing the prices of various chocolates in
+ * a store. You are also given a single integer money, which represents your initial amount
+ * of money.
+ *
+ * You must buy exactly two chocolates in such a way that you still have some non-negative
+ * leftover money. You would like to minimize the sum of the prices of the two chocolates
+ * you buy.
+ *
+ * Return the amount of money you will have leftover after buying the two chocolates. If
+ * there is no way for you to buy two chocolates without ending up in debt, return money.
+ * Note that the leftover must be non-negative.
+ */
+
+/**
+ * @param {number[]} prices
+ * @param {number} money
+ * @return {number}
+ */
+var buyChoco = function(prices, money) {
+  prices.sort((a, b) => a - b);
+  const minCost = prices[0] + prices[1];
+  return minCost <= money ? money - minCost : money;
+};
diff --git a/solutions/2707-extra-characters-in-a-string.js b/solutions/2707-extra-characters-in-a-string.js
new file mode 100644
index 00000000..2d335169
--- /dev/null
+++ b/solutions/2707-extra-characters-in-a-string.js
@@ -0,0 +1,35 @@
+/**
+ * 2707. Extra Characters in a String
+ * https://leetcode.com/problems/extra-characters-in-a-string/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed string s and a dictionary of words dictionary. You have to break
+ * s into one or more non-overlapping substrings such that each substring is present in
+ * dictionary. There may be some extra characters in s which are not present in any of the
+ * substrings.
+ *
+ * Return the minimum number of extra characters left over if you break up s optimally.
+ */
+
+/**
+ * @param {string} s
+ * @param {string[]} dictionary
+ * @return {number}
+ */
+var minExtraChar = function(s, dictionary) {
+  const n = s.length;
+  const dp = new Array(n + 1).fill(Infinity);
+  dp[0] = 0;
+  const dictSet = new Set(dictionary);
+
+  for (let i = 1; i <= n; i++) {
+    dp[i] = dp[i - 1] + 1;
+    for (let j = 0; j < i; j++) {
+      if (dictSet.has(s.slice(j, i))) {
+        dp[i] = Math.min(dp[i], dp[j]);
+      }
+    }
+  }
+
+  return dp[n];
+};
diff --git a/solutions/2709-greatest-common-divisor-traversal.js b/solutions/2709-greatest-common-divisor-traversal.js
new file mode 100644
index 00000000..0db68ad2
--- /dev/null
+++ b/solutions/2709-greatest-common-divisor-traversal.js
@@ -0,0 +1,79 @@
+/**
+ * 2709. Greatest Common Divisor Traversal
+ * https://leetcode.com/problems/greatest-common-divisor-traversal/
+ * Difficulty: Hard
+ *
+ * You are given a 0-indexed integer array nums, and you are allowed to traverse between its
+ * indices. You can traverse between index i and index j, i != j, if and only if gcd(nums[i],
+ * nums[j]) > 1, where gcd is the greatest common divisor.
+ *
+ * Your task is to determine if for every pair of indices i and j in nums, where i < j, there
+ * exists a sequence of traversals that can take us from i to j.
+ *
+ * Return true if it is possible to traverse between all such pairs of indices, or false otherwise.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {boolean}
+ */
+var canTraverseAllPairs = function(nums) {
+  if (nums.length === 1) return true;
+  const n = nums.length;
+  const maxNum = Math.max(...nums);
+  const parent = new Array(maxNum + 1).fill().map((_, i) => i);
+  const rank = new Array(maxNum + 1).fill(0);
+
+  const primeToIndex = new Map();
+  for (let i = 0; i < n; i++) {
+    if (nums[i] === 1) return false;
+    const factors = getPrimeFactors(nums[i]);
+    for (const prime of factors) {
+      if (primeToIndex.has(prime)) {
+        union(primeToIndex.get(prime), i);
+      } else {
+        primeToIndex.set(prime, i);
+      }
+    }
+  }
+
+  const root = find(0);
+  for (let i = 1; i < n; i++) {
+    if (find(i) !== root) return false;
+  }
+
+  return true;
+
+  function find(x) {
+    if (parent[x] !== x) {
+      parent[x] = find(parent[x]);
+    }
+    return parent[x];
+  }
+
+  function union(x, y) {
+    const px = find(x);
+    const py = find(y);
+    if (px === py) return;
+    if (rank[px] < rank[py]) {
+      parent[px] = py;
+    } else if (rank[px] > rank[py]) {
+      parent[py] = px;
+    } else {
+      parent[py] = px;
+      rank[px]++;
+    }
+  }
+
+  function getPrimeFactors(num) {
+    const factors = [];
+    for (let i = 2; i * i <= num; i++) {
+      if (num % i === 0) {
+        factors.push(i);
+        while (num % i === 0) num /= i;
+      }
+    }
+    if (num > 1) factors.push(num);
+    return factors;
+  }
+};
diff --git a/solutions/2710-remove-trailing-zeros-from-a-string.js b/solutions/2710-remove-trailing-zeros-from-a-string.js
new file mode 100644
index 00000000..217d4552
--- /dev/null
+++ b/solutions/2710-remove-trailing-zeros-from-a-string.js
@@ -0,0 +1,16 @@
+/**
+ * 2710. Remove Trailing Zeros From a String
+ * https://leetcode.com/problems/remove-trailing-zeros-from-a-string/
+ * Difficulty: Easy
+ *
+ * Given a positive integer num represented as a string, return the integer num without
+ * trailing zeros as a string.
+ */
+
+/**
+ * @param {string} num
+ * @return {string}
+ */
+var removeTrailingZeros = function(num) {
+  return num.replace(/0+$/g, '');
+};
diff --git a/solutions/2711-difference-of-number-of-distinct-values-on-diagonals.js b/solutions/2711-difference-of-number-of-distinct-values-on-diagonals.js
new file mode 100644
index 00000000..86d12ee8
--- /dev/null
+++ b/solutions/2711-difference-of-number-of-distinct-values-on-diagonals.js
@@ -0,0 +1,55 @@
+/**
+ * 2711. Difference of Number of Distinct Values on Diagonals
+ * https://leetcode.com/problems/difference-of-number-of-distinct-values-on-diagonals/
+ * Difficulty: Medium
+ *
+ * Given a 2D grid of size m x n, you should find the matrix answer of size m x n.
+ *
+ * The cell answer[r][c] is calculated by looking at the diagonal values of the cell grid[r][c]:
+ * - Let leftAbove[r][c] be the number of distinct values on the diagonal to the left and above
+ *   the cell grid[r][c] not including the cell grid[r][c] itself.
+ * - Let rightBelow[r][c] be the number of distinct values on the diagonal to the right and below
+ *   the cell grid[r][c], not including the cell grid[r][c] itself.
+ * - Then answer[r][c] = |leftAbove[r][c] - rightBelow[r][c]|.
+ *
+ * A matrix diagonal is a diagonal line of cells starting from some cell in either the topmost
+ * row or leftmost column and going in the bottom-right direction until the end of the matrix
+ * is reached.
+ *
+ * - For example, in the below diagram the diagonal is highlighted using the cell with indices
+ *   (2, 3) colored gray:
+ *   - Red-colored cells are left and above the cell.
+ *   - Blue-colored cells are right and below the cell.
+ */
+
+/**
+ * @param {number[][]} grid
+ * @return {number[][]}
+ */
+var differenceOfDistinctValues = function(grid) {
+  const rows = grid.length;
+  const cols = grid[0].length;
+  const result = Array.from({ length: rows }, () => new Array(cols).fill(0));
+
+  for (let r = 0; r < rows; r++) {
+    for (let c = 0; c < cols; c++) {
+      const leftAboveSet = new Set();
+      let i = r - 1;
+      let j = c - 1;
+      while (i >= 0 && j >= 0) {
+        leftAboveSet.add(grid[i--][j--]);
+      }
+
+      const rightBelowSet = new Set();
+      i = r + 1;
+      j = c + 1;
+      while (i < rows && j < cols) {
+        rightBelowSet.add(grid[i++][j++]);
+      }
+
+      result[r][c] = Math.abs(leftAboveSet.size - rightBelowSet.size);
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2712-minimum-cost-to-make-all-characters-equal.js b/solutions/2712-minimum-cost-to-make-all-characters-equal.js
new file mode 100644
index 00000000..bc70fa86
--- /dev/null
+++ b/solutions/2712-minimum-cost-to-make-all-characters-equal.js
@@ -0,0 +1,32 @@
+/**
+ * 2712. Minimum Cost to Make All Characters Equal
+ * https://leetcode.com/problems/minimum-cost-to-make-all-characters-equal/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed binary string s of length n on which you can apply two types
+ * of operations:
+ * - Choose an index i and invert all characters from index 0 to index i (both inclusive),
+ *   with a cost of i + 1
+ * - Choose an index i and invert all characters from index i to index n - 1 (both inclusive),
+ *   with a cost of n - i
+ *
+ * Return the minimum cost to make all characters of the string equal.
+ *
+ * Invert a character means if its value is '0' it becomes '1' and vice-versa.
+ */
+
+/**
+ * @param {string} s
+ * @return {number}
+ */
+var minimumCost = function(s) {
+  let result = 0;
+
+  for (let i = 1; i < s.length; i++) {
+    if (s[i] !== s[i - 1]) {
+      result += Math.min(i, s.length - i);
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2716-minimize-string-length.js b/solutions/2716-minimize-string-length.js
new file mode 100644
index 00000000..b16b102b
--- /dev/null
+++ b/solutions/2716-minimize-string-length.js
@@ -0,0 +1,23 @@
+/**
+ * 2716. Minimize String Length
+ * https://leetcode.com/problems/minimize-string-length/
+ * Difficulty: Easy
+ *
+ * Given a string s, you have two types of operation:
+ * 1. Choose an index i in the string, and let c be the character in position i. Delete the
+ *    closest occurrence of c to the left of i (if exists).
+ * 2. Choose an index i in the string, and let c be the character in position i. Delete the
+ *    closest occurrence of c to the right of i (if exists).
+ *
+ * Your task is to minimize the length of s by performing the above operations zero or more times.
+ *
+ * Return an integer denoting the length of the minimized string.
+ */
+
+/**
+ * @param {string} s
+ * @return {number}
+ */
+var minimizedStringLength = function(s) {
+  return new Set(s).size;
+};
diff --git a/solutions/2717-semi-ordered-permutation.js b/solutions/2717-semi-ordered-permutation.js
new file mode 100644
index 00000000..b1717e3c
--- /dev/null
+++ b/solutions/2717-semi-ordered-permutation.js
@@ -0,0 +1,33 @@
+/**
+ * 2717. Semi-Ordered Permutation
+ * https://leetcode.com/problems/semi-ordered-permutation/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed permutation of n integers nums.
+ *
+ * A permutation is called semi-ordered if the first number equals 1 and the last number equals n.
+ * You can perform the below operation as many times as you want until you make nums a semi-ordered
+ * permutation:
+ * - Pick two adjacent elements in nums, then swap them.
+ *
+ * Return the minimum number of operations to make nums a semi-ordered permutation.
+ *
+ * A permutation is a sequence of integers from 1 to n of length n containing each number exactly
+ * once.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var semiOrderedPermutation = function(nums) {
+  let oneIndex = 0;
+  let nIndex = 0;
+
+  for (let i = 0; i < nums.length; i++) {
+    if (nums[i] === 1) oneIndex = i;
+    if (nums[i] === nums.length) nIndex = i;
+  }
+
+  return oneIndex + (nums.length - 1 - nIndex) - (oneIndex > nIndex ? 1 : 0);
+};
diff --git a/solutions/2729-check-if-the-number-is-fascinating.js b/solutions/2729-check-if-the-number-is-fascinating.js
new file mode 100644
index 00000000..12537342
--- /dev/null
+++ b/solutions/2729-check-if-the-number-is-fascinating.js
@@ -0,0 +1,26 @@
+/**
+ * 2729. Check if The Number is Fascinating
+ * https://leetcode.com/problems/check-if-the-number-is-fascinating/
+ * Difficulty: Easy
+ *
+ * You are given an integer n that consists of exactly 3 digits.
+ *
+ * We call the number n fascinating if, after the following modification, the resulting number
+ * contains all the digits from 1 to 9 exactly once and does not contain any 0's:
+ * - Concatenate n with the numbers 2 * n and 3 * n.
+ *
+ * Return true if n is fascinating, or false otherwise.
+ *
+ * Concatenating two numbers means joining them together. For example, the concatenation of 121
+ * and 371 is 121371.
+ */
+
+/**
+ * @param {number} n
+ * @return {boolean}
+ */
+var isFascinating = function(n) {
+  const concatenated = `${n}${2 * n}${3 * n}`;
+  const digitSet = new Set(concatenated);
+  return concatenated.length === 9 && digitSet.size === 9 && !digitSet.has('0');
+};
diff --git a/solutions/2732-find-a-good-subset-of-the-matrix.js b/solutions/2732-find-a-good-subset-of-the-matrix.js
new file mode 100644
index 00000000..1e13f830
--- /dev/null
+++ b/solutions/2732-find-a-good-subset-of-the-matrix.js
@@ -0,0 +1,48 @@
+/**
+ * 2732. Find a Good Subset of the Matrix
+ * https://leetcode.com/problems/find-a-good-subset-of-the-matrix/
+ * Difficulty: Hard
+ *
+ * You are given a 0-indexed m x n binary matrix grid.
+ *
+ * Let us call a non-empty subset of rows good if the sum of each column of the subset is at
+ * most half of the length of the subset.
+ *
+ * More formally, if the length of the chosen subset of rows is k, then the sum of each column
+ * should be at most floor(k / 2).
+ *
+ * Return an integer array that contains row indices of a good subset sorted in ascending order.
+ *
+ * If there are multiple good subsets, you can return any of them. If there are no good subsets,
+ * return an empty array.
+ *
+ * A subset of rows of the matrix grid is any matrix that can be obtained by deleting some (possibly
+ * none or all) rows from grid.
+ */
+
+/**
+ * @param {number[][]} grid
+ * @return {number[]}
+ */
+var goodSubsetofBinaryMatrix = function(grid) {
+  const rows = grid.length;
+  const cols = grid[0].length;
+  const rowMasks = new Map();
+
+  for (let i = 0; i < rows; i++) {
+    let mask = 0;
+    for (let j = 0; j < cols; j++) {
+      mask |= grid[i][j] << j;
+    }
+    if (mask === 0) return [i];
+    rowMasks.set(mask, i);
+  }
+
+  for (const [mask1, i] of rowMasks) {
+    for (const [mask2, j] of rowMasks) {
+      if ((mask1 & mask2) === 0) return [Math.min(i, j), Math.max(i, j)];
+    }
+  }
+
+  return [];
+};
diff --git a/solutions/2733-neither-minimum-nor-maximum.js b/solutions/2733-neither-minimum-nor-maximum.js
new file mode 100644
index 00000000..4dcc9150
--- /dev/null
+++ b/solutions/2733-neither-minimum-nor-maximum.js
@@ -0,0 +1,27 @@
+/**
+ * 2733. Neither Minimum nor Maximum
+ * https://leetcode.com/problems/neither-minimum-nor-maximum/
+ * Difficulty: Easy
+ *
+ * Given an integer array nums containing distinct positive integers, find and return any
+ * number from the array that is neither the minimum nor the maximum value in the array,
+ * or -1 if there is no such number.
+ *
+ * Return the selected integer.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var findNonMinOrMax = function(nums) {
+  if (nums.length < 3) return -1;
+  const minVal = Math.min(nums[0], nums[1], nums[2]);
+  const maxVal = Math.max(nums[0], nums[1], nums[2]);
+
+  for (const num of [nums[0], nums[1], nums[2]]) {
+    if (num !== minVal && num !== maxVal) return num;
+  }
+
+  return -1;
+};
diff --git a/solutions/2739-total-distance-traveled.js b/solutions/2739-total-distance-traveled.js
new file mode 100644
index 00000000..2c2d593d
--- /dev/null
+++ b/solutions/2739-total-distance-traveled.js
@@ -0,0 +1,38 @@
+/**
+ * 2739. Total Distance Traveled
+ * https://leetcode.com/problems/total-distance-traveled/
+ * Difficulty: Easy
+ *
+ * A truck has two fuel tanks. You are given two integers, mainTank representing the fuel present
+ * in the main tank in liters and additionalTank representing the fuel present in the additional
+ * tank in liters.
+ *
+ * The truck has a mileage of 10 km per liter. Whenever 5 liters of fuel get used up in the main
+ * tank, if the additional tank has at least 1 liters of fuel, 1 liters of fuel will be transferred
+ * from the additional tank to the main tank.
+ *
+ * Return the maximum distance which can be traveled.
+ *
+ * Note: Injection from the additional tank is not continuous. It happens suddenly and immediately
+ * for every 5 liters consumed.
+ */
+
+/**
+ * @param {number} mainTank
+ * @param {number} additionalTank
+ * @return {number}
+ */
+var distanceTraveled = function(mainTank, additionalTank) {
+  let distance = 0;
+  let fuel = mainTank;
+
+  while (fuel >= 5 && additionalTank > 0) {
+    distance += 50;
+    fuel -= 5;
+    fuel += 1;
+    additionalTank -= 1;
+  }
+
+  distance += fuel * 10;
+  return distance;
+};
diff --git a/solutions/2740-find-the-value-of-the-partition.js b/solutions/2740-find-the-value-of-the-partition.js
new file mode 100644
index 00000000..8c1f661e
--- /dev/null
+++ b/solutions/2740-find-the-value-of-the-partition.js
@@ -0,0 +1,34 @@
+/**
+ * 2740. Find the Value of the Partition
+ * https://leetcode.com/problems/find-the-value-of-the-partition/
+ * Difficulty: Medium
+ *
+ * You are given a positive integer array nums.
+ *
+ * Partition nums into two arrays, nums1 and nums2, such that:
+ * - Each element of the array nums belongs to either the array nums1 or the array nums2.
+ * - Both arrays are non-empty.
+ * - The value of the partition is minimized.
+ *
+ * The value of the partition is |max(nums1) - min(nums2)|.
+ *
+ * Here, max(nums1) denotes the maximum element of the array nums1, and min(nums2) denotes the
+ * minimum element of the array nums2.
+ *
+ * Return the integer denoting the value of such partition.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var findValueOfPartition = function(nums) {
+  nums.sort((a, b) => a - b);
+  let result = Infinity;
+
+  for (let i = 1; i < nums.length; i++) {
+    result = Math.min(result, nums[i] - nums[i - 1]);
+  }
+
+  return result;
+};
diff --git a/solutions/2742-painting-the-walls.js b/solutions/2742-painting-the-walls.js
new file mode 100644
index 00000000..42275242
--- /dev/null
+++ b/solutions/2742-painting-the-walls.js
@@ -0,0 +1,38 @@
+/**
+ * 2742. Painting the Walls
+ * https://leetcode.com/problems/painting-the-walls/
+ * Difficulty: Hard
+ *
+ * You are given two 0-indexed integer arrays, cost and time, of size n representing the costs
+ * and the time taken to paint n different walls respectively. There are two painters available:
+ * - A paid painter that paints the ith wall in time[i] units of time and takes cost[i] units of
+ *   money.
+ * - A free painter that paints any wall in 1 unit of time at a cost of 0. But the free painter
+ *   can only be used if the paid painter is already occupied.
+ *
+ * Return the minimum amount of money required to paint the n walls.
+ */
+
+/**
+ * @param {number[]} cost
+ * @param {number[]} time
+ * @return {number}
+ */
+var paintWalls = function(cost, time) {
+  const n = cost.length;
+  const dp = new Array(n + 1).fill().map(() => new Array(n + 1).fill(Infinity));
+  dp[0][0] = 0;
+
+  for (let i = 0; i < n; i++) {
+    for (let j = 0; j <= n; j++) {
+      if (dp[i][j] === Infinity) continue;
+
+      dp[i + 1][j] = Math.min(dp[i + 1][j], dp[i][j]);
+
+      const walls = Math.min(n, j + time[i] + 1);
+      dp[i + 1][walls] = Math.min(dp[i + 1][walls], dp[i][j] + cost[i]);
+    }
+  }
+
+  return dp[n][n];
+};
diff --git a/solutions/2744-find-maximum-number-of-string-pairs.js b/solutions/2744-find-maximum-number-of-string-pairs.js
new file mode 100644
index 00000000..b8e9a4ac
--- /dev/null
+++ b/solutions/2744-find-maximum-number-of-string-pairs.js
@@ -0,0 +1,36 @@
+/**
+ * 2744. Find Maximum Number of String Pairs
+ * https://leetcode.com/problems/find-maximum-number-of-string-pairs/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed array words consisting of distinct strings.
+ *
+ * The string words[i] can be paired with the string words[j] if:
+ * - The string words[i] is equal to the reversed string of words[j].
+ * - 0 <= i < j < words.length.
+ *
+ * Return the maximum number of pairs that can be formed from the array words.
+ *
+ * Note that each string can belong in at most one pair.
+ */
+
+/**
+ * @param {string[]} words
+ * @return {number}
+ */
+var maximumNumberOfStringPairs = function(words) {
+  const set = new Set();
+  let result = 0;
+
+  for (const word of words) {
+    const reversed = word[1] + word[0];
+    if (set.has(reversed)) {
+      result++;
+      set.delete(reversed);
+    } else {
+      set.add(word);
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2745-construct-the-longest-new-string.js b/solutions/2745-construct-the-longest-new-string.js
new file mode 100644
index 00000000..c5014fa7
--- /dev/null
+++ b/solutions/2745-construct-the-longest-new-string.js
@@ -0,0 +1,26 @@
+/**
+ * 2745. Construct the Longest New String
+ * https://leetcode.com/problems/construct-the-longest-new-string/
+ * Difficulty: Medium
+ *
+ * You are given three integers x, y, and z.
+ *
+ * You have x strings equal to "AA", y strings equal to "BB", and z strings equal to "AB". You
+ * want to choose some (possibly all or none) of these strings and concatenate them in some order
+ * to form a new string. This new string must not contain "AAA" or "BBB" as a substring.
+ *
+ * Return the maximum possible length of the new string.
+ *
+ * A substring is a contiguous non-empty sequence of characters within a string.
+ */
+
+/**
+ * @param {number} x
+ * @param {number} y
+ * @param {number} z
+ * @return {number}
+ */
+var longestString = function(x, y, z) {
+  const minPairs = Math.min(x, y);
+  return 2 * (minPairs * 2 + (x > minPairs ? 1 : 0) + (y > minPairs ? 1 : 0) + z);
+};
diff --git a/solutions/2748-number-of-beautiful-pairs.js b/solutions/2748-number-of-beautiful-pairs.js
new file mode 100644
index 00000000..28e7a52f
--- /dev/null
+++ b/solutions/2748-number-of-beautiful-pairs.js
@@ -0,0 +1,53 @@
+/**
+ * 2748. Number of Beautiful Pairs
+ * https://leetcode.com/problems/number-of-beautiful-pairs/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed integer array nums. A pair of indices i, j where
+ * 0 <= i < j < nums.length is called beautiful if the first digit of nums[i] and
+ * the last digit of nums[j] are coprime.
+ *
+ * Return the total number of beautiful pairs in nums.
+ *
+ * Two integers x and y are coprime if there is no integer greater than 1 that divides
+ * both of them. In other words, x and y are coprime if gcd(x, y) == 1, where gcd(x, y)
+ * is the greatest common divisor of x and y.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var countBeautifulPairs = function(nums) {
+  let result = 0;
+  for (let i = 0; i < nums.length - 1; i++) {
+    for (let j = i + 1; j < nums.length; j++) {
+      const first = getFirstDigit(nums[i]);
+      const last = getLastDigit(nums[j]);
+      if (gcd(first, last) === 1) {
+        result++;
+      }
+    }
+  }
+
+  return result;
+
+  function gcd(a, b) {
+    while (b) {
+      a %= b;
+      [a, b] = [b, a];
+    }
+    return a;
+  }
+
+  function getFirstDigit(num) {
+    while (num >= 10) {
+      num = Math.floor(num / 10);
+    }
+    return num;
+  }
+
+  function getLastDigit(num) {
+    return num % 10;
+  }
+};
diff --git a/solutions/2751-robot-collisions.js b/solutions/2751-robot-collisions.js
new file mode 100644
index 00000000..53149178
--- /dev/null
+++ b/solutions/2751-robot-collisions.js
@@ -0,0 +1,76 @@
+/**
+ * 2751. Robot Collisions
+ * https://leetcode.com/problems/robot-collisions/
+ * Difficulty: Hard
+ *
+ * There are n 1-indexed robots, each having a position on a line, health, and movement direction.
+ *
+ * You are given 0-indexed integer arrays positions, healths, and a string directions (directions[i]
+ * is either 'L' for left or 'R' for right). All integers in positions are unique.
+ *
+ * All robots start moving on the line simultaneously at the same speed in their given directions.
+ * If two robots ever share the same position while moving, they will collide.
+ *
+ * If two robots collide, the robot with lower health is removed from the line, and the health of
+ * the other robot decreases by one. The surviving robot continues in the same direction it was
+ * going. If both robots have the same health, they are both removed from the line.
+ *
+ * Your task is to determine the health of the robots that survive the collisions, in the same
+ * order that the robots were given, i.e. final health of robot 1 (if survived), final health
+ * of robot 2 (if survived), and so on. If there are no survivors, return an empty array.
+ *
+ * Return an array containing the health of the remaining robots (in the order they were given
+ * in the input), after no further collisions can occur.
+ *
+ * Note: The positions may be unsorted.
+ */
+
+/**
+ * @param {number[]} positions
+ * @param {number[]} healths
+ * @param {string} directions
+ * @return {number[]}
+ */
+var survivedRobotsHealths = function(positions, healths, directions) {
+  const n = positions.length;
+  const robots = Array.from({ length: n }, (_, i) => ({
+    index: i,
+    position: positions[i],
+    health: healths[i],
+    direction: directions[i]
+  }));
+
+  robots.sort((a, b) => a.position - b.position);
+
+  const stack = [];
+  for (const robot of robots) {
+    if (robot.direction === 'R') {
+      stack.push(robot);
+      continue;
+    }
+
+    while (stack.length && stack[stack.length - 1].direction === 'R' && robot.health > 0) {
+      const last = stack[stack.length - 1];
+      if (last.health === robot.health) {
+        stack.pop();
+        robot.health = 0;
+      } else if (last.health > robot.health) {
+        last.health--;
+        robot.health = 0;
+      } else {
+        stack.pop();
+        robot.health--;
+      }
+    }
+    if (robot.health > 0) {
+      stack.push(robot);
+    }
+  }
+
+  const result = new Array(n).fill(0);
+  for (const robot of stack) {
+    result[robot.index] = robot.health;
+  }
+
+  return result.filter(health => health > 0);
+};
diff --git a/solutions/2763-sum-of-imbalance-numbers-of-all-subarrays.js b/solutions/2763-sum-of-imbalance-numbers-of-all-subarrays.js
new file mode 100644
index 00000000..5d7ba4ed
--- /dev/null
+++ b/solutions/2763-sum-of-imbalance-numbers-of-all-subarrays.js
@@ -0,0 +1,51 @@
+/**
+ * 2763. Sum of Imbalance Numbers of All Subarrays
+ * https://leetcode.com/problems/sum-of-imbalance-numbers-of-all-subarrays/
+ * Difficulty: Hard
+ *
+ * The imbalance number of a 0-indexed integer array arr of length n is defined as the number
+ * of indices in sarr = sorted(arr) such that:
+ * - 0 <= i < n - 1, and
+ * - sarr[i+1] - sarr[i] > 1
+ *
+ * Here, sorted(arr) is the function that returns the sorted version of arr.
+ *
+ * Given a 0-indexed integer array nums, return the sum of imbalance numbers of all its subarrays.
+ *
+ * A subarray is a contiguous non-empty sequence of elements within an array.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var sumImbalanceNumbers = function(nums) {
+  const n = nums.length;
+  let result = 0;
+
+  for (let i = 0; i < n; i++) {
+    const seen = new Set();
+    let imbalance = 0;
+
+    for (let j = i; j < n; j++) {
+      const current = nums[j];
+
+      if (!seen.has(current)) {
+        const hasNext = seen.has(current + 1);
+        const hasPrev = seen.has(current - 1);
+
+        if (hasNext && hasPrev) {
+          imbalance--;
+        } else if (!hasNext && !hasPrev && seen.size > 0) {
+          imbalance++;
+        }
+
+        seen.add(current);
+      }
+
+      result += imbalance;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2766-relocate-marbles.js b/solutions/2766-relocate-marbles.js
new file mode 100644
index 00000000..08d51e6f
--- /dev/null
+++ b/solutions/2766-relocate-marbles.js
@@ -0,0 +1,34 @@
+/**
+ * 2766. Relocate Marbles
+ * https://leetcode.com/problems/relocate-marbles/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed integer array nums representing the initial positions of some
+ * marbles. You are also given two 0-indexed integer arrays moveFrom and moveTo of equal length.
+ *
+ * Throughout moveFrom.length steps, you will change the positions of the marbles. On the ith
+ * step, you will move all marbles at position moveFrom[i] to position moveTo[i].
+ *
+ * After completing all the steps, return the sorted list of occupied positions.
+ *
+ * Notes:
+ * - We call a position occupied if there is at least one marble in that position.
+ * - There may be multiple marbles in a single position.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number[]} moveFrom
+ * @param {number[]} moveTo
+ * @return {number[]}
+ */
+var relocateMarbles = function(nums, moveFrom, moveTo) {
+  const set = new Set(nums);
+
+  for (let i = 0; i < moveFrom.length; i++) {
+    set.delete(moveFrom[i]);
+    set.add(moveTo[i]);
+  }
+
+  return [...set].sort((a, b) => a - b);
+};
diff --git a/solutions/2767-partition-string-into-minimum-beautiful-substrings.js b/solutions/2767-partition-string-into-minimum-beautiful-substrings.js
new file mode 100644
index 00000000..45e5b024
--- /dev/null
+++ b/solutions/2767-partition-string-into-minimum-beautiful-substrings.js
@@ -0,0 +1,52 @@
+/**
+ * 2767. Partition String Into Minimum Beautiful Substrings
+ * https://leetcode.com/problems/partition-string-into-minimum-beautiful-substrings/
+ * Difficulty: Medium
+ *
+ * Given a binary string s, partition the string into one or more substrings such that each
+ * substring is beautiful.
+ *
+ * A string is beautiful if:
+ * - It doesn't contain leading zeros.
+ * - It's the binary representation of a number that is a power of 5.
+ *
+ * Return the minimum number of substrings in such partition. If it is impossible to partition
+ * the string s into beautiful substrings, return -1.
+ *
+ * A substring is a contiguous sequence of characters in a string.
+ */
+
+/**
+ * @param {string} s
+ * @return {number}
+ */
+var minimumBeautifulSubstrings = function(s) {
+  const n = s.length;
+  const powersOfFive = new Set();
+  let power = 1;
+  while (power.toString(2).length <= n) {
+    powersOfFive.add(power.toString(2));
+    power *= 5;
+  }
+
+  const result = findMinPartitions(0);
+  return result === Infinity ? -1 : result;
+
+  function findMinPartitions(index) {
+    if (index === n) return 0;
+    if (s[index] === '0') return Infinity;
+
+    let minPartitions = Infinity;
+    for (let end = index + 1; end <= n; end++) {
+      const substring = s.slice(index, end);
+      if (powersOfFive.has(substring)) {
+        const next = findMinPartitions(end);
+        if (next !== Infinity) {
+          minPartitions = Math.min(minPartitions, 1 + next);
+        }
+      }
+    }
+
+    return minPartitions;
+  }
+};
diff --git a/solutions/2769-find-the-maximum-achievable-number.js b/solutions/2769-find-the-maximum-achievable-number.js
new file mode 100644
index 00000000..cfd60aeb
--- /dev/null
+++ b/solutions/2769-find-the-maximum-achievable-number.js
@@ -0,0 +1,20 @@
+/**
+ * 2769. Find the Maximum Achievable Number
+ * https://leetcode.com/problems/find-the-maximum-achievable-number/
+ * Difficulty: Easy
+ *
+ * Given two integers, num and t. A number x is achievable if it can become equal to num
+ * after applying the following operation at most t times:
+ * - Increase or decrease x by 1, and simultaneously increase or decrease num by 1.
+ *
+ * Return the maximum possible value of x.
+ */
+
+/**
+ * @param {number} num
+ * @param {number} t
+ * @return {number}
+ */
+var theMaximumAchievableX = function(num, t) {
+  return num + 2 * t;
+};
diff --git a/solutions/2778-sum-of-squares-of-special-elements.js b/solutions/2778-sum-of-squares-of-special-elements.js
new file mode 100644
index 00000000..fbac7766
--- /dev/null
+++ b/solutions/2778-sum-of-squares-of-special-elements.js
@@ -0,0 +1,28 @@
+/**
+ * 2778. Sum of Squares of Special Elements
+ * https://leetcode.com/problems/sum-of-squares-of-special-elements/
+ * Difficulty: Easy
+ *
+ * You are given a 1-indexed integer array nums of length n.
+ *
+ * An element nums[i] of nums is called special if i divides n, i.e. n % i == 0.
+ *
+ * Return the sum of the squares of all special elements of nums.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var sumOfSquares = function(nums) {
+  const n = nums.length;
+  let total = 0;
+
+  for (let i = 1; i <= n; i++) {
+    if (n % i === 0) {
+      total += nums[i - 1] * nums[i - 1];
+    }
+  }
+
+  return total;
+};
diff --git a/solutions/2779-maximum-beauty-of-an-array-after-applying-operation.js b/solutions/2779-maximum-beauty-of-an-array-after-applying-operation.js
new file mode 100644
index 00000000..1015482b
--- /dev/null
+++ b/solutions/2779-maximum-beauty-of-an-array-after-applying-operation.js
@@ -0,0 +1,41 @@
+/**
+ * 2779. Maximum Beauty of an Array After Applying Operation
+ * https://leetcode.com/problems/maximum-beauty-of-an-array-after-applying-operation/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed array nums and a non-negative integer k.
+ *
+ * In one operation, you can do the following:
+ * - Choose an index i that hasn't been chosen before from the range [0, nums.length - 1].
+ * - Replace nums[i] with any integer from the range [nums[i] - k, nums[i] + k].
+ *
+ * The beauty of the array is the length of the longest subsequence consisting of equal elements.
+ *
+ * Return the maximum possible beauty of the array nums after applying the operation any number
+ * of times.
+ *
+ * Note that you can apply the operation to each index only once.
+ *
+ * A subsequence of an array is a new array generated from the original array by deleting some
+ * elements (possibly none) without changing the order of the remaining elements.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @return {number}
+ */
+var maximumBeauty = function(nums, k) {
+  nums.sort((a, b) => a - b);
+  let result = 0;
+  let left = 0;
+
+  for (let right = 0; right < nums.length; right++) {
+    while (nums[right] - nums[left] > 2 * k) {
+      left++;
+    }
+    result = Math.max(result, right - left + 1);
+  }
+
+  return result;
+};
diff --git a/solutions/2784-check-if-array-is-good.js b/solutions/2784-check-if-array-is-good.js
new file mode 100644
index 00000000..289edd0d
--- /dev/null
+++ b/solutions/2784-check-if-array-is-good.js
@@ -0,0 +1,36 @@
+/**
+ * 2784. Check if Array is Good
+ * https://leetcode.com/problems/check-if-array-is-good/
+ * Difficulty: Easy
+ *
+ * You are given an integer array nums. We consider an array good if it is a permutation of
+ * an array base[n].
+ *
+ * base[n] = [1, 2, ..., n - 1, n, n] (in other words, it is an array of length n + 1 which
+ * contains 1 to n - 1 exactly once, plus two occurrences of n). For example, base[1] = [1, 1]
+ * and base[3] = [1, 2, 3, 3].
+ *
+ * Return true if the given array is good, otherwise return false.
+ *
+ * Note: A permutation of integers represents an arrangement of these numbers.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {boolean}
+ */
+var isGood = function(nums) {
+  const n = Math.max(...nums);
+  if (nums.length !== n + 1) return false;
+
+  const frequency = new Array(n + 1).fill(0);
+  for (const num of nums) {
+    if (num > n) return false;
+    frequency[num]++;
+  }
+
+  for (let i = 1; i < n; i++) {
+    if (frequency[i] !== 1) return false;
+  }
+  return frequency[n] === 2;
+};
diff --git a/solutions/2785-sort-vowels-in-a-string.js b/solutions/2785-sort-vowels-in-a-string.js
new file mode 100644
index 00000000..d4a25c7e
--- /dev/null
+++ b/solutions/2785-sort-vowels-in-a-string.js
@@ -0,0 +1,45 @@
+/**
+ * 2785. Sort Vowels in a String
+ * https://leetcode.com/problems/sort-vowels-in-a-string/
+ * Difficulty: Medium
+ *
+ * Given a 0-indexed string s, permute s to get a new string t such that:
+ * - All consonants remain in their original places. More formally, if there is an index i
+ *   with 0 <= i < s.length such that s[i] is a consonant, then t[i] = s[i].
+ * - The vowels must be sorted in the nondecreasing order of their ASCII values. More formally,
+ *   for pairs of indices i, j with 0 <= i < j < s.length such that s[i] and s[j] are vowels,
+ *   then t[i] must not have a higher ASCII value than t[j].
+ *
+ * Return the resulting string.
+ *
+ * The vowels are 'a', 'e', 'i', 'o', and 'u', and they can appear in lowercase or uppercase.
+ * Consonants comprise all letters that are not vowels.
+ */
+
+/**
+ * @param {string} s
+ * @return {string}
+ */
+var sortVowels = function(s) {
+  const vowels = new Set(['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']);
+  const vowelChars = [];
+
+  for (const char of s) {
+    if (vowels.has(char)) {
+      vowelChars.push(char);
+    }
+  }
+
+  vowelChars.sort();
+
+  const result = [...s];
+  let vowelIndex = 0;
+
+  for (let i = 0; i < s.length; i++) {
+    if (vowels.has(s[i])) {
+      result[i] = vowelChars[vowelIndex++];
+    }
+  }
+
+  return result.join('');
+};
diff --git a/solutions/2788-split-strings-by-separator.js b/solutions/2788-split-strings-by-separator.js
new file mode 100644
index 00000000..6681bef2
--- /dev/null
+++ b/solutions/2788-split-strings-by-separator.js
@@ -0,0 +1,31 @@
+/**
+ * 2788. Split Strings by Separator
+ * https://leetcode.com/problems/split-strings-by-separator/
+ * Difficulty: Easy
+ *
+ * Given an array of strings words and a character separator, split each string in words by
+ * separator.
+ *
+ * Return an array of strings containing the new strings formed after the splits, excluding
+ * empty strings.
+ *
+ * Notes
+ * - separator is used to determine where the split should occur, but it is not included as
+ *   part of the resulting strings.
+ * - A split may result in more than two strings.
+ * - The resulting strings must maintain the same order as they were initially given.
+ */
+
+/**
+ * @param {string[]} words
+ * @param {character} separator
+ * @return {string[]}
+ */
+var splitWordsBySeparator = function(words, separator) {
+  const result = [];
+  for (const word of words) {
+    const splitWords = word.split(separator).filter(part => part !== '');
+    result.push(...splitWords);
+  }
+  return result;
+};
diff --git a/solutions/2789-largest-element-in-an-array-after-merge-operations.js b/solutions/2789-largest-element-in-an-array-after-merge-operations.js
new file mode 100644
index 00000000..3de874a6
--- /dev/null
+++ b/solutions/2789-largest-element-in-an-array-after-merge-operations.js
@@ -0,0 +1,34 @@
+/**
+ * 2789. Largest Element in an Array after Merge Operations
+ * https://leetcode.com/problems/largest-element-in-an-array-after-merge-operations/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed array nums consisting of positive integers.
+ *
+ * You can do the following operation on the array any number of times:
+ * - Choose an integer i such that 0 <= i < nums.length - 1 and nums[i] <= nums[i + 1].
+ *   Replace the element nums[i + 1] with nums[i] + nums[i + 1] and delete the element
+ *   nums[i] from the array.
+ *
+ * Return the value of the largest element that you can possibly obtain in the final array.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var maxArrayValue = function(nums) {
+  let result = nums[nums.length - 1];
+  let currentSum = result;
+
+  for (let i = nums.length - 2; i >= 0; i--) {
+    if (nums[i] <= currentSum) {
+      currentSum += nums[i];
+    } else {
+      currentSum = nums[i];
+    }
+    result = Math.max(result, currentSum);
+  }
+
+  return result;
+};
diff --git a/solutions/2791-count-paths-that-can-form-a-palindrome-in-a-tree.js b/solutions/2791-count-paths-that-can-form-a-palindrome-in-a-tree.js
new file mode 100644
index 00000000..195def8e
--- /dev/null
+++ b/solutions/2791-count-paths-that-can-form-a-palindrome-in-a-tree.js
@@ -0,0 +1,49 @@
+/**
+ * 2791. Count Paths That Can Form a Palindrome in a Tree
+ * https://leetcode.com/problems/count-paths-that-can-form-a-palindrome-in-a-tree/
+ * Difficulty: Hard
+ *
+ * You are given a tree (i.e. a connected, undirected graph that has no cycles) rooted at node
+ * 0 consisting of n nodes numbered from 0 to n - 1. The tree is represented by a 0-indexed
+ * array parent of size n, where parent[i] is the parent of node i. Since node 0 is the root,
+ * parent[0] == -1.
+ *
+ * You are also given a string s of length n, where s[i] is the character assigned to the edge
+ * between i and parent[i]. s[0] can be ignored.
+ *
+ * Return the number of pairs of nodes (u, v) such that u < v and the characters assigned to edges
+ * on the path from u to v can be rearranged to form a palindrome.
+ *
+ * A string is a palindrome when it reads the same backwards as forwards.
+ */
+
+/**
+ * @param {number[]} parent
+ * @param {string} s
+ * @return {number}
+ */
+var countPalindromePaths = function(parent, s) {
+  const n = parent.length;
+  const graph = Array.from({ length: n }, () => []);
+  for (let i = 1; i < n; i++) {
+    graph[parent[i]].push(i);
+  }
+
+  const freq = new Map([[0, 1]]);
+  let result = 0;
+
+  dfs(0, 0);
+  return result;
+
+  function dfs(node, mask) {
+    for (const child of graph[node]) {
+      const newMask = mask ^ (1 << (s[child].charCodeAt(0) - 97));
+      result += freq.get(newMask) || 0;
+      for (let i = 0; i < 26; i++) {
+        result += freq.get(newMask ^ (1 << i)) || 0;
+      }
+      freq.set(newMask, (freq.get(newMask) || 0) + 1);
+      dfs(child, newMask);
+    }
+  }
+};
diff --git a/solutions/2798-number-of-employees-who-met-the-target.js b/solutions/2798-number-of-employees-who-met-the-target.js
new file mode 100644
index 00000000..b3c1f4ac
--- /dev/null
+++ b/solutions/2798-number-of-employees-who-met-the-target.js
@@ -0,0 +1,30 @@
+/**
+ * 2798. Number of Employees Who Met the Target
+ * https://leetcode.com/problems/number-of-employees-who-met-the-target/
+ * Difficulty: Easy
+ *
+ * There are n employees in a company, numbered from 0 to n - 1. Each employee i has worked
+ * for hours[i] hours in the company.
+ *
+ * The company requires each employee to work for at least target hours.
+ *
+ * You are given a 0-indexed array of non-negative integers hours of length n and a non-negative
+ * integer target.
+ *
+ * Return the integer denoting the number of employees who worked at least target hours.
+ */
+
+/**
+ * @param {number[]} hours
+ * @param {number} target
+ * @return {number}
+ */
+var numberOfEmployeesWhoMetTarget = function(hours, target) {
+  let count = 0;
+
+  for (const hoursWorked of hours) {
+    if (hoursWorked >= target) count++;
+  }
+
+  return count;
+};
diff --git a/solutions/2806-account-balance-after-rounded-purchase.js b/solutions/2806-account-balance-after-rounded-purchase.js
new file mode 100644
index 00000000..0862ed28
--- /dev/null
+++ b/solutions/2806-account-balance-after-rounded-purchase.js
@@ -0,0 +1,29 @@
+/**
+ * 2806. Account Balance After Rounded Purchase
+ * https://leetcode.com/problems/account-balance-after-rounded-purchase/
+ * Difficulty: Easy
+ *
+ * Initially, you have a bank account balance of 100 dollars.
+ *
+ * You are given an integer purchaseAmount representing the amount you will spend on a purchase
+ * in dollars, in other words, its price.
+ *
+ * When making the purchase, first the purchaseAmount is rounded to the nearest multiple of 10.
+ * Let us call this value roundedAmount. Then, roundedAmount dollars are removed from your bank
+ * account.
+ *
+ * Return an integer denoting your final bank account balance after this purchase.
+ *
+ * Notes:
+ * - 0 is considered to be a multiple of 10 in this problem.
+ * - When rounding, 5 is rounded upward (5 is rounded to 10, 15 is rounded to 20, 25 to 30, and
+ *   so on).
+ */
+
+/**
+ * @param {number} purchaseAmount
+ * @return {number}
+ */
+var accountBalanceAfterPurchase = function(purchaseAmount) {
+  return 100 - (Math.round(purchaseAmount / 10) * 10);
+};
diff --git a/solutions/2807-insert-greatest-common-divisors-in-linked-list.js b/solutions/2807-insert-greatest-common-divisors-in-linked-list.js
new file mode 100644
index 00000000..ee1b2f8e
--- /dev/null
+++ b/solutions/2807-insert-greatest-common-divisors-in-linked-list.js
@@ -0,0 +1,45 @@
+/**
+ * 2807. Insert Greatest Common Divisors in Linked List
+ * https://leetcode.com/problems/insert-greatest-common-divisors-in-linked-list/
+ * Difficulty: Medium
+ *
+ * Given the head of a linked list head, in which each node contains an integer value.
+ *
+ * Between every pair of adjacent nodes, insert a new node with a value equal to the greatest
+ * common divisor of them.
+ *
+ * Return the linked list after insertion.
+ *
+ * The greatest common divisor of two numbers is the largest positive integer that evenly
+ * divides both numbers.
+ */
+
+/**
+ * Definition for singly-linked list.
+ * function ListNode(val, next) {
+ *     this.val = (val===undefined ? 0 : val)
+ *     this.next = (next===undefined ? null : next)
+ * }
+ */
+/**
+ * @param {ListNode} head
+ * @return {ListNode}
+ */
+var insertGreatestCommonDivisors = function(head) {
+  let current = head;
+  while (current && current.next) {
+    const nextNode = current.next;
+    const divisor = gcd(current.val, nextNode.val);
+    current.next = new ListNode(divisor, nextNode);
+    current = nextNode;
+  }
+  return head;
+
+  function gcd(a, b) {
+    while (b) {
+      a %= b;
+      [a, b] = [b, a];
+    }
+    return a;
+  }
+};
diff --git a/solutions/2810-faulty-keyboard.js b/solutions/2810-faulty-keyboard.js
new file mode 100644
index 00000000..47cb30e8
--- /dev/null
+++ b/solutions/2810-faulty-keyboard.js
@@ -0,0 +1,30 @@
+/**
+ * 2810. Faulty Keyboard
+ * https://leetcode.com/problems/faulty-keyboard/
+ * Difficulty: Easy
+ *
+ * Your laptop keyboard is faulty, and whenever you type a character 'i' on it, it reverses the
+ * string that you have written. Typing other characters works as expected.
+ *
+ * You are given a 0-indexed string s, and you type each character of s using your faulty keyboard.
+ *
+ * Return the final string that will be present on your laptop screen.
+ */
+
+/**
+ * @param {string} s
+ * @return {string}
+ */
+var finalString = function(s) {
+  const result = [];
+
+  for (const char of s) {
+    if (char === 'i') {
+      result.reverse();
+    } else {
+      result.push(char);
+    }
+  }
+
+  return result.join('');
+};
diff --git a/solutions/2815-max-pair-sum-in-an-array.js b/solutions/2815-max-pair-sum-in-an-array.js
new file mode 100644
index 00000000..d6a41368
--- /dev/null
+++ b/solutions/2815-max-pair-sum-in-an-array.js
@@ -0,0 +1,48 @@
+/**
+ * 2815. Max Pair Sum in an Array
+ * https://leetcode.com/problems/max-pair-sum-in-an-array/
+ * Difficulty: Easy
+ *
+ * You are given an integer array nums. You have to find the maximum sum of a pair of numbers from
+ * nums such that the largest digit in both numbers is equal.
+ *
+ * For example, 2373 is made up of three distinct digits: 2, 3, and 7, where 7 is the largest among
+ * them.
+ *
+ * Return the maximum sum or -1 if no such pair exists.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var maxSum = function(nums) {
+  let result = -1;
+  const map = new Map();
+
+  for (const num of nums) {
+    const maxDigit = getMaxDigit(num);
+    if (!map.has(maxDigit)) {
+      map.set(maxDigit, []);
+    }
+    map.get(maxDigit).push(num);
+  }
+
+  for (const numbers of map.values()) {
+    if (numbers.length >= 2) {
+      numbers.sort((a, b) => b - a);
+      result = Math.max(result, numbers[0] + numbers[1]);
+    }
+  }
+
+  return result;
+
+  function getMaxDigit(num) {
+    let max = 0;
+    while (num > 0) {
+      max = Math.max(max, num % 10);
+      num = Math.floor(num / 10);
+    }
+    return max;
+  }
+};
diff --git a/solutions/2816-double-a-number-represented-as-a-linked-list.js b/solutions/2816-double-a-number-represented-as-a-linked-list.js
new file mode 100644
index 00000000..d6ef8c24
--- /dev/null
+++ b/solutions/2816-double-a-number-represented-as-a-linked-list.js
@@ -0,0 +1,54 @@
+/**
+ * 2816. Double a Number Represented as a Linked List
+ * https://leetcode.com/problems/double-a-number-represented-as-a-linked-list/
+ * Difficulty: Medium
+ *
+ * You are given the head of a non-empty linked list representing a non-negative integer without
+ * leading zeroes.
+ *
+ * Return the head of the linked list after doubling it.
+ */
+
+/**
+ * Definition for singly-linked list.
+ * function ListNode(val, next) {
+ *     this.val = (val===undefined ? 0 : val)
+ *     this.next = (next===undefined ? null : next)
+ * }
+ */
+/**
+ * @param {ListNode} head
+ * @return {ListNode}
+ */
+var doubleIt = function(head) {
+  const reversed = reverseList(head);
+  let carry = 0;
+  let current = reversed;
+  let prev = null;
+
+  while (current) {
+    const doubled = current.val * 2 + carry;
+    current.val = doubled % 10;
+    carry = Math.floor(doubled / 10);
+    prev = current;
+    current = current.next;
+  }
+
+  if (carry) {
+    prev.next = new ListNode(carry);
+  }
+
+  return reverseList(reversed);
+
+  function reverseList(node) {
+    let prev = null;
+    let current = node;
+    while (current) {
+      const next = current.next;
+      current.next = prev;
+      prev = current;
+      current = next;
+    }
+    return prev;
+  }
+};
diff --git a/solutions/2824-count-pairs-whose-sum-is-less-than-target.js b/solutions/2824-count-pairs-whose-sum-is-less-than-target.js
new file mode 100644
index 00000000..cdf97867
--- /dev/null
+++ b/solutions/2824-count-pairs-whose-sum-is-less-than-target.js
@@ -0,0 +1,32 @@
+/**
+ * 2824. Count Pairs Whose Sum is Less than Target
+ * https://leetcode.com/problems/count-pairs-whose-sum-is-less-than-target/
+ * Difficulty: Easy
+ *
+ * Given a 0-indexed integer array nums of length n and an integer target, return the number
+ * of pairs (i, j) where 0 <= i < j < n and nums[i] + nums[j] < target.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} target
+ * @return {number}
+ */
+var countPairs = function(nums, target) {
+  let result = 0;
+  let left = 0;
+  let right = nums.length - 1;
+
+  nums.sort((a, b) => a - b);
+
+  while (left < right) {
+    if (nums[left] + nums[right] < target) {
+      result += right - left;
+      left++;
+    } else {
+      right--;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2825-make-string-a-subsequence-using-cyclic-increments.js b/solutions/2825-make-string-a-subsequence-using-cyclic-increments.js
new file mode 100644
index 00000000..b6b96b8f
--- /dev/null
+++ b/solutions/2825-make-string-a-subsequence-using-cyclic-increments.js
@@ -0,0 +1,39 @@
+/**
+ * 2825. Make String a Subsequence Using Cyclic Increments
+ * https://leetcode.com/problems/make-string-a-subsequence-using-cyclic-increments/
+ * Difficulty: Medium
+ *
+ * You are given two 0-indexed strings str1 and str2.
+ *
+ * In an operation, you select a set of indices in str1, and for each index i in the set,
+ * increment str1[i] to the next character cyclically. That is 'a' becomes 'b', 'b' becomes
+ * 'c', and so on, and 'z' becomes 'a'.
+ *
+ * Return true if it is possible to make str2 a subsequence of str1 by performing the operation
+ * at most once, and false otherwise.
+ *
+ * Note: A subsequence of a string is a new string that is formed from the original string by
+ * deleting some (possibly none) of the characters without disturbing the relative positions
+ * of the remaining characters.
+ */
+
+/**
+ * @param {string} str1
+ * @param {string} str2
+ * @return {boolean}
+ */
+var canMakeSubsequence = function(str1, str2) {
+  let i = 0;
+  let j = 0;
+
+  while (i < str1.length && j < str2.length) {
+    const curr = str1[i].charCodeAt(0);
+    const next = curr === 122 ? 97 : curr + 1;
+    if (str1[i] === str2[j] || String.fromCharCode(next) === str2[j]) {
+      j++;
+    }
+    i++;
+  }
+
+  return j === str2.length;
+};
diff --git a/solutions/2826-sorting-three-groups.js b/solutions/2826-sorting-three-groups.js
new file mode 100644
index 00000000..0153b199
--- /dev/null
+++ b/solutions/2826-sorting-three-groups.js
@@ -0,0 +1,34 @@
+/**
+ * 2826. Sorting Three Groups
+ * https://leetcode.com/problems/sorting-three-groups/
+ * Difficulty: Medium
+ *
+ * You are given an integer array nums. Each element in nums is 1, 2 or 3. In each operation,
+ * you can remove an element from nums. Return the minimum number of operations to make nums
+ * non-decreasing.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var minimumOperations = function(nums) {
+  const n = nums.length;
+  const dp = new Array(n + 1).fill(0).map(() => new Array(4).fill(Infinity));
+  dp[0][0] = 0;
+
+  for (let i = 0; i < n; i++) {
+    for (let prev = 0; prev <= 3; prev++) {
+      for (let curr = 1; curr <= 3; curr++) {
+        if (curr >= prev) {
+          dp[i + 1][curr] = Math.min(
+            dp[i + 1][curr],
+            dp[i][prev] + (nums[i] === curr ? 0 : 1)
+          );
+        }
+      }
+    }
+  }
+
+  return Math.min(...dp[n].slice(1));
+};
diff --git a/solutions/2828-check-if-a-string-is-an-acronym-of-words.js b/solutions/2828-check-if-a-string-is-an-acronym-of-words.js
new file mode 100644
index 00000000..c0b34517
--- /dev/null
+++ b/solutions/2828-check-if-a-string-is-an-acronym-of-words.js
@@ -0,0 +1,23 @@
+/**
+ * 2828. Check if a String Is an Acronym of Words
+ * https://leetcode.com/problems/check-if-a-string-is-an-acronym-of-words/
+ * Difficulty: Easy
+ *
+ * Given an array of strings words and a string s, determine if s is an acronym of words.
+ *
+ * The string s is considered an acronym of words if it can be formed by concatenating the
+ * first character of each string in words in order. For example, "ab" can be formed from
+ * ["apple", "banana"], but it can't be formed from ["bear", "aardvark"].
+ *
+ * Return true if s is an acronym of words, and false otherwise.
+ */
+
+/**
+ * @param {string[]} words
+ * @param {string} s
+ * @return {boolean}
+ */
+var isAcronym = function(words, s) {
+  if (words.length !== s.length) return false;
+  return words.every((word, index) => word[0] === s[index]);
+};
diff --git a/solutions/2829-determine-the-minimum-sum-of-a-k-avoiding-array.js b/solutions/2829-determine-the-minimum-sum-of-a-k-avoiding-array.js
new file mode 100644
index 00000000..540df710
--- /dev/null
+++ b/solutions/2829-determine-the-minimum-sum-of-a-k-avoiding-array.js
@@ -0,0 +1,34 @@
+/**
+ * 2829. Determine the Minimum Sum of a k-avoiding Array
+ * https://leetcode.com/problems/determine-the-minimum-sum-of-a-k-avoiding-array/
+ * Difficulty: Medium
+ *
+ * You are given two integers, n and k.
+ *
+ * An array of distinct positive integers is called a k-avoiding array if there does not exist
+ * any pair of distinct elements that sum to k.
+ *
+ * Return the minimum possible sum of a k-avoiding array of length n.
+ */
+
+/**
+ * @param {number} n
+ * @param {number} k
+ * @return {number}
+ */
+var minimumSum = function(n, k) {
+  const set = new Set();
+  let result = 0;
+  let num = 1;
+
+  for (let i = 0; i < n; i++) {
+    while (set.has(k - num)) {
+      num++;
+    }
+    result += num;
+    set.add(num);
+    num++;
+  }
+
+  return result;
+};
diff --git a/solutions/2833-furthest-point-from-origin.js b/solutions/2833-furthest-point-from-origin.js
new file mode 100644
index 00000000..0428216f
--- /dev/null
+++ b/solutions/2833-furthest-point-from-origin.js
@@ -0,0 +1,32 @@
+/**
+ * 2833. Furthest Point From Origin
+ * https://leetcode.com/problems/furthest-point-from-origin/
+ * Difficulty: Easy
+ *
+ * You are given a string moves of length n consisting only of characters 'L', 'R', and '_'.
+ * The string represents your movement on a number line starting from the origin 0.
+ *
+ * In the ith move, you can choose one of the following directions:
+ * - move to the left if moves[i] = 'L' or moves[i] = '_'
+ * - move to the right if moves[i] = 'R' or moves[i] = '_'
+ *
+ * Return the distance from the origin of the furthest point you can get to after n moves.
+ */
+
+/**
+ * @param {string} moves
+ * @return {number}
+ */
+var furthestDistanceFromOrigin = function(moves) {
+  let leftCount = 0;
+  let rightCount = 0;
+  let wildCount = 0;
+
+  for (const move of moves) {
+    if (move === 'L') leftCount++;
+    else if (move === 'R') rightCount++;
+    else wildCount++;
+  }
+
+  return Math.abs(leftCount - rightCount) + wildCount;
+};
diff --git a/solutions/2839-check-if-strings-can-be-made-equal-with-operations-i.js b/solutions/2839-check-if-strings-can-be-made-equal-with-operations-i.js
new file mode 100644
index 00000000..3eb6dfcb
--- /dev/null
+++ b/solutions/2839-check-if-strings-can-be-made-equal-with-operations-i.js
@@ -0,0 +1,25 @@
+/**
+ * 2839. Check if Strings Can be Made Equal With Operations I
+ * https://leetcode.com/problems/check-if-strings-can-be-made-equal-with-operations-i/
+ * Difficulty: Easy
+ *
+ * You are given two strings s1 and s2, both of length 4, consisting of lowercase English
+ * letters.
+ *
+ * You can apply the following operation on any of the two strings any number of times:
+ * - Choose any two indices i and j such that j - i = 2, then swap the two characters at those
+ *   indices in the string.
+ *
+ * Return true if you can make the strings s1 and s2 equal, and false otherwise.
+ */
+
+/**
+ * @param {string} s1
+ * @param {string} s2
+ * @return {boolean}
+ */
+var canBeEqual = function(s1, s2) {
+  const firstPair = [s1[0], s1[2]].sort().join() === [s2[0], s2[2]].sort().join();
+  const secondPair = [s1[1], s1[3]].sort().join() === [s2[1], s2[3]].sort().join();
+  return firstPair && secondPair;
+};
diff --git a/solutions/2840-check-if-strings-can-be-made-equal-with-operations-ii.js b/solutions/2840-check-if-strings-can-be-made-equal-with-operations-ii.js
new file mode 100644
index 00000000..28a8805e
--- /dev/null
+++ b/solutions/2840-check-if-strings-can-be-made-equal-with-operations-ii.js
@@ -0,0 +1,38 @@
+/**
+ * 2840. Check if Strings Can be Made Equal With Operations II
+ * https://leetcode.com/problems/check-if-strings-can-be-made-equal-with-operations-ii/
+ * Difficulty: Medium
+ *
+ * You are given two strings s1 and s2, both of length n, consisting of lowercase English letters.
+ *
+ * You can apply the following operation on any of the two strings any number of times:
+ * - Choose any two indices i and j such that i < j and the difference j - i is even, then swap the
+ *   two characters at those indices in the string.
+ *
+ * Return true if you can make the strings s1 and s2 equal, and false otherwise.
+ */
+
+/**
+ * @param {string} s1
+ * @param {string} s2
+ * @return {boolean}
+ */
+var checkStrings = function(s1, s2) {
+  const evenChars1 = [];
+  const oddChars1 = [];
+  const evenChars2 = [];
+  const oddChars2 = [];
+
+  for (let i = 0; i < s1.length; i++) {
+    if (i % 2 === 0) {
+      evenChars1.push(s1[i]);
+      evenChars2.push(s2[i]);
+    } else {
+      oddChars1.push(s1[i]);
+      oddChars2.push(s2[i]);
+    }
+  }
+
+  return evenChars1.sort().join('') === evenChars2.sort().join('')
+    && oddChars1.sort().join('') === oddChars2.sort().join('');
+};
diff --git a/solutions/2841-maximum-sum-of-almost-unique-subarray.js b/solutions/2841-maximum-sum-of-almost-unique-subarray.js
new file mode 100644
index 00000000..e36e3b1a
--- /dev/null
+++ b/solutions/2841-maximum-sum-of-almost-unique-subarray.js
@@ -0,0 +1,51 @@
+/**
+ * 2841. Maximum Sum of Almost Unique Subarray
+ * https://leetcode.com/problems/maximum-sum-of-almost-unique-subarray/
+ * Difficulty: Medium
+ *
+ * You are given an integer array nums and two positive integers m and k.
+ *
+ * Return the maximum sum out of all almost unique subarrays of length k of nums. If no such
+ * subarray exists, return 0.
+ *
+ * A subarray of nums is almost unique if it contains at least m distinct elements.
+ *
+ * A subarray is a contiguous non-empty sequence of elements within an array.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} m
+ * @param {number} k
+ * @return {number}
+ */
+var maxSum = function(nums, m, k) {
+  const map = new Map();
+  let subarraySum = 0;
+  let result = 0;
+
+  for (let i = 0; i < k; i++) {
+    map.set(nums[i], (map.get(nums[i]) || 0) + 1);
+    subarraySum += nums[i];
+  }
+
+  if (map.size >= m) {
+    result = subarraySum;
+  }
+
+  for (let i = k; i < nums.length; i++) {
+    map.set(nums[i - k], map.get(nums[i - k]) - 1);
+    if (map.get(nums[i - k]) === 0) {
+      map.delete(nums[i - k]);
+    }
+
+    map.set(nums[i], (map.get(nums[i]) || 0) + 1);
+    subarraySum = subarraySum - nums[i - k] + nums[i];
+
+    if (map.size >= m) {
+      result = Math.max(result, subarraySum);
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2846-minimum-edge-weight-equilibrium-queries-in-a-tree.js b/solutions/2846-minimum-edge-weight-equilibrium-queries-in-a-tree.js
new file mode 100644
index 00000000..87c0f17c
--- /dev/null
+++ b/solutions/2846-minimum-edge-weight-equilibrium-queries-in-a-tree.js
@@ -0,0 +1,77 @@
+/**
+ * 2846. Minimum Edge Weight Equilibrium Queries in a Tree
+ * https://leetcode.com/problems/minimum-edge-weight-equilibrium-queries-in-a-tree/
+ * Difficulty: Hard
+ *
+ * There is an undirected tree with n nodes labeled from 0 to n - 1. You are given the integer n and
+ * a 2D integer array edges of length n - 1, where edges[i] = [ui, vi, wi] indicates that there is
+ * an edge between nodes ui and vi with weight wi in the tree.
+ *
+ * You are also given a 2D integer array queries of length m, where queries[i] = [ai, bi]. For each
+ * query, find the minimum number of operations required to make the weight of every edge on the
+ * path from ai to bi equal. In one operation, you can choose any edge of the tree and change its
+ * weight to any value.
+ *
+ * Note that:
+ * - Queries are independent of each other, meaning that the tree returns to its initial state on
+ *   each new query.
+ * - The path from ai to bi is a sequence of distinct nodes starting with node ai and ending with
+ *   node bi such that every two adjacent nodes in the sequence share an edge in the tree.
+ *
+ * Return an array answer of length m where answer[i] is the answer to the ith query.
+ */
+
+/**
+ * @param {number} n
+ * @param {number[][]} edges
+ * @param {number[][]} queries
+ * @return {number[]}
+ */
+var minOperationsQueries = function(n, edges, queries) {
+  const graph = Array.from({ length: n }, () => []);
+  for (const [u, v, w] of edges) {
+    graph[u].push([v, w]);
+    graph[v].push([u, w]);
+  }
+
+  const parent = new Array(n).fill(-1);
+  const weightCount = new Array(n).fill().map(() => new Array(27).fill(0));
+  const depth = new Array(n).fill(0);
+
+  dfs(0, -1, 0);
+
+  const result = [];
+  for (const [u, v] of queries) {
+    const ancestor = lca(u, v);
+    const counts = Array(27).fill(0);
+    for (let i = 1; i <= 26; i++) {
+      counts[i] = weightCount[u][i] + weightCount[v][i] - 2 * weightCount[ancestor][i];
+    }
+    const total = depth[u] + depth[v] - 2 * depth[ancestor];
+    const maxCount = Math.max(...counts);
+    result.push(total - maxCount);
+  }
+
+  return result;
+
+  function dfs(node, par, dep) {
+    parent[node] = par;
+    depth[node] = dep;
+    for (const [next, w] of graph[node]) {
+      if (next !== par) {
+        weightCount[next] = [...weightCount[node]];
+        weightCount[next][w]++;
+        dfs(next, node, dep + 1);
+      }
+    }
+  }
+  function lca(u, v) {
+    if (depth[u] < depth[v]) [u, v] = [v, u];
+    while (depth[u] > depth[v]) u = parent[u];
+    while (u !== v) {
+      u = parent[u];
+      v = parent[v];
+    }
+    return u;
+  }
+};
diff --git a/solutions/2848-points-that-intersect-with-cars.js b/solutions/2848-points-that-intersect-with-cars.js
new file mode 100644
index 00000000..fc4f58de
--- /dev/null
+++ b/solutions/2848-points-that-intersect-with-cars.js
@@ -0,0 +1,27 @@
+/**
+ * 2848. Points That Intersect With Cars
+ * https://leetcode.com/problems/points-that-intersect-with-cars/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed 2D integer array nums representing the coordinates of the cars
+ * parking on a number line. For any index i, nums[i] = [starti, endi] where starti is the
+ * starting point of the ith car and endi is the ending point of the ith car.
+ *
+ * Return the number of integer points on the line that are covered with any part of a car.
+ */
+
+/**
+ * @param {number[][]} nums
+ * @return {number}
+ */
+var numberOfPoints = function(nums) {
+  const set = new Set();
+
+  for (const [start, end] of nums) {
+    for (let i = start; i <= end; i++) {
+      set.add(i);
+    }
+  }
+
+  return set.size;
+};
diff --git a/solutions/2850-minimum-moves-to-spread-stones-over-grid.js b/solutions/2850-minimum-moves-to-spread-stones-over-grid.js
new file mode 100644
index 00000000..b56e1393
--- /dev/null
+++ b/solutions/2850-minimum-moves-to-spread-stones-over-grid.js
@@ -0,0 +1,59 @@
+/**
+ * 2850. Minimum Moves to Spread Stones Over Grid
+ * https://leetcode.com/problems/minimum-moves-to-spread-stones-over-grid/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed 2D integer matrix grid of size 3 * 3, representing the number of
+ * stones in each cell. The grid contains exactly 9 stones, and there can be multiple stones
+ * in a single cell.
+ *
+ * In one move, you can move a single stone from its current cell to any other cell if the two
+ * cells share a side.
+ *
+ * Return the minimum number of moves required to place one stone in each cell.
+ */
+
+/**
+ * @param {number[][]} grid
+ * @return {number}
+ */
+var minimumMoves = function(grid) {
+  const sources = [];
+  const targets = [];
+
+  for (let i = 0; i < 3; i++) {
+    for (let j = 0; j < 3; j++) {
+      if (grid[i][j] > 1) {
+        for (let k = 1; k < grid[i][j]; k++) {
+          sources.push([i, j]);
+        }
+      } else if (grid[i][j] === 0) {
+        targets.push([i, j]);
+      }
+    }
+  }
+
+  let minMoves = Infinity;
+
+  permute(0, 0);
+  return minMoves;
+
+  function permute(index, moves) {
+    if (index === sources.length) {
+      minMoves = Math.min(minMoves, moves);
+      return;
+    }
+
+    for (let i = 0; i < targets.length; i++) {
+      if (targets[i]) {
+        const [si, sj] = sources[index];
+        const [ti, tj] = targets[i];
+        const dist = Math.abs(si - ti) + Math.abs(sj - tj);
+        const temp = targets[i];
+        targets[i] = null;
+        permute(index + 1, moves + dist);
+        targets[i] = temp;
+      }
+    }
+  }
+};
diff --git a/solutions/2855-minimum-right-shifts-to-sort-the-array.js b/solutions/2855-minimum-right-shifts-to-sort-the-array.js
new file mode 100644
index 00000000..9bf69806
--- /dev/null
+++ b/solutions/2855-minimum-right-shifts-to-sort-the-array.js
@@ -0,0 +1,33 @@
+/**
+ * 2855. Minimum Right Shifts to Sort the Array
+ * https://leetcode.com/problems/minimum-right-shifts-to-sort-the-array/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed array nums of length n containing distinct positive integers.
+ * Return the minimum number of right shifts required to sort nums and -1 if this is not
+ * possible.
+ *
+ * A right shift is defined as shifting the element at index i to index (i + 1) % n, for
+ * all indices.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var minimumRightShifts = function(nums) {
+  const n = nums.length;
+  let breakPoint = 0;
+
+  for (let i = 1; i < n; i++) {
+    if (nums[i] < nums[i - 1]) {
+      breakPoint++;
+      if (breakPoint > 1) return -1;
+    }
+  }
+
+  if (breakPoint === 0) return 0;
+  if (nums[n - 1] > nums[0]) return -1;
+
+  return n - (nums.indexOf(Math.min(...nums)));
+};
diff --git a/solutions/2858-minimum-edge-reversals-so-every-node-is-reachable.js b/solutions/2858-minimum-edge-reversals-so-every-node-is-reachable.js
new file mode 100644
index 00000000..dc7b451a
--- /dev/null
+++ b/solutions/2858-minimum-edge-reversals-so-every-node-is-reachable.js
@@ -0,0 +1,62 @@
+/**
+ * 2858. Minimum Edge Reversals So Every Node Is Reachable
+ * https://leetcode.com/problems/minimum-edge-reversals-so-every-node-is-reachable/
+ * Difficulty: Hard
+ *
+ * There is a simple directed graph with n nodes labeled from 0 to n - 1. The graph would form
+ * a tree if its edges were bi-directional.
+ *
+ * You are given an integer n and a 2D integer array edges, where edges[i] = [ui, vi] represents
+ * a directed edge going from node ui to node vi.
+ *
+ * An edge reversal changes the direction of an edge, i.e., a directed edge going from node ui to
+ * node vi becomes a directed edge going from node vi to node ui.
+ *
+ * For every node i in the range [0, n - 1], your task is to independently calculate the minimum
+ * number of edge reversals required so it is possible to reach any other node starting from node
+ * i through a sequence of directed edges.
+ *
+ * Return an integer array answer, where answer[i] is the minimum number of edge reversals required
+ * so it is possible to reach any other node starting from node i through a sequence of directed
+ * edges.
+ */
+
+/**
+ * @param {number} n
+ * @param {number[][]} edges
+ * @return {number[]}
+ */
+var minEdgeReversals = function(n, edges) {
+  const graph = Array.from({ length: n }, () => []);
+
+  for (const [u, v] of edges) {
+    graph[u].push([v, 0]);
+    graph[v].push([u, 1]);
+  }
+
+  const result = new Array(n);
+  const rootReversals = dfs(0, -1);
+
+  reroot(0, -1, rootReversals);
+
+  return result;
+  function dfs(node, parent) {
+    let reversals = 0;
+    for (const [neighbor, cost] of graph[node]) {
+      if (neighbor !== parent) {
+        reversals += cost + dfs(neighbor, node);
+      }
+    }
+    return reversals;
+  }
+
+  function reroot(node, parent, parentReversals) {
+    result[node] = parentReversals;
+    for (const [neighbor, cost] of graph[node]) {
+      if (neighbor !== parent) {
+        const childReversals = result[node] - cost + (1 - cost);
+        reroot(neighbor, node, childReversals);
+      }
+    }
+  }
+};
diff --git a/solutions/2859-sum-of-values-at-indices-with-k-set-bits.js b/solutions/2859-sum-of-values-at-indices-with-k-set-bits.js
new file mode 100644
index 00000000..c14b88d3
--- /dev/null
+++ b/solutions/2859-sum-of-values-at-indices-with-k-set-bits.js
@@ -0,0 +1,31 @@
+/**
+ * 2859. Sum of Values at Indices With K Set Bits
+ * https://leetcode.com/problems/sum-of-values-at-indices-with-k-set-bits/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed integer array nums and an integer k.
+ *
+ * Return an integer that denotes the sum of elements in nums whose corresponding indices have
+ * exactly k set bits in their binary representation.
+ *
+ * The set bits in an integer are the 1's present when it is written in binary.
+ *
+ * For example, the binary representation of 21 is 10101, which has 3 set bits.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @return {number}
+ */
+var sumIndicesWithKSetBits = function(nums, k) {
+  let result = 0;
+
+  for (let i = 0; i < nums.length; i++) {
+    if (i.toString(2).split('1').length - 1 === k) {
+      result += nums[i];
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2860-happy-students.js b/solutions/2860-happy-students.js
new file mode 100644
index 00000000..460015b2
--- /dev/null
+++ b/solutions/2860-happy-students.js
@@ -0,0 +1,38 @@
+/**
+ * 2860. Happy Students
+ * https://leetcode.com/problems/happy-students/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed integer array nums of length n where n is the total number of
+ * students in the class. The class teacher tries to select a group of students so that
+ * all the students remain happy.
+ *
+ * The ith student will become happy if one of these two conditions is met:
+ * - The student is selected and the total number of selected students is strictly greater
+ *   than nums[i].
+ * - The student is not selected and the total number of selected students is strictly less
+ *   than nums[i].
+ *
+ * Return the number of ways to select a group of students so that everyone remains happy.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var countWays = function(nums) {
+  nums.sort((a, b) => a - b);
+  let result = 0;
+  let selected = 0;
+
+  if (0 < nums[0]) result++;
+
+  for (let i = 0; i < nums.length; i++) {
+    selected++;
+    if (selected > nums[i] && (i + 1 === nums.length || selected < nums[i + 1])) {
+      result++;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2862-maximum-element-sum-of-a-complete-subset-of-indices.js b/solutions/2862-maximum-element-sum-of-a-complete-subset-of-indices.js
new file mode 100644
index 00000000..33a8aa2d
--- /dev/null
+++ b/solutions/2862-maximum-element-sum-of-a-complete-subset-of-indices.js
@@ -0,0 +1,46 @@
+/**
+ * 2862. Maximum Element-Sum of a Complete Subset of Indices
+ * https://leetcode.com/problems/maximum-element-sum-of-a-complete-subset-of-indices/
+ * Difficulty: Hard
+ *
+ * You are given a 1-indexed array nums. Your task is to select a complete subset from nums where
+ * every pair of selected indices multiplied is a perfect square,. i. e. if you select ai and aj,
+ * i * j must be a perfect square.
+ *
+ * Return the sum of the complete subset with the maximum sum.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var maximumSum = function(nums) {
+  const n = nums.length;
+  const map = new Map();
+
+  for (let i = 1; i <= n; i++) {
+    let factors = 1;
+    let num = i;
+
+    for (let p = 2; p * p <= num; p++) {
+      let count = 0;
+      while (num % p === 0) {
+        count++;
+        num /= p;
+      }
+      if (count % 2 === 1) factors *= p;
+    }
+    if (num > 1) factors *= num;
+
+    if (!map.has(factors)) map.set(factors, []);
+    map.get(factors).push(nums[i - 1]);
+  }
+
+  let result = 0;
+  for (const group of map.values()) {
+    const sum = group.reduce((a, b) => a + b, 0);
+    result = Math.max(result, sum);
+  }
+
+  return result;
+};
diff --git a/solutions/2864-maximum-odd-binary-number.js b/solutions/2864-maximum-odd-binary-number.js
new file mode 100644
index 00000000..82fd37bc
--- /dev/null
+++ b/solutions/2864-maximum-odd-binary-number.js
@@ -0,0 +1,27 @@
+/**
+ * 2864. Maximum Odd Binary Number
+ * https://leetcode.com/problems/maximum-odd-binary-number/
+ * Difficulty: Easy
+ *
+ * You are given a binary string s that contains at least one '1'.
+ *
+ * You have to rearrange the bits in such a way that the resulting binary number is the maximum
+ * odd binary number that can be created from this combination.
+ *
+ * Return a string representing the maximum odd binary number that can be created from the given
+ * combination.
+ *
+ * Note that the resulting string can have leading zeros.
+ */
+
+/**
+ * @param {string} s
+ * @return {string}
+ */
+var maximumOddBinaryNumber = function(s) {
+  let ones = 0;
+  for (const bit of s) {
+    if (bit === '1') ones++;
+  }
+  return '1'.padStart(ones, '1').padEnd(s.length, '0').slice(1) + '1';
+};
diff --git a/solutions/2865-beautiful-towers-i.js b/solutions/2865-beautiful-towers-i.js
new file mode 100644
index 00000000..f0fa8c07
--- /dev/null
+++ b/solutions/2865-beautiful-towers-i.js
@@ -0,0 +1,44 @@
+/**
+ * 2865. Beautiful Towers I
+ * https://leetcode.com/problems/beautiful-towers-i/
+ * Difficulty: Medium
+ *
+ * You are given an array heights of n integers representing the number of bricks in n
+ * consecutive towers. Your task is to remove some bricks to form a mountain-shaped tower
+ * arrangement. In this arrangement, the tower heights are non-decreasing, reaching a
+ * maximum peak value with one or multiple consecutive towers and then non-increasing.
+ *
+ * Return the maximum possible sum of heights of a mountain-shaped tower arrangement.
+ */
+
+/**
+ * @param {number[]} heights
+ * @return {number}
+ */
+var maximumSumOfHeights = function(heights) {
+  const n = heights.length;
+  let result = 0;
+
+  for (let peak = 0; peak < n; peak++) {
+    let currentSum = heights[peak];
+    let prevHeight = heights[peak];
+
+    for (let i = peak - 1; i >= 0; i--) {
+      const currentHeight = Math.min(heights[i], prevHeight);
+      currentSum += currentHeight;
+      prevHeight = currentHeight;
+    }
+
+    prevHeight = heights[peak];
+
+    for (let i = peak + 1; i < n; i++) {
+      const currentHeight = Math.min(heights[i], prevHeight);
+      currentSum += currentHeight;
+      prevHeight = currentHeight;
+    }
+
+    result = Math.max(result, currentSum);
+  }
+
+  return result;
+};
diff --git a/solutions/2869-minimum-operations-to-collect-elements.js b/solutions/2869-minimum-operations-to-collect-elements.js
new file mode 100644
index 00000000..4f52b704
--- /dev/null
+++ b/solutions/2869-minimum-operations-to-collect-elements.js
@@ -0,0 +1,29 @@
+/**
+ * 2869. Minimum Operations to Collect Elements
+ * https://leetcode.com/problems/minimum-operations-to-collect-elements/
+ * Difficulty: Easy
+ *
+ * You are given an array nums of positive integers and an integer k.
+ *
+ * In one operation, you can remove the last element of the array and add it to your collection.
+ *
+ * Return the minimum number of operations needed to collect elements 1, 2, ..., k.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @return {number}
+ */
+var minOperations = function(nums, k) {
+  const set = new Set();
+  let result = 0;
+
+  for (let i = nums.length - 1; i >= 0; i--) {
+    result++;
+    if (nums[i] <= k) set.add(nums[i]);
+    if (set.size === k) return result;
+  }
+
+  return result;
+};
diff --git a/solutions/2870-minimum-number-of-operations-to-make-array-empty.js b/solutions/2870-minimum-number-of-operations-to-make-array-empty.js
new file mode 100644
index 00000000..c6376c70
--- /dev/null
+++ b/solutions/2870-minimum-number-of-operations-to-make-array-empty.js
@@ -0,0 +1,33 @@
+/**
+ * 2870. Minimum Number of Operations to Make Array Empty
+ * https://leetcode.com/problems/minimum-number-of-operations-to-make-array-empty/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed array nums consisting of positive integers.
+ *
+ * There are two types of operations that you can apply on the array any number of times:
+ * - Choose two elements with equal values and delete them from the array.
+ * - Choose three elements with equal values and delete them from the array.
+ *
+ * Return the minimum number of operations required to make the array empty, or -1 if it is
+ * not possible.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var minOperations = function(nums) {
+  const map = new Map();
+  for (const num of nums) {
+    map.set(num, (map.get(num) || 0) + 1);
+  }
+
+  let result = 0;
+  for (const count of map.values()) {
+    if (count === 1) return -1;
+    result += Math.ceil(count / 3);
+  }
+
+  return result;
+};
diff --git a/solutions/2871-split-array-into-maximum-number-of-subarrays.js b/solutions/2871-split-array-into-maximum-number-of-subarrays.js
new file mode 100644
index 00000000..ff3141ce
--- /dev/null
+++ b/solutions/2871-split-array-into-maximum-number-of-subarrays.js
@@ -0,0 +1,41 @@
+/**
+ * 2871. Split Array Into Maximum Number of Subarrays
+ * https://leetcode.com/problems/split-array-into-maximum-number-of-subarrays/
+ * Difficulty: Medium
+ *
+ * You are given an array nums consisting of non-negative integers.
+ *
+ * We define the score of subarray nums[l..r] such that l <= r as nums[l] AND nums[l + 1]
+ * AND ... AND nums[r] where AND is the bitwise AND operation.
+ *
+ * Consider splitting the array into one or more subarrays such that the following conditions
+ * are satisfied:
+ * - Each element of the array belongs to exactly one subarray.
+ * - The sum of scores of the subarrays is the minimum possible.
+ *
+ * Return the maximum number of subarrays in a split that satisfies the conditions above.
+ *
+ * A subarray is a contiguous part of an array.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var maxSubarrays = function(nums) {
+  const total = nums.reduce((acc, num) => acc & num, nums[0]);
+  if (total !== 0) return 1;
+
+  let result = 0;
+  let current = -1;
+
+  for (const num of nums) {
+    current = current === -1 ? num : current & num;
+    if (current === 0) {
+      result++;
+      current = -1;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2872-maximum-number-of-k-divisible-components.js b/solutions/2872-maximum-number-of-k-divisible-components.js
new file mode 100644
index 00000000..6ff1fdcd
--- /dev/null
+++ b/solutions/2872-maximum-number-of-k-divisible-components.js
@@ -0,0 +1,51 @@
+/**
+ * 2872. Maximum Number of K-Divisible Components
+ * https://leetcode.com/problems/maximum-number-of-k-divisible-components/
+ * Difficulty: Hard
+ *
+ * There is an undirected tree with n nodes labeled from 0 to n - 1. You are given the integer
+ * n and a 2D integer array edges of length n - 1, where edges[i] = [ai, bi] indicates that
+ * there is an edge between nodes ai and bi in the tree.
+ *
+ * You are also given a 0-indexed integer array values of length n, where values[i] is the value
+ * associated with the ith node, and an integer k.
+ *
+ * A valid split of the tree is obtained by removing any set of edges, possibly empty, from the
+ * tree such that the resulting components all have values that are divisible by k, where the
+ * value of a connected component is the sum of the values of its nodes.
+ *
+ * Return the maximum number of components in any valid split.
+ */
+
+/**
+ * @param {number} n
+ * @param {number[][]} edges
+ * @param {number[]} values
+ * @param {number} k
+ * @return {number}
+ */
+var maxKDivisibleComponents = function(n, edges, values, k) {
+  const graph = Array.from({ length: n }, () => []);
+  for (const [u, v] of edges) {
+    graph[u].push(v);
+    graph[v].push(u);
+  }
+
+  let result = 0;
+  dfs(0, -1);
+  return result;
+
+  function dfs(node, parent) {
+    let total = values[node];
+    for (const neighbor of graph[node]) {
+      if (neighbor !== parent) {
+        total += dfs(neighbor, node);
+      }
+    }
+    if (total % k === 0) {
+      result++;
+      return 0;
+    }
+    return total;
+  }
+};
diff --git a/solutions/2894-divisible-and-non-divisible-sums-difference.js b/solutions/2894-divisible-and-non-divisible-sums-difference.js
new file mode 100644
index 00000000..31f068ec
--- /dev/null
+++ b/solutions/2894-divisible-and-non-divisible-sums-difference.js
@@ -0,0 +1,33 @@
+/**
+ * 2894. Divisible and Non-divisible Sums Difference
+ * https://leetcode.com/problems/divisible-and-non-divisible-sums-difference/
+ * Difficulty: Easy
+ *
+ * You are given positive integers n and m.
+ *
+ * Define two integers as follows:
+ * - num1: The sum of all integers in the range [1, n] (both inclusive) that are not divisible by m.
+ * - num2: The sum of all integers in the range [1, n] (both inclusive) that are divisible by m.
+ *
+ * Return the integer num1 - num2.
+ */
+
+/**
+ * @param {number} n
+ * @param {number} m
+ * @return {number}
+ */
+var differenceOfSums = function(n, m) {
+  let nonDivisibleSum = 0;
+  let divisibleSum = 0;
+
+  for (let i = 1; i <= n; i++) {
+    if (i % m === 0) {
+      divisibleSum += i;
+    } else {
+      nonDivisibleSum += i;
+    }
+  }
+
+  return nonDivisibleSum - divisibleSum;
+};
diff --git a/solutions/2895-minimum-processing-time.js b/solutions/2895-minimum-processing-time.js
new file mode 100644
index 00000000..c9ce8504
--- /dev/null
+++ b/solutions/2895-minimum-processing-time.js
@@ -0,0 +1,33 @@
+/**
+ * 2895. Minimum Processing Time
+ * https://leetcode.com/problems/minimum-processing-time/
+ * Difficulty: Medium
+ *
+ * You have a certain number of processors, each having 4 cores. The number of tasks to be executed
+ * is four times the number of processors. Each task must be assigned to a unique core, and each
+ * core can only be used once.
+ *
+ * You are given an array processorTime representing the time each processor becomes available and
+ * an array tasks representing how long each task takes to complete. Return the minimum time needed
+ * to complete all tasks.
+ */
+
+/**
+ * @param {number[]} processorTime
+ * @param {number[]} tasks
+ * @return {number}
+ */
+var minProcessingTime = function(processorTime, tasks) {
+  tasks.sort((a, b) => b - a);
+  processorTime.sort((a, b) => a - b);
+  let result = 0;
+
+  for (let i = 0; i < processorTime.length; i++) {
+    for (let j = 0; j < 4; j++) {
+      const taskIndex = i * 4 + j;
+      result = Math.max(result, processorTime[i] + tasks[taskIndex]);
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2897-apply-operations-on-array-to-maximize-sum-of-squares.js b/solutions/2897-apply-operations-on-array-to-maximize-sum-of-squares.js
new file mode 100644
index 00000000..eab93b10
--- /dev/null
+++ b/solutions/2897-apply-operations-on-array-to-maximize-sum-of-squares.js
@@ -0,0 +1,48 @@
+/**
+ * 2897. Apply Operations on Array to Maximize Sum of Squares
+ * https://leetcode.com/problems/apply-operations-on-array-to-maximize-sum-of-squares/
+ * Difficulty: Hard
+ *
+ * You are given a 0-indexed integer array nums and a positive integer k.
+ *
+ * You can do the following operation on the array any number of times:
+ * - Choose any two distinct indices i and j and simultaneously update the values of nums[i]
+ *   to (nums[i] AND nums[j]) and nums[j] to (nums[i] OR nums[j]). Here, OR denotes the bitwise
+ *   OR operation, and AND denotes the bitwise AND operation.
+ *
+ * You have to choose k elements from the final array and calculate the sum of their squares.
+ *
+ * Return the maximum sum of squares you can achieve.
+ *
+ * Since the answer can be very large, return it modulo 109 + 7.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @return {number}
+ */
+var maxSum = function(nums, k) {
+  const MOD = 1e9 + 7;
+  const bitCounts = new Array(30).fill(0);
+
+  for (const num of nums) {
+    for (let i = 0; i < 30; i++) {
+      if (num & (1 << i)) bitCounts[i]++;
+    }
+  }
+
+  let result = 0;
+  for (let i = 0; i < k; i++) {
+    let current = 0;
+    for (let j = 29; j >= 0; j--) {
+      if (bitCounts[j] > 0) {
+        current |= (1 << j);
+        bitCounts[j]--;
+      }
+    }
+    result = (result + Number((BigInt(current) * BigInt(current)) % BigInt(MOD))) % MOD;
+  }
+
+  return result;
+};
diff --git a/solutions/2899-last-visited-integers.js b/solutions/2899-last-visited-integers.js
new file mode 100644
index 00000000..0adcb661
--- /dev/null
+++ b/solutions/2899-last-visited-integers.js
@@ -0,0 +1,41 @@
+/**
+ * 2899. Last Visited Integers
+ * https://leetcode.com/problems/last-visited-integers/
+ * Difficulty: Easy
+ *
+ * Given an integer array nums where nums[i] is either a positive integer or -1. We need to find
+ * for each -1 the respective positive integer, which we call the last visited integer.
+ *
+ * To achieve this goal, let's define two empty arrays: seen and ans.
+ *
+ * Start iterating from the beginning of the array nums.
+ * - If a positive integer is encountered, prepend it to the front of seen.
+ * - If -1 is encountered, let k be the number of consecutive -1s seen so far (including the
+ *   current -1),
+ *   - If k is less than or equal to the length of seen, append the k-th element of seen to ans.
+ *   - If k is strictly greater than the length of seen, append -1 to ans.
+ *
+ * Return the array ans.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number[]}
+ */
+var lastVisitedIntegers = function(nums) {
+  const seen = [];
+  const result = [];
+  let consecutiveNegatives = 0;
+
+  for (const num of nums) {
+    if (num > 0) {
+      seen.unshift(num);
+      consecutiveNegatives = 0;
+    } else {
+      consecutiveNegatives++;
+      result.push(consecutiveNegatives <= seen.length ? seen[consecutiveNegatives - 1] : -1);
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2900-longest-unequal-adjacent-groups-subsequence-i.js b/solutions/2900-longest-unequal-adjacent-groups-subsequence-i.js
new file mode 100644
index 00000000..b4df7c52
--- /dev/null
+++ b/solutions/2900-longest-unequal-adjacent-groups-subsequence-i.js
@@ -0,0 +1,40 @@
+/**
+ * 2900. Longest Unequal Adjacent Groups Subsequence I
+ * https://leetcode.com/problems/longest-unequal-adjacent-groups-subsequence-i/
+ * Difficulty: Easy
+ *
+ * You are given a string array words and a binary array groups both of length n, where words[i]
+ * is associated with groups[i].
+ *
+ * Your task is to select the longest alternating subsequence from words. A subsequence of words
+ * is alternating if for any two consecutive strings in the sequence, their corresponding elements
+ * in the binary array groups differ. Essentially, you are to choose strings such that adjacent
+ * elements have non-matching corresponding bits in the groups array.
+ *
+ * Formally, you need to find the longest subsequence of an array of indices [0, 1, ..., n - 1]
+ * denoted as [i0, i1, ..., ik-1], such that groups[ij] != groups[ij+1] for each 0 <= j < k - 1
+ * and then find the words corresponding to these indices.
+ *
+ * Return the selected subsequence. If there are multiple answers, return any of them.
+ *
+ * Note: The elements in words are distinct.
+ */
+
+/**
+ * @param {string[]} words
+ * @param {number[]} groups
+ * @return {string[]}
+ */
+var getLongestSubsequence = function(words, groups) {
+  const result = [words[0]];
+  let lastGroup = groups[0];
+
+  for (let i = 1; i < words.length; i++) {
+    if (groups[i] !== lastGroup) {
+      result.push(words[i]);
+      lastGroup = groups[i];
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2901-longest-unequal-adjacent-groups-subsequence-ii.js b/solutions/2901-longest-unequal-adjacent-groups-subsequence-ii.js
new file mode 100644
index 00000000..1a290423
--- /dev/null
+++ b/solutions/2901-longest-unequal-adjacent-groups-subsequence-ii.js
@@ -0,0 +1,68 @@
+/**
+ * 2901. Longest Unequal Adjacent Groups Subsequence II
+ * https://leetcode.com/problems/longest-unequal-adjacent-groups-subsequence-ii/
+ * Difficulty: Medium
+ *
+ * You are given a string array words, and an array groups, both arrays having length n.
+ *
+ * The hamming distance between two strings of equal length is the number of positions at which the
+ * corresponding characters are different.
+ *
+ * You need to select the longest subsequence from an array of indices [0, 1, ..., n - 1], such
+ * that for the subsequence denoted as [i0, i1, ..., ik-1] having length k, the following holds:
+ * - For adjacent indices in the subsequence, their corresponding groups are unequal, i.e.,
+ *   groups[ij] != groups[ij+1], for each j where 0 < j + 1 < k.
+ * - words[ij] and words[ij+1] are equal in length, and the hamming distance between them is 1,
+ *   where 0 < j + 1 < k, for all indices in the subsequence.
+ *
+ * Return a string array containing the words corresponding to the indices (in order) in the
+ * selected subsequence. If there are multiple answers, return any of them.
+ *
+ * Note: strings in words may be unequal in length.
+ */
+
+/**
+ * @param {string[]} words
+ * @param {number[]} groups
+ * @return {string[]}
+ */
+var getWordsInLongestSubsequence = function(words, groups) {
+  const n = words.length;
+  const dp = new Array(n).fill(1);
+  const prev = new Array(n).fill(-1);
+  let maxLen = 1;
+  let lastIndex = 0;
+
+  for (let i = 1; i < n; i++) {
+    for (let j = 0; j < i; j++) {
+      if (groups[i] !== groups[j] && helper(words[i], words[j])) {
+        if (dp[j] + 1 > dp[i]) {
+          dp[i] = dp[j] + 1;
+          prev[i] = j;
+        }
+      }
+    }
+    if (dp[i] > maxLen) {
+      maxLen = dp[i];
+      lastIndex = i;
+    }
+  }
+
+  const result = [];
+  while (lastIndex !== -1) {
+    result.push(words[lastIndex]);
+    lastIndex = prev[lastIndex];
+  }
+
+  return result.reverse();
+
+  function helper(s1, s2) {
+    if (s1.length !== s2.length) return false;
+    let diff = 0;
+    for (let i = 0; i < s1.length; i++) {
+      if (s1[i] !== s2[i]) diff++;
+      if (diff > 1) return false;
+    }
+    return diff === 1;
+  }
+};
diff --git a/solutions/2903-find-indices-with-index-and-value-difference-i.js b/solutions/2903-find-indices-with-index-and-value-difference-i.js
new file mode 100644
index 00000000..2ef70aeb
--- /dev/null
+++ b/solutions/2903-find-indices-with-index-and-value-difference-i.js
@@ -0,0 +1,36 @@
+/**
+ * 2903. Find Indices With Index and Value Difference I
+ * https://leetcode.com/problems/find-indices-with-index-and-value-difference-i/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed integer array nums having length n, an integer indexDifference,
+ * and an integer valueDifference.
+ *
+ * Your task is to find two indices i and j, both in the range [0, n - 1], that satisfy the
+ * following conditions:
+ * - abs(i - j) >= indexDifference, and
+ * - abs(nums[i] - nums[j]) >= valueDifference
+ *
+ * Return an integer array answer, where answer = [i, j] if there are two such indices, and
+ * answer = [-1, -1] otherwise. If there are multiple choices for the two indices, return
+ * any of them.
+ *
+ * Note: i and j may be equal.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} indexDifference
+ * @param {number} valueDifference
+ * @return {number[]}
+ */
+var findIndices = function(nums, indexDifference, valueDifference) {
+  for (let i = 0; i < nums.length; i++) {
+    for (let j = i; j < nums.length; j++) {
+      if (Math.abs(i - j) >= indexDifference && Math.abs(nums[i] - nums[j]) >= valueDifference) {
+        return [i, j];
+      }
+    }
+  }
+  return [-1, -1];
+};
diff --git a/solutions/2904-shortest-and-lexicographically-smallest-beautiful-string.js b/solutions/2904-shortest-and-lexicographically-smallest-beautiful-string.js
new file mode 100644
index 00000000..d328f151
--- /dev/null
+++ b/solutions/2904-shortest-and-lexicographically-smallest-beautiful-string.js
@@ -0,0 +1,48 @@
+/**
+ * 2904. Shortest and Lexicographically Smallest Beautiful String
+ * https://leetcode.com/problems/shortest-and-lexicographically-smallest-beautiful-string/
+ * Difficulty: Medium
+ *
+ * You are given a binary string s and a positive integer k.
+ *
+ * A substring of s is beautiful if the number of 1's in it is exactly k.
+ *
+ * Let len be the length of the shortest beautiful substring.
+ *
+ * Return the lexicographically smallest beautiful substring of string s with length equal to
+ * len. If s doesn't contain a beautiful substring, return an empty string.
+ *
+ * A string a is lexicographically larger than a string b (of the same length) if in the first
+ * position where a and b differ, a has a character strictly larger than the corresponding
+ * character in b.
+ * - For example, "abcd" is lexicographically larger than "abcc" because the first position they
+ *   differ is at the fourth character, and d is greater than c.
+ */
+
+/**
+ * @param {string} s
+ * @param {number} k
+ * @return {string}
+ */
+var shortestBeautifulSubstring = function(s, k) {
+  let minLength = Infinity;
+  let result = '';
+
+  for (let start = 0; start < s.length; start++) {
+    let onesCount = 0;
+    for (let end = start; end < s.length; end++) {
+      if (s[end] === '1') onesCount++;
+      if (onesCount === k) {
+        const currentLength = end - start + 1;
+        const currentSubstring = s.slice(start, end + 1);
+        if (currentLength < minLength
+            || (currentLength === minLength && currentSubstring < result)) {
+          minLength = currentLength;
+          result = currentSubstring;
+        }
+      }
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2908-minimum-sum-of-mountain-triplets-i.js b/solutions/2908-minimum-sum-of-mountain-triplets-i.js
new file mode 100644
index 00000000..31f04c6a
--- /dev/null
+++ b/solutions/2908-minimum-sum-of-mountain-triplets-i.js
@@ -0,0 +1,34 @@
+/**
+ * 2908. Minimum Sum of Mountain Triplets I
+ * https://leetcode.com/problems/minimum-sum-of-mountain-triplets-i/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed array nums of integers.
+ *
+ * A triplet of indices (i, j, k) is a mountain if:
+ * - i < j < k
+ * - nums[i] < nums[j] and nums[k] < nums[j]
+ *
+ * Return the minimum possible sum of a mountain triplet of nums. If no such triplet exists,
+ * return -1.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var minimumSum = function(nums) {
+  let minSum = Infinity;
+
+  for (let i = 0; i < nums.length - 2; i++) {
+    for (let j = i + 1; j < nums.length - 1; j++) {
+      for (let k = j + 1; k < nums.length; k++) {
+        if (nums[i] < nums[j] && nums[k] < nums[j]) {
+          minSum = Math.min(minSum, nums[i] + nums[j] + nums[k]);
+        }
+      }
+    }
+  }
+
+  return minSum === Infinity ? -1 : minSum;
+};
diff --git a/solutions/2909-minimum-sum-of-mountain-triplets-ii.js b/solutions/2909-minimum-sum-of-mountain-triplets-ii.js
new file mode 100644
index 00000000..21e15bd7
--- /dev/null
+++ b/solutions/2909-minimum-sum-of-mountain-triplets-ii.js
@@ -0,0 +1,43 @@
+/**
+ * 2909. Minimum Sum of Mountain Triplets II
+ * https://leetcode.com/problems/minimum-sum-of-mountain-triplets-ii/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed array nums of integers.
+ *
+ * A triplet of indices (i, j, k) is a mountain if:
+ * - i < j < k
+ * - nums[i] < nums[j] and nums[k] < nums[j]
+ *
+ * Return the minimum possible sum of a mountain triplet of nums. If no such triplet
+ * exists, return -1.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var minimumSum = function(nums) {
+  const n = nums.length;
+  const leftMin = new Array(n).fill(Infinity);
+  const rightMin = new Array(n).fill(Infinity);
+
+  leftMin[0] = nums[0];
+  for (let i = 1; i < n; i++) {
+    leftMin[i] = Math.min(leftMin[i - 1], nums[i]);
+  }
+
+  rightMin[n - 1] = nums[n - 1];
+  for (let i = n - 2; i >= 0; i--) {
+    rightMin[i] = Math.min(rightMin[i + 1], nums[i]);
+  }
+
+  let minSum = Infinity;
+  for (let j = 1; j < n - 1; j++) {
+    if (nums[j] > leftMin[j - 1] && nums[j] > rightMin[j + 1]) {
+      minSum = Math.min(minSum, leftMin[j - 1] + nums[j] + rightMin[j + 1]);
+    }
+  }
+
+  return minSum === Infinity ? -1 : minSum;
+};
diff --git a/solutions/2913-subarrays-distinct-element-sum-of-squares-i.js b/solutions/2913-subarrays-distinct-element-sum-of-squares-i.js
new file mode 100644
index 00000000..ebb8fdfb
--- /dev/null
+++ b/solutions/2913-subarrays-distinct-element-sum-of-squares-i.js
@@ -0,0 +1,34 @@
+/**
+ * 2913. Subarrays Distinct Element Sum of Squares I
+ * https://leetcode.com/problems/subarrays-distinct-element-sum-of-squares-i/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed integer array nums.
+ *
+ * The distinct count of a subarray of nums is defined as:
+ * - Let nums[i..j] be a subarray of nums consisting of all the indices from i to j such
+ *   that 0 <= i <= j < nums.length. Then the number of distinct values in nums[i..j] is
+ *   called the distinct count of nums[i..j].
+ *
+ * Return the sum of the squares of distinct counts of all subarrays of nums.
+ *
+ * A subarray is a contiguous non-empty sequence of elements within an array.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var sumCounts = function(nums) {
+  let result = 0;
+
+  for (let i = 0; i < nums.length; i++) {
+    const set = new Set();
+    for (let j = i; j < nums.length; j++) {
+      set.add(nums[j]);
+      result += set.size * set.size;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2914-minimum-number-of-changes-to-make-binary-string-beautiful.js b/solutions/2914-minimum-number-of-changes-to-make-binary-string-beautiful.js
new file mode 100644
index 00000000..2c50bf70
--- /dev/null
+++ b/solutions/2914-minimum-number-of-changes-to-make-binary-string-beautiful.js
@@ -0,0 +1,29 @@
+/**
+ * 2914. Minimum Number of Changes to Make Binary String Beautiful
+ * https://leetcode.com/problems/minimum-number-of-changes-to-make-binary-string-beautiful/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed binary string s having an even length.
+ *
+ * A string is beautiful if it's possible to partition it into one or more substrings such that:
+ * - Each substring has an even length.
+ * - Each substring contains only 1's or only 0's.
+ *
+ * You can change any character in s to 0 or 1.
+ *
+ * Return the minimum number of changes required to make the string s beautiful.
+ */
+
+/**
+ * @param {string} s
+ * @return {number}
+ */
+var minChanges = function(s) {
+  let result = 0;
+
+  for (let i = 0; i < s.length; i += 2) {
+    if (s[i] !== s[i + 1]) result++;
+  }
+
+  return result;
+};
diff --git a/solutions/2917-find-the-k-or-of-an-array.js b/solutions/2917-find-the-k-or-of-an-array.js
new file mode 100644
index 00000000..d37773ad
--- /dev/null
+++ b/solutions/2917-find-the-k-or-of-an-array.js
@@ -0,0 +1,30 @@
+/**
+ * 2917. Find the K-or of an Array
+ * https://leetcode.com/problems/find-the-k-or-of-an-array/
+ * Difficulty: Easy
+ *
+ * You are given an integer array nums, and an integer k. Let's introduce K-or operation
+ * by extending the standard bitwise OR. In K-or, a bit position in the result is set to
+ * 1 if at least k numbers in nums have a 1 in that position.
+ *
+ * Return the K-or of nums.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @return {number}
+ */
+var findKOr = function(nums, k) {
+  let result = 0;
+
+  for (let bit = 0; bit < 31; bit++) {
+    let count = 0;
+    for (const num of nums) {
+      if (num & (1 << bit)) count++;
+    }
+    if (count >= k) result |= (1 << bit);
+  }
+
+  return result;
+};
diff --git a/solutions/2918-minimum-equal-sum-of-two-arrays-after-replacing-zeros.js b/solutions/2918-minimum-equal-sum-of-two-arrays-after-replacing-zeros.js
new file mode 100644
index 00000000..15ea4af7
--- /dev/null
+++ b/solutions/2918-minimum-equal-sum-of-two-arrays-after-replacing-zeros.js
@@ -0,0 +1,40 @@
+/**
+ * 2918. Minimum Equal Sum of Two Arrays After Replacing Zeros
+ * https://leetcode.com/problems/minimum-equal-sum-of-two-arrays-after-replacing-zeros/
+ * Difficulty: Medium
+ *
+ * You are given two arrays nums1 and nums2 consisting of positive integers.
+ *
+ * You have to replace all the 0's in both arrays with strictly positive integers such that the
+ * sum of elements of both arrays becomes equal.
+ *
+ * Return the minimum equal sum you can obtain, or -1 if it is impossible.
+ */
+
+/**
+ * @param {number[]} nums1
+ * @param {number[]} nums2
+ * @return {number}
+ */
+var minSum = function(nums1, nums2) {
+  let sum1 = 0;
+  let zeros1 = 0;
+  for (const num of nums1) {
+    sum1 += num;
+    if (num === 0) zeros1++;
+  }
+
+  let sum2 = 0;
+  let zeros2 = 0;
+  for (const num of nums2) {
+    sum2 += num;
+    if (num === 0) zeros2++;
+  }
+
+  const minSum1 = sum1 + zeros1;
+  const minSum2 = sum2 + zeros2;
+
+  if (minSum1 > sum2 && zeros2 === 0 || minSum2 > sum1 && zeros1 === 0) return -1;
+
+  return Math.max(minSum1, minSum2);
+};
diff --git a/solutions/2923-find-champion-i.js b/solutions/2923-find-champion-i.js
new file mode 100644
index 00000000..c641cd07
--- /dev/null
+++ b/solutions/2923-find-champion-i.js
@@ -0,0 +1,37 @@
+/**
+ * 2923. Find Champion I
+ * https://leetcode.com/problems/find-champion-i/
+ * Difficulty: Easy
+ *
+ * There are n teams numbered from 0 to n - 1 in a tournament.
+ *
+ * Given a 0-indexed 2D boolean matrix grid of size n * n. For all i, j that 0 <= i, j <= n - 1
+ * and i != j team i is stronger than team j if grid[i][j] == 1, otherwise, team j is stronger
+ * than team i.
+ *
+ * Team a will be the champion of the tournament if there is no team b that is stronger than
+ * team a.
+ *
+ * Return the team that will be the champion of the tournament.
+ */
+
+/**
+ * @param {number[][]} grid
+ * @return {number}
+ */
+var findChampion = function(grid) {
+  const n = grid.length;
+
+  for (let i = 0; i < n; i++) {
+    let isChampion = true;
+    for (let j = 0; j < n; j++) {
+      if (i !== j && grid[j][i] === 1) {
+        isChampion = false;
+        break;
+      }
+    }
+    if (isChampion) return i;
+  }
+
+  return -1;
+};
diff --git a/solutions/2924-find-champion-ii.js b/solutions/2924-find-champion-ii.js
new file mode 100644
index 00000000..a475f55d
--- /dev/null
+++ b/solutions/2924-find-champion-ii.js
@@ -0,0 +1,47 @@
+/**
+ * 2924. Find Champion II
+ * https://leetcode.com/problems/find-champion-ii/
+ * Difficulty: Medium
+ *
+ * There are n teams numbered from 0 to n - 1 in a tournament; each team is also a node in a DAG.
+ *
+ * You are given the integer n and a 0-indexed 2D integer array edges of length m representing the
+ * DAG, where edges[i] = [ui, vi] indicates that there is a directed edge from team ui to team vi
+ * in the graph.
+ *
+ * A directed edge from a to b in the graph means that team a is stronger than team b and team b
+ * is weaker than team a.
+ *
+ * Team a will be the champion of the tournament if there is no team b that is stronger than team a.
+ *
+ * Return the team that will be the champion of the tournament if there is a unique champion,
+ * otherwise, return -1.
+ *
+ * Notes:
+ * - A cycle is a series of nodes a1, a2, ..., an, an+1 such that node a1 is the same node as node
+ *   an+1, the nodes a1, a2, ..., an are distinct, and there is a directed edge from the node ai
+ *   to node ai+1 for every i in the range [1, n].
+ * - A DAG is a directed graph that does not have any cycle.
+ */
+
+/**
+ * @param {number} n
+ * @param {number[][]} edges
+ * @return {number}
+ */
+var findChampion = function(n, edges) {
+  const inDegree = new Array(n).fill(0);
+
+  for (const [, v] of edges) {
+    inDegree[v]++;
+  }
+  let champion = -1;
+  for (let i = 0; i < n; i++) {
+    if (inDegree[i] === 0) {
+      if (champion !== -1) return -1;
+      champion = i;
+    }
+  }
+
+  return champion;
+};
diff --git a/solutions/2925-maximum-score-after-applying-operations-on-a-tree.js b/solutions/2925-maximum-score-after-applying-operations-on-a-tree.js
new file mode 100644
index 00000000..55cb4532
--- /dev/null
+++ b/solutions/2925-maximum-score-after-applying-operations-on-a-tree.js
@@ -0,0 +1,58 @@
+/**
+ * 2925. Maximum Score After Applying Operations on a Tree
+ * https://leetcode.com/problems/maximum-score-after-applying-operations-on-a-tree/
+ * Difficulty: Medium
+ *
+ * There is an undirected tree with n nodes labeled from 0 to n - 1, and rooted at node 0. You are
+ * given a 2D integer array edges of length n - 1, where edges[i] = [ai, bi] indicates that there
+ * is an edge between nodes ai and bi in the tree.
+ *
+ * You are also given a 0-indexed integer array values of length n, where values[i] is the value
+ * associated with the ith node.
+ *
+ * You start with a score of 0. In one operation, you can:
+ * - Pick any node i.
+ * - Add values[i] to your score.
+ * - Set values[i] to 0.
+ *
+ * A tree is healthy if the sum of values on the path from the root to any leaf node is different
+ * than zero.
+ *
+ * Return the maximum score you can obtain after performing these operations on the tree any
+ * number of times so that it remains healthy.
+ */
+
+/**
+ * @param {number[][]} edges
+ * @param {number[]} values
+ * @return {number}
+ */
+var maximumScoreAfterOperations = function(edges, values) {
+  const n = values.length;
+  const graph = new Array(n).fill().map(() => []);
+
+  for (const [u, v] of edges) {
+    graph[u].push(v);
+    graph[v].push(u);
+  }
+
+  const totalSum = values.reduce((sum, val) => sum + val, 0);
+  const minToKeep = dfs(0, -1);
+
+  return totalSum - minToKeep;
+
+  function dfs(node, parent) {
+    const children = graph[node].filter(child => child !== parent);
+
+    if (children.length === 0) {
+      return values[node];
+    }
+
+    let childrenSum = 0;
+    for (const child of children) {
+      childrenSum += dfs(child, node);
+    }
+
+    return Math.min(values[node], childrenSum);
+  }
+};
diff --git a/solutions/2928-distribute-candies-among-children-i.js b/solutions/2928-distribute-candies-among-children-i.js
new file mode 100644
index 00000000..fe0c287d
--- /dev/null
+++ b/solutions/2928-distribute-candies-among-children-i.js
@@ -0,0 +1,28 @@
+/**
+ * 2928. Distribute Candies Among Children I
+ * https://leetcode.com/problems/distribute-candies-among-children-i/
+ * Difficulty: Easy
+ *
+ * You are given two positive integers n and limit.
+ *
+ * Return the total number of ways to distribute n candies among 3 children such that no child
+ * gets more than limit candies.
+ */
+
+/**
+ * @param {number} n
+ * @param {number} limit
+ * @return {number}
+ */
+var distributeCandies = function(n, limit) {
+  let result = 0;
+
+  for (let i = 0; i <= Math.min(n, limit); i++) {
+    for (let j = 0; j <= Math.min(n - i, limit); j++) {
+      const k = n - i - j;
+      if (k >= 0 && k <= limit) result++;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2929-distribute-candies-among-children-ii.js b/solutions/2929-distribute-candies-among-children-ii.js
new file mode 100644
index 00000000..40e830ec
--- /dev/null
+++ b/solutions/2929-distribute-candies-among-children-ii.js
@@ -0,0 +1,30 @@
+/**
+ * 2929. Distribute Candies Among Children II
+ * https://leetcode.com/problems/distribute-candies-among-children-ii/
+ * Difficulty: Medium
+ *
+ * You are given two positive integers n and limit.
+ *
+ * Return the total number of ways to distribute n candies among 3 children such that no child
+ * gets more than limit candies.
+ */
+
+/**
+ * @param {number} n
+ * @param {number} limit
+ * @return {number}
+ */
+var distributeCandies = function(n, limit) {
+  const minCandies = Math.max(0, n - 2 * limit);
+  const maxCandies = Math.min(n, limit);
+  let result = 0;
+
+  for (let i = minCandies; i <= maxCandies; i++) {
+    const remaining = n - i;
+    const minSecond = Math.max(0, remaining - limit);
+    const maxSecond = Math.min(remaining, limit);
+    result += maxSecond - minSecond + 1;
+  }
+
+  return result;
+};
diff --git a/solutions/2932-maximum-strong-pair-xor-i.js b/solutions/2932-maximum-strong-pair-xor-i.js
new file mode 100644
index 00000000..67477b17
--- /dev/null
+++ b/solutions/2932-maximum-strong-pair-xor-i.js
@@ -0,0 +1,37 @@
+/**
+ * 2932. Maximum Strong Pair XOR I
+ * https://leetcode.com/problems/maximum-strong-pair-xor-i/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed integer array nums. A pair of integers x and y is called a strong pair
+ * if it satisfies the condition:
+ * - |x - y| <= min(x, y)
+ *
+ * You need to select two integers from nums such that they form a strong pair and their bitwise
+ * XOR is the maximum among all strong pairs in the array.
+ *
+ * Return the maximum XOR value out of all possible strong pairs in the array nums.
+ *
+ * Note that you can pick the same integer twice to form a pair.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var maximumStrongPairXor = function(nums) {
+  let result = 0;
+  nums.sort((a, b) => a - b);
+
+  for (let i = 0; i < nums.length; i++) {
+    for (let j = i; j < nums.length; j++) {
+      if (nums[j] - nums[i] <= Math.min(nums[i], nums[j])) {
+        result = Math.max(result, nums[i] ^ nums[j]);
+      } else {
+        break;
+      }
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2933-high-access-employees.js b/solutions/2933-high-access-employees.js
new file mode 100644
index 00000000..98c9a73f
--- /dev/null
+++ b/solutions/2933-high-access-employees.js
@@ -0,0 +1,54 @@
+/**
+ * 2933. High-Access Employees
+ * https://leetcode.com/problems/high-access-employees/
+ * Difficulty: Medium
+ *
+ * You are given a 2D 0-indexed array of strings, accessTimes, with size n. For each i where
+ * 0 <= i <= n - 1, accessTimes[i][0] represents the name of an employee, and accessTimes[i][1]
+ * represents the access time of that employee. All entries in accessTimes are within the same day.
+ *
+ * The access time is represented as four digits using a 24-hour time format, for example, "0800"
+ * or "2250".
+ *
+ * An employee is said to be high-access if he has accessed the system three or more times within
+ * a one-hour period.
+ *
+ * Times with exactly one hour of difference are not considered part of the same one-hour period.
+ * For example, "0815" and "0915" are not part of the same one-hour period.
+ *
+ * Access times at the start and end of the day are not counted within the same one-hour period.
+ * For example, "0005" and "2350" are not part of the same one-hour period.
+ *
+ * Return a list that contains the names of high-access employees with any order you want.
+ */
+
+/**
+ * @param {string[][]} accessTimes
+ * @return {string[]}
+ */
+var findHighAccessEmployees = function(accessTimes) {
+  const employeeAccess = new Map();
+
+  for (const [name, time] of accessTimes) {
+    const minutes = parseInt(time.slice(0, 2)) * 60 + parseInt(time.slice(2));
+    if (!employeeAccess.has(name)) {
+      employeeAccess.set(name, []);
+    }
+    employeeAccess.get(name).push(minutes);
+  }
+
+  const result = [];
+  for (const [name, times] of employeeAccess) {
+    times.sort((a, b) => a - b);
+    if (times.length >= 3) {
+      for (let i = 0; i <= times.length - 3; i++) {
+        if (times[i + 2] - times[i] < 60) {
+          result.push(name);
+          break;
+        }
+      }
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2934-minimum-operations-to-maximize-last-elements-in-arrays.js b/solutions/2934-minimum-operations-to-maximize-last-elements-in-arrays.js
new file mode 100644
index 00000000..c2803a60
--- /dev/null
+++ b/solutions/2934-minimum-operations-to-maximize-last-elements-in-arrays.js
@@ -0,0 +1,57 @@
+/**
+ * 2934. Minimum Operations to Maximize Last Elements in Arrays
+ * https://leetcode.com/problems/minimum-operations-to-maximize-last-elements-in-arrays/
+ * Difficulty: Medium
+ *
+ * You are given two 0-indexed integer arrays, nums1 and nums2, both having length n.
+ *
+ * You are allowed to perform a series of operations (possibly none).
+ *
+ * In an operation, you select an index i in the range [0, n - 1] and swap the values of
+ * nums1[i] and nums2[i].
+ *
+ * Your task is to find the minimum number of operations required to satisfy the following
+ * conditions:
+ * - nums1[n - 1] is equal to the maximum value among all elements of nums1, i.e.,
+ *   nums1[n - 1] = max(nums1[0], nums1[1], ..., nums1[n - 1]).
+ * - nums2[n - 1] is equal to the maximum value among all elements of nums2, i.e.,
+ *   nums2[n - 1] = max(nums2[0], nums2[1], ..., nums2[n - 1]).
+ *
+ * Return an integer denoting the minimum number of operations needed to meet both conditions,
+ * or -1 if it is impossible to satisfy both conditions.
+ */
+
+/**
+ * @param {number[]} nums1
+ * @param {number[]} nums2
+ * @return {number}
+ */
+var minOperations = function(nums1, nums2) {
+  const n = nums1.length;
+  const last1 = nums1[n - 1];
+  const last2 = nums2[n - 1];
+
+  let swapsNoChange = 0;
+  let swapsChange = 0;
+
+  for (let i = 0; i < n - 1; i++) {
+    if (nums1[i] > last1 || nums2[i] > last2) {
+      if (nums2[i] > last1 || nums1[i] > last2) {
+        return -1;
+      }
+      swapsNoChange++;
+    }
+    if (nums1[i] > last2 || nums2[i] > last1) {
+      if (nums2[i] > last2 || nums1[i] > last1) {
+        return -1;
+      }
+      swapsChange++;
+    }
+  }
+
+  if (last1 !== last2) {
+    swapsChange++;
+  }
+
+  return Math.min(swapsNoChange, swapsChange);
+};
diff --git a/solutions/2937-make-three-strings-equal.js b/solutions/2937-make-three-strings-equal.js
new file mode 100644
index 00000000..c7dad334
--- /dev/null
+++ b/solutions/2937-make-three-strings-equal.js
@@ -0,0 +1,35 @@
+/**
+ * 2937. Make Three Strings Equal
+ * https://leetcode.com/problems/make-three-strings-equal/
+ * Difficulty: Easy
+ *
+ * You are given three strings: s1, s2, and s3. In one operation you can choose one of these
+ * strings and delete its rightmost character. Note that you cannot completely empty a string.
+ *
+ * Return the minimum number of operations required to make the strings equal. If it is
+ * impossible to make them equal, return -1.
+ */
+
+/**
+ * @param {string} s1
+ * @param {string} s2
+ * @param {string} s3
+ * @return {number}
+ */
+var findMinimumOperations = function(s1, s2, s3) {
+  const minLength = Math.min(s1.length, s2.length, s3.length);
+
+  let commonPrefixLength = 0;
+  for (let i = 0; i < minLength; i++) {
+    if (s1[i] !== s2[i] || s2[i] !== s3[i]) {
+      break;
+    }
+    commonPrefixLength++;
+  }
+
+  if (commonPrefixLength === 0) {
+    return -1;
+  }
+
+  return s1.length + s2.length + s3.length - 3 * commonPrefixLength;
+};
diff --git a/solutions/2938-separate-black-and-white-balls.js b/solutions/2938-separate-black-and-white-balls.js
new file mode 100644
index 00000000..cd8d022d
--- /dev/null
+++ b/solutions/2938-separate-black-and-white-balls.js
@@ -0,0 +1,33 @@
+/**
+ * 2938. Separate Black and White Balls
+ * https://leetcode.com/problems/separate-black-and-white-balls/
+ * Difficulty: Medium
+ *
+ * There are n balls on a table, each ball has a color black or white.
+ *
+ * You are given a 0-indexed binary string s of length n, where 1 and 0 represent black and white
+ * balls, respectively.
+ *
+ * In each step, you can choose two adjacent balls and swap them.
+ *
+ * Return the minimum number of steps to group all the black balls to the right and all the white
+ * balls to the left.
+ */
+
+/**
+ * @param {string} s
+ * @return {number}
+ */
+var minimumSteps = function(s) {
+  let result = 0;
+  let whiteCount = 0;
+
+  for (let i = 0; i < s.length; i++) {
+    if (s[i] === '0') {
+      result += i - whiteCount;
+      whiteCount++;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2942-find-words-containing-character.js b/solutions/2942-find-words-containing-character.js
new file mode 100644
index 00000000..9fadea6b
--- /dev/null
+++ b/solutions/2942-find-words-containing-character.js
@@ -0,0 +1,28 @@
+/**
+ * 2942. Find Words Containing Character
+ * https://leetcode.com/problems/find-words-containing-character/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed array of strings words and a character x.
+ *
+ * Return an array of indices representing the words that contain the character x.
+ *
+ * Note that the returned array may be in any order.
+ */
+
+/**
+ * @param {string[]} words
+ * @param {character} x
+ * @return {number[]}
+ */
+var findWordsContaining = function(words, x) {
+  const result = [];
+
+  for (let i = 0; i < words.length; i++) {
+    if (words[i].includes(x)) {
+      result.push(i);
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2946-matrix-similarity-after-cyclic-shifts.js b/solutions/2946-matrix-similarity-after-cyclic-shifts.js
new file mode 100644
index 00000000..4d93251f
--- /dev/null
+++ b/solutions/2946-matrix-similarity-after-cyclic-shifts.js
@@ -0,0 +1,35 @@
+/**
+ * 2946. Matrix Similarity After Cyclic Shifts
+ * https://leetcode.com/problems/matrix-similarity-after-cyclic-shifts/
+ * Difficulty: Easy
+ *
+ * You are given an m x n integer matrix mat and an integer k. The matrix rows are 0-indexed.
+ *
+ * The following proccess happens k times:
+ * - Even-indexed rows (0, 2, 4, ...) are cyclically shifted to the left.
+ * - Odd-indexed rows (1, 3, 5, ...) are cyclically shifted to the right.
+ *
+ * Return true if the final modified matrix after k steps is identical to the original matrix,
+ * and false otherwise.
+ */
+
+/**
+ * @param {number[][]} mat
+ * @param {number} k
+ * @return {boolean}
+ */
+var areSimilar = function(mat, k) {
+  const m = mat.length;
+  const n = mat[0].length;
+
+  for (let i = 0; i < m; i++) {
+    for (let j = 0; j < n; j++) {
+      const shift = i % 2 === 0 ? (j - k % n + n) % n : (j + k % n) % n;
+      if (mat[i][j] !== mat[i][shift]) {
+        return false;
+      }
+    }
+  }
+
+  return true;
+};
diff --git a/solutions/2947-count-beautiful-substrings-i.js b/solutions/2947-count-beautiful-substrings-i.js
new file mode 100644
index 00000000..0972a990
--- /dev/null
+++ b/solutions/2947-count-beautiful-substrings-i.js
@@ -0,0 +1,51 @@
+/**
+ * 2947. Count Beautiful Substrings I
+ * https://leetcode.com/problems/count-beautiful-substrings-i/
+ * Difficulty: Medium
+ *
+ * You are given a string s and a positive integer k.
+ *
+ * Let vowels and consonants be the number of vowels and consonants in a string.
+ *
+ * A string is beautiful if:
+ * - vowels == consonants.
+ * - (vowels * consonants) % k == 0, in other terms the multiplication of vowels and
+ *   consonants is divisible by k.
+ *
+ * Return the number of non-empty beautiful substrings in the given string s.
+ *
+ * A substring is a contiguous sequence of characters in a string.
+ *
+ * Vowel letters in English are 'a', 'e', 'i', 'o', and 'u'.
+ *
+ * Consonant letters in English are every letter except vowels.
+ */
+
+/**
+ * @param {string} s
+ * @param {number} k
+ * @return {number}
+ */
+var beautifulSubstrings = function(s, k) {
+  const vowels = new Set(['a', 'e', 'i', 'o', 'u']);
+  let result = 0;
+
+  for (let start = 0; start < s.length; start++) {
+    let vowelCount = 0;
+    let consonantCount = 0;
+
+    for (let end = start; end < s.length; end++) {
+      if (vowels.has(s[end])) {
+        vowelCount++;
+      } else {
+        consonantCount++;
+      }
+
+      if (vowelCount === consonantCount && (vowelCount * consonantCount) % k === 0) {
+        result++;
+      }
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2951-find-the-peaks.js b/solutions/2951-find-the-peaks.js
new file mode 100644
index 00000000..45e40576
--- /dev/null
+++ b/solutions/2951-find-the-peaks.js
@@ -0,0 +1,30 @@
+/**
+ * 2951. Find the Peaks
+ * https://leetcode.com/problems/find-the-peaks/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed array mountain. Your task is to find all the peaks in the
+ * mountain array.
+ *
+ * Return an array that consists of indices of peaks in the given array in any order.
+ *
+ * Notes:
+ * - A peak is defined as an element that is strictly greater than its neighboring elements.
+ * - The first and last elements of the array are not a peak.
+ */
+
+/**
+ * @param {number[]} mountain
+ * @return {number[]}
+ */
+var findPeaks = function(mountain) {
+  const result = [];
+
+  for (let i = 1; i < mountain.length - 1; i++) {
+    if (mountain[i] > mountain[i - 1] && mountain[i] > mountain[i + 1]) {
+      result.push(i);
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2952-minimum-number-of-coins-to-be-added.js b/solutions/2952-minimum-number-of-coins-to-be-added.js
new file mode 100644
index 00000000..8290c3f1
--- /dev/null
+++ b/solutions/2952-minimum-number-of-coins-to-be-added.js
@@ -0,0 +1,41 @@
+/**
+ * 2952. Minimum Number of Coins to be Added
+ * https://leetcode.com/problems/minimum-number-of-coins-to-be-added/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed integer array coins, representing the values of the coins available,
+ * and an integer target.
+ *
+ * An integer x is obtainable if there exists a subsequence of coins that sums to x.
+ *
+ * Return the minimum number of coins of any value that need to be added to the array so that every
+ * integer in the range [1, target] is obtainable.
+ *
+ * A subsequence of an array is a new non-empty array that is formed from the original array by
+ * deleting some (possibly none) of the elements without disturbing the relative positions of the
+ * remaining elements.
+ */
+
+/**
+ * @param {number[]} coins
+ * @param {number} target
+ * @return {number}
+ */
+var minimumAddedCoins = function(coins, target) {
+  coins.sort((a, b) => a - b);
+  let result = 0;
+  let currentMax = 0;
+  let index = 0;
+
+  while (currentMax < target) {
+    if (index < coins.length && coins[index] <= currentMax + 1) {
+      currentMax += coins[index];
+      index++;
+    } else {
+      currentMax += currentMax + 1;
+      result++;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2956-find-common-elements-between-two-arrays.js b/solutions/2956-find-common-elements-between-two-arrays.js
new file mode 100644
index 00000000..8189c0e2
--- /dev/null
+++ b/solutions/2956-find-common-elements-between-two-arrays.js
@@ -0,0 +1,39 @@
+/**
+ * 2956. Find Common Elements Between Two Arrays
+ * https://leetcode.com/problems/find-common-elements-between-two-arrays/
+ * Difficulty: Easy
+ *
+ * You are given two integer arrays nums1 and nums2 of sizes n and m, respectively.
+ * Calculate the following values:
+ * - answer1 : the number of indices i such that nums1[i] exists in nums2.
+ * - answer2 : the number of indices i such that nums2[i] exists in nums1.
+ *
+ * Return [answer1,answer2].
+ */
+
+/**
+ * @param {number[]} nums1
+ * @param {number[]} nums2
+ * @return {number[]}
+ */
+var findIntersectionValues = function(nums1, nums2) {
+  const set1 = new Set(nums1);
+  const set2 = new Set(nums2);
+
+  let count1 = 0;
+  let count2 = 0;
+
+  for (const num of nums1) {
+    if (set2.has(num)) {
+      count1++;
+    }
+  }
+
+  for (const num of nums2) {
+    if (set1.has(num)) {
+      count2++;
+    }
+  }
+
+  return [count1, count2];
+};
diff --git a/solutions/2957-remove-adjacent-almost-equal-characters.js b/solutions/2957-remove-adjacent-almost-equal-characters.js
new file mode 100644
index 00000000..c62070dc
--- /dev/null
+++ b/solutions/2957-remove-adjacent-almost-equal-characters.js
@@ -0,0 +1,32 @@
+/**
+ * 2957. Remove Adjacent Almost-Equal Characters
+ * https://leetcode.com/problems/remove-adjacent-almost-equal-characters/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed string word.
+ *
+ * In one operation, you can pick any index i of word and change word[i] to any lowercase
+ * English letter.
+ *
+ * Return the minimum number of operations needed to remove all adjacent almost-equal
+ * characters from word.
+ *
+ * Two characters a and b are almost-equal if a == b or a and b are adjacent in the alphabet.
+ */
+
+/**
+ * @param {string} word
+ * @return {number}
+ */
+var removeAlmostEqualCharacters = function(word) {
+  let result = 0;
+
+  for (let i = 1; i < word.length; i++) {
+    if (Math.abs(word.charCodeAt(i) - word.charCodeAt(i - 1)) <= 1) {
+      result++;
+      i++;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2958-length-of-longest-subarray-with-at-most-k-frequency.js b/solutions/2958-length-of-longest-subarray-with-at-most-k-frequency.js
new file mode 100644
index 00000000..4efcb001
--- /dev/null
+++ b/solutions/2958-length-of-longest-subarray-with-at-most-k-frequency.js
@@ -0,0 +1,40 @@
+/**
+ * 2958. Length of Longest Subarray With at Most K Frequency
+ * https://leetcode.com/problems/length-of-longest-subarray-with-at-most-k-frequency/
+ * Difficulty: Medium
+ *
+ * You are given an integer array nums and an integer k.
+ *
+ * The frequency of an element x is the number of times it occurs in an array.
+ *
+ * An array is called good if the frequency of each element in this array is less than or
+ * equal to k.
+ *
+ * Return the length of the longest good subarray of nums.
+ *
+ * A subarray is a contiguous non-empty sequence of elements within an array.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @return {number}
+ */
+var maxSubarrayLength = function(nums, k) {
+  const map = new Map();
+  let result = 0;
+  let left = 0;
+
+  for (let right = 0; right < nums.length; right++) {
+    map.set(nums[right], (map.get(nums[right]) || 0) + 1);
+
+    while (map.get(nums[right]) > k) {
+      map.set(nums[left], map.get(nums[left]) - 1);
+      left++;
+    }
+
+    result = Math.max(result, right - left + 1);
+  }
+
+  return result;
+};
diff --git a/solutions/2960-count-tested-devices-after-test-operations.js b/solutions/2960-count-tested-devices-after-test-operations.js
new file mode 100644
index 00000000..6c118fb3
--- /dev/null
+++ b/solutions/2960-count-tested-devices-after-test-operations.js
@@ -0,0 +1,40 @@
+/**
+ * 2960. Count Tested Devices After Test Operations
+ * https://leetcode.com/problems/count-tested-devices-after-test-operations/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed integer array batteryPercentages having length n, denoting the
+ * battery percentages of n 0-indexed devices.
+ *
+ * Your task is to test each device i in order from 0 to n - 1, by performing the following
+ * test operations:
+ * - If batteryPercentages[i] is greater than 0:
+ *   - Increment the count of tested devices.
+ *   - Decrease the battery percentage of all devices with indices j in the range [i + 1, n - 1]
+ *     by 1, ensuring their battery percentage never goes below 0, i.e,
+ *     batteryPercentages[j] = max(0, batteryPercentages[j] - 1).
+ *   - Move to the next device.
+ * - Otherwise, move to the next device without performing any test.
+ *
+ * Return an integer denoting the number of devices that will be tested after performing the test
+ * operations in order.
+ */
+
+/**
+ * @param {number[]} batteryPercentages
+ * @return {number}
+ */
+var countTestedDevices = function(batteryPercentages) {
+  let result = 0;
+
+  for (let i = 0; i < batteryPercentages.length; i++) {
+    if (batteryPercentages[i] > 0) {
+      result++;
+      for (let j = i + 1; j < batteryPercentages.length; j++) {
+        batteryPercentages[j] = Math.max(0, batteryPercentages[j] - 1);
+      }
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2961-double-modular-exponentiation.js b/solutions/2961-double-modular-exponentiation.js
new file mode 100644
index 00000000..1a9f9162
--- /dev/null
+++ b/solutions/2961-double-modular-exponentiation.js
@@ -0,0 +1,43 @@
+/**
+ * 2961. Double Modular Exponentiation
+ * https://leetcode.com/problems/double-modular-exponentiation/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed 2D array variables where variables[i] = [ai, bi, ci, mi], and an
+ * integer target.
+ *
+ * An index i is good if the following formula holds:
+ * - 0 <= i < variables.length
+ * - ((aibi % 10)ci) % mi == target
+ *
+ * Return an array consisting of good indices in any order.
+ */
+
+/**
+ * @param {number[][]} variables
+ * @param {number} target
+ * @return {number[]}
+ */
+var getGoodIndices = function(variables, target) {
+  const result = [];
+
+  for (let i = 0; i < variables.length; i++) {
+    const [base, exp1, exp2, modulus] = variables[i];
+
+    let inner = 1;
+    for (let j = 0; j < exp1; j++) {
+      inner = (inner * base) % 10;
+    }
+
+    let count = 1;
+    for (let j = 0; j < exp2; j++) {
+      count = (count * inner) % modulus;
+    }
+
+    if (count === target) {
+      result.push(i);
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2962-count-subarrays-where-max-element-appears-at-least-k-times.js b/solutions/2962-count-subarrays-where-max-element-appears-at-least-k-times.js
new file mode 100644
index 00000000..1a67fad9
--- /dev/null
+++ b/solutions/2962-count-subarrays-where-max-element-appears-at-least-k-times.js
@@ -0,0 +1,35 @@
+/**
+ * 2962. Count Subarrays Where Max Element Appears at Least K Times
+ * https://leetcode.com/problems/count-subarrays-where-max-element-appears-at-least-k-times/
+ * Difficulty: Medium
+ *
+ * You are given an integer array nums and a positive integer k.
+ *
+ * Return the number of subarrays where the maximum element of nums appears at least k times in
+ * that subarray.
+ *
+ * A subarray is a contiguous sequence of elements within an array.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @return {number}
+ */
+var countSubarrays = function(nums, k) {
+  const maxNum = Math.max(...nums);
+  let maxCount = 0;
+  let left = 0;
+  let result = 0;
+
+  for (let right = 0; right < nums.length; right++) {
+    if (nums[right] === maxNum) maxCount++;
+    while (maxCount >= k) {
+      result += nums.length - right;
+      if (nums[left] === maxNum) maxCount--;
+      left++;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2963-count-the-number-of-good-partitions.js b/solutions/2963-count-the-number-of-good-partitions.js
new file mode 100644
index 00000000..9144b31e
--- /dev/null
+++ b/solutions/2963-count-the-number-of-good-partitions.js
@@ -0,0 +1,43 @@
+/**
+ * 2963. Count the Number of Good Partitions
+ * https://leetcode.com/problems/count-the-number-of-good-partitions/
+ * Difficulty: Hard
+ *
+ * You are given a 0-indexed array nums consisting of positive integers.
+ *
+ * A partition of an array into one or more contiguous subarrays is called good if no two
+ * subarrays contain the same number.
+ *
+ * Return the total number of good partitions of nums.
+ *
+ * Since the answer may be large, return it modulo 109 + 7.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var numberOfGoodPartitions = function(nums) {
+  const mod = 1e9 + 7;
+  const map = new Map();
+  let segments = 0;
+  let end = -1;
+
+  for (let i = 0; i < nums.length; i++) {
+    map.set(nums[i], i);
+  }
+
+  for (let i = 0; i < nums.length; i++) {
+    if (i > end) {
+      segments++;
+    }
+    end = Math.max(end, map.get(nums[i]));
+  }
+
+  let result = 1;
+  for (let i = 1; i < segments; i++) {
+    result = (result * 2) % mod;
+  }
+
+  return result;
+};
diff --git a/solutions/2966-divide-array-into-arrays-with-max-difference.js b/solutions/2966-divide-array-into-arrays-with-max-difference.js
new file mode 100644
index 00000000..3da39b41
--- /dev/null
+++ b/solutions/2966-divide-array-into-arrays-with-max-difference.js
@@ -0,0 +1,33 @@
+/**
+ * 2966. Divide Array Into Arrays With Max Difference
+ * https://leetcode.com/problems/divide-array-into-arrays-with-max-difference/
+ * Difficulty: Medium
+ *
+ * You are given an integer array nums of size n where n is a multiple of 3 and a positive
+ * integer k.
+ *
+ * Divide the array nums into n / 3 arrays of size 3 satisfying the following condition:
+ * - The difference between any two elements in one array is less than or equal to k.
+ *
+ * Return a 2D array containing the arrays. If it is impossible to satisfy the conditions, return
+ * an empty array. And if there are multiple answers, return any of them.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @return {number[][]}
+ */
+var divideArray = function(nums, k) {
+  nums.sort((a, b) => a - b);
+  const result = [];
+
+  for (let i = 0; i < nums.length; i += 3) {
+    if (nums[i + 2] - nums[i] > k) {
+      return [];
+    }
+    result.push([nums[i], nums[i + 1], nums[i + 2]]);
+  }
+
+  return result;
+};
diff --git a/solutions/2970-count-the-number-of-incremovable-subarrays-i.js b/solutions/2970-count-the-number-of-incremovable-subarrays-i.js
new file mode 100644
index 00000000..269065a7
--- /dev/null
+++ b/solutions/2970-count-the-number-of-incremovable-subarrays-i.js
@@ -0,0 +1,46 @@
+/**
+ * 2970. Count the Number of Incremovable Subarrays I
+ * https://leetcode.com/problems/count-the-number-of-incremovable-subarrays-i/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed array of positive integers nums.
+ *
+ * A subarray of nums is called incremovable if nums becomes strictly increasing on removing the
+ * subarray. For example, the subarray [3, 4] is an incremovable subarray of [5, 3, 4, 6, 7] because
+ * removing this subarray changes the array [5, 3, 4, 6, 7] to [5, 6, 7] which is strictly
+ * increasing.
+ *
+ * Return the total number of incremovable subarrays of nums.
+ *
+ * Note that an empty array is considered strictly increasing.
+ *
+ * A subarray is a contiguous non-empty sequence of elements within an array.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var incremovableSubarrayCount = function(nums) {
+  let result = 0;
+
+  for (let start = 0; start < nums.length; start++) {
+    for (let end = start; end < nums.length; end++) {
+      let isIncreasing = true;
+      let prev = -Infinity;
+
+      for (let i = 0; i < nums.length; i++) {
+        if (i >= start && i <= end) continue;
+        if (nums[i] <= prev) {
+          isIncreasing = false;
+          break;
+        }
+        prev = nums[i];
+      }
+
+      if (isIncreasing) result++;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2971-find-polygon-with-the-largest-perimeter.js b/solutions/2971-find-polygon-with-the-largest-perimeter.js
new file mode 100644
index 00000000..15d2e501
--- /dev/null
+++ b/solutions/2971-find-polygon-with-the-largest-perimeter.js
@@ -0,0 +1,33 @@
+/**
+ * 2971. Find Polygon With the Largest Perimeter
+ * https://leetcode.com/problems/find-polygon-with-the-largest-perimeter/
+ * Difficulty: Medium
+ *
+ * You are given an array of positive integers nums of length n.
+ *
+ * A polygon is a closed plane figure that has at least 3 sides. The longest side of a polygon is
+ * smaller than the sum of its other sides.
+ *
+ * Conversely, if you have k (k >= 3) positive real numbers a1, a2, a3, ..., ak where
+ * a1 <= a2 <= a3 <= ... <= ak and a1 + a2 + a3 + ... + ak-1 > ak, then there always exists
+ * a polygon with k sides whose lengths are a1, a2, a3, ..., ak.
+ *
+ * The perimeter of a polygon is the sum of lengths of its sides.
+ *
+ * Return the largest possible perimeter of a polygon whose sides can be formed from nums, or -1
+ * if it is not possible to create a polygon.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var largestPerimeter = function(nums) {
+  nums.sort((a, b) => b - a);
+  for (let i = 0; i < nums.length - 2; i++) {
+    if (nums[i] < nums.slice(i + 1).reduce((sum, num) => sum + num, 0)) {
+      return nums.slice(i).reduce((sum, num) => sum + num, 0);
+    }
+  }
+  return -1;
+};
diff --git a/solutions/2976-minimum-cost-to-convert-string-i.js b/solutions/2976-minimum-cost-to-convert-string-i.js
new file mode 100644
index 00000000..9107955d
--- /dev/null
+++ b/solutions/2976-minimum-cost-to-convert-string-i.js
@@ -0,0 +1,59 @@
+/**
+ * 2976. Minimum Cost to Convert String I
+ * https://leetcode.com/problems/minimum-cost-to-convert-string-i/
+ * Difficulty: Medium
+ *
+ * You are given two 0-indexed strings source and target, both of length n and consisting of
+ * lowercase English letters. You are also given two 0-indexed character arrays original and
+ * changed, and an integer array cost, where cost[i] represents the cost of changing the character
+ * original[i] to the character changed[i].
+ *
+ * You start with the string source. In one operation, you can pick a character x from the string
+ * and change it to the character y at a cost of z if there exists any index j such that
+ * cost[j] == z, original[j] == x, and changed[j] == y.
+ *
+ * Return the minimum cost to convert the string source to the string target using any number of
+ * operations. If it is impossible to convert source to target, return -1.
+ *
+ * Note that there may exist indices i, j such that original[j] == original[i] and
+ * changed[j] == changed[i].
+ */
+
+/**
+ * @param {string} source
+ * @param {string} target
+ * @param {character[]} original
+ * @param {character[]} changed
+ * @param {number[]} cost
+ * @return {number}
+ */
+var minimumCost = function(source, target, original, changed, cost) {
+  const graph = new Array(26).fill().map(() => new Array(26).fill(Infinity));
+  for (let i = 0; i < 26; i++) graph[i][i] = 0;
+
+  for (let i = 0; i < original.length; i++) {
+    const from = original[i].charCodeAt(0) - 97;
+    const to = changed[i].charCodeAt(0) - 97;
+    graph[from][to] = Math.min(graph[from][to], cost[i]);
+  }
+
+  for (let k = 0; k < 26; k++) {
+    for (let i = 0; i < 26; i++) {
+      for (let j = 0; j < 26; j++) {
+        graph[i][j] = Math.min(graph[i][j], graph[i][k] + graph[k][j]);
+      }
+    }
+  }
+
+  let result = 0;
+  for (let i = 0; i < source.length; i++) {
+    if (source[i] !== target[i]) {
+      const from = source[i].charCodeAt(0) - 97;
+      const to = target[i].charCodeAt(0) - 97;
+      if (graph[from][to] === Infinity) return -1;
+      result += graph[from][to];
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2980-check-if-bitwise-or-has-trailing-zeros.js b/solutions/2980-check-if-bitwise-or-has-trailing-zeros.js
new file mode 100644
index 00000000..e3afe838
--- /dev/null
+++ b/solutions/2980-check-if-bitwise-or-has-trailing-zeros.js
@@ -0,0 +1,36 @@
+/**
+ * 2980. Check if Bitwise OR Has Trailing Zeros
+ * https://leetcode.com/problems/check-if-bitwise-or-has-trailing-zeros/
+ * Difficulty: Easy
+ *
+ * You are given an array of positive integers nums.
+ *
+ * You have to check if it is possible to select two or more elements in the array such
+ * that the bitwise OR of the selected elements has at least one trailing zero in its
+ * binary representation.
+ *
+ * For example, the binary representation of 5, which is "101", does not have any trailing
+ * zeros, whereas the binary representation of 4, which is "100", has two trailing zeros.
+ *
+ * Return true if it is possible to select two or more elements whose bitwise OR has trailing
+ * zeros, return false otherwise.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {boolean}
+ */
+var hasTrailingZeros = function(nums) {
+  let evenCount = 0;
+
+  for (const num of nums) {
+    if (num % 2 === 0) {
+      evenCount++;
+      if (evenCount >= 2) {
+        return true;
+      }
+    }
+  }
+
+  return false;
+};
diff --git a/solutions/2981-find-longest-special-substring-that-occurs-thrice-i.js b/solutions/2981-find-longest-special-substring-that-occurs-thrice-i.js
new file mode 100644
index 00000000..ac12f932
--- /dev/null
+++ b/solutions/2981-find-longest-special-substring-that-occurs-thrice-i.js
@@ -0,0 +1,39 @@
+/**
+ * 2981. Find Longest Special Substring That Occurs Thrice I
+ * https://leetcode.com/problems/find-longest-special-substring-that-occurs-thrice-i/
+ * Difficulty: Medium
+ *
+ * You are given a string s that consists of lowercase English letters.
+ *
+ * A string is called special if it is made up of only a single character. For example, the
+ * string "abc" is not special, whereas the strings "ddd", "zz", and "f" are special.
+ *
+ * Return the length of the longest special substring of s which occurs at least thrice,
+ * or -1 if no special substring occurs at least thrice.
+ *
+ * A substring is a contiguous non-empty sequence of characters within a string.
+ */
+
+/**
+ * @param {string} s
+ * @return {number}
+ */
+var maximumLength = function(s) {
+  const map = new Map();
+  let result = -1;
+
+  for (let i = 0; i < s.length; i++) {
+    for (let len = 1; len <= s.length - i; len++) {
+      const substr = s.slice(i, i + len);
+      if (substr.split('').every(c => c === substr[0])) {
+        const count = (map.get(substr) || 0) + 1;
+        map.set(substr, count);
+        if (count >= 3) {
+          result = Math.max(result, len);
+        }
+      }
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/2997-minimum-number-of-operations-to-make-array-xor-equal-to-k.js b/solutions/2997-minimum-number-of-operations-to-make-array-xor-equal-to-k.js
new file mode 100644
index 00000000..b1d492eb
--- /dev/null
+++ b/solutions/2997-minimum-number-of-operations-to-make-array-xor-equal-to-k.js
@@ -0,0 +1,38 @@
+/**
+ * 2997. Minimum Number of Operations to Make Array XOR Equal to K
+ * https://leetcode.com/problems/minimum-number-of-operations-to-make-array-xor-equal-to-k/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed integer array nums and a positive integer k.
+ *
+ * You can apply the following operation on the array any number of times:
+ * - Choose any element of the array and flip a bit in its binary representation. Flipping a bit
+ *   means changing a 0 to 1 or vice versa.
+ *
+ * Return the minimum number of operations required to make the bitwise XOR of all elements of the
+ * final array equal to k.
+ *
+ * Note that you can flip leading zero bits in the binary representation of elements. For example,
+ * for the number (101)2 you can flip the fourth bit and obtain (1101)2.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @return {number}
+ */
+var minOperations = function(nums, k) {
+  let xorResult = 0;
+  for (const num of nums) {
+    xorResult ^= num;
+  }
+
+  let result = 0;
+  let diff = xorResult ^ k;
+  while (diff > 0) {
+    result += diff & 1;
+    diff >>= 1;
+  }
+
+  return result;
+};
diff --git a/solutions/2998-minimum-number-of-operations-to-make-x-and-y-equal.js b/solutions/2998-minimum-number-of-operations-to-make-x-and-y-equal.js
new file mode 100644
index 00000000..cc18c133
--- /dev/null
+++ b/solutions/2998-minimum-number-of-operations-to-make-x-and-y-equal.js
@@ -0,0 +1,45 @@
+/**
+ * 2998. Minimum Number of Operations to Make X and Y Equal
+ * https://leetcode.com/problems/minimum-number-of-operations-to-make-x-and-y-equal/
+ * Difficulty: Medium
+ *
+ * You are given two positive integers x and y.
+ *
+ * In one operation, you can do one of the four following operations:
+ * 1. Divide x by 11 if x is a multiple of 11.
+ * 2. Divide x by 5 if x is a multiple of 5.
+ * 3. Decrement x by 1.
+ * 4. Increment x by 1.
+ *
+ * Return the minimum number of operations required to make x and y equal.
+ */
+
+/**
+ * @param {number} x
+ * @param {number} y
+ * @return {number}
+ */
+var minimumOperationsToMakeEqual = function(x, y) {
+  const queue = [[x, 0]];
+  const visited = new Set([x]);
+
+  while (queue.length) {
+    const [current, steps] = queue.shift();
+
+    if (current === y) return steps;
+
+    const nextStates = [];
+    if (current % 11 === 0) nextStates.push(current / 11);
+    if (current % 5 === 0) nextStates.push(current / 5);
+    nextStates.push(current - 1, current + 1);
+
+    for (const next of nextStates) {
+      if (next >= 0 && next <= 10000 && !visited.has(next)) {
+        visited.add(next);
+        queue.push([next, steps + 1]);
+      }
+    }
+  }
+
+  return -1;
+};
diff --git a/solutions/3002-maximum-size-of-a-set-after-removals.js b/solutions/3002-maximum-size-of-a-set-after-removals.js
new file mode 100644
index 00000000..66f30fd1
--- /dev/null
+++ b/solutions/3002-maximum-size-of-a-set-after-removals.js
@@ -0,0 +1,41 @@
+/**
+ * 3002. Maximum Size of a Set After Removals
+ * https://leetcode.com/problems/maximum-size-of-a-set-after-removals/
+ * Difficulty: Medium
+ *
+ * You are given two 0-indexed integer arrays nums1 and nums2 of even length n.
+ *
+ * You must remove n / 2 elements from nums1 and n / 2 elements from nums2. After the removals,
+ * you insert the remaining elements of nums1 and nums2 into a set s.
+ *
+ * Return the maximum possible size of the set s.
+ */
+
+/**
+ * @param {number[]} nums1
+ * @param {number[]} nums2
+ * @return {number}
+ */
+var maximumSetSize = function(nums1, nums2) {
+  const n = nums1.length;
+  const set1 = new Set(nums1);
+  const set2 = new Set(nums2);
+
+  let unique1 = set1.size;
+  let unique2 = set2.size;
+  let common = 0;
+
+  for (const num of set1) {
+    if (set2.has(num)) common++;
+  }
+
+  unique1 -= common;
+  unique2 -= common;
+
+  const max1 = Math.min(unique1, n / 2);
+  const max2 = Math.min(unique2, n / 2);
+  const remaining = n / 2 - max1 + n / 2 - max2;
+  const maxCommon = Math.min(common, remaining);
+
+  return max1 + max2 + maxCommon;
+};
diff --git a/solutions/3005-count-elements-with-maximum-frequency.js b/solutions/3005-count-elements-with-maximum-frequency.js
new file mode 100644
index 00000000..cb89603e
--- /dev/null
+++ b/solutions/3005-count-elements-with-maximum-frequency.js
@@ -0,0 +1,35 @@
+/**
+ * 3005. Count Elements With Maximum Frequency
+ * https://leetcode.com/problems/count-elements-with-maximum-frequency/
+ * Difficulty: Easy
+ *
+ * You are given an array nums consisting of positive integers.
+ *
+ * Return the total frequencies of elements in nums such that those elements all have the
+ * maximum frequency.
+ *
+ * The frequency of an element is the number of occurrences of that element in the array.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var maxFrequencyElements = function(nums) {
+  const map = new Map();
+  let maxFreq = 0;
+  let result = 0;
+
+  for (const num of nums) {
+    const count = (map.get(num) || 0) + 1;
+    map.set(num, count);
+    if (count > maxFreq) {
+      maxFreq = count;
+      result = count;
+    } else if (count === maxFreq) {
+      result += count;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/3010-divide-an-array-into-subarrays-with-minimum-cost-i.js b/solutions/3010-divide-an-array-into-subarrays-with-minimum-cost-i.js
new file mode 100644
index 00000000..26a184a5
--- /dev/null
+++ b/solutions/3010-divide-an-array-into-subarrays-with-minimum-cost-i.js
@@ -0,0 +1,32 @@
+/**
+ * 3010. Divide an Array Into Subarrays With Minimum Cost I
+ * https://leetcode.com/problems/divide-an-array-into-subarrays-with-minimum-cost-i/
+ * Difficulty: Easy
+ *
+ * You are given an array of integers nums of length n.
+ *
+ * The cost of an array is the value of its first element. For example, the cost of [1,2,3]
+ * is 1 while the cost of [3,4,1] is 3.
+ *
+ * You need to divide nums into 3 disjoint contiguous subarrays.
+ *
+ * Return the minimum possible sum of the cost of these subarrays.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var minimumCost = function(nums) {
+  const n = nums.length;
+  let result = Infinity;
+
+  for (let i = 1; i < n - 1; i++) {
+    for (let j = i + 1; j < n; j++) {
+      const cost = nums[0] + nums[i] + nums[j];
+      result = Math.min(result, cost);
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/3011-find-if-array-can-be-sorted.js b/solutions/3011-find-if-array-can-be-sorted.js
new file mode 100644
index 00000000..c395e89e
--- /dev/null
+++ b/solutions/3011-find-if-array-can-be-sorted.js
@@ -0,0 +1,57 @@
+/**
+ * 3011. Find if Array Can Be Sorted
+ * https://leetcode.com/problems/find-if-array-can-be-sorted/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed array of positive integers nums.
+ *
+ * In one operation, you can swap any two adjacent elements if they have the same number of
+ * set bits. You are allowed to do this operation any number of times (including zero).
+ *
+ * Return true if you can sort the array in ascending order, else return false.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {boolean}
+ */
+var canSortArray = function(nums) {
+  const sorted = [...nums].sort((a, b) => a - b);
+  const bitGroups = [];
+  let currentBits = countSetBits(nums[0]);
+  let group = [nums[0]];
+
+  for (let i = 1; i < nums.length; i++) {
+    const bits = countSetBits(nums[i]);
+    if (bits === currentBits) {
+      group.push(nums[i]);
+    } else {
+      bitGroups.push(group);
+      group = [nums[i]];
+      currentBits = bits;
+    }
+  }
+  bitGroups.push(group);
+
+  let index = 0;
+  for (const group of bitGroups) {
+    const groupSorted = [...group].sort((a, b) => a - b);
+    for (const num of groupSorted) {
+      if (num !== sorted[index]) {
+        return false;
+      }
+      index++;
+    }
+  }
+
+  return true;
+
+  function countSetBits(num) {
+    let count = 0;
+    while (num) {
+      count += num & 1;
+      num >>= 1;
+    }
+    return count;
+  }
+};
diff --git a/solutions/3014-minimum-number-of-pushes-to-type-word-i.js b/solutions/3014-minimum-number-of-pushes-to-type-word-i.js
new file mode 100644
index 00000000..347e798e
--- /dev/null
+++ b/solutions/3014-minimum-number-of-pushes-to-type-word-i.js
@@ -0,0 +1,42 @@
+/**
+ * 3014. Minimum Number of Pushes to Type Word I
+ * https://leetcode.com/problems/minimum-number-of-pushes-to-type-word-i/
+ * Difficulty: Easy
+ *
+ * You are given a string word containing distinct lowercase English letters.
+ *
+ * Telephone keypads have keys mapped with distinct collections of lowercase English letters,
+ * which can be used to form words by pushing them. For example, the key 2 is mapped with
+ * ["a","b","c"], we need to push the key one time to type "a", two times to type "b", and
+ * three times to type "c".
+ *
+ * It is allowed to remap the keys numbered 2 to 9 to distinct collections of letters. The
+ * keys can be remapped to any amount of letters, but each letter must be mapped to exactly
+ * one key. You need to find the minimum number of times the keys will be pushed to type
+ * the string word.
+ *
+ * Return the minimum number of pushes needed to type word after remapping the keys.
+ *
+ * An example mapping of letters to keys on a telephone keypad is given below. Note that
+ * 1, *, #, and 0 do not map to any letters.
+ */
+
+/**
+ * @param {string} word
+ * @return {number}
+ */
+var minimumPushes = function(word) {
+  const frequency = new Array(26).fill(0);
+  for (const char of word) {
+    frequency[char.charCodeAt(0) - 97]++;
+  }
+  frequency.sort((a, b) => b - a);
+
+  let result = 0;
+  for (let i = 0; i < frequency.length; i++) {
+    if (frequency[i] === 0) break;
+    result += frequency[i] * (Math.floor(i / 8) + 1);
+  }
+
+  return result;
+};
diff --git a/solutions/3015-count-the-number-of-houses-at-a-certain-distance-i.js b/solutions/3015-count-the-number-of-houses-at-a-certain-distance-i.js
new file mode 100644
index 00000000..02801f91
--- /dev/null
+++ b/solutions/3015-count-the-number-of-houses-at-a-certain-distance-i.js
@@ -0,0 +1,57 @@
+/**
+ * 3015. Count the Number of Houses at a Certain Distance I
+ * https://leetcode.com/problems/count-the-number-of-houses-at-a-certain-distance-i/
+ * Difficulty: Medium
+ *
+ * You are given three positive integers n, x, and y.
+ *
+ * In a city, there exist houses numbered 1 to n connected by n streets. There is a street
+ * connecting the house numbered i with the house numbered i + 1 for all 1 <= i <= n - 1.
+ * An additional street connects the house numbered x with the house numbered y.
+ *
+ * For each k, such that 1 <= k <= n, you need to find the number of pairs of houses (house1,
+ * house2) such that the minimum number of streets that need to be traveled to reach house2
+ * from house1 is k.
+ *
+ * Return a 1-indexed array result of length n where result[k] represents the total number
+ * of pairs of houses such that the minimum streets required to reach one house from the
+ * other is k.
+ *
+ * Note that x and y can be equal.
+ */
+
+/**
+ * @param {number} n
+ * @param {number} x
+ * @param {number} y
+ * @return {number[]}
+ */
+var countOfPairs = function(n, x, y) {
+  const distances = new Array(n + 1).fill().map(() => new Array(n + 1).fill(Infinity));
+
+  for (let i = 1; i <= n; i++) {
+    distances[i][i] = 0;
+    if (i < n) distances[i][i + 1] = distances[i + 1][i] = 1;
+  }
+
+  distances[x][y] = distances[y][x] = 1;
+
+  for (let k = 1; k <= n; k++) {
+    for (let i = 1; i <= n; i++) {
+      for (let j = 1; j <= n; j++) {
+        distances[i][j] = Math.min(distances[i][j], distances[i][k] + distances[k][j]);
+      }
+    }
+  }
+
+  const result = new Array(n + 1).fill(0);
+  for (let i = 1; i <= n; i++) {
+    for (let j = 1; j <= n; j++) {
+      if (i !== j && distances[i][j] !== Infinity) {
+        result[distances[i][j]]++;
+      }
+    }
+  }
+
+  return result.slice(1);
+};
diff --git a/solutions/3016-minimum-number-of-pushes-to-type-word-ii.js b/solutions/3016-minimum-number-of-pushes-to-type-word-ii.js
new file mode 100644
index 00000000..5a54a46c
--- /dev/null
+++ b/solutions/3016-minimum-number-of-pushes-to-type-word-ii.js
@@ -0,0 +1,41 @@
+/**
+ * 3016. Minimum Number of Pushes to Type Word II
+ * https://leetcode.com/problems/minimum-number-of-pushes-to-type-word-ii/
+ * Difficulty: Medium
+ *
+ * You are given a string word containing lowercase English letters.
+ *
+ * Telephone keypads have keys mapped with distinct collections of lowercase English letters,
+ * which can be used to form words by pushing them. For example, the key 2 is mapped with
+ * ["a","b","c"], we need to push the key one time to type "a", two times to type "b", and
+ * three times to type "c".
+ *
+ * It is allowed to remap the keys numbered 2 to 9 to distinct collections of letters. The
+ * keys can be remapped to any amount of letters, but each letter must be mapped to exactly
+ * one key. You need to find the minimum number of times the keys will be pushed to type the
+ * string word.
+ *
+ * Return the minimum number of pushes needed to type word after remapping the keys.
+ *
+ * An example mapping of letters to keys on a telephone keypad is given below. Note that
+ * 1, *, #, and 0 do not map to any letters.
+ */
+
+/**
+ * @param {string} word
+ * @return {number}
+ */
+var minimumPushes = function(word) {
+  const frequency = new Array(26).fill(0);
+  for (const char of word) {
+    frequency[char.charCodeAt(0) - 97]++;
+  }
+  frequency.sort((a, b) => b - a);
+
+  let result = 0;
+  for (let i = 0; i < frequency.length && frequency[i] > 0; i++) {
+    result += frequency[i] * (Math.floor(i / 8) + 1);
+  }
+
+  return result;
+};
diff --git a/solutions/3019-number-of-changing-keys.js b/solutions/3019-number-of-changing-keys.js
new file mode 100644
index 00000000..f48c69f0
--- /dev/null
+++ b/solutions/3019-number-of-changing-keys.js
@@ -0,0 +1,30 @@
+/**
+ * 3019. Number of Changing Keys
+ * https://leetcode.com/problems/number-of-changing-keys/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed string s typed by a user. Changing a key is defined as using a key
+ * different from the last used key. For example, s = "ab" has a change of a key while s = "bBBb"
+ * does not have any.
+ *
+ * Return the number of times the user had to change the key.
+ *
+ * Note: Modifiers like shift or caps lock won't be counted in changing the key that is if a user
+ * typed the letter 'a' and then the letter 'A' then it will not be considered as a changing of key.
+ */
+
+/**
+ * @param {string} s
+ * @return {number}
+ */
+var countKeyChanges = function(s) {
+  let result = 0;
+
+  for (let i = 1; i < s.length; i++) {
+    if (s[i].toLowerCase() !== s[i - 1].toLowerCase()) {
+      result++;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/3021-alice-and-bob-playing-flower-game.js b/solutions/3021-alice-and-bob-playing-flower-game.js
new file mode 100644
index 00000000..4335643c
--- /dev/null
+++ b/solutions/3021-alice-and-bob-playing-flower-game.js
@@ -0,0 +1,37 @@
+/**
+ * 3021. Alice and Bob Playing Flower Game
+ * https://leetcode.com/problems/alice-and-bob-playing-flower-game/
+ * Difficulty: Medium
+ *
+ * Alice and Bob are playing a turn-based game on a circular field surrounded by flowers.
+ * The circle represents the field, and there are x flowers in the clockwise direction
+ * between Alice and Bob, and y flowers in the anti-clockwise direction between them.
+ *
+ * The game proceeds as follows:
+ * 1. Alice takes the first turn.
+ * 2. In each turn, a player must choose either the clockwise or anti-clockwise direction
+ *    and pick one flower from that side.
+ * 3. At the end of the turn, if there are no flowers left at all, the current player
+ *    captures their opponent and wins the game.
+ *
+ * Given two integers, n and m, the task is to compute the number of possible pairs (x, y)
+ * that satisfy the conditions:
+ * - Alice must win the game according to the described rules.
+ * - The number of flowers x in the clockwise direction must be in the range [1,n].
+ * - The number of flowers y in the anti-clockwise direction must be in the range [1,m].
+ *
+ * Return the number of possible pairs (x, y) that satisfy the conditions mentioned in the
+ * statement.
+ */
+
+/**
+ * @param {number} n
+ * @param {number} m
+ * @return {number}
+ */
+var flowerGame = function(n, m) {
+  const evenN = Math.floor(n / 2);
+  const evenM = Math.floor(m / 2);
+
+  return evenN * (m - evenM) + (n - evenN) * evenM;
+};
diff --git a/solutions/3024-type-of-triangle.js b/solutions/3024-type-of-triangle.js
new file mode 100644
index 00000000..0a62411d
--- /dev/null
+++ b/solutions/3024-type-of-triangle.js
@@ -0,0 +1,27 @@
+/**
+ * 3024. Type of Triangle
+ * https://leetcode.com/problems/type-of-triangle/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed integer array nums of size 3 which can form the sides of a triangle.
+ * - A triangle is called equilateral if it has all sides of equal length.
+ * - A triangle is called isosceles if it has exactly two sides of equal length.
+ * - A triangle is called scalene if all its sides are of different lengths.
+ *
+ * Return a string representing the type of triangle that can be formed or "none" if it cannot
+ * form a triangle.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {string}
+ */
+var triangleType = function(nums) {
+  const [sideA, sideB, sideC] = nums.sort((a, b) => a - b);
+
+  if (sideA + sideB <= sideC) return 'none';
+  if (sideA === sideB && sideB === sideC) return 'equilateral';
+  if (sideA === sideB || sideB === sideC) return 'isosceles';
+
+  return 'scalene';
+};
diff --git a/solutions/3025-find-the-number-of-ways-to-place-people-i.js b/solutions/3025-find-the-number-of-ways-to-place-people-i.js
new file mode 100644
index 00000000..d0b579c1
--- /dev/null
+++ b/solutions/3025-find-the-number-of-ways-to-place-people-i.js
@@ -0,0 +1,43 @@
+/**
+ * 3025. Find the Number of Ways to Place People I
+ * https://leetcode.com/problems/find-the-number-of-ways-to-place-people-i/
+ * Difficulty: Medium
+ *
+ * You are given a 2D array points of size n x 2 representing integer coordinates of some points
+ * on a 2D plane, where points[i] = [xi, yi].
+ *
+ * Count the number of pairs of points (A, B), where
+ * - A is on the upper left side of B, and
+ * - there are no other points in the rectangle (or line) they make (including the border).
+ *
+ * Return the count.
+ */
+
+/**
+ * @param {number[][]} points
+ * @return {number}
+ */
+var numberOfPairs = function(points) {
+  points.sort((a, b) => a[0] === b[0] ? b[1] - a[1] : a[0] - b[0]);
+  let result = 0;
+
+  for (let i = 0; i < points.length; i++) {
+    for (let j = i + 1; j < points.length; j++) {
+      if (points[i][1] >= points[j][1]) {
+        let isValid = true;
+        for (let k = 0; k < points.length; k++) {
+          if (k !== i && k !== j) {
+            if (points[k][0] >= points[i][0] && points[k][0] <= points[j][0]
+                && points[k][1] <= points[i][1] && points[k][1] >= points[j][1]) {
+              isValid = false;
+              break;
+            }
+          }
+        }
+        if (isValid) result++;
+      }
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/3027-find-the-number-of-ways-to-place-people-ii.js b/solutions/3027-find-the-number-of-ways-to-place-people-ii.js
new file mode 100644
index 00000000..6077d142
--- /dev/null
+++ b/solutions/3027-find-the-number-of-ways-to-place-people-ii.js
@@ -0,0 +1,68 @@
+/**
+ * 3027. Find the Number of Ways to Place People II
+ * https://leetcode.com/problems/find-the-number-of-ways-to-place-people-ii/
+ * Difficulty: Hard
+ *
+ * You are given a 2D array points of size n x 2 representing integer coordinates of some points
+ * on a 2D-plane, where points[i] = [xi, yi].
+ *
+ * We define the right direction as positive x-axis (increasing x-coordinate) and the left
+ * direction as negative x-axis (decreasing x-coordinate). Similarly, we define the up direction
+ * as positive y-axis (increasing y-coordinate) and the down direction as negative y-axis
+ * (decreasing y-coordinate)
+ *
+ * You have to place n people, including Alice and Bob, at these points such that there is exactly
+ * one person at every point. Alice wants to be alone with Bob, so Alice will build a rectangular
+ * fence with Alice's position as the upper left corner and Bob's position as the lower right
+ * corner of the fence (Note that the fence might not enclose any area, i.e. it can be a line).
+ * If any person other than Alice and Bob is either inside the fence or on the fence, Alice will
+ * be sad.
+ *
+ * Return the number of pairs of points where you can place Alice and Bob, such that Alice does not
+ * become sad on building the fence.
+ *
+ * Note that Alice can only build a fence with Alice's position as the upper left corner, and Bob's
+ * position as the lower right corner. For example, Alice cannot build either of the fences in the
+ * picture below with four corners (1, 1), (1, 3), (3, 1), and (3, 3), because:
+ * - With Alice at (3, 3) and Bob at (1, 1), Alice's position is not the upper left corner and Bob's
+ *   position is not the lower right corner of the fence.
+ * - With Alice at (1, 3) and Bob at (1, 1), Bob's position is not the lower right corner of the
+ *   fence.
+ */
+
+/**
+ * @param {number[][]} points
+ * @return {number}
+ */
+var numberOfPairs = function(points) {
+  points.sort((a, b) => a[0] === b[0] ? b[1] - a[1] : a[0] - b[0]);
+  let result = 0;
+
+  for (let i = 0; i < points.length; i++) {
+    const [, maxY] = points[i];
+    let minY = -Infinity;
+
+    for (let j = i + 1; j < points.length; j++) {
+      const [, y] = points[j];
+      if (y <= maxY && y > minY) {
+        let isValid = true;
+        for (let k = 0; k < points.length; k++) {
+          if (k !== i && k !== j) {
+            const [x, ky] = points[k];
+            if (x >= points[i][0] && x <= points[j][0]
+                && ky <= points[i][1] && ky >= points[j][1]) {
+              isValid = false;
+              break;
+            }
+          }
+        }
+        if (isValid) {
+          result++;
+          minY = y;
+        }
+      }
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/3028-ant-on-the-boundary.js b/solutions/3028-ant-on-the-boundary.js
new file mode 100644
index 00000000..fab768da
--- /dev/null
+++ b/solutions/3028-ant-on-the-boundary.js
@@ -0,0 +1,38 @@
+/**
+ * 3028. Ant on the Boundary
+ * https://leetcode.com/problems/ant-on-the-boundary/
+ * Difficulty: Easy
+ *
+ * An ant is on a boundary. It sometimes goes left and sometimes right.
+ *
+ * You are given an array of non-zero integers nums. The ant starts reading nums from the
+ * first element of it to its end. At each step, it moves according to the value of the
+ * current element:
+ * - If nums[i] < 0, it moves left by -nums[i] units.
+ * - If nums[i] > 0, it moves right by nums[i] units.
+ *
+ * Return the number of times the ant returns to the boundary.
+ *
+ * Notes:
+ * - There is an infinite space on both sides of the boundary.
+ * - We check whether the ant is on the boundary only after it has moved |nums[i]| units.
+ *   In other words, if the ant crosses the boundary during its movement, it does not count.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var returnToBoundaryCount = function(nums) {
+  let position = 0;
+  let result = 0;
+
+  for (const step of nums) {
+    position += step;
+    if (position === 0) {
+      result++;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/3029-minimum-time-to-revert-word-to-initial-state-i.js b/solutions/3029-minimum-time-to-revert-word-to-initial-state-i.js
new file mode 100644
index 00000000..07d7e492
--- /dev/null
+++ b/solutions/3029-minimum-time-to-revert-word-to-initial-state-i.js
@@ -0,0 +1,33 @@
+/**
+ * 3029. Minimum Time to Revert Word to Initial State I
+ * https://leetcode.com/problems/minimum-time-to-revert-word-to-initial-state-i/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed string word and an integer k.
+ *
+ * At every second, you must perform the following operations:
+ * - Remove the first k characters of word.
+ * - Add any k characters to the end of word.
+ *
+ * Note that you do not necessarily need to add the same characters that you removed.
+ * However, you must perform both operations at every second.
+ *
+ * Return the minimum time greater than zero required for word to revert to its initial state.
+ */
+
+/**
+ * @param {string} word
+ * @param {number} k
+ * @return {number}
+ */
+var minimumTimeToInitialState = function(word, k) {
+  const n = word.length;
+
+  for (let i = 1; i * k <= n; i++) {
+    if (word.slice(i * k) === word.slice(0, n - i * k)) {
+      return i;
+    }
+  }
+
+  return Math.ceil(n / k);
+};
diff --git a/solutions/3030-find-the-grid-of-region-average.js b/solutions/3030-find-the-grid-of-region-average.js
new file mode 100644
index 00000000..d15b7ada
--- /dev/null
+++ b/solutions/3030-find-the-grid-of-region-average.js
@@ -0,0 +1,94 @@
+/**
+ * 3030. Find the Grid of Region Average
+ * https://leetcode.com/problems/find-the-grid-of-region-average/
+ * Difficulty: Medium
+ *
+ * You are given m x n grid image which represents a grayscale image, where image[i][j]
+ * represents a pixel with intensity in the range [0..255]. You are also given a non-negative
+ * integer threshold.
+ *
+ * Two pixels are adjacent if they share an edge.
+ *
+ * A region is a 3 x 3 subgrid where the absolute difference in intensity between any two
+ * adjacent pixels is less than or equal to threshold.
+ *
+ * All pixels in a region belong to that region, note that a pixel can belong to multiple regions.
+ *
+ * You need to calculate a m x n grid result, where result[i][j] is the average intensity of the
+ * regions to which image[i][j] belongs, rounded down to the nearest integer. If image[i][j]
+ * belongs to multiple regions, result[i][j] is the average of the rounded-down average intensities
+ * of these regions, rounded down to the nearest integer. If image[i][j] does not belong to any
+ * region, result[i][j] is equal to image[i][j].
+ *
+ * Return the grid result.
+ */
+
+/**
+ * @param {number[][]} image
+ * @param {number} threshold
+ * @return {number[][]}
+ */
+var resultGrid = function(image, threshold) {
+  const rows = image.length;
+  const cols = image[0].length;
+  const result = Array.from({ length: rows }, () => new Array(cols).fill(0));
+  const regionCount = Array.from({ length: rows }, () => new Array(cols).fill(0));
+
+  for (let i = 0; i <= rows - 3; i++) {
+    for (let j = 0; j <= cols - 3; j++) {
+      if (isValidRegion(i, j)) {
+        const regionAvg = calculateRegionAverage(i, j);
+
+        for (let r = i; r < i + 3; r++) {
+          for (let c = j; c < j + 3; c++) {
+            result[r][c] += regionAvg;
+            regionCount[r][c]++;
+          }
+        }
+      }
+    }
+  }
+
+  for (let i = 0; i < rows; i++) {
+    for (let j = 0; j < cols; j++) {
+      if (regionCount[i][j] === 0) {
+        result[i][j] = image[i][j];
+      } else {
+        result[i][j] = Math.floor(result[i][j] / regionCount[i][j]);
+      }
+    }
+  }
+
+  return result;
+
+  function calculateRegionAverage(startRow, startCol) {
+    let sum = 0;
+    for (let i = startRow; i < startRow + 3; i++) {
+      for (let j = startCol; j < startCol + 3; j++) {
+        sum += image[i][j];
+      }
+    }
+    return Math.floor(sum / 9);
+  }
+
+  function isValidRegion(startRow, startCol) {
+    const directions = [[-1, 0], [1, 0], [0, -1], [0, 1]];
+
+    for (let i = startRow; i < startRow + 3; i++) {
+      for (let j = startCol; j < startCol + 3; j++) {
+        for (const [dr, dc] of directions) {
+          const newRow = i + dr;
+          const newCol = j + dc;
+
+          if (newRow >= startRow && newRow < startRow + 3
+              && newCol >= startCol && newCol < startCol + 3) {
+            if (Math.abs(image[i][j] - image[newRow][newCol]) > threshold) {
+              return false;
+            }
+          }
+        }
+      }
+    }
+    return true;
+  }
+};
diff --git a/solutions/3033-modify-the-matrix.js b/solutions/3033-modify-the-matrix.js
new file mode 100644
index 00000000..6d8b09ab
--- /dev/null
+++ b/solutions/3033-modify-the-matrix.js
@@ -0,0 +1,38 @@
+/**
+ * 3033. Modify the Matrix
+ * https://leetcode.com/problems/modify-the-matrix/
+ * Difficulty: Easy
+ *
+ * Given a 0-indexed m x n integer matrix matrix, create a new 0-indexed matrix called answer.
+ * Make answer equal to matrix, then replace each element with the value -1 with the maximum
+ * element in its respective column.
+ *
+ * Return the matrix answer.
+ */
+
+/**
+ * @param {number[][]} matrix
+ * @return {number[][]}
+ */
+var modifiedMatrix = function(matrix) {
+  const m = matrix.length;
+  const n = matrix[0].length;
+  const result = matrix.map(row => [...row]);
+  const colMaxes = new Array(n).fill(-Infinity);
+
+  for (let j = 0; j < n; j++) {
+    for (let i = 0; i < m; i++) {
+      colMaxes[j] = Math.max(colMaxes[j], matrix[i][j]);
+    }
+  }
+
+  for (let i = 0; i < m; i++) {
+    for (let j = 0; j < n; j++) {
+      if (result[i][j] === -1) {
+        result[i][j] = colMaxes[j];
+      }
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/3034-number-of-subarrays-that-match-a-pattern-i.js b/solutions/3034-number-of-subarrays-that-match-a-pattern-i.js
new file mode 100644
index 00000000..d95a2c36
--- /dev/null
+++ b/solutions/3034-number-of-subarrays-that-match-a-pattern-i.js
@@ -0,0 +1,41 @@
+/**
+ * 3034. Number of Subarrays That Match a Pattern I
+ * https://leetcode.com/problems/number-of-subarrays-that-match-a-pattern-i/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed integer array nums of size n, and a 0-indexed integer array pattern
+ * of size m consisting of integers -1, 0, and 1.
+ *
+ * A subarray nums[i..j] of size m + 1 is said to match the pattern if the following conditions
+ * hold for each element pattern[k]:
+ * - nums[i + k + 1] > nums[i + k] if pattern[k] == 1.
+ * - nums[i + k + 1] == nums[i + k] if pattern[k] == 0.
+ * - nums[i + k + 1] < nums[i + k] if pattern[k] == -1.
+ *
+ * Return the count of subarrays in nums that match the pattern.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number[]} pattern
+ * @return {number}
+ */
+var countMatchingSubarrays = function(nums, pattern) {
+  let result = 0;
+  const m = pattern.length;
+
+  for (let i = 0; i <= nums.length - m - 1; i++) {
+    let isMatch = true;
+    for (let j = 0; j < m; j++) {
+      const diff = nums[i + j + 1] - nums[i + j];
+      if ((pattern[j] === 1 && diff <= 0) || (pattern[j] === 0 && diff !== 0)
+          || (pattern[j] === -1 && diff >= 0)) {
+        isMatch = false;
+        break;
+      }
+    }
+    if (isMatch) result++;
+  }
+
+  return result;
+};
diff --git a/solutions/3035-maximum-palindromes-after-operations.js b/solutions/3035-maximum-palindromes-after-operations.js
new file mode 100644
index 00000000..8897c387
--- /dev/null
+++ b/solutions/3035-maximum-palindromes-after-operations.js
@@ -0,0 +1,46 @@
+/**
+ * 3035. Maximum Palindromes After Operations
+ * https://leetcode.com/problems/maximum-palindromes-after-operations/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed string array words having length n and containing 0-indexed strings.
+ *
+ * You are allowed to perform the following operation any number of times (including zero):
+ * - Choose integers i, j, x, and y such that 0 <= i, j < n, 0 <= x < words[i].length,
+ *   0 <= y < words[j].length, and swap the characters words[i][x] and words[j][y].
+ *
+ * Return an integer denoting the maximum number of palindromes words can contain, after performing
+ * some operations.
+ *
+ * Note: i and j may be equal during an operation.
+ */
+
+/**
+ * @param {string[]} words
+ * @return {number}
+ */
+var maxPalindromesAfterOperations = function(words) {
+  const charCount = new Array(26).fill(0);
+  let pairCount = 0;
+  let result = 0;
+
+  for (const word of words) {
+    for (const char of word) {
+      charCount[char.charCodeAt(0) - 97]++;
+    }
+  }
+
+  for (const count of charCount) {
+    pairCount += Math.floor(count / 2);
+  }
+
+  const lengths = words.map(word => word.length).sort((a, b) => a - b);
+  for (const length of lengths) {
+    if (pairCount >= Math.floor(length / 2)) {
+      pairCount -= Math.floor(length / 2);
+      result++;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/3038-maximum-number-of-operations-with-the-same-score-i.js b/solutions/3038-maximum-number-of-operations-with-the-same-score-i.js
new file mode 100644
index 00000000..d1e825cb
--- /dev/null
+++ b/solutions/3038-maximum-number-of-operations-with-the-same-score-i.js
@@ -0,0 +1,33 @@
+/**
+ * 3038. Maximum Number of Operations With the Same Score I
+ * https://leetcode.com/problems/maximum-number-of-operations-with-the-same-score-i/
+ * Difficulty: Easy
+ *
+ * You are given an array of integers nums. Consider the following operation:
+ * - Delete the first two elements nums and define the score of the operation as the sum of
+ *   these two elements.
+ *
+ * You can perform this operation until nums contains fewer than two elements. Additionally,
+ * the same score must be achieved in all operations.
+ *
+ * Return the maximum number of operations you can perform.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var maxOperations = function(nums) {
+  let result = 0;
+  const targetScore = nums[0] + nums[1];
+
+  for (let i = 0; i < nums.length - 1; i += 2) {
+    if (nums[i] + nums[i + 1] === targetScore) {
+      result++;
+    } else {
+      break;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/3039-apply-operations-to-make-string-empty.js b/solutions/3039-apply-operations-to-make-string-empty.js
new file mode 100644
index 00000000..82cc2e56
--- /dev/null
+++ b/solutions/3039-apply-operations-to-make-string-empty.js
@@ -0,0 +1,45 @@
+/**
+ * 3039. Apply Operations to Make String Empty
+ * https://leetcode.com/problems/apply-operations-to-make-string-empty/
+ * Difficulty: Medium
+ *
+ * You are given a string s.
+ *
+ * Consider performing the following operation until s becomes empty:
+ * - For every alphabet character from 'a' to 'z', remove the first occurrence of that
+ *   character in s (if it exists).
+ *
+ * For example, let initially s = "aabcbbca". We do the following operations:
+ * - Remove the underlined characters s = "aabcbbca". The resulting string is s = "abbca".
+ * - Remove the underlined characters s = "abbca". The resulting string is s = "ba".
+ * - Remove the underlined characters s = "ba". The resulting string is s = "".
+ *
+ * Return the value of the string s right before applying the last operation. In the
+ * example above, answer is "ba".
+ */
+
+/**
+ * @param {string} s
+ * @return {string}
+ */
+var lastNonEmptyString = function(s) {
+  const charCount = new Array(26).fill(0);
+  let maxFrequency = 0;
+
+  for (const char of s) {
+    const index = char.charCodeAt(0) - 97;
+    charCount[index]++;
+    maxFrequency = Math.max(maxFrequency, charCount[index]);
+  }
+
+  let result = '';
+  for (let i = s.length - 1; i >= 0; i--) {
+    const index = s.charCodeAt(i) - 97;
+    if (charCount[index] === maxFrequency) {
+      result = s[i] + result;
+      charCount[index]--;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/3043-find-the-length-of-the-longest-common-prefix.js b/solutions/3043-find-the-length-of-the-longest-common-prefix.js
new file mode 100644
index 00000000..13ad3b97
--- /dev/null
+++ b/solutions/3043-find-the-length-of-the-longest-common-prefix.js
@@ -0,0 +1,50 @@
+/**
+ * 3043. Find the Length of the Longest Common Prefix
+ * https://leetcode.com/problems/find-the-length-of-the-longest-common-prefix/
+ * Difficulty: Medium
+ *
+ * You are given two arrays with positive integers arr1 and arr2.
+ *
+ * A prefix of a positive integer is an integer formed by one or more of its digits, starting
+ * from its leftmost digit. For example, 123 is a prefix of the integer 12345, while 234 is not.
+ *
+ * A common prefix of two integers a and b is an integer c, such that c is a prefix of both a
+ * and b. For example, 5655359 and 56554 have common prefixes 565 and 5655 while 1223 and 43456
+ * do not have a common prefix.
+ *
+ * You need to find the length of the longest common prefix between all pairs of integers (x, y)
+ * such that x belongs to arr1 and y belongs to arr2.
+ *
+ * Return the length of the longest common prefix among all pairs. If no common prefix exists
+ * among them, return 0.
+ */
+
+/**
+ * @param {number[]} arr1
+ * @param {number[]} arr2
+ * @return {number}
+ */
+var longestCommonPrefix = function(arr1, arr2) {
+  const prefixSet = new Set();
+  let result = 0;
+
+  for (const num of arr1) {
+    let prefix = num;
+    while (prefix > 0) {
+      prefixSet.add(prefix);
+      prefix = Math.floor(prefix / 10);
+    }
+  }
+
+  for (const num of arr2) {
+    let prefix = num;
+    while (prefix > 0) {
+      if (prefixSet.has(prefix)) {
+        result = Math.max(result, String(prefix).length);
+      }
+      prefix = Math.floor(prefix / 10);
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/3044-most-frequent-prime.js b/solutions/3044-most-frequent-prime.js
new file mode 100644
index 00000000..cde4f2e9
--- /dev/null
+++ b/solutions/3044-most-frequent-prime.js
@@ -0,0 +1,68 @@
+/**
+ * 3044. Most Frequent Prime
+ * https://leetcode.com/problems/most-frequent-prime/
+ * Difficulty: Medium
+ *
+ * You are given a m x n 0-indexed 2D matrix mat. From every cell, you can create numbers
+ * in the following way:
+ * - There could be at most 8 paths from the cells namely: east, south-east, south, south-west,
+ *   west, north-west, north, and north-east.
+ * - Select a path from them and append digits in this path to the number being formed by
+ *   traveling in this direction.
+ * - Note that numbers are generated at every step, for example, if the digits along the path
+ *   are 1, 9, 1, then there will be three numbers generated along the way: 1, 19, 191.
+ *
+ * Return the most frequent prime number greater than 10 out of all the numbers created by
+ * traversing the matrix or -1 if no such prime number exists. If there are multiple prime
+ * numbers with the highest frequency, then return the largest among them.
+ *
+ * Note: It is invalid to change the direction during the move.
+ */
+
+/**
+ * @param {number[][]} mat
+ * @return {number}
+ */
+var mostFrequentPrime = function(mat) {
+  const m = mat.length;
+  const n = mat[0].length;
+  const frequency = new Map();
+  const directions = [[0, 1], [1, 1], [1, 0], [1, -1], [0, -1], [-1, -1], [-1, 0], [-1, 1]];
+
+  const isPrime = num => {
+    if (num <= 1) return false;
+    for (let i = 2; i * i <= num; i++) {
+      if (num % i === 0) return false;
+    }
+    return true;
+  };
+
+  for (let i = 0; i < m; i++) {
+    for (let j = 0; j < n; j++) {
+      for (const [dx, dy] of directions) {
+        let x = i;
+        let y = j;
+        let num = 0;
+        while (x >= 0 && x < m && y >= 0 && y < n) {
+          num = num * 10 + mat[x][y];
+          if (num > 10 && isPrime(num)) {
+            frequency.set(num, (frequency.get(num) || 0) + 1);
+          }
+          x += dx;
+          y += dy;
+        }
+      }
+    }
+  }
+
+  let maxFreq = 0;
+  let result = -1;
+  for (const [num, freq] of frequency) {
+    if (freq > maxFreq || (freq === maxFreq && num > result)) {
+      maxFreq = freq;
+      result = num;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/3046-split-the-array.js b/solutions/3046-split-the-array.js
new file mode 100644
index 00000000..14f28868
--- /dev/null
+++ b/solutions/3046-split-the-array.js
@@ -0,0 +1,28 @@
+/**
+ * 3046. Split the Array
+ * https://leetcode.com/problems/split-the-array/
+ * Difficulty: Easy
+ *
+ * You are given an integer array nums of even length. You have to split the array into two
+ * parts nums1 and nums2 such that:
+ * - nums1.length == nums2.length == nums.length / 2.
+ * - nums1 should contain distinct elements.
+ * - nums2 should also contain distinct elements.
+ *
+ * Return true if it is possible to split the array, and false otherwise.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {boolean}
+ */
+var isPossibleToSplit = function(nums) {
+  const map = new Map();
+
+  for (const num of nums) {
+    map.set(num, (map.get(num) || 0) + 1);
+    if (map.get(num) > 2) return false;
+  }
+
+  return true;
+};
diff --git a/solutions/3047-find-the-largest-area-of-square-inside-two-rectangles.js b/solutions/3047-find-the-largest-area-of-square-inside-two-rectangles.js
new file mode 100644
index 00000000..7075570e
--- /dev/null
+++ b/solutions/3047-find-the-largest-area-of-square-inside-two-rectangles.js
@@ -0,0 +1,39 @@
+/**
+ * 3047. Find the Largest Area of Square Inside Two Rectangles
+ * https://leetcode.com/problems/find-the-largest-area-of-square-inside-two-rectangles/
+ * Difficulty: Medium
+ *
+ * There exist n rectangles in a 2D plane with edges parallel to the x and y axis. You
+ * are given two 2D integer arrays bottomLeft and topRight where bottomLeft[i] = [a_i, b_i]
+ * and topRight[i] = [c_i, d_i] represent the bottom-left and top-right coordinates of the
+ * ith rectangle, respectively.
+ *
+ * You need to find the maximum area of a square that can fit inside the intersecting
+ * region of at least two rectangles. Return 0 if such a square does not exist.
+ */
+
+/**
+ * @param {number[][]} bottomLeft
+ * @param {number[][]} topRight
+ * @return {number}
+ */
+var largestSquareArea = function(bottomLeft, topRight) {
+  const n = bottomLeft.length;
+  let maxSide = 0;
+
+  for (let i = 0; i < n; i++) {
+    for (let j = i + 1; j < n; j++) {
+      const xLeft = Math.max(bottomLeft[i][0], bottomLeft[j][0]);
+      const yBottom = Math.max(bottomLeft[i][1], bottomLeft[j][1]);
+      const xRight = Math.min(topRight[i][0], topRight[j][0]);
+      const yTop = Math.min(topRight[i][1], topRight[j][1]);
+
+      if (xLeft < xRight && yBottom < yTop) {
+        const side = Math.min(xRight - xLeft, yTop - yBottom);
+        maxSide = Math.max(maxSide, side);
+      }
+    }
+  }
+
+  return maxSide * maxSide;
+};
diff --git a/solutions/3065-minimum-operations-to-exceed-threshold-value-i.js b/solutions/3065-minimum-operations-to-exceed-threshold-value-i.js
new file mode 100644
index 00000000..53ae27ae
--- /dev/null
+++ b/solutions/3065-minimum-operations-to-exceed-threshold-value-i.js
@@ -0,0 +1,27 @@
+/**
+ * 3065. Minimum Operations to Exceed Threshold Value I
+ * https://leetcode.com/problems/minimum-operations-to-exceed-threshold-value-i/
+ * Difficulty: Easy
+ *
+ * You are given a 0-indexed integer array nums, and an integer k.
+ *
+ * In one operation, you can remove one occurrence of the smallest element of nums.
+ *
+ * Return the minimum number of operations needed so that all elements of the array are greater
+ * than or equal to k.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @return {number}
+ */
+var minOperations = function(nums, k) {
+  let operations = 0;
+
+  for (const num of nums) {
+    if (num < k) operations++;
+  }
+
+  return operations;
+};
diff --git a/solutions/3067-count-pairs-of-connectable-servers-in-a-weighted-tree-network.js b/solutions/3067-count-pairs-of-connectable-servers-in-a-weighted-tree-network.js
new file mode 100644
index 00000000..cfcb71ff
--- /dev/null
+++ b/solutions/3067-count-pairs-of-connectable-servers-in-a-weighted-tree-network.js
@@ -0,0 +1,64 @@
+/**
+ * 3067. Count Pairs of Connectable Servers in a Weighted Tree Network
+ * https://leetcode.com/problems/count-pairs-of-connectable-servers-in-a-weighted-tree-network/
+ * Difficulty: Medium
+ *
+ * You are given an unrooted weighted tree with n vertices representing servers numbered from 0
+ * to n - 1, an array edges where edges[i] = [ai, bi, weighti] represents a bidirectional edge
+ * between vertices ai and bi of weight weighti. You are also given an integer signalSpeed.
+ *
+ * Two servers a and b are connectable through a server c if:
+ * - a < b, a != c and b != c.
+ * - The distance from c to a is divisible by signalSpeed.
+ * - The distance from c to b is divisible by signalSpeed.
+ * - The path from c to b and the path from c to a do not share any edges.
+ *
+ * Return an integer array count of length n where count[i] is the number of server pairs that are
+ * connectable through the server i.
+ */
+
+/**
+ * @param {number[][]} edges
+ * @param {number} signalSpeed
+ * @return {number[]}
+ */
+var countPairsOfConnectableServers = function(edges, signalSpeed) {
+  const n = edges.length + 1;
+  const graph = Array.from({ length: n }, () => []);
+  for (const [u, v, w] of edges) {
+    graph[u].push([v, w]);
+    graph[v].push([u, w]);
+  }
+
+  const result = new Array(n).fill(0);
+  for (let i = 0; i < n; i++) {
+    result[i] = countValidPairs(i);
+  }
+  return result;
+
+  function countValidPairs(root) {
+    function dfs(node, parent, distance) {
+      let count = distance % signalSpeed === 0 ? 1 : 0;
+      for (const [next, weight] of graph[node]) {
+        if (next !== parent) {
+          count += dfs(next, node, distance + weight);
+        }
+      }
+      return count;
+    }
+
+    let totalPairs = 0;
+    const counts = [];
+    for (const [child, weight] of graph[root]) {
+      const count = dfs(child, root, weight);
+      counts.push(count);
+    }
+
+    let sum = 0;
+    for (const count of counts) {
+      totalPairs += sum * count;
+      sum += count;
+    }
+    return totalPairs;
+  }
+};
diff --git a/solutions/3068-find-the-maximum-sum-of-node-values.js b/solutions/3068-find-the-maximum-sum-of-node-values.js
new file mode 100644
index 00000000..27666217
--- /dev/null
+++ b/solutions/3068-find-the-maximum-sum-of-node-values.js
@@ -0,0 +1,52 @@
+/**
+ * 3068. Find the Maximum Sum of Node Values
+ * https://leetcode.com/problems/find-the-maximum-sum-of-node-values/
+ * Difficulty: Hard
+ *
+ * There exists an undirected tree with n nodes numbered 0 to n - 1. You are given a 0-indexed
+ * 2D integer array edges of length n - 1, where edges[i] = [ui, vi] indicates that there is an
+ * edge between nodes ui and vi in the tree. You are also given a positive integer k, and a
+ * 0-indexed array of non-negative integers nums of length n, where nums[i] represents the
+ * value of the node numbered i.
+ *
+ * Alice wants the sum of values of tree nodes to be maximum, for which Alice can perform the
+ * following operation any number of times (including zero) on the tree:
+ * - Choose any edge [u, v] connecting the nodes u and v, and update their values as follows:
+ *   - nums[u] = nums[u] XOR k
+ *   - nums[v] = nums[v] XOR k
+ *
+ * Return the maximum possible sum of the values Alice can achieve by performing the operation
+ * any number of times.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @param {number[][]} edges
+ * @return {number}
+ */
+var maximumValueSum = function(nums, k, edges) {
+  let totalSum = 0;
+  let minChange = Infinity;
+  let changeCount = 0;
+
+  for (const num of nums) {
+    const xored = num ^ k;
+    const change = xored - num;
+
+    if (change > 0) {
+      totalSum += xored;
+      changeCount++;
+    } else {
+      totalSum += num;
+    }
+
+    minChange = Math.min(minChange, Math.abs(change));
+  }
+
+  if (changeCount % 2 === 0) {
+    return totalSum;
+  }
+
+  return totalSum - minChange;
+};
diff --git a/solutions/3069-distribute-elements-into-two-arrays-i.js b/solutions/3069-distribute-elements-into-two-arrays-i.js
new file mode 100644
index 00000000..ed2f0d96
--- /dev/null
+++ b/solutions/3069-distribute-elements-into-two-arrays-i.js
@@ -0,0 +1,37 @@
+/**
+ * 3069. Distribute Elements Into Two Arrays I
+ * https://leetcode.com/problems/distribute-elements-into-two-arrays-i/
+ * Difficulty: Easy
+ *
+ * You are given a 1-indexed array of distinct integers nums of length n.
+ *
+ * You need to distribute all the elements of nums between two arrays arr1 and arr2 using n
+ * operations. In the first operation, append nums[1] to arr1. In the second operation,
+ * append nums[2] to arr2. Afterwards, in the ith operation:
+ * - If the last element of arr1 is greater than the last element of arr2, append nums[i] to arr1.
+ *   Otherwise, append nums[i] to arr2.
+ *
+ * The array result is formed by concatenating the arrays arr1 and arr2. For example, if
+ * arr1 == [1,2,3] and arr2 == [4,5,6], then result = [1,2,3,4,5,6].
+ *
+ * Return the array result.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number[]}
+ */
+var resultArray = function(nums) {
+  const arr1 = [nums[0]];
+  const arr2 = [nums[1]];
+
+  for (let i = 2; i < nums.length; i++) {
+    if (arr1[arr1.length - 1] > arr2[arr2.length - 1]) {
+      arr1.push(nums[i]);
+    } else {
+      arr2.push(nums[i]);
+    }
+  }
+
+  return [...arr1, ...arr2];
+};
diff --git a/solutions/3070-count-submatrices-with-top-left-element-and-sum-less-than-k.js b/solutions/3070-count-submatrices-with-top-left-element-and-sum-less-than-k.js
new file mode 100644
index 00000000..93cd1cb1
--- /dev/null
+++ b/solutions/3070-count-submatrices-with-top-left-element-and-sum-less-than-k.js
@@ -0,0 +1,39 @@
+/**
+ * 3070. Count Submatrices with Top-Left Element and Sum Less Than k
+ * https://leetcode.com/problems/count-submatrices-with-top-left-element-and-sum-less-than-k/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed integer matrix grid and an integer k.
+ *
+ * Return the number of submatrices that contain the top-left element of the grid, and have a sum
+ * less than or equal to k.
+ */
+
+/**
+ * @param {number[][]} grid
+ * @param {number} k
+ * @return {number}
+ */
+var countSubmatrices = function(grid, k) {
+  const rows = grid.length;
+  const cols = grid[0].length;
+  const prefixSum = Array.from({ length: rows + 1 }, () => new Array(cols + 1).fill(0));
+
+  for (let i = 1; i <= rows; i++) {
+    for (let j = 1; j <= cols; j++) {
+      prefixSum[i][j] = grid[i-1][j-1] + prefixSum[i-1][j]
+        + prefixSum[i][j-1] - prefixSum[i-1][j-1];
+    }
+  }
+
+  let result = 0;
+  for (let i = 1; i <= rows; i++) {
+    for (let j = 1; j <= cols; j++) {
+      if (prefixSum[i][j] <= k) {
+        result++;
+      }
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/3071-minimum-operations-to-write-the-letter-y-on-a-grid.js b/solutions/3071-minimum-operations-to-write-the-letter-y-on-a-grid.js
new file mode 100644
index 00000000..15ad3700
--- /dev/null
+++ b/solutions/3071-minimum-operations-to-write-the-letter-y-on-a-grid.js
@@ -0,0 +1,63 @@
+/**
+ * 3071. Minimum Operations to Write the Letter Y on a Grid
+ * https://leetcode.com/problems/minimum-operations-to-write-the-letter-y-on-a-grid/
+ * Difficulty: Medium
+ *
+ * You are given a 0-indexed n x n grid where n is odd, and grid[r][c] is 0, 1, or 2.
+ *
+ * We say that a cell belongs to the Letter Y if it belongs to one of the following:
+ * - The diagonal starting at the top-left cell and ending at the center cell of the grid.
+ * - The diagonal starting at the top-right cell and ending at the center cell of the grid.
+ * - The vertical line starting at the center cell and ending at the bottom border of the grid.
+ *
+ * The Letter Y is written on the grid if and only if:
+ * - All values at cells belonging to the Y are equal.
+ * - All values at cells not belonging to the Y are equal.
+ * - The values at cells belonging to the Y are different from the values at cells not belonging
+ *   to the Y.
+ *
+ * Return the minimum number of operations needed to write the letter Y on the grid given that
+ * in one operation you can change the value at any cell to 0, 1, or 2.
+ */
+
+/**
+ * @param {number[][]} grid
+ * @return {number}
+ */
+var minimumOperationsToWriteY = function(grid) {
+  const n = grid.length;
+  const center = Math.floor(n / 2);
+  const yCells = [];
+  const nonYCells = [];
+
+  for (let i = 0; i < n; i++) {
+    for (let j = 0; j < n; j++) {
+      if ((i === j && i <= center) || (i === n - 1 - j && i <= center)
+          || (j === center && i >= center)) {
+        yCells.push(grid[i][j]);
+      } else {
+        nonYCells.push(grid[i][j]);
+      }
+    }
+  }
+
+  const yCounts = [0, 0, 0];
+  const nonYCounts = [0, 0, 0];
+
+  for (const val of yCells) yCounts[val]++;
+  for (const val of nonYCells) nonYCounts[val]++;
+
+  let minOperations = Infinity;
+
+  for (let yVal = 0; yVal <= 2; yVal++) {
+    for (let nonYVal = 0; nonYVal <= 2; nonYVal++) {
+      if (yVal !== nonYVal) {
+        const yOps = yCells.length - yCounts[yVal];
+        const nonYOps = nonYCells.length - nonYCounts[nonYVal];
+        minOperations = Math.min(minOperations, yOps + nonYOps);
+      }
+    }
+  }
+
+  return minOperations;
+};
diff --git a/solutions/3074-apple-redistribution-into-boxes.js b/solutions/3074-apple-redistribution-into-boxes.js
new file mode 100644
index 00000000..27e3f17a
--- /dev/null
+++ b/solutions/3074-apple-redistribution-into-boxes.js
@@ -0,0 +1,38 @@
+/**
+ * 3074. Apple Redistribution into Boxes
+ * https://leetcode.com/problems/apple-redistribution-into-boxes/
+ * Difficulty: Easy
+ *
+ * You are given an array apple of size n and an array capacity of size m.
+ *
+ * There are n packs where the ith pack contains apple[i] apples. There are m boxes as well,
+ * and the ith box has a capacity of capacity[i] apples.
+ *
+ * Return the minimum number of boxes you need to select to redistribute these n packs of
+ * apples into boxes.
+ *
+ * Note that, apples from the same pack can be distributed into different boxes.
+ */
+
+/**
+ * @param {number[]} apple
+ * @param {number[]} capacity
+ * @return {number}
+ */
+var minimumBoxes = function(apple, capacity) {
+  const totalApples = apple.reduce((sum, num) => sum + num, 0);
+  const sortedCapacities = capacity.sort((a, b) => b - a);
+  let currentCapacity = 0;
+  let result = 0;
+
+  for (const box of sortedCapacities) {
+    if (currentCapacity < totalApples) {
+      currentCapacity += box;
+      result++;
+    } else {
+      break;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/3075-maximize-happiness-of-selected-children.js b/solutions/3075-maximize-happiness-of-selected-children.js
new file mode 100644
index 00000000..853a0851
--- /dev/null
+++ b/solutions/3075-maximize-happiness-of-selected-children.js
@@ -0,0 +1,35 @@
+/**
+ * 3075. Maximize Happiness of Selected Children
+ * https://leetcode.com/problems/maximize-happiness-of-selected-children/
+ * Difficulty: Medium
+ *
+ * You are given an array happiness of length n, and a positive integer k.
+ *
+ * There are n children standing in a queue, where the ith child has happiness value
+ * happiness[i]. You want to select k children from these n children in k turns.
+ *
+ * In each turn, when you select a child, the happiness value of all the children that
+ * have not been selected till now decreases by 1. Note that the happiness value cannot
+ * become negative and gets decremented only if it is positive.
+ *
+ * Return the maximum sum of the happiness values of the selected children you can
+ * achieve by selecting k children.
+ */
+
+/**
+ * @param {number[]} happiness
+ * @param {number} k
+ * @return {number}
+ */
+var maximumHappinessSum = function(happiness, k) {
+  const sortedHappiness = happiness.sort((a, b) => b - a);
+  let result = 0;
+
+  for (let i = 0; i < k; i++) {
+    const currentHappiness = sortedHappiness[i] - i;
+    if (currentHappiness <= 0) break;
+    result += currentHappiness;
+  }
+
+  return result;
+};
diff --git a/solutions/3076-shortest-uncommon-substring-in-an-array.js b/solutions/3076-shortest-uncommon-substring-in-an-array.js
new file mode 100644
index 00000000..60559014
--- /dev/null
+++ b/solutions/3076-shortest-uncommon-substring-in-an-array.js
@@ -0,0 +1,56 @@
+/**
+ * 3076. Shortest Uncommon Substring in an Array
+ * https://leetcode.com/problems/shortest-uncommon-substring-in-an-array/
+ * Difficulty: Medium
+ *
+ * You are given an array arr of size n consisting of non-empty strings.
+ *
+ * Find a string array answer of size n such that:
+ * - answer[i] is the shortest substring of arr[i] that does not occur as a substring in any
+ *   other string in arr. If multiple such substrings exist, answer[i] should be the
+ *   lexicographically smallest. And if no such substring exists, answer[i] should be an
+ *   empty string.
+ *
+ * Return the array answer.
+ */
+
+/**
+ * @param {string[]} arr
+ * @return {string[]}
+ */
+var shortestSubstrings = function(arr) {
+  const n = arr.length;
+  const result = new Array(n).fill('');
+
+  for (let i = 0; i < n; i++) {
+    const str = arr[i];
+    let minLen = Infinity;
+    let minSubstr = '';
+
+    for (let len = 1; len <= str.length; len++) {
+      for (let start = 0; start <= str.length - len; start++) {
+        const substr = str.slice(start, start + len);
+        if (isUnique(substr, i)) {
+          if (len < minLen || (len === minLen && substr < minSubstr)) {
+            minLen = len;
+            minSubstr = substr;
+          }
+        }
+      }
+      if (minSubstr) break;
+    }
+
+    result[i] = minSubstr;
+  }
+
+  return result;
+
+  function isUnique(substr, strIdx) {
+    for (let i = 0; i < n; i++) {
+      if (i !== strIdx && arr[i].includes(substr)) {
+        return false;
+      }
+    }
+    return true;
+  }
+};
diff --git a/solutions/3079-find-the-sum-of-encrypted-integers.js b/solutions/3079-find-the-sum-of-encrypted-integers.js
new file mode 100644
index 00000000..8bdaf881
--- /dev/null
+++ b/solutions/3079-find-the-sum-of-encrypted-integers.js
@@ -0,0 +1,41 @@
+/**
+ * 3079. Find the Sum of Encrypted Integers
+ * https://leetcode.com/problems/find-the-sum-of-encrypted-integers/
+ * Difficulty: Easy
+ *
+ * You are given an integer array nums containing positive integers. We define a function
+ * encrypt such that encrypt(x) replaces every digit in x with the largest digit in x.
+ * For example, encrypt(523) = 555 and encrypt(213) = 333.
+ *
+ * Return the sum of encrypted elements.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var sumOfEncryptedInt = function(nums) {
+  let result = 0;
+
+  for (const num of nums) {
+    let maxDigit = 0;
+    let temp = num;
+    let digitCount = 0;
+
+    while (temp > 0) {
+      maxDigit = Math.max(maxDigit, temp % 10);
+      temp = Math.floor(temp / 10);
+      digitCount++;
+    }
+
+    let encrypted = 0;
+    while (digitCount > 0) {
+      encrypted = encrypted * 10 + maxDigit;
+      digitCount--;
+    }
+
+    result += encrypted;
+  }
+
+  return result;
+};
diff --git a/solutions/3083-existence-of-a-substring-in-a-string-and-its-reverse.js b/solutions/3083-existence-of-a-substring-in-a-string-and-its-reverse.js
new file mode 100644
index 00000000..8af3eb50
--- /dev/null
+++ b/solutions/3083-existence-of-a-substring-in-a-string-and-its-reverse.js
@@ -0,0 +1,26 @@
+/**
+ * 3083. Existence of a Substring in a String and Its Reverse
+ * https://leetcode.com/problems/existence-of-a-substring-in-a-string-and-its-reverse/
+ * Difficulty: Easy
+ *
+ * Given a string s, find any substring of length 2 which is also present in the reverse of s.
+ *
+ * Return true if such a substring exists, and false otherwise.
+ */
+
+/**
+ * @param {string} s
+ * @return {boolean}
+ */
+var isSubstringPresent = function(s) {
+  const reversed = s.split('').reverse().join('');
+
+  for (let i = 0; i < s.length - 1; i++) {
+    const substr = s.slice(i, i + 2);
+    if (reversed.includes(substr)) {
+      return true;
+    }
+  }
+
+  return false;
+};
diff --git a/solutions/3084-count-substrings-starting-and-ending-with-given-character.js b/solutions/3084-count-substrings-starting-and-ending-with-given-character.js
new file mode 100644
index 00000000..be6b8bc2
--- /dev/null
+++ b/solutions/3084-count-substrings-starting-and-ending-with-given-character.js
@@ -0,0 +1,21 @@
+/**
+ * 3084. Count Substrings Starting and Ending with Given Character
+ * https://leetcode.com/problems/count-substrings-starting-and-ending-with-given-character/
+ * Difficulty: Medium
+ *
+ * You are given a string s and a character c. Return the total number of substrings of s
+ * that start and end with c.
+ */
+
+/**
+ * @param {string} s
+ * @param {character} c
+ * @return {number}
+ */
+var countSubstrings = function(s, c) {
+  let count = 0;
+  for (const char of s) {
+    if (char === c) count++;
+  }
+  return (count * (count + 1)) / 2;
+};
diff --git a/solutions/3085-minimum-deletions-to-make-string-k-special.js b/solutions/3085-minimum-deletions-to-make-string-k-special.js
new file mode 100644
index 00000000..98db902e
--- /dev/null
+++ b/solutions/3085-minimum-deletions-to-make-string-k-special.js
@@ -0,0 +1,45 @@
+/**
+ * 3085. Minimum Deletions to Make String K-Special
+ * https://leetcode.com/problems/minimum-deletions-to-make-string-k-special/
+ * Difficulty: Medium
+ *
+ * You are given a string word and an integer k.
+ *
+ * We consider word to be k-special if |freq(word[i]) - freq(word[j])| <= k for all indices i
+ * and j in the string.
+ *
+ * Here, freq(x) denotes the frequency of the character x in word, and |y| denotes the absolute
+ * value of y.
+ *
+ * Return the minimum number of characters you need to delete to make word k-special.
+ */
+
+/**
+ * @param {string} word
+ * @param {number} k
+ * @return {number}
+ */
+var minimumDeletions = function(word, k) {
+  const freq = new Array(26).fill(0);
+
+  for (const char of word) {
+    freq[char.charCodeAt(0) - 97]++;
+  }
+
+  const counts = freq.filter(x => x > 0).sort((a, b) => a - b);
+  let minDeletions = Infinity;
+  for (let i = 0; i < counts.length; i++) {
+    let deletions = 0;
+    for (let j = 0; j < i; j++) {
+      deletions += counts[j];
+    }
+    for (let j = i; j < counts.length; j++) {
+      if (counts[j] - counts[i] > k) {
+        deletions += counts[j] - (counts[i] + k);
+      }
+    }
+    minDeletions = Math.min(minDeletions, deletions);
+  }
+
+  return minDeletions;
+};
diff --git a/solutions/3090-maximum-length-substring-with-two-occurrences.js b/solutions/3090-maximum-length-substring-with-two-occurrences.js
new file mode 100644
index 00000000..84003cd8
--- /dev/null
+++ b/solutions/3090-maximum-length-substring-with-two-occurrences.js
@@ -0,0 +1,31 @@
+/**
+ * 3090. Maximum Length Substring With Two Occurrences
+ * https://leetcode.com/problems/maximum-length-substring-with-two-occurrences/
+ * Difficulty: Easy
+ *
+ * Given a string s, return the maximum length of a substring such that it contains at most
+ * two occurrences of each character.
+ */
+
+/**
+ * @param {string} s
+ * @return {number}
+ */
+var maximumLengthSubstring = function(s) {
+  let result = 0;
+  const map = new Map();
+
+  for (let left = 0, right = 0; right < s.length; right++) {
+    map.set(s[right], (map.get(s[right]) || 0) + 1);
+
+    while (map.get(s[right]) > 2) {
+      map.set(s[left], map.get(s[left]) - 1);
+      if (map.get(s[left]) === 0) map.delete(s[left]);
+      left++;
+    }
+
+    result = Math.max(result, right - left + 1);
+  }
+
+  return result;
+};
diff --git a/solutions/3091-apply-operations-to-make-sum-of-array-greater-than-or-equal-to-k.js b/solutions/3091-apply-operations-to-make-sum-of-array-greater-than-or-equal-to-k.js
new file mode 100644
index 00000000..a1c50bd6
--- /dev/null
+++ b/solutions/3091-apply-operations-to-make-sum-of-array-greater-than-or-equal-to-k.js
@@ -0,0 +1,33 @@
+/**
+ * 3091. Apply Operations to Make Sum of Array Greater Than or Equal to k
+ * https://leetcode.com/problems/apply-operations-to-make-sum-of-array-greater-than-or-equal-to-k/
+ * Difficulty: Medium
+ *
+ * You are given a positive integer k. Initially, you have an array nums = [1].
+ *
+ * You can perform any of the following operations on the array any number of times (possibly zero):
+ * - Choose any element in the array and increase its value by 1.
+ * - Duplicate any element in the array and add it to the end of the array.
+ *
+ * Return the minimum number of operations required to make the sum of elements of the final array
+ * greater than or equal to k.
+ */
+
+/**
+ * @param {number} k
+ * @return {number}
+ */
+var minOperations = function(k) {
+  if (k === 1) return 0;
+
+  let result = Infinity;
+  for (let increments = 0; increments <= Math.ceil(Math.sqrt(k)); increments++) {
+    const value = 1 + increments;
+    const duplicates = Math.ceil(k / value) - 1;
+    if (duplicates >= 0) {
+      result = Math.min(result, increments + duplicates);
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/3095-shortest-subarray-with-or-at-least-k-i.js b/solutions/3095-shortest-subarray-with-or-at-least-k-i.js
new file mode 100644
index 00000000..0f03aa97
--- /dev/null
+++ b/solutions/3095-shortest-subarray-with-or-at-least-k-i.js
@@ -0,0 +1,35 @@
+/**
+ * 3095. Shortest Subarray With OR at Least K I
+ * https://leetcode.com/problems/shortest-subarray-with-or-at-least-k-i/
+ * Difficulty: Easy
+ *
+ * You are given an array nums of non-negative integers and an integer k.
+ *
+ * An array is called special if the bitwise OR of all of its elements is at least k.
+ *
+ * Return the length of the shortest special non-empty subarray of nums, or return -1 if
+ * no special subarray exists.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @return {number}
+ */
+var minimumSubarrayLength = function(nums, k) {
+  if (k === 0) return 1;
+
+  let minLength = Infinity;
+  for (let start = 0; start < nums.length; start++) {
+    let orResult = 0;
+    for (let end = start; end < nums.length; end++) {
+      orResult |= nums[end];
+      if (orResult >= k) {
+        minLength = Math.min(minLength, end - start + 1);
+        break;
+      }
+    }
+  }
+
+  return minLength === Infinity ? -1 : minLength;
+};
diff --git a/solutions/3097-shortest-subarray-with-or-at-least-k-ii.js b/solutions/3097-shortest-subarray-with-or-at-least-k-ii.js
new file mode 100644
index 00000000..f85c9879
--- /dev/null
+++ b/solutions/3097-shortest-subarray-with-or-at-least-k-ii.js
@@ -0,0 +1,48 @@
+/**
+ * 3097. Shortest Subarray With OR at Least K II
+ * https://leetcode.com/problems/shortest-subarray-with-or-at-least-k-ii/
+ * Difficulty: Medium
+ *
+ * You are given an array nums of non-negative integers and an integer k.
+ *
+ * An array is called special if the bitwise OR of all of its elements is at least k.
+ *
+ * Return the length of the shortest special non-empty subarray of nums, or return -1 if no
+ * special subarray exists.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @return {number}
+ */
+var minimumSubarrayLength = function(nums, k) {
+  if (k === 0) return 1;
+
+  const bitCounts = new Array(32).fill(0);
+  let minLength = Infinity;
+  let orValue = 0;
+  let left = 0;
+
+  for (let right = 0; right < nums.length; right++) {
+    const num = nums[right];
+    for (let bit = 0; bit < 32; bit++) {
+      if (num & (1 << bit)) bitCounts[bit]++;
+      if (bitCounts[bit] > 0) orValue |= 1 << bit;
+    }
+
+    while (orValue >= k && left <= right) {
+      minLength = Math.min(minLength, right - left + 1);
+      const leftNum = nums[left];
+      for (let bit = 0; bit < 32; bit++) {
+        if (leftNum & (1 << bit)) {
+          bitCounts[bit]--;
+          if (bitCounts[bit] === 0) orValue &= ~(1 << bit);
+        }
+      }
+      left++;
+    }
+  }
+
+  return minLength === Infinity ? -1 : minLength;
+};
diff --git a/solutions/3099-harshad-number.js b/solutions/3099-harshad-number.js
new file mode 100644
index 00000000..f096f4c8
--- /dev/null
+++ b/solutions/3099-harshad-number.js
@@ -0,0 +1,22 @@
+/**
+ * 3099. Harshad Number
+ * https://leetcode.com/problems/harshad-number/
+ * Difficulty: Easy
+ *
+ * An integer divisible by the sum of its digits is said to be a Harshad number. You are given
+ * an integer x. Return the sum of the digits of x if x is a Harshad number, otherwise, return -1.
+ */
+
+/**
+ * @param {number} x
+ * @return {number}
+ */
+var sumOfTheDigitsOfHarshadNumber = function(x) {
+  let digitSum = 0;
+  let num = x;
+  while (num > 0) {
+    digitSum += num % 10;
+    num = Math.floor(num / 10);
+  }
+  return x % digitSum === 0 ? digitSum : -1;
+};
diff --git a/solutions/3100-water-bottles-ii.js b/solutions/3100-water-bottles-ii.js
new file mode 100644
index 00000000..a251d5d6
--- /dev/null
+++ b/solutions/3100-water-bottles-ii.js
@@ -0,0 +1,43 @@
+/**
+ * 3100. Water Bottles II
+ * https://leetcode.com/problems/water-bottles-ii/
+ * Difficulty: Medium
+ *
+ * You are given two integers numBottles and numExchange.
+ *
+ * numBottles represents the number of full water bottles that you initially have. In one
+ * operation, you can perform one of the following operations:
+ * - Drink any number of full water bottles turning them into empty bottles.
+ * - Exchange numExchange empty bottles with one full water bottle. Then, increase
+ *   numExchange by one.
+ *
+ * Note that you cannot exchange multiple batches of empty bottles for the same value of
+ * numExchange. For example, if numBottles == 3 and numExchange == 1, you cannot exchange
+ * 3 empty water bottles for 3 full bottles.
+ *
+ * Return the maximum number of water bottles you can drink.
+ */
+
+/**
+ * @param {number} numBottles
+ * @param {number} numExchange
+ * @return {number}
+ */
+var maxBottlesDrunk = function(numBottles, numExchange) {
+  let result = 0;
+  let full = numBottles;
+  let empty = 0;
+
+  while (full > 0) {
+    result += full;
+    empty += full;
+    full = 0;
+    if (empty >= numExchange) {
+      full = 1;
+      empty -= numExchange;
+      numExchange++;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/3170-lexicographically-minimum-string-after-removing-stars.js b/solutions/3170-lexicographically-minimum-string-after-removing-stars.js
new file mode 100644
index 00000000..c0efec6b
--- /dev/null
+++ b/solutions/3170-lexicographically-minimum-string-after-removing-stars.js
@@ -0,0 +1,40 @@
+/**
+ * 3170. Lexicographically Minimum String After Removing Stars
+ * https://leetcode.com/problems/lexicographically-minimum-string-after-removing-stars/
+ * Difficulty: Medium
+ *
+ * You are given a string s. It may contain any number of '*' characters. Your task is to
+ * remove all '*' characters.
+ *
+ * While there is a '*', do the following operation:
+ * - Delete the leftmost '*' and the smallest non-'*' character to its left. If there are several
+ *   smallest characters, you can delete any of them.
+ *
+ * Return the lexicographically smallest resulting string after removing all '*' characters.
+ */
+
+/**
+ * @param {string} s
+ * @return {string}
+ */
+var clearStars = function(s) {
+  const chars = s.split('');
+  const deleted = new Set();
+  const stacks = new Array(26).fill().map(() => []);
+
+  for (let i = 0; i < s.length; i++) {
+    if (s[i] === '*') {
+      for (let j = 0; j < 26; j++) {
+        if (stacks[j].length) {
+          deleted.add(stacks[j].pop());
+          deleted.add(i);
+          break;
+        }
+      }
+    } else {
+      stacks[s[i].charCodeAt(0) - 97].push(i);
+    }
+  }
+
+  return chars.filter((_, i) => !deleted.has(i)).join('');
+};
diff --git a/solutions/3178-find-the-child-who-has-the-ball-after-k-seconds.js b/solutions/3178-find-the-child-who-has-the-ball-after-k-seconds.js
new file mode 100644
index 00000000..cdbd5d88
--- /dev/null
+++ b/solutions/3178-find-the-child-who-has-the-ball-after-k-seconds.js
@@ -0,0 +1,25 @@
+/**
+ * 3178. Find the Child Who Has the Ball After K Seconds
+ * https://leetcode.com/problems/find-the-child-who-has-the-ball-after-k-seconds/
+ * Difficulty: Easy
+ *
+ * You are given two positive integers n and k. There are n children numbered from 0 to n - 1
+ * standing in a queue in order from left to right.
+ *
+ * Initially, child 0 holds a ball and the direction of passing the ball is towards the right
+ * direction. After each second, the child holding the ball passes it to the child next to
+ * them. Once the ball reaches either end of the line, i.e. child 0 or child n - 1, the direction
+ * of passing is reversed.
+ *
+ * Return the number of the child who receives the ball after k seconds.
+ */
+
+/**
+ * @param {number} n
+ * @param {number} k
+ * @return {number}
+ */
+var numberOfChild = function(n, k) {
+  const position = k % (2 * (n - 1));
+  return position < n ? position : 2 * n - position - 2;
+};
diff --git a/solutions/3335-total-characters-in-string-after-transformations-i.js b/solutions/3335-total-characters-in-string-after-transformations-i.js
new file mode 100644
index 00000000..e62e76ea
--- /dev/null
+++ b/solutions/3335-total-characters-in-string-after-transformations-i.js
@@ -0,0 +1,47 @@
+/**
+ * 3335. Total Characters in String After Transformations I
+ * https://leetcode.com/problems/total-characters-in-string-after-transformations-i/
+ * Difficulty: Medium
+ *
+ * You are given a string s and an integer t, representing the number of transformations to
+ * perform. In one transformation, every character in s is replaced according to the following
+ * rules:
+ * - If the character is 'z', replace it with the string "ab".
+ * - Otherwise, replace it with the next character in the alphabet. For example, 'a' is replaced
+ *   with 'b', 'b' is replaced with 'c', and so on.
+ *
+ * Return the length of the resulting string after exactly t transformations.
+ *
+ * Since the answer may be very large, return it modulo 109 + 7.
+ */
+
+/**
+ * @param {string} s
+ * @param {number} t
+ * @return {number}
+ */
+var lengthAfterTransformations = function(s, t) {
+  const MOD = 1e9 + 7;
+  const freq = new Array(26).fill(0);
+
+  for (const char of s) {
+    freq[char.charCodeAt(0) - 97]++;
+  }
+
+  for (let i = 0; i < t; i++) {
+    const newFreq = new Array(26).fill(0);
+    for (let j = 0; j < 25; j++) {
+      newFreq[j + 1] = freq[j];
+    }
+    newFreq[0] = (newFreq[0] + freq[25]) % MOD;
+    newFreq[1] = (newFreq[1] + freq[25]) % MOD;
+    freq.splice(0, 26, ...newFreq);
+  }
+
+  let result = 0;
+  for (const count of freq) {
+    result = (result + count) % MOD;
+  }
+
+  return result;
+};
diff --git a/solutions/3337-total-characters-in-string-after-transformations-ii.js b/solutions/3337-total-characters-in-string-after-transformations-ii.js
new file mode 100644
index 00000000..91d4d6aa
--- /dev/null
+++ b/solutions/3337-total-characters-in-string-after-transformations-ii.js
@@ -0,0 +1,78 @@
+/**
+ * 3337. Total Characters in String After Transformations II
+ * https://leetcode.com/problems/total-characters-in-string-after-transformations-ii/
+ * Difficulty: Hard
+ *
+ * You are given a string s consisting of lowercase English letters, an integer t representing
+ * the number of transformations to perform, and an array nums of size 26. In one transformation,
+ * every character in s is replaced according to the following rules:
+ * - Replace s[i] with the next nums[s[i] - 'a'] consecutive characters in the alphabet. For
+ *   example, if s[i] = 'a' and nums[0] = 3, the character 'a' transforms into the next 3
+ *   consecutive characters ahead of it, which results in "bcd".
+ * - The transformation wraps around the alphabet if it exceeds 'z'. For example, if s[i] = 'y'
+ *   and nums[24] = 3, the character 'y' transforms into the next 3 consecutive characters ahead
+ *   of it, which results in "zab".
+ *
+ * Return the length of the resulting string after exactly t transformations.
+ *
+ * Since the answer may be very large, return it modulo 109 + 7.
+ */
+
+/**
+ * @param {string} s
+ * @param {number} t
+ * @param {number[]} nums
+ * @return {number}
+ */
+var lengthAfterTransformations = function(s, t, nums) {
+  const MOD = 1000000007n;
+  const freq = new Array(26).fill(0n);
+
+  for (const char of s) {
+    freq[char.charCodeAt(0) - 97]++;
+  }
+
+  const matrix = new Array(26).fill().map(() => new Array(26).fill(0n));
+  for (let i = 0; i < 26; i++) {
+    for (let j = 0; j < nums[i]; j++) {
+      matrix[(i + j + 1) % 26][i] = 1n;
+    }
+  }
+
+  const finalMatrix = matrixPower(matrix, t);
+  let total = 0n;
+
+  for (let i = 0; i < 26; i++) {
+    let sum = 0n;
+    for (let j = 0; j < 26; j++) {
+      sum = (sum + finalMatrix[i][j] * freq[j]) % MOD;
+    }
+    total = (total + sum) % MOD;
+  }
+
+  return Number(total);
+
+  function matrixMultiply(a, b) {
+    const result = new Array(26).fill().map(() => new Array(26).fill(0n));
+    for (let i = 0; i < 26; i++) {
+      for (let j = 0; j < 26; j++) {
+        for (let k = 0; k < 26; k++) {
+          result[i][j] = (result[i][j] + a[i][k] * b[k][j]) % MOD;
+        }
+      }
+    }
+    return result;
+  }
+
+  function matrixPower(mat, power) {
+    let result = new Array(26).fill().map(() => new Array(26).fill(0n));
+    for (let i = 0; i < 26; i++) result[i][i] = 1n;
+
+    while (power > 0) {
+      if (power & 1) result = matrixMultiply(result, mat);
+      mat = matrixMultiply(mat, mat);
+      power >>= 1;
+    }
+    return result;
+  }
+};
diff --git a/solutions/3341-find-minimum-time-to-reach-last-room-i.js b/solutions/3341-find-minimum-time-to-reach-last-room-i.js
new file mode 100644
index 00000000..fae5957b
--- /dev/null
+++ b/solutions/3341-find-minimum-time-to-reach-last-room-i.js
@@ -0,0 +1,55 @@
+/**
+ * 3341. Find Minimum Time to Reach Last Room I
+ * https://leetcode.com/problems/find-minimum-time-to-reach-last-room-i/
+ * Difficulty: Medium
+ *
+ * There is a dungeon with n x m rooms arranged as a grid.
+ *
+ * You are given a 2D array moveTime of size n x m, where moveTime[i][j] represents the minimum
+ * time in seconds when you can start moving to that room. You start from the room (0, 0) at
+ * time t = 0 and can move to an adjacent room. Moving between adjacent rooms takes exactly
+ * one second.
+ *
+ * Return the minimum time to reach the room (n - 1, m - 1).
+ *
+ * Two rooms are adjacent if they share a common wall, either horizontally or vertically.
+ */
+
+/**
+ * @param {number[][]} moveTime
+ * @return {number}
+ */
+var minTimeToReach = function(moveTime) {
+  const rows = moveTime.length;
+  const cols = moveTime[0].length;
+  const distances = Array.from({ length: rows }, () => new Array(cols).fill(Infinity));
+  const pq = new PriorityQueue((a, b) => a[0] - b[0]);
+  pq.enqueue([0, 0, 0]);
+  const directions = [[0, 1], [1, 0], [0, -1], [-1, 0]];
+
+  distances[0][0] = 0;
+
+  while (!pq.isEmpty()) {
+    const [time, row, col] = pq.dequeue();
+
+    if (row === rows - 1 && col === cols - 1) return time;
+
+    if (time > distances[row][col]) continue;
+
+    for (const [dr, dc] of directions) {
+      const newRow = row + dr;
+      const newCol = col + dc;
+
+      if (newRow < 0 || newRow >= rows || newCol < 0 || newCol >= cols) continue;
+
+      const newTime = Math.max(time, moveTime[newRow][newCol]) + 1;
+
+      if (newTime < distances[newRow][newCol]) {
+        distances[newRow][newCol] = newTime;
+        pq.enqueue([newTime, newRow, newCol]);
+      }
+    }
+  }
+
+  return distances[rows - 1][cols - 1];
+};
diff --git a/solutions/3342-find-minimum-time-to-reach-last-room-ii.js b/solutions/3342-find-minimum-time-to-reach-last-room-ii.js
new file mode 100644
index 00000000..24c9fc5a
--- /dev/null
+++ b/solutions/3342-find-minimum-time-to-reach-last-room-ii.js
@@ -0,0 +1,57 @@
+/**
+ * 3342. Find Minimum Time to Reach Last Room II
+ * https://leetcode.com/problems/find-minimum-time-to-reach-last-room-ii/
+ * Difficulty: Medium
+ *
+ * There is a dungeon with n x m rooms arranged as a grid.
+ *
+ * You are given a 2D array moveTime of size n x m, where moveTime[i][j] represents the minimum
+ * time in seconds when you can start moving to that room. You start from the room (0, 0) at
+ * time t = 0 and can move to an adjacent room. Moving between adjacent rooms takes one
+ * second for one move and two seconds for the next, alternating between the two.
+ *
+ * Return the minimum time to reach the room (n - 1, m - 1).
+ *
+ * Two rooms are adjacent if they share a common wall, either horizontally or vertically.
+ */
+
+/**
+ * @param {number[][]} moveTime
+ * @return {number}
+ */
+var minTimeToReach = function(moveTime) {
+  const rows = moveTime.length;
+  const cols = moveTime[0].length;
+  const distances = Array.from({ length: rows }, () => new Array(cols).fill(Infinity));
+  const pq = new PriorityQueue((a, b) => a[0] - b[0]);
+  pq.enqueue([0, 0, 0, 0]);
+  const directions = [[0, 1], [1, 0], [0, -1], [-1, 0]];
+
+  distances[0][0] = 0;
+
+  while (!pq.isEmpty()) {
+    const [time, row, col, moveCount] = pq.dequeue();
+
+    if (row === rows - 1 && col === cols - 1) return time;
+
+    if (time > distances[row][col]) continue;
+
+    for (const [dr, dc] of directions) {
+      const newRow = row + dr;
+      const newCol = col + dc;
+
+      if (newRow < 0 || newRow >= rows || newCol < 0 || newCol >= cols) continue;
+
+      const moveCost = moveCount % 2 === 0 ? 1 : 2;
+      const startTime = Math.max(time, moveTime[newRow][newCol]);
+      const newTime = startTime + moveCost;
+
+      if (newTime < distances[newRow][newCol]) {
+        distances[newRow][newCol] = newTime;
+        pq.enqueue([newTime, newRow, newCol, moveCount + 1]);
+      }
+    }
+  }
+
+  return distances[rows - 1][cols - 1];
+};
diff --git a/solutions/3343-count-number-of-balanced-permutations.js b/solutions/3343-count-number-of-balanced-permutations.js
new file mode 100644
index 00000000..0e27eae1
--- /dev/null
+++ b/solutions/3343-count-number-of-balanced-permutations.js
@@ -0,0 +1,70 @@
+/**
+ * 3343. Count Number of Balanced Permutations
+ * https://leetcode.com/problems/count-number-of-balanced-permutations/
+ * Difficulty: Hard
+ *
+ * You are given a string num. A string of digits is called balanced if the sum of the digits
+ * at even indices is equal to the sum of the digits at odd indices.
+ *
+ * Return the number of distinct permutations of num that are balanced.
+ *
+ * Since the answer may be very large, return it modulo 109 + 7.
+ *
+ * A permutation is a rearrangement of all the characters of a string.
+ */
+
+/**
+ * @param {string} num
+ * @return {number}
+ */
+var countBalancedPermutations = function(num) {
+  const MOD = 1e9 + 7;
+  const n = num.length;
+  const digitCounts = new Array(10).fill(0);
+  let totalSum = 0;
+
+  for (const char of num) {
+    const digit = parseInt(char);
+    digitCounts[digit]++;
+    totalSum += digit;
+  }
+
+  if (totalSum % 2) return 0;
+
+  const memo = new Map();
+
+  function combination(n, r) {
+    if (r > n) return 0;
+    if (r === 0 || r === n) return 1;
+    if (r > n - r) r = n - r;
+
+    let result = 1n;
+    for (let i = 0; i < r; i++) {
+      result = result * BigInt(n - i) / BigInt(i + 1);
+    }
+    return Number(result % BigInt(MOD));
+  }
+
+  function exploreDigits(digit, oddSlots, evenSlots, targetBalance) {
+    if (oddSlots === 0 && evenSlots === 0 && targetBalance === 0) return 1;
+    if (digit < 0 || oddSlots < 0 || evenSlots < 0 || targetBalance < 0) return 0;
+
+    const key = `${digit},${oddSlots},${evenSlots},${targetBalance}`;
+    if (memo.has(key)) return memo.get(key);
+
+    let result = 0;
+    for (let oddCount = 0; oddCount <= digitCounts[digit]; oddCount++) {
+      const evenCount = digitCounts[digit] - oddCount;
+      const ways = (BigInt(combination(oddSlots, oddCount))
+        * BigInt(combination(evenSlots, evenCount))) % BigInt(MOD);
+      const next = BigInt(exploreDigits(digit - 1, oddSlots - oddCount,
+        evenSlots - evenCount, targetBalance - digit * oddCount));
+      result = (result + Number((ways * next) % BigInt(MOD))) % MOD;
+    }
+
+    memo.set(key, result);
+    return result;
+  }
+
+  return exploreDigits(9, n - Math.floor(n / 2), Math.floor(n / 2), totalSum / 2);
+};
diff --git a/solutions/3355-zero-array-transformation-i.js b/solutions/3355-zero-array-transformation-i.js
new file mode 100644
index 00000000..21b9bc13
--- /dev/null
+++ b/solutions/3355-zero-array-transformation-i.js
@@ -0,0 +1,43 @@
+/**
+ * 3355. Zero Array Transformation I
+ * https://leetcode.com/problems/zero-array-transformation-i/
+ * Difficulty: Medium
+ *
+ * You are given an integer array nums of length n and a 2D array queries, where
+ * queries[i] = [li, ri].
+ *
+ * For each queries[i]:
+ * - Select a subset of indices within the range [li, ri] in nums.
+ * - Decrement the values at the selected indices by 1.
+ *
+ * A Zero Array is an array where all elements are equal to 0.
+ *
+ * Return true if it is possible to transform nums into a Zero Array after processing all the
+ * queries sequentially, otherwise return false.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number[][]} queries
+ * @return {boolean}
+ */
+var isZeroArray = function(nums, queries) {
+  const maxDecrements = new Array(nums.length).fill(0);
+
+  for (const [left, right] of queries) {
+    maxDecrements[left]++;
+    if (right + 1 < nums.length) {
+      maxDecrements[right + 1]--;
+    }
+  }
+
+  let currentDecrements = 0;
+  for (let i = 0; i < nums.length; i++) {
+    currentDecrements += maxDecrements[i];
+    if (nums[i] > currentDecrements) {
+      return false;
+    }
+  }
+
+  return true;
+};
diff --git a/solutions/3362-zero-array-transformation-iii.js b/solutions/3362-zero-array-transformation-iii.js
new file mode 100644
index 00000000..f6d979bb
--- /dev/null
+++ b/solutions/3362-zero-array-transformation-iii.js
@@ -0,0 +1,53 @@
+/**
+ * 3362. Zero Array Transformation III
+ * https://leetcode.com/problems/zero-array-transformation-iii/
+ * Difficulty: Medium
+ *
+ * You are given an integer array nums of length n and a 2D array queries where
+ * queries[i] = [li, ri].
+ *
+ * Each queries[i] represents the following action on nums:
+ * - Decrement the value at each index in the range [li, ri] in nums by at most 1.
+ * - The amount by which the value is decremented can be chosen independently for each index.
+ *
+ * A Zero Array is an array with all its elements equal to 0.
+ *
+ * Return the maximum number of elements that can be removed from queries, such that nums can
+ * still be converted to a zero array using the remaining queries. If it is not possible to
+ * convert nums to a zero array, return -1.
+ */
+
+/**
+ * @param {number[]} nums
+ * @param {number[][]} queries
+ * @return {number}
+ */
+var maxRemoval = function(nums, queries) {
+  queries.sort((a, b) => a[0] - b[0]);
+  const endIndexHeap = new MaxPriorityQueue();
+  const expiredQueries = new Array(nums.length + 1).fill(0);
+  let operationCount = 0;
+  let queryIndex = 0;
+
+  for (let numIndex = 0; numIndex < nums.length; numIndex++) {
+    operationCount -= expiredQueries[numIndex];
+
+    while (queryIndex < queries.length && queries[queryIndex][0] === numIndex) {
+      endIndexHeap.push(queries[queryIndex][1]);
+      queryIndex++;
+    }
+
+    while (
+      operationCount < nums[numIndex] && !endIndexHeap.isEmpty() && endIndexHeap.front() >= numIndex
+    ) {
+      operationCount++;
+      expiredQueries[endIndexHeap.pop() + 1]++;
+    }
+
+    if (operationCount < nums[numIndex]) {
+      return -1;
+    }
+  }
+
+  return endIndexHeap.size();
+};
diff --git a/solutions/3372-maximize-the-number-of-target-nodes-after-connecting-trees-i.js b/solutions/3372-maximize-the-number-of-target-nodes-after-connecting-trees-i.js
new file mode 100644
index 00000000..c4ce5f98
--- /dev/null
+++ b/solutions/3372-maximize-the-number-of-target-nodes-after-connecting-trees-i.js
@@ -0,0 +1,87 @@
+/**
+ * 3372. Maximize the Number of Target Nodes After Connecting Trees I
+ * https://leetcode.com/problems/maximize-the-number-of-target-nodes-after-connecting-trees-i/
+ * Difficulty: Medium
+ *
+ * There exist two undirected trees with n and m nodes, with distinct labels in ranges [0, n - 1]
+ * and [0, m - 1], respectively.
+ *
+ * You are given two 2D integer arrays edges1 and edges2 of lengths n - 1 and m - 1, respectively,
+ * where edges1[i] = [ai, bi] indicates that there is an edge between nodes ai and bi in the first
+ * tree and edges2[i] = [ui, vi] indicates that there is an edge between nodes ui and vi in the
+ * second tree. You are also given an integer k.
+ *
+ * Node u is target to node v if the number of edges on the path from u to v is less than or equal
+ * to k. Note that a node is always target to itself.
+ *
+ * Return an array of n integers answer, where answer[i] is the maximum possible number of nodes
+ * target to node i of the first tree if you have to connect one node from the first tree to
+ * another node in the second tree.
+ *
+ * Note that queries are independent from each other. That is, for every query you will remove
+ * the added edge before proceeding to the next query.
+ */
+
+/**
+ * @param {number[][]} edges1
+ * @param {number[][]} edges2
+ * @param {number} k
+ * @return {number[]}
+ */
+var maxTargetNodes = function(edges1, edges2, k) {
+  const graph1 = buildGraph(edges1);
+  const graph2 = buildGraph(edges2);
+  const n = edges1.length + 1;
+  const m = edges2.length + 1;
+
+  let tree2Max = 0;
+  if (k > 0) {
+    tree2Max = Math.max(...Array.from({ length: m }, (_, i) =>
+      countReachable(graph2, i, k - 1)
+    ));
+  }
+
+  const result = [];
+  for (let i = 0; i < n; i++) {
+    const tree1Count = countReachable(graph1, i, k);
+    result.push(tree1Count + tree2Max);
+  }
+
+  return result;
+
+  function buildGraph(edges) {
+    const graph = {};
+    for (const [u, v] of edges) {
+      if (!graph[u]) graph[u] = [];
+      if (!graph[v]) graph[v] = [];
+      graph[u].push(v);
+      graph[v].push(u);
+    }
+    return graph;
+  }
+
+  function countReachable(graph, start, maxDist) {
+    const queue = [start];
+    const visited = new Set([start]);
+    let count = 1;
+    let dist = 0;
+
+    while (queue.length > 0 && dist < maxDist) {
+      const size = queue.length;
+      dist++;
+      for (let i = 0; i < size; i++) {
+        const node = queue.shift();
+        if (graph[node]) {
+          for (const neighbor of graph[node]) {
+            if (!visited.has(neighbor)) {
+              visited.add(neighbor);
+              queue.push(neighbor);
+              count++;
+            }
+          }
+        }
+      }
+    }
+    return count;
+  }
+};
diff --git a/solutions/3373-maximize-the-number-of-target-nodes-after-connecting-trees-ii.js b/solutions/3373-maximize-the-number-of-target-nodes-after-connecting-trees-ii.js
new file mode 100644
index 00000000..8ac956f1
--- /dev/null
+++ b/solutions/3373-maximize-the-number-of-target-nodes-after-connecting-trees-ii.js
@@ -0,0 +1,79 @@
+/**
+ * 3373. Maximize the Number of Target Nodes After Connecting Trees II
+ * https://leetcode.com/problems/maximize-the-number-of-target-nodes-after-connecting-trees-ii/
+ * Difficulty: Hard
+ *
+ * There exist two undirected trees with n and m nodes, labeled from [0, n - 1] and [0, m - 1],
+ * respectively.
+ *
+ * You are given two 2D integer arrays edges1 and edges2 of lengths n - 1 and m - 1, respectively,
+ * where edges1[i] = [ai, bi] indicates that there is an edge between nodes ai and bi in the first
+ * tree and edges2[i] = [ui, vi] indicates that there is an edge between nodes ui and vi in the
+ * second tree.
+ *
+ * Node u is target to node v if the number of edges on the path from u to v is even. Note that
+ * a node is always target to itself.
+ *
+ * Return an array of n integers answer, where answer[i] is the maximum possible number of nodes
+ * that are target to node i of the first tree if you had to connect one node from the first tree
+ * to another node in the second tree.
+ *
+ * Note that queries are independent from each other. That is, for every query you will remove the
+ * added edge before proceeding to the next query.
+ */
+
+/**
+ * @param {number[][]} edges1
+ * @param {number[][]} edges2
+ * @return {number[]}
+ */
+var maxTargetNodes = function(edges1, edges2) {
+  const graph1 = buildGraph(edges1);
+  const graph2 = buildGraph(edges2);
+  const n = graph1.length;
+  const { color: color1 } = getBipartiteGroups(graph1);
+  const { maxGroup: maxGroup2 } = getBipartiteGroups(graph2);
+  const group0Count = color1.filter(c => c === 0).length;
+  const group1Count = n - group0Count;
+  const result = new Array(n);
+
+  for (let i = 0; i < n; i++) {
+    result[i] = (color1[i] === 0 ? group0Count : group1Count) + maxGroup2;
+  }
+
+  return result;
+
+  function buildGraph(edges) {
+    const n = edges.length + 1;
+    const graph = Array.from({ length: n }, () => []);
+    for (const [u, v] of edges) {
+      graph[u].push(v);
+      graph[v].push(u);
+    }
+    return graph;
+  }
+
+  function getBipartiteGroups(graph) {
+    const n = graph.length;
+    const color = new Array(n).fill(-1);
+    const groups = [0, 0];
+
+    for (let i = 0; i < n; i++) {
+      if (color[i] === -1) {
+        dfs(i, 0);
+      }
+    }
+
+    return { color, maxGroup: Math.max(groups[0], groups[1]) };
+
+    function dfs(node, c) {
+      color[node] = c;
+      groups[c]++;
+      for (const neighbor of graph[node]) {
+        if (color[neighbor] === -1) {
+          dfs(neighbor, 1 - c);
+        }
+      }
+    }
+  }
+};
diff --git a/solutions/3403-find-the-lexicographically-largest-string-from-the-box-i.js b/solutions/3403-find-the-lexicographically-largest-string-from-the-box-i.js
new file mode 100644
index 00000000..313bc4c7
--- /dev/null
+++ b/solutions/3403-find-the-lexicographically-largest-string-from-the-box-i.js
@@ -0,0 +1,39 @@
+/**
+ * 3403. Find the Lexicographically Largest String From the Box I
+ * https://leetcode.com/problems/find-the-lexicographically-largest-string-from-the-box-i/
+ * Difficulty: Medium
+ *
+ * You are given a string word, and an integer numFriends.
+ *
+ * Alice is organizing a game for her numFriends friends. There are multiple rounds in the game,
+ * where in each round:
+ * - word is split into numFriends non-empty strings, such that no previous round has had the
+ *   exact same split.
+ * - All the split words are put into a box.
+ *
+ * Find the lexicographically largest string from the box after all the rounds are finished.
+ */
+
+/**
+ * @param {string} word
+ * @param {number} numFriends
+ * @return {string}
+ */
+var answerString = function(word, numFriends) {
+  if (numFriends === 1) return word;
+
+  let result = '';
+  const wordLength = word.length;
+
+  for (let startIndex = 0; startIndex < wordLength; startIndex++) {
+    const maxLength = wordLength - numFriends + 1;
+    const endIndex = Math.min(startIndex + maxLength, wordLength);
+    const substring = word.slice(startIndex, endIndex);
+
+    if (substring > result) {
+      result = substring;
+    }
+  }
+
+  return result;
+};
diff --git a/solutions/3423-maximum-difference-between-adjacent-elements-in-a-circular-array.js b/solutions/3423-maximum-difference-between-adjacent-elements-in-a-circular-array.js
new file mode 100644
index 00000000..dae3e36c
--- /dev/null
+++ b/solutions/3423-maximum-difference-between-adjacent-elements-in-a-circular-array.js
@@ -0,0 +1,25 @@
+/**
+ * 3423. Maximum Difference Between Adjacent Elements in a Circular Array
+ * https://leetcode.com/problems/maximum-difference-between-adjacent-elements-in-a-circular-array/
+ * Difficulty: Easy
+ *
+ * Given a circular array nums, find the maximum absolute difference between adjacent elements.
+ *
+ * Note: In a circular array, the first and last elements are adjacent.
+ */
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var maxAdjacentDistance = function(nums) {
+  let result = 0;
+
+  for (let i = 0; i < nums.length; i++) {
+    const next = (i + 1) % nums.length;
+    const diff = Math.abs(nums[i] - nums[next]);
+    result = Math.max(result, diff);
+  }
+
+  return result;
+};
diff --git a/solutions/3442-maximum-difference-between-even-and-odd-frequency-i.js b/solutions/3442-maximum-difference-between-even-and-odd-frequency-i.js
new file mode 100644
index 00000000..313d3fb5
--- /dev/null
+++ b/solutions/3442-maximum-difference-between-even-and-odd-frequency-i.js
@@ -0,0 +1,39 @@
+/**
+ * 3442. Maximum Difference Between Even and Odd Frequency I
+ * https://leetcode.com/problems/maximum-difference-between-even-and-odd-frequency-i/
+ * Difficulty: Easy
+ *
+ * You are given a string s consisting of lowercase English letters.
+ *
+ * Your task is to find the maximum difference diff = freq(a1) - freq(a2) between the frequency
+ * of characters a1 and a2 in the string such that:
+ * - a1 has an odd frequency in the string.
+ * - a2 has an even frequency in the string.
+ *
+ * Return this maximum difference.
+ */
+
+/**
+ * @param {string} s
+ * @return {number}
+ */
+var maxDifference = function(s) {
+  const map = new Map();
+
+  for (const char of s) {
+    map.set(char, (map.get(char) || 0) + 1);
+  }
+
+  let maxOdd = 0;
+  let minEven = Infinity;
+
+  for (const freq of map.values()) {
+    if (freq % 2 === 1) {
+      maxOdd = Math.max(maxOdd, freq);
+    } else {
+      minEven = Math.min(minEven, freq);
+    }
+  }
+
+  return maxOdd - minEven;
+};
diff --git a/solutions/3445-maximum-difference-between-even-and-odd-frequency-ii.js b/solutions/3445-maximum-difference-between-even-and-odd-frequency-ii.js
new file mode 100644
index 00000000..3648091e
--- /dev/null
+++ b/solutions/3445-maximum-difference-between-even-and-odd-frequency-ii.js
@@ -0,0 +1,70 @@
+/**
+ * 3445. Maximum Difference Between Even and Odd Frequency II
+ * https://leetcode.com/problems/maximum-difference-between-even-and-odd-frequency-ii/
+ * Difficulty: Hard
+ *
+ * You are given a string s and an integer k. Your task is to find the maximum difference between
+ * the frequency of two characters, freq[a] - freq[b], in a substring subs of s, such that:
+ * - subs has a size of at least k.
+ * - Character a has an odd frequency in subs.
+ * - Character b has an even frequency in subs.
+ *
+ * Return the maximum difference.
+ *
+ * Note that subs can contain more than 2 distinct characters.
+ */
+
+/**
+ * @param {string} s
+ * @param {number} k
+ * @return {number}
+ */
+var maxDifference = function(s, k) {
+  const n = s.length;
+  let result = -Infinity;
+
+  const calculateParityStatus = (freqA, freqB) => {
+    return ((freqA & 1) << 1) | (freqB & 1);
+  };
+
+  for (const charA of ['0', '1', '2', '3', '4']) {
+    for (const charB of ['0', '1', '2', '3', '4']) {
+      if (charA === charB) continue;
+
+      const minDifferences = [Infinity, Infinity, Infinity, Infinity];
+      let currentFreqA = 0;
+      let currentFreqB = 0;
+      let prefixFreqA = 0;
+      let prefixFreqB = 0;
+      let leftBoundary = -1;
+
+      for (let rightIndex = 0; rightIndex < n; rightIndex++) {
+        currentFreqA += s[rightIndex] === charA ? 1 : 0;
+        currentFreqB += s[rightIndex] === charB ? 1 : 0;
+
+        while (rightIndex - leftBoundary >= k && currentFreqB - prefixFreqB >= 2) {
+          const prefixStatus = calculateParityStatus(prefixFreqA, prefixFreqB);
+          minDifferences[prefixStatus] = Math.min(
+            minDifferences[prefixStatus],
+            prefixFreqA - prefixFreqB
+          );
+          leftBoundary++;
+          prefixFreqA += s[leftBoundary] === charA ? 1 : 0;
+          prefixFreqB += s[leftBoundary] === charB ? 1 : 0;
+        }
+
+        const currentStatus = calculateParityStatus(currentFreqA, currentFreqB);
+        const targetStatus = currentStatus ^ 0b10;
+
+        if (minDifferences[targetStatus] !== Infinity) {
+          result = Math.max(
+            result,
+            currentFreqA - currentFreqB - minDifferences[targetStatus]
+          );
+        }
+      }
+    }
+  }
+
+  return result;
+};