diff --git a/README.md b/README.md index 13c33f3c..447e564d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# 1,785 LeetCode solutions in JavaScript +# 2,000+ LeetCode solutions in JavaScript [https://leetcodejavascript.com](https://leetcodejavascript.com) @@ -1656,51 +1656,269 @@ 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| 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| +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| +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| +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| +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| 2579|[Count Total Number of Colored Cells](./solutions/2579-count-total-number-of-colored-cells.js)|Medium| 2594|[Minimum Time to Repair Cars](./solutions/2594-minimum-time-to-repair-cars.js)|Medium| @@ -1755,13 +1973,18 @@ 2845|[Count of Interesting Subarrays](./solutions/2845-count-of-interesting-subarrays.js)|Medium| 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| +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| 2918|[Minimum Equal Sum of Two Arrays After Replacing Zeros](./solutions/2918-minimum-equal-sum-of-two-arrays-after-replacing-zeros.js)|Medium| +2942|[Find Words Containing Character](./solutions/2942-find-words-containing-character.js)|Easy| 2948|[Make Lexicographically Smallest Array by Swapping Elements](./solutions/2948-make-lexicographically-smallest-array-by-swapping-elements.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| 2965|[Find Missing and Repeated Values](./solutions/2965-find-missing-and-repeated-values.js)|Easy| 2999|[Count the Number of Powerful Integers](./solutions/2999-count-the-number-of-powerful-integers.js)|Hard| +3024|[Type of Triangle](./solutions/3024-type-of-triangle.js)|Easy| 3042|[Count Prefix and Suffix Pairs I](./solutions/3042-count-prefix-and-suffix-pairs-i.js)|Easy| 3066|[Minimum Operations to Exceed Threshold Value II](./solutions/3066-minimum-operations-to-exceed-threshold-value-ii.js)|Medium| +3068|[Find the Maximum Sum of Node Values](./solutions/3068-find-the-maximum-sum-of-node-values.js)|Hard| 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| @@ -1779,7 +2002,9 @@ 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| 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| 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/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/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/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/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/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/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/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/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/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/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(); +};